Shift + Alt + ←/→ 仅横向扩展列选区域,固定行区间、动态调整列边界,自动补空格维持矩形;Shift + Alt + ↑/↓ 仅纵向裁剪行区间,不改变列位置;需开启 columnSelection 且注意 macOS 系统快捷键冲突。

列选区域横向扩展:Shift + Alt + ←/→ 为什么只动列不动行
列选择模式下,Shift + Alt + ← 或 Shift + Alt + → 是唯一能左右调整矩形选区宽度的快捷键。它不改变起始行和结束行,只增减列范围——比如你选中了第3–5列,按一次 → 就变成第3–6列,再按一次变成第3–7列。
这个行为本质是「固定行区间、动态列边界」:VSCode 把当前列选区域抽象为 [startLine, endLine, startColumn, endColumn] 四元组,左右键只修改后两个值。如果你在某行末尾(比如第80列)按 →,该行会自动补空格以维持矩形形状;但其他行不会因此换行或缩进。
- 横向扩展时,所有被覆盖行都会强制对齐到新列边界,空格自动填充(不可禁用)
- 如果某行实际长度短于目标列号,VSCode 会在该行末尾插入空格,确保矩形闭合
-
←键收缩时,不会删已有空格——只缩小选区范围,已有内容不受影响
纵向收缩:Shift + Alt + ↑/↓ 实际触发的是“行区间裁剪”
Shift + Alt + ↑ 和 Shift + Alt + ↓ 看似在“移动光标”,实则是在重新定义列选区域的上下边界。假设你原本选中第2–6行,按一次 ↑ 后变为第2–5行,再按一次变为第2–4行——不是光标上移,而是 endLine 值持续递减。
关键点在于:这个操作不依赖当前光标所在行,只读取列选区域的原始 startLine 和 endLine。哪怕你松开鼠标后把光标移到第10行,只要列选状态还在,↑/↓ 依然作用于最初划定的行区间。
- 纵向收缩不改变列位置,也不触发任何文本删除或插入
- 若收缩后
startLine == endLine,区域退化为单行列选,此时可直接输入覆盖该行指定列范围 - 一旦执行了任何编辑操作(如输入字符或按
Delete),列选状态自动退出,后续↑/↓就变成普通光标移动
Alt+拖拽与快捷键混用时的优先级冲突
当你先用 Alt + 鼠标拖拽 创建列选区域,再按 Shift + Alt + → 扩展列宽,VSCode 默认以鼠标拖拽的起始列为基准,向右扩展。但如果你中途松开 Alt 键,再按快捷键,就可能触发普通多光标行为(比如 Ctrl + Alt + ↓ 插入新光标),而非列选扩展。
- 列选状态下,必须保持
Alt(Windows/Linux)或Option(macOS)键按下才能使用Shift + Alt + 方向键 - 如果快捷键失效,先检查是否开启了
"editor.columnSelection": true——该配置关闭时,Alt + 拖拽会降级为普通多光标 - macOS 用户注意:
Option + Shift + 方向键在某些键盘布局下会被系统截获(如输入特殊符号),建议在系统设置中禁用「按下修饰键时显示特殊字符菜单」
列选区域边界越界时的静默处理逻辑
当用快捷键把列选区域扩展到某行实际长度之外(比如某行只有10个字符,却试图选中第15列),VSCode 不报错,也不中断操作,而是自动在该行末尾补空格,并将选区延伸过去。但这个补空行为仅限于当前编辑会话——保存文件时这些空格会真实写入。
- 横向越界补空格是“可见但不可见”的:你看到矩形框延伸出去了,但源码里那些空格只有在你输入内容或保存后才真正存在
- 纵向越界(比如选中第100行,但文件只有50行)不会自动添加空行,
↓键在最后一行就停止响应 - 最易忽略的一点:列选区域一旦跨过制表符(
\t),其列计算基于“可视位置”而非字节偏移——一个\t可能占4列或8列,取决于编辑器设置的 tabSize,这会导致鼠标拖拽和快捷键扩展结果不一致


















