【问题标题】:when statement to exclude specified folders and files from showing an extension command in a context menuwhen 语句排除指定文件夹和文件在上下文菜单中显示扩展命令
【发布时间】:2022-01-20 19:05:35
【问题描述】:

在我的 VS Code 扩展中,我希望在资源管理器视图中提供一些命令,并希望它们的可用性基于所选内容。假设我在 VS Code 中打开一个文件夹,该文件夹有以下内容:

/a
/a/1.txt
/a/2.txt

/b
/b/3.txt
/b/4.txt

/c
/c/5.txt
/c/6.txt

我希望在选择文件夹“c”或其中的任何内容时出现命令,但不是 a 或 b。

另外,我希望逻辑排除特定文件夹(及其内容),而不是包含特定文件夹(例如,我希望逻辑是,“命令是适用于所有除了 a或b")

在我的扩展程序的 activate() 函数中,我有:

  vscode.commands.executeCommand(
    'setContext',
    'ext.list',
    [
      'a',
      'b'
    ]
  );

在我的package.json 中,我有:

{
  "command": "samplecommand",
  "when": "resourceFilename in ext.list"
}

当我运行此命令时,我发现当我选择文件夹 a 或 b 时该命令可用,但当我选择其中的任何项目时(如 a/1.txt)则不可用。我尝试使用a/*a/.*a/*.*,但没有找到任何有效的方法。

那么,当使用“resourceFilename in”时,它是否支持正则表达式?还是只进行精确的字符串匹配?选择文件夹或文件夹中的一项时,如何获得肯定匹配?

好的,接下来,我还是想排除命令,当我尝试时:

{
  "command": "samplecommand",
  "when": "!(resourceFilename in ext.list)"
}

...或:

{
  "command": "samplecommand",
  "when": "resourceFilename !in ext.list"
}

...对于 a、b 或 c,该命令都不会出现。是否可以测试文件名何时在列表中 not?看来这总是评估为假。

所以,TL;DR,我想在资源管理器视图中过滤命令,然后不显示特定文件夹和文件夹中的项目。这可能吗?

【问题讨论】:

    标签: visual-studio-code vscode-extensions


    【解决方案1】:

    第一个问题:

    你有

    "contributes": {
       "menus": {
         "explorer/context": [
           {
             "command": "ext.samplecommand",
             "when": "resourceFilename in ext.list"
           }
         ]
       }
    }
    

    还有一个'ext.list', [ 'a', 'b' ]

    当我运行它时,我发现该命令在我有时可用 选择了文件夹 a 或 b,但当我有任何项目时没有 它被选中(如a/1.txt)。我尝试使用a/*a/.*a/*.*,但我 还没有找到任何有效的方法。

    resourceFilename 解析为类似a 的文件夹和myFile.js 的文件。所以"resourceFilename in ext.list" 对文件夹起作用,因为resourceFilename 解析为ab(如果它们被选中)。但它对文件没有帮助,因为resourceFilename 不解析为文件夹名称,而是解析为文件名。

    要让菜单项同时显示文件夹及其包含的文件,您可以这样做:

    "menus": {
      "explorer/context": [
        {
          "when": "resourceFilename in ext.list || !explorerResourceIsFolder && resourceDirname =~ /(\\/|\\\\)(bundle|concat)$/",
          "command": "ext.samplecommand"
        }
      ]
    }
    

    其中(bundle|concat) 代表dirname,您希望包含的文件。

    这回答了您关于when 子句中支持正则表达式的问题。是的,见key-value when clause operator

    when 子句有一个键值对匹配运算符。这 表达式key =~ value 将右侧视为常规 与左侧匹配的表达式。

    以上使用resourceDirname =~ /(\\/|\\\\)(bundle|concat)$

    这将检查resourceDirname\bundle/bundle\concat/concat 中的结尾(在反斜杠或正斜杠之前有很多转义)。 p>


    现在,到达您的最终目的地 - 过滤菜单以显示特定文件夹和文件的命令。

    我认为没有办法否定resourceFilename in ext.list“运算符”。我好像想起了一个github issue,但是现在找不到了。

    但是还有另一种方法,因为我们可以使用上面when 子句中看到的正则表达式。但它必须有点棘手,因为我们试图排除某些文件夹和文件。试试这个:

    "menus": {
      "explorer/context": [
        {
          "when": "explorerResourceIsFolder && resourcePath =~ /.*?(?<!(\\\\|\\\/)(bundle|concat))$/ || !explorerResourceIsFolder && resourceDirname =~ /.*?(?<!(\\\\|\\\/)(bundle|concat))$/",
          "command": "ext.samplecommand"
        }
      ]
    },
    

    • explorerResourceIsFolder &amp;&amp; resourcePath =~ /.*?(?&lt;!(\\\\|\\\/)(bundle|concat))$

    当所选资源为文件夹时,检查其resourcePath,这将是其以文件夹名称结尾的完整文件路径。

    所以resourcePath =~ /.*?(?&lt;!(\\\\|\\\/)(bundle|concat))$ 使用否定的lookbehind 来匹配 以名为bundleconcat 在此示例中的文件夹结尾的文件夹路径(您的ab) .

    • !explorerResourceIsFolder &amp;&amp; resourceDirname =~ /.*?(?&lt;!(\\\\|\\\/)(bundle|concat))$/

    当所选资源是文件而不是文件夹时,检查其resourceDirname,这将是其以文件夹名称结尾的完整文件路径。

    因此,像上面一样,它使用否定的lookbehind 仅匹配带有dirnames 而不是bundleconcat 的文件。


    因此,总而言之,由于不能否定 resourceFilename in ext.list 类型的构造,因此您必须使用 when 子句的 key =~ value 类型,并确保将其与正确的资源名称进行比较。并通过使用某种正则表达式否定环顾来“否定”它。


    要弄清楚这一点,Developer: Inspect Context Keys 命令是非常宝贵的。它允许您查看资源管理器文件夹和文件可用的上下文键以及这些键的值。这就是我发现resourcePath 最适合文件夹和resourceDirname 最适合文件的原因——因为在这两种情况下,完整路径都以文件夹名称结尾。

    Inspect Context Keys utility documentation

    【讨论】:

    • 谢谢马克,这是关于使用Developer: Inspect Context Keys的一个很好的提示
    • 另外,只是一个更新,这似乎对我正在寻找的东西有用{ "command": "samplecommand", "when": "resourcePath =~ /^((?!\/(foo|bar)).)*$/" },
    猜你喜欢
    • 2019-12-01
    • 2019-03-13
    • 2013-04-12
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-01-02
    • 1970-01-01
    • 2016-11-11
    相关资源
    最近更新 更多