1. 先把编辑器当成一门要打磨的手艺
我大概是在第三个项目上被 VS Code “教育”了一次。当时团队里有位老哥,同样的需求,他敲了三下键盘、两个命令面板动作就改完了十几个文件,我在旁边点鼠标点了两分钟,还漏了两处。那天之后我才意识到,编辑器这东西不是装上就能用的,它更像一把需要自己开刃的刀:出厂状态只是“能切”,真正好用要靠你按自己的手型去磨。
这篇东西想聊的就是 VS Code 里那些高频、常被忽略、但一旦上手就回不去的常用功能。它解决的核心问题很朴素——把重复劳动压缩成肌肉记忆,让注意力留给真正要思考的部分。内容会覆盖快捷键体系、配置分层、多光标与正则替换、代码片段、扩展选型、调试与任务配置、代码导航、版本控制集成,以及一堆踩过的坑。适合两类人看:刚装完编辑器还在用鼠标点菜单的新手,和用了两三年但总觉得自己“还差点意思”的中段选手。
我尽量按真实使用顺序来讲,不按菜单顺序讲。因为菜单是给探索用的,真实场景里没人会去翻“编辑→查找”。
2. 配置体系先搭对,后面全是顺水推舟
2.1 用户配置和工作区配置,分错了会很难受
VS Code 的配置分两层:用户级(User)和工作区级(Workspace)。用户级存在你自己的机器上,对所有项目生效;工作区级存在项目根目录的.vscode/settings.json里,跟着仓库走。
这条分界线很多人一开始就搞错。常见错误是把项目相关的路径、格式化规则、解释器路径全写进用户配置,结果换一个项目就报错,改半天才发现是全局配置在作祟。我的划分标准很粗暴:
| 配置类型 | 放用户级 | 放工作区级 |
|---|---|---|
| 字体、字号、行高、主题 | 是 | 否 |
| 自动保存、自动格式化开关 | 是(默认习惯) | 视项目而定 |
| 格式化器选择(index.html/black/prettier) | 否 | 是 |
| 语言解释器路径、SDK 版本 | 否 | 是 |
| 保存时执行的修复动作 | 视情况 | 建议是 |
| 文件排除规则(如排除构建产物) | 否 | 是 |
判断标准就一句话:换一台机器、换一个项目,这条配置还该不该一样?该一样就用户级,不该一样就工作区级。
顺带说,工作区配置文件一定要提交进仓库。团队里格式化规则不统一,代码评审里能吵出花——缩进两格还是四格、单引号双引号、行尾分号,这些本该由工具解决的问题不该占用人的精力。
2.2 一份可以直接抄的 settings.json
下面这份是我这几年沉淀下来的骨架,注释写明理由,能直接拿去改:
{ // 编辑器基础观感 "editor.fontSize": 15, "editor.lineHeight": 1.6, "editor.fontFamily": "'JetBrains Mono', 'Fira Code', Consolas, monospace", "editor.fontLigatures": true, "editor.renderWhitespace": "boundary", "editor.bracketPairColorization.enabled": true, "editor.guides.bracketPairs": "active", "editor.minimap.enabled": false, // 保存与格式化 "editor.formatOnSave": true, "editor.formatOnPaste": false, "files.autoSave": "onFocusChange", "files.trimTrailingWhitespace": true, "files.insertFinalNewline": true, // 搜索与文件树,排除噪音 "search.exclude": { "**/node_modules": true, "**/dist": true, "**/build": true, "**/.git": true, "**/__pycache__": true, "**/*.min.js": true }, "files.watcherExclude": { "**/node_modules/**": true, "**/dist/**": true, "**/.git/objects/**": true }, // 补全与建议 "editor.suggestSelection": "first", "editor.quickSuggestions": { "strings": true }, "editor.tabCompletion": "on", "editor.snippetSuggestions": "top", // 终端 "terminal.integrated.defaultProfile.windows": "PowerShell", "terminal.integrated.scrollback": 10000 }几个点值得单独说。
editor.minimap.enabled: false是我个人偏好,小屏笔记本上 minimap 占宽约 80~100px,视觉噪音大于收益。但如果你常在几千行的单文件里跳转,开着它当“导航缩略图”是合理的,取舍看你的屏幕宽度。
files.watcherExclude这一项很多人不写,写了才知道多重要。文件监听器在大型仓库上会吃掉相当可观的内存和 CPU,尤其是node_modules里成千上万的小文件。我见过一个两万文件的目录,不做排除时编辑器冷启动要十几秒,加上这一项之后回到两三秒。这个不是玄学,是监听句柄数量的直接差距。
editor.tabCompletion: "on"打开后,按 Tab 会接受补全建议,比按回车更顺手,因为手指不用离开主键区。
注意:
editor.formatOnSave只对已经配置了格式化器的语言生效。如果你打开保存自动格式化却没装对应格式化器,保存时不会有任何反应,也不会报错,很多人在这里困惑很久。先确认右下角语言模式旁有没有格式化器,再去排查别的原因。
2.3 配置同步与备份的正确姿势
配置同步功能官方是内置的,登录账号即可。但我更推荐另存一份到自己的私有仓库,理由有两条:一是同步历史上能回溯到具体时间点,改坏了一键回退;二是团队里要批量铺配置时,可以直接拉取。
我通常会同步这几样东西:settings.json、keybindings.json、snippets/目录,以及一份扩展清单。扩展清单可以这样导出:
code --list-extensions > extensions.txt换机器时批量安装:
cat extensions.txt | xargs -L 1 code --install-extensionWindows 下的 PowerShell 版本:
Get-Content extensions.txt | ForEach-Object { code --install-extension $_ }这个技巧救过我两次。一次是公司换发设备,一次是我手滑把用户目录清空。有清单在手,二十分钟就恢复到原来的手感,不用凭记忆一个个找扩展。
3. 快捷键:效率的第一层杠杆
3.1 真正需要形成肌肉记忆的十几组
快捷键不用背全表,那样性价比极低。我按“每天至少用十次”的标准筛出下面这些,建议一周练三五组,两周就能固化:
| 操作 | Windows / Linux | macOS | 说明 |
|---|---|---|---|
| 命令面板 | Ctrl+Shift+P | Cmd+Shift+P | 万能入口,忘快捷键就靠它 |
| 快速打开文件 | Ctrl+P | Cmd+P | 支持路径模糊匹配 |
| 全局搜索 | Ctrl+Shift+F | Cmd+Shift+F | 支持正则和文件过滤 |
| 当前文件替换 | Ctrl+H | Cmd+Option+F | 替换面板和查找面板共用 |
| 多光标加选 | Ctrl+D | Cmd+D | 选中下一个相同词 |
| 列选择 | Shift+Alt+拖拽 | Shift+Option+拖拽 | 竖着选一列 |
| 上下移动行 | Alt+↑ / ↓ | Option+↑ / ↓ | 不用剪切粘贴 |
| 复制行到下方 | Shift+Alt+↓ | Shift+Option+↓ | 写重复结构极快 |
| 删除当前行 | Ctrl+Shift+K | Cmd+Shift+K | 不用先选中 |
| 折叠/展开区域 | Ctrl+Shift+[ / ] | Cmd+Option+[ / ] | 读大文件必备 |
| 跳转到定义 | F12 | F12 | 或按住 Ctrl 点击 |
| 查找所有引用 | Shift+F12 | Shift+F12 | 重构前必看 |
| 重命名符号 | F2 | F2 | 语义级重命名,不是文本替换 |
| 打开终端 | Ctrl+` | Ctrl+` | 反引号那个键 |
| 切换侧边栏 | Ctrl+B | Cmd+B | 小屏省空间 |
| 分屏编辑 | Ctrl+\ | Cmd+\ | 左右对照看代码 |
| 跳转到指定行 | Ctrl+G | Ctrl+G | 报错行号直达 |
把这些整理成一个小卡片贴在显示器边上,比自己硬记有效。我当年就是把 Ctrl+D 和 Ctrl+Shift+L 写成便签贴了两周。
3.2 命令面板里藏着一大半功能
命令面板(Ctrl+Shift+P)是 VS Code 最被低估的入口。它不只是“找不到菜单在哪里时用”,还有几个玩法值得说:
输入>前缀是执行命令,去掉>前缀则是搜索文件。所以Ctrl+P之后直接输文件名,Ctrl+Shift+P之后输命令名,这两个本质上是一个交互,只是默认行为不同。
更实用的是命令面板里能直接改设置。输入settings会列出所有可切换项,比如输入format on save,回车就是切换这一项的开关,不用打开设置界面翻。我刚上手那会儿,一半的配置是这么改的。
还有一个动作叫Developer: Reload Window。扩展装完不生效、界面卡住、语言服务没起来,第一反应都应该是它。比重启编辑器快十倍,脚本环境也能保留。
3.3 自定义键位的判断原则
什么时候该自定义键位?我的原则是:只有当某个操作每天触发十次以上,且默认键位需要你抬手时才改。
举个我自己的例子。我习惯用Ctrl+Shift+O打开符号大纲,但默认这个组合在部分键盘布局上会和外部的输入法切换冲突。改法是在keybindings.json里覆盖:
[ { "key": "ctrl+alt+o", "command": "workbench.action.gotoSymbol", "when": "editorFocus" }, { "key": "ctrl+shift+k", "command": "-editor.action.deleteLines", "when": "editorTextFocus" } ]注意第二段那个减号前缀,它的含义是“取消默认绑定”。这个语法很多人不知道,想禁用默认键位时乱改,其实只要在命令前面加个-。
when子句也别忽略。不加条件的自定义键位会全局生效,包括在输入框里打字的时候,很容易出现“输着输着代码变了”的诡异问题。常见的条件有editorFocus、editorTextFocus、terminalFocus、inQuickOpen,写清楚能省掉一堆迷惑。
4. 编辑核心能力:多光标、正则、片段
4.1 多光标的三条路径
多光标是把重复劳动砍掉的最直接手段。它有三种触发方式,用途完全不同:
第一种,Ctrl+D逐个加选。光标停在某个词上,按一次选中它,按第二次选中下一个相同词。适合“只改这几处”的场景。如果选多了,Ctrl+U往回退一个,这个回退操作知道的人不多但很救命。
第二种,Alt+点击手动加点。想在哪里加就在哪里加,最自由,但手数多的时候累。适合改动点位置不规则的情况。
第三种,Ctrl+Shift+L全选当前词的所有出现。这个是重锤,一次全选。改完一次搞定,但如果文件里有同名变量在不同上下文里,容易改错。用它之前先按Ctrl+F2看一眼总数,心里有数。
列选择(Shift+Alt+拖拽)在改表格形式的配置、对齐的常量列表时特别好用。比如一批十六进制色值要从#RRGGBB改成#RRGGBBAA,竖着选一列直接补即可,不用逐行编辑。
注意:多光标模式下撤销是整体撤销的。也就是说你十个光标改完发现方向错了,一次
Ctrl+Z会回退全部十处,不会一处一处退。改大批量之前先存个档或者先提交,比事后后悔强。
4.2 正则查找替换:这才是真正的效率分水岭
Ctrl+H打开替换面板,点一下.*图标就进入正则模式。这一步开启之后,很多“看起来要写脚本”的活都能在编辑器里三分钟干完。
举几个真实用过的场景。
把下划线命名批量改成驼峰。匹配_([a-z]),替换为\U$1。这里$1是捕获组,\U表示转大写。这条在改老代码风格时救过我一整晚。
给一批函数调用加上前缀。匹配^(\s*)(foo\()替换成$1prefix_$2。^锚定行首、\s*吃掉缩进,这样不会破坏原有的层级。
去掉行尾多余的分号空格。匹配[;,\s]+$替换为空。注意这个一定要先在小范围试,因为如果文件里有模板字符串,可能会误伤。
把多行的键值对重排成单行。匹配(\w+):\s*("[^"]*"|\d+),替换为$1: $2,。这个在做配置迁移时非常高频。
搜索面板还有几个隐藏开关值得知道:Aa区分大小写、ab全词匹配、.*正则。三个开关的组合能大幅减少误匹配。另外,全局搜索(Ctrl+Shift+F)除了文本,还能用files to include和files to exclude做路径过滤,比如只在src/**/*.ts里找,排除*.test.ts。
4.3 代码片段:把个人习惯固化成模板
代码片段(Snippet)是我认为投入产出比最高的一项配置,但用的人远比想象中少。它的本质是给一段固定结构起个短名字,输入短名字按 Tab 展开。
配置入口是文件 → 首选项 → 配置用户代码片段,选语言或者选全局。下面是我常用的一个 Python 主函数入口片段:
{ "Main Guard": { "prefix": "main", "body": [ "def main() -> None:", " \"\"\"${1:入口说明}\"\"\"", " $0", "", "", "if __name__ == \"__main__\":", " main()" ], "description": "带类型注解的主函数骨架" } }$1、$2是制表位,按 Tab 会在它们之间跳转,$0是最终光标停的位置。${1:默认文字}是带默认值的制表位,展开后直接选中,直接打字就是替换。
同一个文件名还能放多个片段,prefix相同的会被合并到候选列表里。我建了一套自己的片段库,覆盖日志打印、异常捕获、单测骨架、HTTP 请求模板这几类。一年下来至少省了几百次复制粘贴。
一个小心得:片段的命名要短且不冲突。main、try、log、test这种两三字母的最舒服。如果 prefix 太长的像function-main-entry-guard,你打字的时间已经够手写一半了。
5. 扩展选型:少而精才是正道
5.1 判断一个扩展该不该装的三个问题
扩展商店里几万个插件,容易陷入“装了一堆、一个没用”的状态。我给自己定了三个筛选题:
第一,它解决的是高频问题还是低频问题?一年用两次的功能不值得占用启动时间和内存。比如某些特定框架的脚手架生成器,一年新建三个项目,手动做也行。
第二,它有没有语言服务以外的副作用?有些扩展会替换自带的语法解析,导致代码跳转变慢、悬浮提示变成一堆无关信息。装完发现体验变差,就该卸载。
第三,它是否活跃维护?一年没更新、issue 区堆满无人回复的,谨慎。尤其要注意和工作区信任机制配合的扩展,某些老扩展在新版本上会出现权限相关的问题。
按这个标准筛下来,我长期保留的扩展不超过十五个,剩下的都是按项目临时装、用完就禁用的。
5.2 我现在的分层清单
| 类别 | 典型用途 | 是否常驻 |
|---|---|---|
| 语言支持 | 各语言的语法高亮与语言服务 | 常驻(按需精简) |
| 格式化 | 统一代码风格 | 常驻 |
| 静态检查 | 提交前发现明显问题 | 常驻 |
| Git 增强 | 行内 blame、历史查看 | 常驻 |
| 路径补全 | 写 import 和文件引用 | 常驻 |
| 容器/远程开发 | 在隔离环境里编译验证 | 按项目 |
| 主题与图标 | 纯观感 | 看心情 |
| 框架专用工具 | 框架模板、脚手架 | 按项目,用完禁用 |
有几个使用要点值得单独提。
格式化器只留一个。如果同时装了多个能格式化同一语言的扩展,保存时可能互相覆盖,出现“保存两次结果不一样”的怪现象。解决办法是显式声明[python]这类语言级配置,写死editor.defaultFormatter,别靠默认选择。
静态检查要看清工作区信任状态。部分检查扩展在未受信任的工作区里不会执行,导致你以为它没生效。看一下状态栏有没有提示。
工作区推荐扩展清单值得维护。在.vscode/extensions.json里写recommendations数组,团队新人克隆仓库后会收到安装提示。这个小动作能减少大量“我这里跑不起来”的沟通成本:
{ "recommendations": [ "editorconfig.editorconfig", "esbenp.prettier-vscode", "dbaeumer.vscode-eslint" ], "unwantedRecommendations": [] }5.3 扩展拖慢启动时该怎么查
症状是冷启动变慢、输入有延迟、保存卡一两秒。排查顺序我一般是这样的:
第一步,看启动耗时。命令面板执行Developer: Startup Performance,会列出各个扩展的激活耗时。超过一千毫秒的扩展基本可以判定为慢源。
第二步,用扩展二分法。全部禁用,然后一半一半地开,二十个扩展最多五轮就能定位,比逐个试快得多。
第三步,注意那些“启动即激活”的扩展。很多扩展可以配置成按语言激活,不打开对应文件就不加载。这不是扩展本身的问题,是激活时机的问题。
注意:不要在排查性能问题时直接卸载扩展。先禁用,确认是它之后再决定卸不卸。因为有些扩展的配置存在同步空间里,卸了配置会一起丢,重装后要重新配一遍。
6. 把命令行搬进编辑器:任务与调试
6.1 tasks.json:常用命令的固定入口
tasks.json的意义是把“打开终端、切到目录、敲长命令”这套动作压成一个快捷键。写一次,后面天天用。
{ "version": "2.0.0", "tasks": [ { "label": "构建:开发模式", "type": "shell", "command": "npm run build:dev", "group": { "kind": "build", "isDefault": true }, "problemMatcher": ["$tsc"], "presentation": { "reveal": "always", "panel": "shared", "clear": true } }, { "label": "测试:单文件", "type": "shell", "command": "npm run test -- ${fileBasenameNoExtension}", "group": "test" } ] }group.isDefault: true的作用是让Ctrl+Shift+B直接跑这个任务,不用每次选。problemMatcher是关键项,它负责把命令输出里的错误解析成可点击的列表,配上之后输出面板里的报错能直接跳转到对应行。这个配置漏写的后果是任务能跑、但报错只能肉眼找。
${fileBasenameNoExtension}这类变量是内置的,含义是当前打开文件的文件名(不含扩展名)。同理还有${file}(完整路径)、${workspaceFolder}(工作区根)、${fileDirname}。用它们能让一个任务适配任意文件,而不是写死路径。
presentation.clear: true表示每次运行前清屏,长输出的任务打开它,日志会干净很多。
6.2 launch.json:调试不是只能靠打印
调试器配置看着吓人,其实常用的就那几个字段。下面是一个 Node 服务的例子:
{ "version": "0.2.0", "configurations": [ { "name": "启动服务并附加", "type": "node", "request": "launch", "program": "${workspaceFolder}/src/index.js", "env": { "NODE_ENV": "development" }, "console": "integratedTerminal", "restart": true, "skipFiles": ["<node_internals>/**"] } ] }request有launch和attach两种。前者是编辑器帮你起进程,后者是连到已经在跑的进程上。改代码后想快速重跑,launch更方便;调试容器里已经跑着的服务,用attach配端口号。
console: "integratedTerminal"这个设置我强烈建议加上。默认的调试控制台不支持交互输入,一旦程序需要读标准输入就会卡住。切到集成终端之后,输入输出都正常。
skipFiles是为了避免单步时误入依赖库代码。不加的话,按一下 F11 能跳进很深的地方,找回来要按半天。把node_modules和内置模块都跳掉,调试体验会干净很多。
条件断点也值得会用:在断点上右键,可以设“表达式成立时才停”,比如i === 500。循环里出问题的时候,比一直按继续强得多。
6.3 集成终端的几个实用点
终端是编辑器里用得最频繁的面板之一,有几个细节能明显改善体验。
分屏与分组。终端面板支持横向、纵向拆分。我习惯开三个:一个跑服务、一个跑命令、一个专门看日志。Ctrl+Shift+5是拆分快捷键。
命令历史跨会话保留。默认 shell 的历史是保留的,但在 Windows 上要确认 shell 配置文件路径正确,否则每次打开都是空的。
任务与终端互不干扰。任务是“跑完就结束”的,终端是“一直开着”的。不要用终端去跑长驻服务然后反复手工敲,把它写成任务,稳定得多。
滚动缓冲区大小。默认值在长时间跑日志时会截断,terminal.integrated.scrollback调大到一万行,翻日志时不会出现“前面没了”的窘境。这一项的代价是内存占用,但通常可以接受。
7. 代码阅读与导航:看懂比写快更重要
7.1 符号导航的三个层级
接手陌生项目时,大部分人第一反应是全局搜索,但其实有三个更快的入口。
文件级:Ctrl+P输入文件名。名字记不全也没关系,输几个特征字母做模糊匹配。比如userController输uc就能命中。
文件内:Ctrl+Shift+O打开符号列表。这个是我认为最被低估的功能。一个两千行的文件,打开符号列表输入几个字,直接跳到目标函数,比在文件里滚动快一个数量级。列表里带@前缀还能按类别过滤,函数、变量、类分开看。
项目级:Ctrl+T搜索全项目符号。不记得在哪个文件里,只记得函数名,用它最快。
7.2 引用查找和语义重命名
Shift+F12查找所有引用,这个动作应该成为改代码前的固定前置。我见过太多案例是“改了个函数名,忘了调用处”,结果线上报错。引用列表左侧会标出哪些是读、哪些是写,扫一眼就能判断影响面。
F2重命名是语义级的,不是文本替换。它会调用语言服务,只改真正的符号引用,不会误改字符串里的同名文字。这个差别太重要了——文本替换改一处名字,可能把日志文案、配置键名全带偏;语义重命名不会。
这里有个前提:语言服务正常工作时才有效。如果状态栏显示语言服务还在加载,或者项目太大索引没建完,F2 可能退化成文本替换。判断方法很简单,把光标放到一个变量上,看悬浮提示有没有类型信息。有,说明语义分析在跑;没有,就等一下再说。
7.3 折叠、面包屑与大纲的组合用法
读一个大文件,我一般按这个顺序:先看面包屑(顶部那行路径),知道自己在哪一层;再看大纲视图(侧边栏),看整体结构;最后用折叠把不关心的段收起来,只留正在改的部分。
折叠有个细节:Ctrl+K Ctrl+0是全部折叠,Ctrl+K Ctrl+J是全部展开,Ctrl+Shift+[是折叠当前区域。改完一块代码把其余部分折起来,屏幕上只剩二十行有效内容,专注度完全不一样。
面包屑支持点击跳转,也支持在符号之间前后跳。在层层嵌套的回调里迷路时,点面包屑往上一层就能出来,比按返回键可靠。
8. 版本控制集成:内置的就够用
8.1 侧边栏 Git 面板的实质用法
内置的 Git 面板很多人只用来点“提交”,其实它承担了三个更有价值的动作。
逐块暂存。改了一个文件的两处,但只想提交其中一处。在差异视图里选中那几行,右键“暂存所选范围”,就只提交这部分。这个能力在提交粒度上非常有用,能做到一个提交只做一件事。
行内历史。把光标放到某一行,看它的 blame 信息(需要装对应扩展或开启内置设置),能直接看到这行是哪次提交改的、改之前是什么。定位“这行为什么变成这样”时,比翻提交日志快得多。
提交信息与描述分离。提交框输入短标题,下面还有一行可以写详细描述。养成写清楚“为什么改”的习惯,半年后回来看会感谢自己。
8.2 冲突解决界面怎么读
冲突文件打开后会出现几个操作按钮:Accept Current、Accept Incoming、Accept Both、Compare Changes。新手最容易犯的错是见冲突就点“接受两者”,结果把两份代码拼在一起,语法都过不了。
我的处理顺序是:先点Compare Changes,左右分栏看清楚两边各自改了什么、为什么改;再决定保留哪边或者怎么合并。合并完一定要搜一下有没有残留的冲突标记,<<<<<<<、=======、>>>>>>>这三个符号漏一个就会编译失败。
一个实用技巧:先提交手头的工作再做合并。合并出问题时能一键回到合并前,不用看着一堆混乱的文件发愁。
8.3 差异视图的对比逻辑
差异视图默认是行级对比,但字符级差异会用深色标出来。看的时候先看标了颜色的那几处,往往改动就在那里,不用逐行扫。
还有一个容易被忽略的点:差异视图支持并排和行内两种模式。并排适合看整体,行内适合看单处细微改动。右上角切换按钮或者设置里可以改默认值。文件很长、改动很碎的时候,行内模式更省眼。
9. 常见问题速查与排查思路
9.1 高频问题对照表
| 现象 | 最可能的原因 | 处理动作 |
|---|---|---|
| 保存没自动格式化 | 未配置该语言的格式化器 | 检查右下角语言模式,显式指定defaultFormatter |
| 跳转到定义失效 | 语言服务未就绪或索引未完成 | 等待索引完成,或重载窗口 |
| 智能提示只剩关键字 | 语言服务崩溃或工作区过大 | 查看输出面板的语言服务日志 |
| 搜索搜不到文件内容 | 被search.exclude排除 | 检查设置里的排除规则 |
| 输入明显卡顿 | 大文件 + 高亮 + 检查器叠加 | 关闭该文件的语法检查,或拆分文件 |
| 终端中文显示乱码 | 编码不一致 | 终端配置里显式指定 UTF-8 |
| 扩展装了没反应 | 工作区信任限制或激活条件 | 查看扩展输出日志,确认激活时机 |
| Git 面板不显示改动 | 打开的不是仓库根目录,或忽略规则命中 | 确认目录层级,检查忽略文件 |
| 多光标撤销一次全退 | 撤销栈按操作整体记录 | 改大批量前先暂存或提交 |
| 保存后文件末尾多空行 | insertFinalNewline与格式化器冲突 | 二者取一,保持团队一致 |
9.2 排查的通用方法论
遇到“说不清原因”的问题,我有一套固定顺序,几乎每次都能定位:
第一步,重载窗口。命令面板执行Developer: Reload Window。这一下能解决大概三成的问题,成本极低,先做。
第二步,看输出面板。Ctrl+Shift+U打开输出,右上角下拉能选各个扩展和语言服务的日志。真正的原因九成在这里,只是大多数人没打开过。
第三步,二分禁用扩展。全禁,确认问题消失,然后一半一半地开。二十个扩展最多五轮,比逐个试快得多。
第四步,新建一个最小复现。空目录、单个文件、默认配置。如果新环境正常,问题就在你的配置或扩展;如果新环境也异常,那大概率是编辑器版本或环境依赖的问题。
第五步,看版本。更新之后突然出问题,先看更新日志里有没有相关改动。有些行为是官方有意调整的,不是 bug。
9.3 几个踩过才知道的坑
坑一:把项目专属的路径写进了用户设置。换项目后所有跳转变红。教训是配置分层一定要做对,项目相关的全部进工作区配置。
坑二:同时开了多个格式化扩展。保存两次结果不一样,改代码的时候还以为是自己的问题。现在我都显式写defaultFormatter,不留歧义。
坑三:在不信任的工作区里期待检查器工作。表现是扩展图标是灰的,命令也不报错,就是不干活。养成看状态栏的习惯。
坑四:用文本替换改函数名。结果日志模板、字典键名、注释里的同名词全被改了。后来一律用F2语义重命名,实在不能用才退回正则替换,而且必须先预览。
坑五:文件监听器拖垮编辑器。一个依赖目录几千个小文件,冷启动十几秒。加了files.watcherExclude之后恢复正常。这个坑值得写进每个项目的初始化清单。
提示:把上面这些坑写进团队的仓库说明文档,比口头传达有效得多。配置类问题一旦形成文档,重复提问能减少一大半。
10. 一些我自己磨出来的小习惯
最后聊几个不成体系但确实天天在用的做法。
给常用动作配一个统一的“改前快照”。无论是批量正则替换、语义重命名,还是多光标大改,动手前先按一次保存、提交一次,或者至少复制一份文件。这不是谨慎,是省时间——出错之后的重做成本远高于快照那两秒。
键盘和鼠标不要硬性二选一。有些场面鼠标就是快,比如在文件树里点几下进入深层目录,比如拖拽调整分屏大小。真正拖慢效率的是“该用键盘的地方用了鼠标”,不是鼠标本身。判断标准很简单:如果这个动作每天重复十次以上,就必须有键盘路径。
配置文件要定期清理。每季度看一次settings.json,把那些当初为某个项目加的、现在已经不需要的设置删掉。配置积累到两百行之后,找一条设置的时间比重新想一遍还长,反而不划算。
别为了“看起来专业”而装扩展。我见过配置里有五六个主题切换扩展、三个图标包、一堆状态栏装饰的,实际编辑效率一点没高。把时间花在多光标、正则替换、代码片段这三样上,收益比装二十个扩展大得多。
编辑器是给自己用的,不是给别人看的。那份配置长什么样不重要,重要的是你敲下第一个字符到代码跑起来之间,没有一次操作是多余的。我到现在还在改我的键位,每换一次键盘布局都会调一遍,这件事本来就没有终点。