如何配置Zsh使CTRL-R唤起hh工具并保留用户输入
Alright, let's solve this hh + Ctrl-R binding issue in Zsh (with oh-my-zsh) once and for all! The default hh setup only kicks in when your command line is empty, but we can tweak it to work seamlessly with pre-entered text—exactly what you need.
Step 1: Add the Custom Binding Code
First, we'll replace the default Ctrl-R binding with a custom Zsh widget that handles pre-entered input properly. You can add this code directly to your ~/.zshrc file, or drop it into a new file in ~/.oh-my-zsh/custom/ (like ~/.oh-my-zsh/custom/hh-custom.zsh—oh-my-zsh automatically loads all .zsh files in this directory):
# Unbind default Ctrl-R to avoid conflicts with hh bindkey -r '^R' # Define a custom widget to integrate hh with current command line input hh-with-preinput() { # Save the current command line content to restore later if needed local original_buffer="$BUFFER" # Run hh, passing your pre-entered text as the initial search query local selected_command=$(hh --query "$original_buffer") # Handle exit actions (Esc, Ctrl-C, Ctrl-G): restore original input if [ $? -ne 0 ]; then BUFFER="$original_buffer" CURSOR=${#BUFFER} # Move cursor to the end of your original input zle redisplay return fi # If a history command was selected, replace buffer and move cursor to end if [ -n "$selected_command" ]; then BUFFER="$selected_command" CURSOR=${#BUFFER} fi } # Register the widget and bind it to Ctrl-R zle -N hh-with-preinput bindkey '^R' hh-with-preinput
Step 2: What This Code Does (Breakdown)
Let's walk through the logic so you understand how it fits your needs:
- Unbind default Ctrl-R: Clears any existing binding for Ctrl-R so our custom widget can take over without conflicts.
- Save original input: Stores your current command line text in
original_buffer—this lets us restore your input if you exit hh without selecting a command. - Pass input to hh: Using
hh --query "$original_buffer"tells hh to start searching with your pre-entered text, so you only see relevant history entries right away. - Exit behavior: If you press Esc, Ctrl-C, or Ctrl-G to exit hh, the widget restores your original command line and moves the cursor to the end—like you never pressed Ctrl-R at all.
- Selection behavior: When you pick a history command and press Enter, the widget replaces your current input with the selected command, ready to execute immediately.
Step 3: Test the Setup
- Reload your Zsh config to apply the changes:
source ~/.zshrc - Try it out:
- Type something like
gitin your command line, then press Ctrl-R. hh will show all your historical commands containinggit. - Press Enter on a command to replace your current input with it.
- Press Esc, Ctrl-C, or Ctrl-G to go back to your original
gitinput.
- Type something like
That's all—this setup gives you exactly the behavior you're looking for.
内容的提问来源于stack exchange,提问作者Ruslan Stelmachenko

