when 子句上下文

Visual Studio Code 根据 VS Code 用户界面中可见和活动的元素设置各种上下文键和特定值。这些上下文可用于选择性地启用或禁用扩展命令和用户界面元素,例如菜单和视图。

例如,VS Code 使用 when 子句来启用或禁用命令键绑定,您可以在默认键绑定 JSON 中看到(首选项:打开默认键盘快捷键 (JSON)):

{ "key": "f5",  "command": "workbench.action.debug.start",
                   "when": "debuggersAvailable && !inDebugMode" },

上面,内置的开始调试命令有键盘快捷键F5,只有当有适当的调试器可用时(上下文键debuggersAvailable为真)且编辑器不在调试模式下(上下文键inDebugMode为假)时才会启用。

条件运算符

when 子句可以由上下文键(例如,inDebugMode)组成,也可以使用各种运算符来表达更细致的编辑器状态。

逻辑运算符

逻辑运算符允许组合简单的上下文键或包含其他逻辑、相等、比较、匹配、in/not in运算符或括号表达式的when子句表达式。

Operator Symbol Example
Not ! "!editorReadonly" or "!(editorReadonly || inDebugMode)"
And && "textInputFocus && !editorReadonly"
Or || "isLinux || isWindows"

关于逻辑运算符优先级的说明:上表按从高到低的优先级顺序列出了运算符。示例:

Written as Interpreted as
!foo && bar (!foo) && bar
!foo || bar (!foo) || bar
foo || bar && baz foo || (bar && baz)
!foo && bar || baz (!foo && bar) || baz
!(foo || bar) && baz (remains same) !(foo || bar) && baz

相等运算符

您可以检查上下文键的值是否等于指定的值。请注意,右侧是一个值,而不是解释为上下文键,这意味着它不会在上下文中查找。

Operator Symbol Example
Equality == "editorLangId == typescript" or "editorLangId == 'typescript'"
Inequality != "resourceExtname != .js" or "resourceExtname != '.js'"

备注:

  • 如果右侧的值是包含空格的字符串,则必须用单引号括起来 - "resourceFilename == 'My New File.md'"
  • === 的行为与 == 相同,!== 的行为与 != 相同

比较运算符

你可以将一个上下文键的值与一个数字进行比较。请注意,操作符的左右两侧必须用空格分隔 - foo < 1,但不能是 foo<1

Operator Symbols Example
Greater than >, >= "gitOpenRepositoryCount >= 1" but not "gitOpenRepositoryCount>=1"
Less than <, <= "workspaceFolderCount < 2" but not "workspaceFolderCount<2"

匹配操作符

(之前的名称:键值对匹配操作符)

Operator Symbol Example
Matches =~ "resourceScheme =~ /^untitled$|^file$/"

有一个匹配操作符(=~)用于when子句。表达式key =~ regularExpressionLiteral将右侧视为正则表达式字面量,以匹配左侧。例如,要为所有Docker文件贡献上下文菜单项,可以使用:

   "when": "resourceFilename =~ /docker/"

备注:

  • =~ 操作符的右侧遵循与 JavaScript 中的正则表达式字面量相同的规则(参考),除了字符需要遵循 JSON 字符串和正则表达式的转义规则。例如,匹配子字符串 file:// 的正则表达式字面量在 JavaScript 中为 /file:\/\//,但在 when 子句中为 /file:\\/\\//,因为反斜杠需要在 JSON 字符串中转义,而斜杠需要在正则表达式模式中转义。
  • 不存在运算符 !=~,但你可以否定匹配表达式 - !(foo =~ /baz/)

正则表达式标志

可以在正则表达式字面量中使用标志。例如,resourceFilename =~ /json/imyContextKey =~ /baz/si

支持的标志:i, s, m, u.

忽略的标志:g, y.

'in' 和 'not in' 条件运算符

in 操作符用于 when 子句,允许在另一个上下文键的值中动态查找上下文键的值。例如,如果你想为包含某种类型文件(或无法静态知道的内容)的文件夹添加上下文菜单命令,你现在可以使用 in 操作符来实现。你可以使用 not in 操作符来检查相反的条件。

