diff --git a/crates/forge_main/src/zsh/plugin.rs b/crates/forge_main/src/zsh/plugin.rs index b54e3e9baa..c91ee70a9a 100644 --- a/crates/forge_main/src/zsh/plugin.rs +++ b/crates/forge_main/src/zsh/plugin.rs @@ -426,6 +426,20 @@ mod tests { assert_eq!(actual, expected); } + /// Regression: forge keybindings must survive zsh-vi-mode's `zvm_init` + /// by re-applying via `zvm_after_init_commands` (#2681). + #[test] + fn test_generated_plugin_registers_zvm_after_init_hook() { + use pretty_assertions::assert_eq; + + let fixture = generate_zsh_plugin().unwrap(); + let actual = fixture.contains("function _forge_apply_keybindings()") + && fixture.contains("typeset -ga zvm_after_init_commands") + && fixture.contains("zvm_after_init_commands+=('_forge_apply_keybindings')"); + let expected = true; + assert_eq!(actual, expected); + } + #[test] fn test_setup_zsh_integration_without_nerd_font_config() { use tempfile::TempDir; diff --git a/shell-plugin/lib/bindings.zsh b/shell-plugin/lib/bindings.zsh index 432d0cb421..0476dd43cf 100644 --- a/shell-plugin/lib/bindings.zsh +++ b/shell-plugin/lib/bindings.zsh @@ -35,11 +35,17 @@ function forge-bracketed-paste() { zle reset-prompt } -# Register the bracketed paste widget to fix highlighting on paste -zle -N bracketed-paste forge-bracketed-paste +# Re-applied after zsh-vi-mode's `zvm_init` precmd hook, which rebuilds the +# main/viins/vicmd keymaps and otherwise silently clobbers these bindings. +function _forge_apply_keybindings() { + zle -N bracketed-paste forge-bracketed-paste + bindkey '^M' forge-accept-line + bindkey '^J' forge-accept-line + bindkey '^I' forge-completion +} + +_forge_apply_keybindings -# Bind Enter to our custom accept-line that transforms :commands -bindkey '^M' forge-accept-line -bindkey '^J' forge-accept-line -# Update the Tab binding to use the new completion widget -bindkey '^I' forge-completion # Tab for both @ and :command completion +# Harmless no-op when zsh-vi-mode (jeffreytse/zsh-vi-mode) isn't loaded. +typeset -ga zvm_after_init_commands +zvm_after_init_commands+=('_forge_apply_keybindings')