From 3cf445e73923ece64cf580b91a2429ed5546a1bc Mon Sep 17 00:00:00 2001 From: Julian Prein Date: Wed, 6 Aug 2025 12:19:56 +0200 Subject: [PATCH] zsh:keys: Modify fzf's cd widget to be "in-prompt" Currently, fzf's cd widget executes the cd command via accept-line, so the command is also visible in the scrollback buffer. In contrast to this, the cd-{forward,backward,up} suite changes the directory in-place, without touching BUFFER, with an additional prompt redraw (one could say "in-prompt"). Since I find this more appealing, overwrite the default fzf widget with a custom one that has the same behaviour. --- .config/zsh/zshrc.d/60-keys.zsh | 25 +++++++++++++++++++++++++ 1 file changed, 25 insertions(+) diff --git a/.config/zsh/zshrc.d/60-keys.zsh b/.config/zsh/zshrc.d/60-keys.zsh index 64b6d6d..44116f6 100644 --- a/.config/zsh/zshrc.d/60-keys.zsh +++ b/.config/zsh/zshrc.d/60-keys.zsh @@ -126,6 +126,27 @@ function cd-up { } zle -N cd-up +# Modified version of +# https://github.com/junegunn/fzf/blame/f864f8b5f7ab/shell/key-bindings.zsh#L81-L99 +# that changes the directory "in-prompt" like cd-{forward,backward,up}; meaning +# that the `cd` command is executed in the background with a prompt redraw +# instead of via `$BUFFER` and `accept-line`. +fzf-cd-inprompt-widget() { + setopt localoptions pipefail no_aliases 2>/dev/null + local dir="$( + FZF_DEFAULT_COMMAND=${FZF_ALT_C_COMMAND:-} \ + FZF_DEFAULT_OPTS=$(__fzf_defaults "--reverse --walker=dir,follow,hidden --scheme=path" "${FZF_ALT_C_OPTS-} +m") \ + FZF_DEFAULT_OPTS_FILE='' $(__fzfcmd) < /dev/tty)" + if [[ -z "$dir" ]]; then + zle redisplay + return 0 + fi + # --- modifications start here --- + pushd -q "$dir" + redraw-prompt +} +zle -N fzf-cd-inprompt-widget + # cycle through `dirs` with ^o and ^i similar to the jumplist in vim. # Need AUTO_PUSHD (see options.zsh) bindkey '^O' cd-backward @@ -256,3 +277,7 @@ FZF_CTRL_T_COMMAND="${FZF_DEFAULT_COMMAND} 2>/dev/null" # See .zprofile for FZF_ALT_C_COMMAND comp-source "$ZDOTDIR/plugins/fzf/shell/key-bindings.zsh" + +# Overwrite fzf's Alt-C binding to be "in-prompt" (see above) +bindkey -M vicmd '\ec' fzf-cd-inprompt-widget +bindkey -M viins '\ec' fzf-cd-inprompt-widget