Operator Symbol Example
In in "resourceFilename in supportedFolders"
Not in not in "resourceFilename not in supportedFolders"

首先,确定哪些文件夹应支持该命令,并将文件夹名称添加到数组中。然后,使用setContext命令将数组转换为上下文键:

vscode.commands.executeCommand('setContext', 'ext.supportedFolders', [
  'test',
  'foo',
  'bar'
]);

// or

// Note in this case (using an object), the value doesn't matter, it is based on the existence of the key in the object
// The value must be of a simple type
vscode.commands.executeCommand('setContext', 'ext.supportedFolders', {
  test: true,
  foo: 'anything',
  bar: false
});

然后,在package.json中,你可以为explorer/context菜单添加一个菜单贡献:

// Note, this assumes you have already defined a command called ext.doSpecial
"menus": {
  "explorer/context": [
    {
      "command": "ext.doSpecial",
      "when": "explorerResourceIsFolder && resourceFilename in ext.supportedFolders"
    }
  ]
}

在那个例子中,我们获取了resourceFilename的值(在这种情况下是文件夹的名称),并在ext.supportedFolders的值中检查其是否存在。如果存在,菜单将会显示。这个强大的操作符应该允许更丰富的条件和动态贡献,支持when子句,例如菜单、视图等。

可用的上下文键

以下是一些可用的上下文键,它们会评估为布尔值 true/false。

这里的列表并不详尽,您可以通过在键盘快捷键编辑器(首选项:打开键盘快捷键)中搜索和过滤,或查看默认键绑定JSON文件(首选项:打开默认键盘快捷键(JSON))来找到其他when子句上下文。您还可以使用检查上下文键工具来识别您感兴趣的上下文键。

