bashdirectoryfzf

How to add a specific folder tree to the fzf search list?


I use fzf in bash on Gentoo Linux and configured it in the ~/.bashrc with

if [ -x "$(command -v fzf)"  ]
then
    source /usr/share/fzf/key-bindings.bash
fi


export FZF_DEFAULT_OPTS="
--layout=reverse
--info=inline
--height=80%
--multi
--preview-window=:hidden
--preview '([[ -f {} ]] && (bat --style=numbers --color=always {} || cat {})) || ([[ -d {} ]] && (tree -C {} | less)) || echo {} 2> /dev/null | head -200'
--color='hl:148,hl+:154,pointer:032,marker:010,bg+:237,gutter:008'
--prompt='∼ ' --pointer='▶' --marker='✓'
--bind 'ctrl-p:toggle-preview'
--bind 'ctrl-a:select-all'
--bind 'ctrl-y:execute-silent(echo {+} | pbcopy)'
--bind 'ctrl-e:execute(echo {+} | xargs -o vim)'
--bind 'ctrl-v:execute(code {+})'
"

CTRL-T should now provide a fuzzy search in ~/my/.. and in /usr/local/. What is the best way to teach fzf about these two directory trees?


Solution

  • Short Answer:

    You should use the variable FZF_CTRL_T_COMMAND and set your custom command. In this case you should use something like this:

    export FZF_CTRL_T_COMMAND="find ~/my/.. /usr/local"
    

    And now, when you press Ctrl-T you will be able to search only in those directories.

    Long Answer:

    I realized that you should use FZF_CTRL_T_COMMAND variable by inspecting into the key-bindings file, in my case, this one is located in: /usr/share/bash-completion/completions/fzf-key-bindings in your case might be /usr/share/fzf/key-bindings.bash.

    If you check in that file you should see a function called __fzf_select__ and inside this one you might have something like this:

    __fzf_select__() {
      local cmd opts
      cmd="${FZF_CTRL_T_COMMAND:-"command find -L . -mindepth 1 \\( -path '*/\\.*' -o -fstype 'sysfs' -o -fstype 'devfs' -o -fstype 'devtmpfs' -o -fstype 'proc' \\) -prune \
        -o -type f -print \
        -o -type d -print \
        -o -type l -print 2> /dev/null | cut -b3-"}"
      opts="--height ${FZF_TMUX_HEIGHT:-40%} --bind=ctrl-z:ignore --reverse $FZF_DEFAULT_OPTS $FZF_CTRL_T_OPTS -m"
      eval "$cmd" |
        FZF_DEFAULT_OPTS="$opts" $(__fzfcmd) "$@" |
        while read -r item; do
          printf '%q ' "$item"  # escape special chars
        done
    }
    

    As you can see, the assignation in the third line: cmd="${FZF_CTRL_T_COMMAND:-"command find -L . ..."}" means that the command to execute will be what FZF_CTRL_T_COMMAND variable has, but if this is empty then it should execute the function defined there: command find -L . ..

    Maybe you should take a look at the assignment command find -L ... and set your FZF_CTRL_T_COMMAND similarly or you can simply set it as I specified in the short answer and it will work: export FZF_CTRL_T_COMMAND="find ~/my/.. /usr/local"