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