【问题标题】:Set a key binding conditionally based on file type根据文件类型有条件地设置键绑定
【发布时间】:2017-10-26 15:34:37
【问题描述】:

我想使用相同的键映射来运行不同的命令,具体取决于当前在 Sublime Text 3 中编辑的文件类型。我在 .sublime-keymap 中使用什么 context 来控制它?

例如:

{
   "keys": ["super+shift+h"],
   "context": ?????, // --> want this for .vue files
   "command": "htmlprettify"
},
{
   "keys": ["super+shift+h"],
   "context": ?????, // --> want this for all other files
   "command": "js_prettier"
}

...或者有比使用上下文更好/更简单的方法吗?

(我可以这样做,它会运行两个命令,但我需要它是一个或另一个。)

{
    "keys": ["super+shift+h"],
    "commands": [
        {"command": "htmlprettify"}, {"command": "js_prettier"}
    ]
},

【问题讨论】:

    标签: sublimetext3


    【解决方案1】:

    是的,您需要为此使用context。也可以定义您自己的自定义命令来检测您正在编辑的文件类型并执行不同的操作,但这仍将依赖相同的检查机制并且涉及更多,因此更容易且意图更清晰直接在键绑定中进行。

    您想要的上下文将使用selector 键来检查当前光标位置的范围是否特定于您当前正在编辑的文件类型。

    例如,我在自定义键绑定中有此键绑定,因此在编辑 Markdown 文件时,用于换行文本的键始终在 79 列处换行,即使我将标尺设置为 80 列。

    {
        "keys": ["alt+q"], 
        "command": "wrap_lines", 
        "args": {"width": 79}, 
        "context": [
            { 
                "key": "selector", 
                "operator": "equal", 
                "operand": "text.html.markdown"
            }
        ]
    },
    

    为了知道在operand 部分中放置什么范围,您可以使用菜单中的Tools > Developer > Show Scope Name 命令(或相关的键绑定,您可以通过检查菜单查看)同时光标位于您希望键绑定起作用的位置。

    根据光标在文件中的位置,范围将更具体到文件中的特定位置,并且您使用的范围越多,键绑定就越具体。

    比如这里的作用域是text.html.markdown;如果我只使用text,它将适用于所有文本文件(纯文本、任何 HTML 文件等),而使用 text.html 会将其限制为 HTML 文件和 markdown 文件。

    如果希望命令在所有其他类型的文件中工作,您根本不需要使用任何上下文。如果没有上下文,则键绑定始终全局可用,除非另一个具有上下文的绑定更具体地针对当前情况

    这就是为什么在上述情况下,我可以将 Alt+Q 键绑定到此命令,并让它在 Markdown 文件中以不同的方式工作,但在所有其他情况下,它只会做它通常会。


    [编辑]

    正如您在下面的评论中提到的,我忘了提到键绑定的顺序是相关的,尽管这并不总是完全显而易见的(如我上面的示例)。

    根据Key Bindings 上的Unofficial Documentation

    键映射文件中的键绑定从底部到顶部进行评估。第一个匹配的上下文获胜。

    因此,如果您要对同一个键进行多个绑定,则需要将最通用的一个放在文件中的最前面,将最具体的一个放在最后,这样当 Sublime 遍历匹配的绑定列表时,只有当没有更具体的适用时,它才会达到通用的。

    作为一个人为的示例,以下一组键绑定使 Alt+F1 键在Lua 源文件中插入与在所有其他文件中不同的文本。如果顺序颠倒,则首先找到全局键(并且始终匹配):

    {
        "keys": ["alt+f1"], "command": "insert", "args": {
            "characters": "The Global Key Binding"
        }
    },
    
    {
        "keys": ["alt+f1"], "command": "insert", "args": {
            "characters": "The Lua Key Binding"
        },
        "context": [
            { "key": "selector", "operator": "equal", "operand": "source.lua" },
        ],
    },
    

    还要注意,Sublime 中的许多资源(包括sublime-keymap)可以在多个包中指定,这会导致 Sublime 将所有类似命名的文件组合在一起。

    这发生在in a specific order,大致概括为首先是Default,最后是User,以及介于两者之间的所有其他内容(完整详细信息请参见链接)。

    您的自定义键绑定将始终位于 User 包中,因此最后加载,这意味着您可能始终可以安全地覆盖任何内容并让顺序符合您的期望。

    在某些情况下,您安装的包的默认键绑定包含上下文,并且您希望以更全局的方式重用该键,同时不干扰包键绑定。

    在这种情况下,您需要将默认绑定复制到您自己的用户键绑定以及自定义绑定,以便确保排序仍然正确。

    不过,这可能是非常罕见的情况。

    【讨论】:

    • 非常感谢您!这让我走了 90% 的路,关于如何找到当前范围的详细信息特别有帮助。我必须解决的一个额外问题,您可能希望将其合并到这个答案中,即定义的键绑定的顺序显然很重要:上下文“text.html.vue”的更具体规则必须遵循通用规则——将它们反过来会导致通用规则在所有上下文中运行。
    • 答案已更新,很抱歉最初忘记了该部分。很高兴你让一切都正常工作。 :)
    • 例如文件类型为“php”时如何绑定?
    • @Matrix 您可以使用 Tools > Developer > Show Scope Name 获取 PHP 范围,并将该值用作 context 中的 operand
    • 谢谢,这行得通:) embedding.php 这里
    猜你喜欢
    • 2023-01-20
    • 1970-01-01
    • 1970-01-01
    • 2013-04-12
    • 2014-08-13
    • 2011-06-27
    • 2018-07-06
    • 2022-10-16
    相关资源
    最近更新 更多