files.trimtrailingwhitespace 设为 true 后,保存时自动删除每行末尾空格和制表符(含空行内空格),但不删空行、行首/行中空白;需写入项目级 .vscode/settings.json,避免被语言配置或 .editorconfig 覆盖。

files.trimTrailingWhitespace 开启即生效,无需插件、不依赖 Prettier 或 ESLint,保存时自动删每行末尾空格和制表符(含空行内的空格),但不会动空行本身或行中/行首空白。
怎么配才真起作用
这个配置默认是 false,必须显式设为 true,且推荐写进项目根目录的 .vscode/settings.json 中:
- 只改用户级设置 → 别人 clone 代码后 Git diff 里全是空格变更,协作灾难
- 已存在
.vscode/settings.json→ 检查有没有某处写了"files.trimTrailingWhitespace": false,比如语言专属块"[markdown]"会覆盖全局 - 右下角状态栏语言 ID 是
plaintext而不是javascript→ 语言级配置压根没加载,files.trimTrailingWhitespace不触发
为什么保存了空格还在
不是配置没写对,而是被更高优先级机制拦截了:
- 文件是只读的(Git LFS 锁定、权限受限、被其他进程占用)→ VSCode 根本不执行 trim
- 光标焦点不在编辑器内(停在终端、搜索框或侧边栏)→
Ctrl+S实际没触发文件保存 - 项目根目录有
.editorconfig,且写了trim_trailing_whitespace = false→ EditorConfig 插件会强制关掉 VSCode 行为 - 当前语言模式(如
makefile、shellscript)在 VSCode 内置逻辑中默认禁用 → 需单独加语言级配置:"[makefile]": {"files.trimTrailingWhitespace": true}
files.trimTrailingWhitespace 到底删什么、不删什么
它名字很老实:只删“尾随空白字符”,即每行末尾的空格、\t、\r,包括空行里的空格;但绝不碰换行符本身:
- 一行末尾有 5 个空格 → 保存后变成纯内容 + 原换行符
- 一行只有 3 个空格 → 保存后变成空行(只剩一个
\n) - 一行本来就是纯
\n(干净空行)→ 完全不动,仍保留为单个换行 - 行首或行中空格(如
let x = 1;中的空格)→ 一概不管
要不要和 editor.formatOnSave 一起开
可以,但得清楚顺序和风险:
- 执行顺序固定:先调用格式化器(Prettier/ESLint)→ 再执行
files.trimTrailingWhitespace - 如果格式化器输出带空格,VSCode 还会再扫一遍;但如果它重排 import 并插入新空行,后续 trim 可能破坏结构意图
- 真正统一控制建议关掉
editor.formatOnSave,只留原生三件套:files.trimTrailingWhitespace+files.trimFinalNewlines+files.insertFinalNewline
最常被忽略的是空行里的空格——它会被删,但空行本身还在;而文件末尾连续多个换行符,得靠 files.trimFinalNewlines 单独处理。这两个开关不联动,必须各自确认开启且未被覆盖。











