From fa7e740249fc8a67e91e931d69a02e571644d336 Mon Sep 17 00:00:00 2001 From: Marty Oehme Date: Sun, 12 Oct 2025 13:23:42 +0200 Subject: [PATCH] terminal: Add fzf file insertion and zoxide cd key binds The following is added to all three shells bash, zsh, nushell: Pressing c-t at any time lets you insert a file/dir at the current cursor location using fzf. Same for 'T' in vicmd mode. Pressing alt-c at any time lets you jump to that directory using zoxide, with the zle editor content intact. Same for 'C' in vicmd mode. Zsh implementation from: https://github.com/ajeetdsouza/zoxide/issues/357 Bash implementation: https://github.com/ajeetdsouza/zoxide/issues/516 Nushell implementation taken from: https://github.com/junegunn/fzf/issues/4122 TODO: Nushell fzf mapping has one problem in that it does not quote the selected file in any way. So any file with e.g. a space in it will have to be manually fixed afterwards. --- terminal/.bashrc | 42 +++++++++++++++++++++----- terminal/.config/nushell/config.nu | 47 ++++++++++++++++++++++++++---- terminal/.config/zsh/.zshrc | 26 +++++++++++++++++ 3 files changed, 101 insertions(+), 14 deletions(-) diff --git a/terminal/.bashrc b/terminal/.bashrc index cea3f14..9a03b5a 100644 --- a/terminal/.bashrc +++ b/terminal/.bashrc @@ -12,16 +12,16 @@ CONFDIR="${XDG_CONFIG_HOME:-$HOME/.config}" [ -f "$CONFDIR/sh/alias" ] && source "$CONFDIR/sh/alias" # load additional aliases if [ -d "$CONFDIR/sh/alias.d" ]; then - for _alias in "$CONFDIR/sh/alias.d"/*.sh; do - . "$_alias" - done - unset _alias + for _alias in "$CONFDIR/sh/alias.d"/*.sh; do + . "$_alias" + done + unset _alias fi if [ -d "$CONFDIR/bash/alias.d" ]; then - for _alias in "$CONFDIR/bash/alias.d"/*.sh; do - . "$_alias" - done - unset _alias + for _alias in "$CONFDIR/bash/alias.d"/*.sh; do + . "$_alias" + done + unset _alias fi alias ls='ls --color=auto' @@ -35,4 +35,30 @@ set -o vi stty time 0 bind 'set keyseq-timeout 1' +# insert files with c-t or T in vicmd mode +FZF_CTRL_R_COMMAND="" FZF_ALT_C_COMMAND="" eval "$(fzf --bash)" +builtin bind -m vi-command '"T": "\C-z\C-t\C-z"' + +_run-cdi() { + # Get the directory from zoxide query + local dir=$(zoxide query -i) + + # If no directory is found, clear the line + if [[ -z "$dir" ]]; then + echo '' + return + fi + + # Call cd with the directory + cd -- "$dir" + + # Return the exit status of cd + return $? +} +# Make the function _run-cdi available +# shellcheck disable=SC2016 +bind -x '"\ec": "`_run-cdi`"' +# shellcheck disable=SC2016 +bind -m vi-command -x '"C": "`_run-cdi`"' + eval "$(atuin init bash)" diff --git a/terminal/.config/nushell/config.nu b/terminal/.config/nushell/config.nu index d7a0390..ebfefae 100644 --- a/terminal/.config/nushell/config.nu +++ b/terminal/.config/nushell/config.nu @@ -38,18 +38,18 @@ zoxide init nushell | save -f ($nu.data-dir | path join "vendor/autoload/zoxide. # load carapace completions source ~/.cache/carapace/init.nu - # keybinds $env.config.keybindings = [ { modifier: control keycode: char_o mode: [emacs, vi_normal, vi_insert] event: null }, { name: clear_screen - modifier: control - keycode: char_t + modifier: alt + keycode: char_l mode: ["emacs", "vi_normal", "vi_insert"] - event: { - send: ClearScreen - } + event: [ + {edit: Clear} + {send: Enter} + ] } { name: open_editor @@ -60,6 +60,41 @@ $env.config.keybindings = [ send: OpenEditor } } + { + name: run_zoxide + modifier: alt + keycode: char_c + mode: ["emacs", "vi_normal", "vi_insert"] + event: { + send: executehostcommand + cmd: "zoxide query --interactive" + } + } + { + name: run_zoxide_vicmd + modifier: shift + keycode: char_c + mode: [ "vi_normal"] + event: { + send: executehostcommand + cmd: "zoxide query --interactive" + } + } + { + name: insert_file_fzf + modifier: control + keycode: char_t + mode: ["emacs", "vi_normal", "vi_insert"] + event: { + send: executehostcommand + cmd: " + let fzf_ctrl_t_command = \$\"fd --type file --hidden | fzf --preview 'bat --color=always --style=full --line-range=:500 {}' \"; + let result = nu -l -i -c $fzf_ctrl_t_command; + commandline edit --append $result; + commandline set-cursor --end + " + } + } ] alias l = ls diff --git a/terminal/.config/zsh/.zshrc b/terminal/.config/zsh/.zshrc index 4bea925..40561b5 100644 --- a/terminal/.config/zsh/.zshrc +++ b/terminal/.config/zsh/.zshrc @@ -49,6 +49,9 @@ unset PLUG_FOLDER # simple fzf-tab settings zstyle ":fzf-tab:*" fzf-flags "--ansi" "--expect='$continuous_trigger,$print_query'" "--color=hl:$(($#headers == 0 ? 108 : 255))" "--nth=2,3" "--layout=reverse" "--height=${FZF_TMUX_HEIGHT:-75%}" "--tiebreak=begin" "-m" "--bind=tab:down,btab:up,change:top,ctrl-space:toggle" "--cycle" "--query=$query" "--header-lines=$#headers" "--print-query" +# enable inserting files or dirs using fzf with ctrl-t +FZF_CTRL_R_COMMAND="" FZF_ALT_C_COMMAND="" source <(fzf --zsh) + zstyle ':fzf-tab:*' fzf-command fzf # format colorful groups for different completion actions zstyle ':completion:*:descriptions' format '[%d]' @@ -208,6 +211,29 @@ _fix_cursor() { } precmd_functions+=(_fix_cursor) +_run-cdi() { + local dir="$(eval "zoxide query -i")" + if [[ -z "$dir" ]]; then + zle redisplay + return 0 + fi + zle push-line + BUFFER="builtin cd -- ${(q)dir}" + zle accept-line + local ret=$? + unset dir + zle reset-prompt + return $ret +} +zle -N _run-cdi + +# use alt-c or C in cmd mode to change dir using zoxide +bindkey '\ec' _run-cdi +bindkey -M vicmd 'C' _run-cdi +# add file insertion with fzf to T in cmd mode (c-t in insert) +# insert-mode keybind is above, using regular fzf sourcing +bindkey -M vicmd 'T' fzf-file-widget + # space puts a space, even in cmd mode bindkey -a ' ' magic-space # always allow backspace/delete to remove letters