Sublime Text 无法保存时自动排序 JSON 键,因 Junk-Drawer 插件不监听保存事件且仅支持手动触发单对象排序;需自写插件监听 on_pre_save,校验 JSON 语法后全文件解析重排并替换。

Sublime Text 本身不支持保存时自动排序 JSON 键,Junk-Drawer 插件也**没有提供“保存即排序”的钩子功能**——它只提供手动命令 sort_json_object_keys,需主动触发。
为什么 Junk-Drawer 不能自动排序?
Junk-Drawer 是一个轻量级工具集,不监听 on_pre_save 或 on_post_save 事件,也不读取文件类型上下文自动判断是否为 JSON。它的 sort_json_object_keys 命令仅在用户显式调用(如快捷键或右键菜单)时运行,且默认只处理当前光标所在的一个 JSON 对象(非整个文件),也不校验语法有效性。
如何实现“保存时自动排序 JSON 键”?
必须借助 Sublime Text 的插件机制,自己写一个极简的监听插件。核心逻辑是:监听 on_pre_save 事件 → 判断当前视图是否为 JSON(通过 view.settings().get("syntax"))→ 解析并重排键 → 替换文本区域。
- 将以下代码保存为
Packages/User/json_auto_sort.py(Packages可通过 Preferences → Browse Packages… 打开) - 依赖 Python
json模块,不依赖外部库 - 仅对语法识别为 JSON 的文件生效(如
JSON.sublime-syntax或JSON (JSON5).sublime-syntax) - 跳过含语法错误的文件(
json.loads()失败则不修改)
import json import sublime import sublime_pluginclass JsonAutoSortListener(sublime_plugin.EventListener): def on_pre_save(self, view): syntax = view.settings().get("syntax", "") if not ("JSON" in syntax or "json" in syntax.lower()): return
region = sublime.Region(0, view.size()) text = view.substr(region) try: obj = json.loads(text) # 仅对 dict 类型重排(忽略数组、字符串等) if isinstance(obj, dict): sorted_obj = {k: obj[k] for k in sorted(obj.keys())} new_text = json.dumps(sorted_obj, indent=2, ensure_ascii=False) + "\n" view.replace(sublime.Edit(), region, new_text) except (json.JSONDecodeError, ValueError, TypeError): pass常见问题与坑
直接用
Junk-Drawer的sort_json_object_keys命令无法满足“自动”需求,但有人误以为启用它后加个快捷键绑定就能替代自动保存行为——其实不行,因为:
- 它不作用于整个文件,只处理光标所在最近的
{...}块 - 它不格式化缩进,只重排键顺序,输出可能和原缩进不一致
- 它不会跳过注释(JSON 标准不支持注释,但 Sublime 常用 JSON5 语法),一旦含
//或/* */就会解析失败 - 若想兼容 JSON5(带注释),必须换用
json5库,而 Sublime 内置 Python 不含该模块,需额外打包或改用 Node.js 方案(更重)
真正可靠的自动排序只在保存前做一次完整解析+序列化,不依赖光标位置,也不处理部分对象——这点容易被忽略,直到你发现某些嵌套对象的键没被排,才意识到 Junk-Drawer 的作用域限制太强。










