atom中自定义emmet缩写必须通过snippets.cson文件实现,路径为~/.atom/snippets.cson(windows为%userprofile%.atom\snippets.cson),需严格遵循cson语法、精确匹配scope(如.text.html.basic)、定义prefix与body,修改后执行snippets: reload snippets生效。

Atom 中的 Emmet 插件本身不提供“自定义缩写规则”的图形界面或配置项,emmet-atom 也不允许你直接改写 html:5 或 ul>li*3 这类内置缩写的输出结构——它只负责解析和展开。真要覆盖或新增缩写行为,必须绕过 Emmet 核心,走 Atom 原生 snippets 路线。
snippets.cson 是唯一生效入口
所有自定义缩写(包括模拟 Emmet 行为)都得写进 ~/.atom/snippets.cson(Windows 是 %USERPROFILE%\.atom\snippets.cson),不能用 snippets.json,也不能放错目录。Atom 只认这个路径下的 CSON 文件,且优先级高于 snippets/ 目录里的文件。
- 文件必须是合法 CSON:禁止末尾逗号、禁止 JSON 风格双引号、字符串含空格需加单引号(如
'source.js.jsx') - scope 必须精确匹配当前文件的实际作用域,比如
text.html.vue(不是.vue)或source.css(不是css) - 修改后执行
Snippets: Reload Snippets(Cmd+Shift+P / Ctrl+Shift+P),不用重启 Atom,但已打开的文件得重新触发语法高亮(比如切到其他语言再切回)
想让 mydiv → $1?用 prefix + body
这不是 Emmet 的功能,而是 Atom snippet 的标准写法。你无法让 Emmet 把 mydiv 当作缩写识别,但可以定义一个 snippet,让它在输入 mydiv 后按 Tab 就插入目标结构。
- scope 写成
'.text.html.basic'(HTML 文件)或'.source.css'(CSS 文件) -
prefix是触发词,比如mydiv;body是展开内容,支持$1、$2占位符 - 别用
${1:default}—— Atom 的 CSON 不支持这种语法,会整个 snippet 失效;默认值只能靠$1后手动填 - 示例(HTML 中):
'.text.html.basic': 'mydiv': 'prefix': 'mydiv' 'body': '<div class="${1:container}">$2</div>'
为什么写了没反应?九成是 scope 或光标位置错了
最常踩的坑不是代码写错,而是作用域不匹配或光标不在有效位置。
- 查当前 scope:Cmd+Shift+P → 输入
Editor: Log Cursor Scope,看输出是不是你写的 scope(比如text.html.basic,不是text.html) - 确保右下角语言标识是 HTML/CSS,不是 Plain Text;Emmet 和 snippets 都依赖这个标识
- 光标必须在行首或空行中才能触发 snippet;如果前面有字符、缩进或空格,Tab 会缩进而不是展开
- 多个 scope 用逗号分隔:
'.source.js, .source.jsx',不能用竖线或空格
jsx / vue / markdown 里想用 Emmet 缩写?得配 keymap.cson
Emmet 默认只绑定在 text.html.basic 和 source.css 等少数 scope 上。在 .jsx 或 .vue 文件里输 div + Tab 没反应,是因为 Tab 键根本没被映射过去。
- 打开
keymap.cson(Cmd+Shift+P →Application: Open Your Keymap) - 追加一行:
'.source.js, .source.jsx': 'tab': 'emmet:expand-abbreviation'
- 注意:不要覆盖整个文件,只加这一段;保存后立即生效
- 如果用了
atom-beautify,它可能劫持 Tab,要去它的设置里关掉 “On Tab” 格式化选项
真正麻烦的不是写 snippet,而是每次改完都要验证 scope 是否精准、占位符是否连续、CSON 语法是否多了一个逗号——这些细节不报错,只静默失效。