Context name True when
Editor contexts
editorFocus An editor has focus, either the text or a widget.
editorTextFocus The text in an editor has focus (cursor is blinking).
textInputFocus Any editor has focus (regular editor, debug REPL, etc.).
inputFocus Any text input area has focus (editors or text boxes).
editorTabMovesFocus Whether Tab will move focus out of the editor.
editorHasSelection Text is selected in the editor.
editorHasMultipleSelections Multiple regions of text are selected (multiple cursors).
editorReadonly The editor is read only.
editorLangId True when the editor's associated language ID matches.
Example: "editorLangId == typescript".
isInDiffEditor The active editor is a difference editor.
isInEmbeddedEditor True when the focus is inside an embedded editor.
Operating system contexts
isLinux True when the OS is Linux.
isMac True when the OS is macOS.
isWindows True when the OS is Windows.
isWeb True when accessing the editor from the Web.
List contexts
listFocus A list has focus.
listSupportsMultiselect A list supports multi select.
listHasSelectionOrFocus A list has selection or focus.
listDoubleSelection A list has a selection of 2 elements.
listMultiSelection A list has a selection of multiple elements.
Mode contexts
inSnippetMode The editor is in snippet mode.
inQuickOpen The Quick Open dropdown has focus.
Resource contexts
resourceScheme True when the resource Uri scheme matches.
Example: "resourceScheme == file"
resourceFilename True when the Explorer or editor filename matches.
Example: "resourceFilename == gulpfile.js"
resourceExtname True when the Explorer or editor filename extension matches.
Example: "resourceExtname == .js"
resourceDirname True when the Explorer or editor's resource absolute folder path matches.
Example: "resourceDirname == /users/alice/project/src"
resourcePath True when the Explorer or editor's resource absolute path matches.
Example: "resourcePath == /users/alice/project/gulpfile.js"
resourceLangId True when the Explorer or editor title language ID matches.
Example: "resourceLangId == markdown"
isFileSystemResource True when the Explorer or editor file is a file system resource that can be handled from a file system provider.
resourceSet True when an Explorer or editor file is set.
resource The full Uri of the Explorer or editor file.
Explorer contexts
explorerViewletVisible True if Explorer view is visible.
explorerViewletFocus True if Explorer view has keyboard focus.
filesExplorerFocus True if File Explorer section has keyboard focus.
openEditorsFocus True if OPEN EDITORS section has keyboard focus.
explorerResourceIsFolder True if a folder is selected in the Explorer.
Editor widget contexts
findWidgetVisible Editor Find widget is visible.
suggestWidgetVisible Suggestion widget (IntelliSense) is visible.
suggestWidgetMultipleSuggestions Multiple suggestions are displayed.
renameInputVisible Rename input text box is visible.
referenceSearchVisible Peek References peek window is open.
inReferenceSearchEditor The Peek References peek window editor has focus.
config.editor.stablePeek Keep peek editors open (controlled by editor.stablePeek setting).
codeActionMenuVisible Code Action menu is visible.
parameterHintsVisible Parameter hints are visible (controlled by editor.parameterHints.enabled setting).
parameterHintsMultipleSignatures Multiple parameter hints are displayed.
Debugger contexts
debuggersAvailable An appropriate debugger extension is available.
inDebugMode A debug session is running.
debugState Active debugger state.
Possible values are inactive, initializing, stopped, running.
debugType True when debug type matches.
Example: "debugType == 'node'".
inDebugRepl Focus is in the Debug Console REPL.
Integrated terminal contexts
terminalFocus An integrated terminal has focus.
terminalIsOpen An integrated terminal is opened.
Timeline view contexts
timelineFollowActiveEditor True if the Timeline view is following the active editor.
Timeline view item contexts
timelineItem True when the timeline item's context value matches.
Example: "timelineItem =~ /git:file:commit\\b/".
Extension contexts
extension True when the extension's ID matches.
Example: "extension == eamodio.gitlens".
extensionStatus True when the extension is installed.
Example: "extensionStatus == installed".
extensionHasConfiguration True if the extension has configuration.
Global UI contexts
notificationFocus Notification has keyboard focus.
notificationCenterVisible Notification Center is visible at the bottom right of VS Code.
notificationToastsVisible Notification toast is visible at the bottom right of VS Code.
searchViewletVisible Search view is open.
sideBarVisible Side Bar is displayed.
sideBarFocus Side Bar has focus.
panelFocus Panel has focus.
inZenMode Window is in Zen Mode.
isCenteredLayout Editor is in centered layout mode.
workbenchState Can be empty, folder (1 folder), or workspace.
workspaceFolderCount Count of workspace folders.
replaceActive Search view Replace text box is open.
view For view/title and view/item/context, the view to display the command in.
Example: "view == myViewsExplorerID".
viewItem For view/item/context, the contextValue from the tree item.
Example: "viewItem == someContextValue".
webviewId For webview/context, the webview ID to display the command in.
Example: "webviewId == catCoding".
isFullscreen True when window is in fullscreen.
focusedView The identifier of the currently focused view.
canNavigateBack True if it is possible to navigate back.
canNavigateForward True if it is possible to navigate forward.
canNavigateToLastEditLocation True if it is possible to navigate to the last edit location.
Global Editor UI contexts
textCompareEditorVisible At least one diff (compare) editor is visible.
textCompareEditorActive A diff (compare) editor is active.
editorIsOpen True if one editor is open.
groupEditorsCount Number of editors in a group.
activeEditorGroupEmpty True if the active editor group has no editors.
activeEditorGroupIndex A number starting from 1 reflecting the position of an editor group in the editor grid.
The group with index 1 will be the first in the top-left corner.
activeEditorGroupLast Will be true for the last editor group in the editor grid.
multipleEditorGroups True when multiple editor groups are present.
activeEditor The identifier of the active editor in a group.
activeEditorIsDirty True when the active editor in a group is dirty.
activeEditorIsNotPreview True when the active editor in a group is not in preview mode.
activeEditorIsPinned True when the active editor in a group is pinned.
inSearchEditor True when focus is inside a search editor.
activeWebviewPanelId The id of the currently active webview panel.
activeCustomEditorId The id of the currently active custom editor.
Configuration settings contexts
config.editor.minimap.enabled True when the setting editor.minimap.enabled is true.

注意: 你可以在这里使用任何评估为布尔值的用户或工作区设置,前缀为 "config."

