ARTICLE DETAIL

资讯详情

深耕网站视觉设计与运营推广的一线实战洞察。

Onivim 2 按键绑定(Key Bindings)配置完全指南:keybindings.json 格式、when 条件上下文与命令参考

Onivim 2 按键绑定(Key Bindings)配置完全指南:keybindings.json 格式、when 条件上下文与命令参考 开发工具代码编辑器桌面应用【免费下载链接】oni2Native, lightweight modal code editor项目地址https://gitcode.com/gh_mirrors/on/oni2点击查看免费下载Onivim 2 的按键绑定体系在设计上力求与 VSCode 的 Key Bindings 兼容同时完整保留 Vim 用户的映射习惯——你既可以用C-P这类 Vim 风格键位也可以用CtrlP这类 VSCode 风格写法还可以通过jj、jk键序列和from/to重映射实现类:inoremap的效果。本文以 key-bindings.md 为核心结合src/Feature/Input/下的真实解析与执行代码完整讲解键位文件的编辑方式、JSON 规则格式、when上下文表达式、内置命令清单以及 Leader Key 的使用方法读完即可动手定制属于你自己的 Onivim 2 键位方案。编辑按键绑定文件Onivim 2 的按键绑定存放在一个 JSON 数组中文件名为keybindings.json。打开它的标准流程是按CommandShiftPMac或ControlShiftPWindows / Linux呼出命令面板选择Preferences: Open keybindings File。该命令在源码中对应workbench.action.openDefaultKeybindingsFile实现在 src/Feature/Input/Feature_Input.reCommands.openDefaultKeybindingsFile其行为是取出keybindingLoader记录的文件路径并发出OpenFile效果打开该文件见 Feature_Input.re。首次创建时Onivim 2 会生成一份默认骨架内容定义在 src/Core/ConfigurationDefaults.re形如[ // See the onivim documentation for details on the format: // https://onivim.github.io/docs/configuration/key-bindings // Add key bindings here, for example: // { key: TAB, command: workbench.action.quickOpen, when: editorTextFocus }, // { key: jk, command: vim.esc, when: insertMode }, ]文件保存后会被实时重载KeybindingsLoadersrc/Feature/Input/KeybindingsLoader.re监听 JSON 文件的保存事件saveTick递增触发重新订阅解析结果通过KeybindingsReloaded消息更新状态机并逐个替换旧的用户绑定updateKeybindings见 Feature_Input.re。若解析出错错误信息会以通知的形式上报ErrorNotifications见 Feature_Input.re。Keybinding 格式按键绑定定义为 JSON 数组每条规则形如[ { key: C-P, command: workbench.action.quickOpen, when: editorTextFocus } ]每条规则由三个部分组成key描述按下的按键组合Vim 风格或 VSCode 风格详见下文command要执行命令的标识符when可选一个布尔表达式根据当前编辑器状态决定该规则是否生效。从源码看解析器还支持额外字段args命令参数和 remap 专用的from/to/recursive详见 src/Feature/Input/Keybindings.re 中的Decode.binding与Decode.remap。匹配顺序与优先级按键按下时规则按以下逻辑处理规则从底向上逐条评估第一条同时满足key与when条件的规则胜出若命中且带有command则执行该命令若没有任何规则命中按键会被透传给libvim交由 Vim 处理对应InputStateMachine产生的Unhandled效果见 src/Feature/Input/InputStateMachine.re。Onivim 2 自带一套默认规则而用户自定义规则会被追加到列表底部——因此用户的绑定总是先于默认绑定被评估。实现上用户绑定被单独登记userBindings在重载时先全部移除再重新加入状态机默认绑定则始终存在见 Feature_Input.re。key格式key参数同时支持Vim 风格和VSCode 风格两种写法。Vim 风格Vim 风格的键位用和包裹支持以下修饰符修饰符说明示例C-Control 键C-PS-Shift 键S-PA-Alt 键A-PD-Command 键D-P注意与 Vim 的一个区别是Onivim 中的D-在 Linux 和 Windows 上分别对应 Meta 键与 Win 键。修饰符可以组合使用例如[ { key: C-S-P, command: workbench.action.quickOpen, when: editorTextFocus } ]C-S-P表示需要同时按下 Control、Shift 和 P 三个键。VSCode 风格VSCode 风格使用友好名称例如修饰符说明示例CtrlControl 键CtrlPShiftShift 键ShiftPAltAlt 键AltJMetaMeta / Command / Windows 键Cmd同上CmdPWin同上WinP在源码实现中两种风格最终都会被解析为统一的EditorInput.Matcher.tSchema.resolve通过EditorInput.Matcher.parse(~explicitShiftKeyNeededtrue, key)解析绑定键src/Feature/Input/Schema.re。explicitShiftKeyNeededtrue意味着 JSON 中必须显式写出 Shift如S-P这与 VSCode 的解析行为保持一致而在处理 VimL 映射VimMap消息时该开关被置为false以便J这类字符能自动解析为Shiftj见 Feature_Input.re。键序列Key SequencesOnivim 2 支持将绑定注册为键序列需要连续按下多个键才会触发。例如{ key: jk, command: vim.esc, when: insertMode }该规则要求先按j、再按k才会执行。键序列与普通组合键统一由EditorInput.Matcher表示Sequence(keys)并在candidates/commandToAvailableBindings中被枚举见 Feature_Input.re。Remaps重映射除直接绑定命令外同一份配置文件还支持remap。重映射对 Vim 用户更自然它匹配一个键序列然后产出一组新的按键。remap 需要 3 个字段from源键格式与key相同to目标键格式与key相同when重映射生效的上下文子句。示例{ from: jj, to: esc, when: editorTextFocus insertMode }它在功能上等价于:inoremap jj ESC。解析器还会读取可选的recursive字段默认false即默认非递归映射行为接近noremap系列见 Keybindings.re。重映射的命中同样先经过when条件求值再通过InputStateMachine.addMapping注册Feature_Input.re若to目标键解析失败会返回MapParseError通知用户见 Feature_Input.re。为防止无限循环状态机还内置了RemapRecursionLimitHit效果进行保护InputStateMachine.re。when条件上下文Onivim 2 通过when子句精确控制键绑定何时生效。条件运算符条件表达式支持以下运算符运算符符号示例或\|\|listFocus \|\| textInputFocus与insertMode suggestWidgetVisible表达式可以用()分组例如(editorTextFocus !insertMode) || suggestWidgetVisible底层实现中when字符串由WhenExpr.parse解析成表达式树Defined、Eq、Neq、Regex、And、Or、Not、Value再通过WhenExpr.evaluate结合当前的ContextKeys求值见 src/Core/WhenExpr/WhenExpr.rei。上下文键由各组件通过ContextKeys.Schema.define/bool/string声明后聚合WhenExpr.rei例如输入框组件贡献textInputFocus、VimList 组件贡献vimListNavigation见 src/Components/InputText/Component_InputText.re 与 src/Components/VimList/Component_VimList.re。与 VSCode 通用的上下文上下文名为真的时机editorFocus编辑器获得焦点editorTextFocus编辑器文本区获得焦点hasSearchResults存在搜索结果inSnippetMode有 snippet 会话处于活动状态renameInputVisible重命名输入框可见suggestWidgetVisible建议自动补全浮窗可见textInputFocus文本输入区获得焦点terminalFocus终端获得焦点activeViewlet上下文键对应当前打开的侧边栏面板 idworkbench.view.explorer—— 文件浏览器workbench.view.extensions—— 扩展workbench.view.scm—— 源码管理workbench.view.search—— 搜索editorLangId上下文键对应当前编辑器的语言标识符与状态栏显示的值一致可与其它上下文组合例如{ key: F12, command: editor.action.revealDefinition, when: editorFocus editorLangId typescript }Onivim 2 特有的上下文上下文名为真的时机insertMode当前编辑器处于插入模式normalMode当前编辑器处于普通模式visualMode当前编辑器处于可视模式sneakModeSneak 模式激活commandLineFocusVim 命令行打开listFocus列表如下拉菜单获得焦点sideBarFocus侧边栏获得焦点且可见sideBarVisible侧边栏可见paneFocus底部面板获得焦点vimListNavigation处于可 Vim 导航的列表中vimTreeNavigation处于文件浏览器中值得注意Vim 的模式上下文是动态映射的。当 VimL 执行:imap、:nmap等映射命令时Feature_Input会把 Vim 映射模式翻译为对应的when表达式——例如 Insert 模式映射为insertMode、Normal 模式映射为normalMode、Visual 模式映射为visualMode、CommandLine 模式映射为commandLineFocus等等见 Feature_Input.re 的vimMapModeToWhenExpr。这意味着你在 keybindings.json 里写的when条件与 VimL 的:map命令最终进入的是同一条输入状态机通道。命令参考以下表格列出 Onivim 2 内置的默认按键与命令。表中以删除线~~标注的条目表示该默认绑定可能尚未完全接线或仅部分生效。通用命令默认按键说明命令CommandShiftP / ControlShiftP显示命令面板workbench.action.showCommandsCommandShiftM / ControlShiftM显示问题面板workbench.actions.view.problemsCommandP / ControlP快速打开文件选择器workbench.action.quickOpenControlTab在编辑器组内导航到下一个编辑器workbench.action.quickOpenNavigateNextInEditorPickerShiftControlTab在编辑器组内导航到上一个编辑器workbench.action.quickOpenNavigatePreviousInEditorPickerCommandPageDown导航到下一个标签页workbench.action.nextEditorCommandPageUp导航到上一个标签页workbench.action.previousEditorCommand / Control放大workbench.action.zoomInCommand- / Control-缩小workbench.action.zoomOutCommand0 / Control0重置缩放workbench.action.zoomReset基础编辑默认按键说明命令ControlV / CommandV从剪贴板粘贴editor.action.clipboardPasteActionControlS / CommandS保存文件workbench.action.files.save语言特性默认按键说明命令F2重命名editor.action.renameF12 或gd跳转到定义editor.action.revealDefinitionShiftF12跳转到引用editor.action.goToReferences列表 / 菜单命令注意部分列表选择命令可能尚未完全接线例如可能不遵守垂直/水平打开方式。默认按键说明命令上箭头 / ControlP焦点上移list.focusUp下箭头 / ControlN焦点下移list.focusDownEnter选中当前项list.selectShift-Enter选中当前项垂直打开oni.list.selectVerticalCtrl-x选中当前项水平打开oni.list.selectHorizontalCtrl-t选中当前项新标签页oni.list.selectNewTab搜索面板默认按键说明命令F4聚焦下一个搜索结果search.action.focusNextSearchResultShiftF4聚焦上一个搜索结果search.action.focusPreviousSearchResult侧边栏默认按键说明命令CommandShiftE / ControlShiftE聚焦资源管理器workbench.view.explorerCommandShiftF / ControlShiftF聚焦搜索workbench.action.findInFilesCommandShiftX / ControlShiftX聚焦扩展workbench.view.extensionsControlShiftG聚焦源代码管理workbench.view.scmControlW, ControlJ向下导航一个分区vim.window.moveDownControlW, ControlK向上导航一个分区vim.window.moveUpSnippets默认按键说明命令n/a插入 Snippeteditor.action.insertSnippetn/a配置用户 snippetsworkbench.action.openSnippets窗口管理默认按键说明命令ControlW, ControlV垂直分割view.splitVerticalControlW, ControlS水平分割view.splitHorizontalControlW, ControlH移动到左侧分割window.moveLeftControlW, ControlL移动到右侧分割window.moveRightControlW, ControlJ向下移动分割window.moveDownControlW, ControlK向上移动分割window.moveUpControlW, ControlR向前旋转view.rotateForwardControlW, ControlShiftR向后旋转view.rotateBackward减小编辑器尺寸workbench.action.decreaseViewSize增大编辑器尺寸workbench.action.increaseViewSizeControlW, 水平减小编辑器尺寸vim.decreaseHorizontalWindowSizeControlW, 水平增大编辑器尺寸vim.increaseHorizontalWindowSizeControlW, -垂直减小编辑器尺寸vim.decreaseVerticalWindowSizeControlW, 垂直增大编辑器尺寸vim.increaseVerticalWindowSize向上减小编辑器尺寸vim.decreaseWindowSizeUp向上增大编辑器尺寸vim.increaseWindowSizeUo向下减小编辑器尺寸vim.decreaseWindowSizeDown向下增大编辑器尺寸vim.increaseWindowSizeDown向左减小编辑器尺寸vim.decreaseWindowSizeLeft向左增大编辑器尺寸vim.increaseWindowSizeLeft向右减小编辑器尺寸vim.decreaseWindowSizeRight向右增大编辑器尺寸vim.increaseWindowSizeRightControlW, O最大化编辑器workbench.action.maximizeEditorControlW, |水平最大化编辑器vim.maximizeWindowWidthControlW, _垂直最大化编辑器vim.maximizeWindowHeight切换编辑器组尺寸workbench.action.toggleEditorWidthsControlW, 重置编辑器尺寸workbench.action.evenEditorWidthsVim 命令默认按键说明命令Escape向 Vim 发送ESCvim.esc附加命令默认按键说明命令n/a启用按键显示器keyDisplayer.enablen/a禁用按键显示器keyDisplayer.disable按键显示器Key Displayer用于在屏幕上实时回显你按下的键便于调试键位其开关命令对应Command(EnableKeyDisplayer)/Command(DisableKeyDisplayer)消息源码见 Feature_Input.re。Ex 命令绑定以:冒号开头的command会被解释为 Vim 的 Ex 命令且可以携带参数。示例{ key: kk, command: :split, when: editorTextFocus }, { key: C-D, command: :d 2, when: insertMode }第一条例绑定普通模式下的kk执行:split第二条在插入模式下按C-D执行:d 2删除 2 行。实现上这类绑定在解析时被包装为VimExCommand执行体见 src/Feature/Input/InputStateMachine.re并直接进入输入状态机VimL 的:map ... :cmd映射也会走同一条VimExCommand通道Feature_Input.re。Leader KeyLeader 键通过配置项vim.leader指定注意它位于configuration.json而不是keybindings.json{ vim.leader: space }也可以使用 Ex 命令指定:nmap space Leader定义好 leader 后它可以同时用于keybindings.json和 VimL 映射命令[ { key: Leaderp, command: workbench.action.quickOpen, when: editorTextFocus normalMode } ]或等价地在 VimL 中:nnoremap Leaderp C-S-P在源码中vim.leader通过CustomDecoders.physicalKey解码值(none)表示未设置其余字符串按 VSCode 风格显式 Shift解析为物理键见 Feature_Input.re。每次keyDown/keyUp/text处理都会读取该配置将其作为 leader 传给InputStateMachineFeature_Input.re因此Leaderp中的Leader会被替换为实际的物理键参与匹配。进阶技巧结合 Vim 的映射与超时控制VimL 映射自动接入在 VimL 中执行:map、:noremap等命令时Feature_Input会通过VimMap消息解析映射内容并注册进同一套输入状态机Feature_Input.re因此 VimL 定义的映射与 keybindings.json 定义的绑定遵循同一套匹配优先级和when语义。超时控制vim.timeout配置对应 Vim 的timeout/timeoutlen决定键序列匹配的超时时间默认 1 秒可以设为布尔值true/false或毫秒整数超时后状态机会清空未完成的键序列见 Feature_Input.re 与CustomDecoders.Timeout。如果你的jj、jk键序列感觉粘键可以调小该值。错误即通知keybindings.json 中存在无法解析的条目时Onivim 2 不会整体拒绝文件而是跳过坏条目、保留其余有效绑定并把错误列表以通知形式展示Keybindings.re、KeybindingsLoader.re方便你边改边看哪里写错了。兼容旧格式解析器同时兼容早期的{ bindings: [...] }对象格式并会把quickOpen.open、commandPalette.open等旧命令名自动升级为workbench.action.quickOpen、workbench.action.showCommandsKeybindings.re。小结Onivim 2 的按键绑定设计融合了三套能力与 VSCode 兼容的 JSON 规则key/command/when、Vim 用户熟悉的键序列与 remap 语义、以及统一的when条件上下文体系。通过 docs/docs/configuration/key-bindings.md 这份文档与 src/Feature/Input/ 下的实现Keybindings.re负责解析、Schema.re负责解析为匹配器、InputStateMachine.re负责按键状态机、Feature_Input.re负责整体调度你既可以用keybindings.json声明式地完成绝大多数键位定制也可以继续依赖 VimL 的:map/:noremap传统映射并借助vim.leader、vim.timeout与按键显示器精确调优输入体验。赞分享开发工具代码编辑器桌面应用【免费下载链接】oni2Native, lightweight modal code editor项目地址https://gitcode.com/gh_mirrors/on/oni2点击查看免费下载相关推荐Trippy TUI 按键绑定完全指南默认键位表、--tui-key-bindings 与配置文件自定义Trippy TUI 按键绑定完全指南默认键位表、 tui key bindings 与配置文件自定义 Trippy 是一款网络诊断工具其 TUI终端用户网络CLI运维Draft.js 按键绑定Key Bindings完全指南从内置默认命令到自定义快捷键映射Draft.js 按键绑定Key Bindings完全指南从内置默认命令到自定义快捷键映射 Editor 组件通过 keyBindingFn 属性将键盘事前端UI组件Trippy TUI 按键绑定参考默认按键表、命令行与配置文件自定义实战指南Trippy TUI 按键绑定参考默认按键表、命令行与配置文件自定义实战指南 本文是 Trippy 网络诊断工具 TUI 界面的按键绑定Key Bindin网络CLI运维上一篇Awesome Cheatsheets火电科技速查锅炉控制与emissions管理下一篇从重叠到精准Detectron中NMS改进与边界框优化实战指南创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考
返回列表