Fzf: "Dedicated completion key" for bash

Created on 28 Dec 2019  路  1Comment  路  Source: junegunn/fzf

  • [x] I have read through the manual page (man fzf)
  • [x] I have the latest version of fzf
  • [x] I have searched through the existing issues

Info

  • OS

    • [x] Linux

    • [ ] Mac OS X

    • [ ] Windows

    • [ ] Etc.

  • Shell

    • [x] bash

    • [ ] zsh

    • [ ] fish

Problem / Steps to reproduce

Not sure how to implement "Dedicated completion key" (https://github.com/junegunn/fzf/wiki/Configuring-fuzzy-completion) for bash. Here is my attempt at it (complete with commented out failed attempts):
```# required for fzf
[ -f ~/.fzf.bash ] && source ~/.fzf.bash
[ -f ~/.git.bash ] && . ~/.git.bash

export FZF_COMPLETION_TRIGGER='' # previously '**'
bind -x '"\C-e": fzf-completion'

alias ^E='fzf-completion' # doesn't work

```

Thanks!

question tip

Most helpful comment

The exact equivalent is not possible in bash because unlike in zsh, you have to register a completion function for each command, command by command. So, we have to use a different mechanism to implement similar functionality.

Write a function for a specific type of list and bind it to a dedicated key like so:

# Complete word. Works on bash 4+
fzf-word-widget() {
  local prefix=${READLINE_LINE:0:$READLINE_POINT}
  local token=$(sed 's/.* //' <<< "$prefix")
  [ ${#token} -gt 0 ] && prefix=${prefix::-${#token}}

  local selected="$(fzf --height=10 --reverse --border --info=inline --query="$token" < /usr/share/dict/words)"
  [ -z "$selected" ] && return

  READLINE_LINE="$prefix$selected${READLINE_LINE:$READLINE_POINT}"
  READLINE_POINT=$(( READLINE_POINT - ${#token} + ${#selected} ))
}

bind -m emacs-standard -x '"\C-x\C-w": "fzf-word-widget"'

Similarly, you can write functions for directories, processes, etc and bind them to different keys. Or, you could write a smarter "one-size-fits-all" function that extracts the name of the command on the prompt and automatically starts fzf with the most appropriate type of list. That would be really cool.

>All comments

The exact equivalent is not possible in bash because unlike in zsh, you have to register a completion function for each command, command by command. So, we have to use a different mechanism to implement similar functionality.

Write a function for a specific type of list and bind it to a dedicated key like so:

# Complete word. Works on bash 4+
fzf-word-widget() {
  local prefix=${READLINE_LINE:0:$READLINE_POINT}
  local token=$(sed 's/.* //' <<< "$prefix")
  [ ${#token} -gt 0 ] && prefix=${prefix::-${#token}}

  local selected="$(fzf --height=10 --reverse --border --info=inline --query="$token" < /usr/share/dict/words)"
  [ -z "$selected" ] && return

  READLINE_LINE="$prefix$selected${READLINE_LINE:$READLINE_POINT}"
  READLINE_POINT=$(( READLINE_POINT - ${#token} + ${#selected} ))
}

bind -m emacs-standard -x '"\C-x\C-w": "fzf-word-widget"'

Similarly, you can write functions for directories, processes, etc and bind them to different keys. Or, you could write a smarter "one-size-fits-all" function that extracts the name of the command on the prompt and automatically starts fzf with the most appropriate type of list. That would be really cool.

Was this page helpful?
0 / 5 - 0 ratings