atom不支持嵌套代码片段,仅支持联动占位符;典型写法为${2:$1}实现内容同步,需确保scope匹配、缩进正确、序号无误,且严禁$0置于首位。

嵌套代码片段在 Atom 中并不存在——只有联动占位符
Atom 的 snippet 机制不支持“嵌套片段”(比如一个 snippet 调用另一个 snippet),所谓“嵌套”实际是指在同一个 snippet 的 body 中,用变量引用实现内容联动。最典型的就是 ${2:$1} 这种写法:第二个位置自动填充第一个位置输入的内容。
常见错误是以为可以像 VS Code 那样用 $TM_SELECTED_TEXT 或嵌套 prefix 触发,但 Atom 没有这类动态上下文变量(除非装第三方插件,且稳定性差)。所有“嵌套感”都靠 $1、$2 和 ${n:m} 组合模拟。
-
${1:MyComponent}定义首个可编辑占位符,并带默认值 -
${2:$1}表示第二个位置初始值 = 第一个位置当前内容,且两者同步变更(改一处,另一处实时更新) - 不能写成
$2=$1或${2:${1}}—— Atom 解析失败,tab stop 失效 - 若需“多层联动”,例如组件名 → 文件名 → 导出名,得手动展开为
${1:Button}、${2:$1}、${3:$1},三者共用同一数字
scope 写错,联动就完全不生效
联动占位符只在 snippet 正确加载后才起作用。而加载的前提是 scope 匹配当前文件的真实 grammar scope —— 不是文件后缀,不是右下角显示名,而是光标所在位置的完整 scope 链。
执行 Ctrl+Shift+P → 输入 Editor: Log Cursor Scope,你会看到类似 source.js.jsx meta.function.js 的输出。这时如果 snippet 的 scope 只写了 '.source.js',它就不会激活。
- 正确写法是
'.source.js.jsx'(精准匹配),或['.source.js', '.source.js.jsx', '.source.tsx'](数组形式跨类型) - 别用
*测试——虽然能触发,但所有文件都加载该 snippet,容易冲突,且联动逻辑在非目标语言中可能报错 - 确认右下角语言标识不是
Plain Text;如果是,点击切换为对应语言,否则 scope 根本不参与匹配
body 缩进和换行写错,$1/$2 就变普通文本
Atom 对 body 字符串的格式极其敏感:缩进不对、换行没转义、引号不闭合,都会导致整个 snippet 被跳过,占位符变成字面量输出(比如你看到的是 $1 而不是光标停在那里)。
-
body必须与prefix:同级缩进(通常为两个空格),顶格写会解析失败 - 多行内容推荐用 CoffeeScript 的三引号
"""包裹,内部换行直接回车,不用写\n - 如果不用三引号,则必须显式写
\n换行,且整行字符串用单引号包裹,例如:'const $1 = () => {\n return $2;\n}' - 字符串内含单引号要转义:
'console.log(\'$1\');',否则 CSON 解析中断
为什么按 Tab 光标直接消失了?
这是新手最高频的问题,根本原因几乎总是 $0 位置设置不当。Atom 把 $0 当作“退出编辑态”的唯一信号,一旦它出现在第一个可跳转位置,你敲下 Tab 的瞬间,编辑器就认为输入完成,光标立即跳出 snippet 上下文。
- 绝对不要把
$0放在body开头,例如$0 const $1 = ... - 合理位置是结尾,比如函数末尾、标签闭合后:
export default $1;$0 - 如果真想让光标停在开头(比如写完就立刻编辑第一个参数),用
$1开头,而不是$0 - 检查有没有误把
$1写成$0—— 这种笔误极难肉眼发现,但后果立竿见影
${2:$1} 就退化成静态文本,连最基本的光标跳转都失效。











