sublime snippet 必须放在 packages/user/ 目录下、文件名带 .sublime-snippet 后缀、scope 与当前语法作用域严格匹配,三者缺一不可;其他路径、错误后缀或 scope 不符均导致失效。

Snippet 文件放错位置,按 Tab 就不会响
Sublime 只加载 Packages/User/ 目录下的 .sublime-snippet 文件,其他路径一律无效——桌面、项目根目录、Packages/MyPlugin/ 里存了也等于没写。
最稳妥做法:菜单栏选 Preferences → Browse Packages…,直接进入 User 文件夹新建文件。Windows/macOS/Linux 路径不同,但这个菜单永远指向对的位置。
- 文件名必须带
.sublime-snippet后缀(不是.snippet、.xml或隐藏的.txt) - 改完保存不用重启 Sublime,但若之前已有同名文件,得删掉旧的再试,否则可能触发旧内容
- 用系统搜索查
<tabtrigger>log</tabtrigger>,能快速揪出重复或残留的 snippet
scope 写错,JS 里输 log 就是不展开
Sublime 不看文件后缀,只认当前光标处的语法作用域(syntax scope)。你写的是 .js 文件,但右下角显示 Plain Text,那所有 <scope></scope> 都失效;Vue 的 <script></script> 块里 scope 很可能是 source.js.embedded.html,不是 source.js。
查真实 scope 的唯一可靠方式:Ctrl+Shift+P(Win/Linux)或 Cmd+Shift+P(macOS),输入 Developer: Show Scope Name,状态栏会显示完整链,比如 source.js meta.function.js,复制粘贴进 <scope></scope> 即可。
- 常用 scope 值(大小写敏感):
source.js(JS)、source.ts(TS)、text.html.basic(HTML)、source.css(CSS) - 多语言支持写法:
<scope>source.js,source.ts,source.jsx</scope>,逗号后不能有空格 - scope 留空 = 全局生效,但容易误触发,不推荐
content 里换行缩进乱码,或 $1 不跳转
<content></content> 必须用 包裹,否则 、<code>&、换行符会被 XML 解析器吃掉,导致片段静默失效或插入乱码。
占位符必须处于 CDATA 的顶层文本流中,不能嵌套在 XML 标签里(比如写在注释或属性值里),否则 $1 会变成字面量,光标根本不会跳过去。
- 跳转位编号必须连续:
$1、$2、$3,断号(比如只有$1和$3)会导致后续跳转失效 -
$0是最终光标位置,必须有且只能有一个 -
${1:default}表示默认值,Tab 跳过时保留default;${1:}表示留空;\$才能输出真实美元符号
想让 snippet 支持选中文本包裹,但总失败
包裹选中内容需要显式依赖 $SELECTION 变量,但它只在你**先选中文字**的前提下才生效——没选就按 Tab,$SELECTION 会变为空字符串,结果就是只插入前后模板,中间啥也没有。
常见错误是把 $SELECTION 和普通占位符混用,比如 <div class="${1:cls}">$SELECTION</div>,一旦没选中,就生成空 <div class="cls"></div>,而不是报错或提示。
- 安全写法:单独为包裹场景建一个 snippet,比如
wrap-div,并明确文档说明“请先选中内容” - 变量不支持嵌套:
${TM_FILENAME%.*}这类 Shell 截断语法直接失效,可用的只有$TM_FILENAME_BASE、$TM_FILEPATH等内置变量 - 同一变量多次出现(如
${1:name}在开头和结尾),首次输入后自动同步更新,这是唯一能实现“镜像编辑”的方式
Developer: Show Scope Name,再确认文件真在 User 目录下,最后检查 CDATA 和跳转编号。其余都是细节。











