Sublime Text的Python API仅在插件环境中有效,必须继承TextCommand或WindowCommand并置于Packages目录下;HTTP请求需用set_timeout_async异步执行,结果写回须切回主线程并使用有效edit对象。

Sublime Text 的 Python API 只能在插件环境里跑
直接在 Sublime 控制台或外部 Python 解释器里调用 sublime、sublime_plugin 这些模块,一定会报 ModuleNotFoundError 或 AttributeError。这不是你代码写错了,是 Sublime 的 API 根本不对外暴露——它只加载在自己的进程里,且只对 .py 插件文件生效。
常见错误现象:
– 在终端执行 python my_script.py 报错 NameError: name 'sublime' is not defined
– 用 import sublime 后调用 sublime.active_window() 返回 None(实际是模块存在但未初始化)
- 唯一合法入口:把脚本写成 Sublime 插件,即放在
Packages/User/或独立包目录下的.py文件,且继承sublime_plugin.TextCommand/sublime_plugin.WindowCommand - 插件必须有
run(self, edit)方法,edit对象不能缓存、不能跨函数传递,且仅在run执行期间有效 - 想调试?用
sublime.status_message("debug: xxx")或写日志到sublime.log_commands(True)开启的控制台,别依赖print()
用 TextCommand 实现“选中文字自动调用 HTTP API”
这是最常用场景:用户选一段 JSON,按快捷键,脚本发请求、解析响应、插入结果。核心难点不在 HTTP,而在如何安全获取选区、避免编辑冲突。
使用场景:
– 格式化 JSON(调用在线 formatter)
– 查询正则匹配效果(发给 regex101 类服务)
– 提交代码片段到内部 lint 服务
立即学习“Python免费学习笔记(深入)”;
- 必须用
view.substr(region)拿内容,别用view.substr(view.sel()[0])直接套——如果没选中会崩溃,要先判断if not view.sel(): return - HTTP 请求不能阻塞主线程,否则 UI 冻结。必须用
sublime.set_timeout_async(..., 0)包一层,把 requests 调用移出 UI 线程 - 返回结果写回编辑器时,必须再切回主线程:
sublime.set_timeout(lambda: view.replace(edit, region, result))—— 注意edit对象不能跨线程传
class ApiPostCommand(sublime_plugin.TextCommand):
def run(self, edit):
for region in self.view.sel():
if not region.empty():
text = self.view.substr(region)
sublime.set_timeout_async(lambda: self._do_api_call(text, region))
<pre class='brush:php;toolbar:false;'>def _do_api_call(self, text, region):
try:
resp = requests.post("https://httpbin.org/post", json={"data": text})
result = resp.json()["json"]["data"].upper() # 示例处理
sublime.set_timeout(lambda: self.view.replace(
self.view.begin_edit(), region, result
))
except Exception as e:
sublime.status_message(f"API failed: {e}")sublime_plugin.WindowCommand 和 TextCommand 的关键区别
选错基类会导致功能残缺或报错。不是“都能用”,而是“该用哪个取决于你要操作什么”。
-
TextCommand:只能在有打开的文本视图(tab)时触发,self.view永远非空;适合处理当前文件内容(如替换、格式化) -
WindowCommand:只要窗口存在就能运行,self.window可用,但self.view可能为None;适合新建文件、切换面板、批量操作多个标签页 - 没有
ApplicationCommand的公开稳定接口,别试图监听全局按键或启动时自动运行——Sublime 不允许插件接管应用生命周期 - 命令名(如
api_post)由类名ApiPostCommand自动推导,下划线转中划线,但首字母必须小写;命名错误会导致命令找不到
调试时容易被忽略的三个硬限制
这些不是 bug,是 Sublime 的设计约束,绕不开,只能适应。
-
edit对象 5 秒后自动失效,超时调用view.insert(edit, ...)会抛RuntimeError—— 别在异步回调里等太久才写回 - 插件加载后修改代码,不会热更新;必须重启 Sublime 或手动执行
Package Control: Satisfy Dependencies(如果用了第三方库) - requests、urllib 等网络库可以装,但不能用
pip install直接装进 Sublime 的 Python;得用Package Control安装带二进制依赖的包,或把纯 Python 库整个复制进插件目录
真正卡住人的,往往不是怎么发请求,而是 edit 生命周期、线程切换、插件加载时机这三件事叠在一起——少一个条件满足,脚本就静默失败。

