可见/聚焦视图时的子句上下文

你可以有一个when子句来检查特定的View是否可见或获得焦点。

Context name True when
view.${viewId}.visible True when specific view is visible.
Example: "view.workbench.explorer.fileView.visible"
focusedView True when specific view is focused.
Example: "focusedView == 'workbench.explorer.fileView'"

查看标识符:

  • workbench.explorer.fileView - 文件资源管理器
  • workbench.explorer.openEditorsView - 打开的编辑器
  • outline - 大纲视图
  • timeline - 时间线视图
  • workbench.scm - 源代码控制
  • workbench.scm.repositories - 源代码控制仓库
  • workbench.debug.variablesView - 变量
  • workbench.debug.watchExpressionsView - 监视
  • workbench.debug.callStackView - 调用堆栈
  • workbench.debug.loadedScriptsView - 已加载的脚本
  • workbench.debug.breakPointsView - 断点
  • workbench.debug.disassemblyView - 反汇编
  • workbench.views.extensions.installed - 已安装的扩展
  • extensions.recommendedList - 推荐的扩展
  • workbench.panel.markers.view - 问题
  • workbench.panel.output - 输出
  • workbench.panel.repl.view - 调试控制台
  • terminal - 集成终端
  • workbench.panel.comments - 评论

当子句上下文中的可见视图容器

你可以有一个when子句来检查特定的View Container是否可见

Context name True when
activeViewlet True when view container is visible in the sidebar.
Example: "activeViewlet == 'workbench.view.explorer'"
activePanel True when view container is visible in the panel.
Example: "activePanel == 'workbench.panel.output'"
activeAuxiliary True when view container is visible in the secondary sidebar.
Example: "activeAuxiliary == 'workbench.view.debug'"

查看容器标识符:

  • workbench.view.explorer - 文件资源管理器
  • workbench.view.search - 搜索
  • workbench.view.scm - 源代码控制
  • workbench.view.debug - 运行
  • workbench.view.extensions - 扩展
  • workbench.panel.markers - 问题
  • workbench.panel.output - 输出
  • workbench.panel.repl - 调试控制台
  • terminal - 集成终端
  • workbench.panel.comments - 评论

如果你想要一个仅在特定视图容器获得焦点时启用的when子句,请结合使用sideBarFocuspanelFocusauxiliaryBarFocusactiveViewletactivePanelactiveAuxiliary上下文键。

例如,下面的when子句仅在文件资源管理器具有焦点时为真:

"sideBarFocus && activeViewlet == 'workbench.view.explorer'"

在when子句中检查设置

在when子句中,您可以通过在配置(设置)值前加上config.来引用它,例如config.editor.tabCompletionconfig.breadcrumbs.enabled

添加自定义when子句上下文

如果您正在编写自己的VS Code扩展,并且需要使用when子句上下文来启用/禁用命令、菜单或视图,而现有的键都不适合您的需求,您可以使用setContext命令添加自己的上下文键。

下面的第一个示例将键 myExtension.showMyCommand 设置为 true,您可以在启用命令或使用 when 属性时使用它。第二个示例存储了一个值,您可以在 when 子句中使用它来检查酷炫的开放事物数量是否大于 2。

vscode.commands.executeCommand('setContext', 'myExtension.showMyCommand', true);

vscode.commands.executeCommand('setContext', 'myExtension.numberOfCoolOpenThings', 4);

检查上下文键实用工具

如果您想在运行时查看所有当前活动的上下文键,您可以使用命令面板中的开发者:检查上下文键命令(⇧⌘P (Windows, Linux Ctrl+Shift+P))。检查上下文键将在VS Code开发者工具的控制台标签中显示上下文键及其值(帮助 > 切换开发者工具)。

当你运行Developer: Inspect Context Keys时,你的光标会高亮显示VS Code UI中的元素,当你点击一个元素时,当前的上下文键及其状态将以对象的形式输出到控制台。

检查上下文键输出

活动上下文键的列表非常广泛,可能包含您已安装的扩展中的自定义上下文键

注意:一些上下文键是用于VS Code内部使用的,未来可能会有所更改。