如何将范围分配给 sublime text 3 上下文菜单?

How to assign a scope to a sublime text 3 context menu?

我通过在具有以下配置的 Packages/user 文件夹中创建 Context.sublime-menu 文件,为 sublime text 3 添加了右键单击上下文菜单:

[
    {
        "caption": "wrap with try",
        "mnemonic": "t",
        "id": "try",
        "command": "insert_snippet",
        "args": { "name": "Packages/User/js-try.sublime-snippet" }
    }
]

这很好用。但我希望它只在当前文件是 javascript 文件时出现,就像你可以通过配置 <scope>source.js</scope> 为片段分配范围一样。一方面我没有找到任何关于此的文档,另一方面我看到有上下文菜单以这种方式运行,所以我知道它是可能的。 有谁知道如何做到这一点?

菜单项可见性由引用的命令控制。请参阅 https://www.sublimetext.com/docs/3/api_reference.html#sublime_plugin.TextCommand 中的 is_visible 方法。

由于内置 insert_snippet 命令总是 returns True 此方法,要实现此目的,您需要编写一个(小的)自定义插件作为所需命令的包装器:

  • 从工具菜单 -> 开发人员 -> 新插件...
  • 将模板替换为:
import sublime
import sublime_plugin


class ProxyCommand(sublime_plugin.TextCommand):
    def run(self, edit, command_name, scope_selector, **kwargs):
        self.view.run_command(command_name, kwargs)

    def is_visible(self, command_name, scope_selector, **kwargs):
        return self.view.match_selector(self.view.sel()[0].begin(), scope_selector)
  • 将其保存在用户包中,类似于 proxy_command.py - 基本文件名无关紧要,只有扩展名很重要
  • 现在,将您的上下文菜单条目更改为:(请注意,我们现在要求菜单条目指向我们刚刚创建的 proxy 命令,并传入参数以告诉它哪个范围(选择器)它应该是活跃的,执行哪个真正的命令以及使用什么参数。)
[
    {
        "caption": "wrap with try",
        "mnemonic": "t",
        "id": "try",
        "command": "proxy",
        "args": {
            "command_name": "insert_snippet",
            "name": "Packages/User/js-try.sublime-snippet",
            "scope_selector": "source.js",
        },
    }
]

您可以更进一步,构建一个通用的代码片段包装器命令,它可以读取代码片段文件(使用 sublime.load_resource API 然后解析 XML)查看那里指定的 <scope> 是否匹配,而不是要求在上下文菜单条目中输入(/可能重复)。