sublime text 插件必须继承 sublime_plugin.textcommand 或 windowcommand、放在 packages 目录下、类名以 command 结尾、实现 run(self, edit, **kwargs) 方法,且所有文本修改须通过 edit 对象原子化执行。

Sublime Text 本身不支持直接运行 Python 脚本处理选区或文件内容——它只允许你写 sublime_plugin.TextCommand 或 sublime_plugin.WindowCommand 插件,且必须放在 Packages 目录下、以 .py 结尾、继承对应基类,否则根本不会被加载。
为什么写个简单替换脚本却“没反应”?
常见错误是把 Python 脚本当成普通 .py 文件双击运行,或用命令行执行——这完全绕过了 Sublime 的插件机制。Sublime 只在启动时扫描 Packages/ 下合法插件,并绑定到命令面板或快捷键。
- 插件文件必须放在
Packages/User/(推荐)或Packages/MyPluginName/下 - 类名必须以
Command结尾,比如TrimTrailingSpacesCommand - 类必须继承
sublime_plugin.TextCommand(操作当前视图)或sublime_plugin.WindowCommand(操作整个窗口) - 方法名必须是
run(self, edit, **kwargs),edit对象是唯一允许修改文本的句柄
如何安全地批量修改选区文本?
不能直接对 view.substr() 返回的字符串做原地修改,所有变更必须通过 edit 对象调用 view.replace()、view.insert() 或 view.erase()。否则会触发「RuntimeError: Invalid edit object」。
- 先用
view.sel()获取所有选区(Region对象列表) - 倒序遍历选区(从后往前),避免前面替换导致后续
Region偏移失效 - 每次
view.replace(edit, region, new_text)必须传入原始region,不能复用已修改后的坐标 - 如果要处理整行,用
view.line(region)扩展区域;需要去重或合并选区时,手动排序并合并Region
示例:给每个非空选区加前后括号
def run(self, edit):
for region in reversed(self.view.sel()):
if not region.empty():
text = self.view.substr(region)
self.view.replace(edit, region, f"({text})")
如何让脚本响应快捷键或命令面板?
插件生效后,需手动绑定快捷键或添加命令面板项,Sublime 不会自动注册。命令名由类名去掉 Command 后缀、转为蛇形命名生成——例如 ConvertToUppercaseCommand 对应命令名 convert_to_uppercase。
- 快捷键绑定写在
Preferences → Key Bindings的用户文件中,格式:{"keys": ["ctrl+alt+u"], "command": "convert_to_uppercase"} - 命令面板项需新建
Default.sublime-commands文件(同级目录),内容为 JSON 数组,每项含caption和command - 命令名拼错、大小写不一致、缺连字符,都会导致「command not found」错误但无提示
- 改完插件保存后,无需重启 Sublime,但需确保控制台没报
ImportError或语法错误(按Ctrl+`查看)
哪些操作容易引发崩溃或不可逆误改?
最危险的是在 run() 外部缓存 view 或 region 对象,或在循环中多次调用 view.sel() 动态读取——因为用户可能中途手动修改选区,导致逻辑错乱甚至死循环。
- 所有文本读取(
view.substr())和写入(view.replace())必须成对出现在同一run()中 - 不要在插件里调用
subprocess阻塞主线程,会导致 UI 卡死;如需外部工具,用sublime.set_timeout_async()拆出异步任务 - 正则替换慎用
view.find_all()后直接replace(),它返回的Region是快照,若文件已被其他操作修改,位置可能失效 - 调试优先用
sublime.status_message("msg"),而不是print()——后者输出到控制台但不易发现
真正难的不是写逻辑,而是理解 Sublime 的编辑模型:它不让你“自由读写”,只给你一次 edit 会话窗口,所有动作必须原子化、可预测、不可中断。











