Skip to content

Commit

Permalink
Add glob completion & enhance fzf integration
Browse files Browse the repository at this point in the history
Address issue #51.
  • Loading branch information
marlonrichert committed Jun 17, 2020
1 parent e03aeb2 commit 15d9f23
Show file tree
Hide file tree
Showing 2 changed files with 51 additions and 47 deletions.
7 changes: 6 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ When you source
| --- | --- |
| [<kbd>↓</kbd>](# "down") | Select a completion or (in multi-line buffer) move cursor down |
| [<kbd>↑</kbd>](# "up") | Do fuzzy history search or (in multi-line buffer) move cursor up |
| [<kbd>⌃␣</kbd>](# "ctrl-space") | Change directory (in empty buffer), expand alias, insert longest common prefix (on glob expression) or do fuzzy file search |
| [<kbd>⌃␣</kbd>](# "ctrl-space") | Change directory (in empty buffer), correct spelling, expand alias, insert longest common prefix (on glob expressions) or do fuzzy file search |
| [<kbd>⌥↓</kbd>](# "alt-down") | Enter completion menu (also in multi-line buffer) |
| [<kbd>⌥↑</kbd>](# "alt-up") | Do fuzzy history search (also in multi-line buffer) |

Expand Down Expand Up @@ -175,6 +175,11 @@ zstyle ':autocomplete:tab:*' completion insert
**Note:** This last option also changes the listings slightly to not do completion to the left of
what you've typed (unless that would result in zero matches).

To have [<kbd>⇥</kbd>](# "tab") use [`fzf`'s completion feature](#requirements):
```shell
zstyle ':autocomplete:tab:*' completion fzf
```


### Customize autocompletion messages
You can customize the various messages that the autocompletion feature shows.
Expand Down
91 changes: 45 additions & 46 deletions zsh-autocomplete.zsh
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@
[[ ! -v ZLE_REMOVE_SUFFIX_CHARS ]] && export ZLE_REMOVE_SUFFIX_CHARS=$' \t\n;&'

[[ ! -v _autocomplete__options ]] && export _autocomplete__options=(
ALWAYS_TO_END COMPLETE_ALIASES GLOB_COMPLETE GLOB_DOTS LIST_PACKED
no_CASE_GLOB no_COMPLETE_IN_WORD no_LIST_BEEP
ALWAYS_TO_END COMPLETE_ALIASES GLOB_DOTS GLOB_STAR_SHORT LIST_PACKED
no_CASE_GLOB no_COMPLETE_IN_WORD no_GLOB_COMPLETE no_LIST_BEEP
)

# Workaround for issue #43
Expand Down Expand Up @@ -84,8 +84,6 @@ _autocomplete.main.hook() {
reply=( "^(${(b)prefix}${punct}(#i)${(b)nonpunct[1]}*)"
"${(b)prefix}${punct}[[:punct:]]*" )
fi'
zstyle -e ':completion:*' glob '
[[ $PREFIX$SUFFIX == *[\*\(\|\<\[\?\^\#]* ]] && reply=( "true" ) || reply=( "false" )'

zstyle -e ':completion:*' tag-order '
reply=( "(|*-)argument-* (|*-)option[-+]* values" "options" )
Expand All @@ -96,38 +94,27 @@ _autocomplete.main.hook() {
fi'
zstyle ':completion:*:(-command-|cd|z):*' tag-order '! users' '-'

zstyle ':completion:*:expand:*' tag-order '! all-expansions original'

zstyle -e ':completion:*' max-errors '
reply=( $(( min(7, (${#PREFIX} + ${#SUFFIX}) / 2 - 1) )) numeric )'

zstyle -e ':completion:*' glob '
[[ $PREFIX$SUFFIX == *[\*\(\|\<\[\?\^\#]* ]] && reply=( "true" ) || reply=( "false" )'
zstyle ':completion:*' expand prefix suffix
zstyle ':completion:*' list-suffixes false
zstyle ':completion:*' path-completion false
zstyle ':completion:*:(-command-|cd|z):*' list-suffixes true
zstyle ':completion:*:(-command-|cd|z):*' path-completion true

zstyle ':completion:*' file-patterns \
'*(#q^-/):all-files:file *(-/):directories:directory' '%p:globbed-files:"file or directory"'
zstyle ':completion:*:-command-:*' file-patterns \
'*(-/):directories:directory %p(#q^-/):globbed-files:executable' '*:all-files:file'
zstyle ':completion:*:z:*' file-patterns '%p(-/):directories:directory'
zstyle ':completion:*' list-suffixes true
zstyle ':completion:*' path-completion true
zstyle ':completion:*' list-dirs-first true
zstyle ':completion:*:z:*' file-patterns '%p(-/):directories'

local directory_tags=( local-directories directory-stack named-directories directories )
zstyle ':completion:*' group-order all-files directories globbed-files
zstyle ':completion:*:(-command-|cd|z):*' group-order globbed-files directories all-files
zstyle ':completion:*:(all-files|globbed-files)' group-name ''
zstyle ':completion:*:cd|z:*:globbed-files' group-name 'directories'
zstyle ':completion:*:('${(j:|:)directory_tags}')' group-name 'directories'
zstyle ':completion:*:('${(j:|:)directory_tags}')' matcher 'm:{[:lower:]}={[:upper:]}'
zstyle ':completion:*:('${(j:|:)directory_tags}')' matcher \
'm:{[:lower:][:upper:]-_}={[:upper:][:lower:]_-}'

if zstyle -t ':autocomplete:' groups 'always'; then
zstyle ':completion:*' format '%F{yellow}%d:%f'
zstyle ':completion:*' group-name ''
fi

zstyle ':completion:*:expansions' format '%F{yellow}%d:%f'
zstyle ':completion:*:expansions' group-name ''
zstyle ':completion:*:messages' format '%F{blue}%d%f'
zstyle ':completion:*:warnings' format '%F{red}%d%f'
zstyle ':completion:*' auto-description '%F{yellow}%d%f'
Expand All @@ -144,10 +131,9 @@ _autocomplete.main.hook() {
zstyle ':completion:correct-word:*' add-space false
zstyle ':completion:correct-word:*' glob false

zstyle ':completion:list-choices:*' glob false
zstyle ':completion:list-choices:*' menu ''

zstyle ':completion:expand-word:*' completer _expand_alias _expand
zstyle ':completion:expand-word:*' glob true

zstyle ':completion:list-expand:*' completer _expand _complete _ignored _approximate
zstyle ':completion:list-expand:complete:*' matcher-list \
Expand All @@ -159,8 +145,6 @@ _autocomplete.main.hook() {
local punct=${(M)suffix##[[:punct:]]##}
reply=( "${(b)prefix}${punct}[[:punct:]]*" )'
zstyle ':completion:list-expand:*' tag-order '*'
zstyle ':completion:list-expand:*' list-suffixes true
zstyle ':completion:list-expand:*' path-completion true
zstyle ':completion:list-expand:*' format '%F{yellow}%d:%f'
zstyle ':completion:list-expand:*' group-name ''
zstyle ':completion:list-expand:*' extra-verbose true
Expand Down Expand Up @@ -248,7 +232,7 @@ _autocomplete.main.hook() {
fi
zle -C correct-word complete-word _autocomplete.correct-word.completion-widget
bindkey '^[ ' self-insert-unmeta

local tab_completion
zstyle -s ":autocomplete:tab:" completion tab_completion || tab_completion='accept'
case $tab_completion in
Expand Down Expand Up @@ -293,6 +277,12 @@ _autocomplete.main.hook() {
else
bindkey $key[Tab] complete-word
fi
;;
'fzf')
export fzf_default_completion='complete-word'
;;
esac
if [[ $tab_completion == (accept|fzf) ]]; then
zle -C complete-word complete-word _autocomplete.complete-word.completion-widget
bindkey $key[BackTab] list-expand
zle -C list-expand menu-select _autocomplete.list-expand.completion-widget
Expand All @@ -308,23 +298,22 @@ _autocomplete.main.hook() {
bindkey -M menuselect -s $key[BackTab] $key[DeleteList]$key[Undo]$key[BackTab]
bindkey -M menuselect -s $key[Undo] $key[DeleteList]$key[Undo]
fi
;;
esac
fi

[[ -v ZSH_AUTOSUGGEST_IGNORE_WIDGETS ]] && ZSH_AUTOSUGGEST_IGNORE_WIDGETS+=(
prompt_\*
user:_zsh_highlight_widget_\*-zle-line-finish
user:_zsh_highlight_widget_\*-zle-line-finish
)
[[ -v ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS ]] && ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS+=(
forward-char
forward-char
vi-forward-char
)

_autocomplete.no-op() { :; }
if [[ ! -v functions[_zsh_highlight] ]]; then
if [[ ! -v functions[_zsh_highlight] ]]; then
functions[_zsh_highlight]=$functions[_autocomplete.no-op]
fi
if [[ ! -v functions[_zsh_autosuggest_highlight_apply] ]]; then
if [[ ! -v functions[_zsh_autosuggest_highlight_apply] ]]; then
functions[_zsh_autosuggest_highlight_apply]=$functions[_autocomplete.no-op]
fi

Expand Down Expand Up @@ -598,7 +587,6 @@ _autocomplete.warning() {

_autocomplete.correct-word.completion-widget() {
setopt localoptions noshortloops warncreateglobal extendedglob $_autocomplete__options
unsetopt GLOB_COMPLETE

if [[ ${LBUFFER[-1]} != [[:IDENT:]] || ${RBUFFER[1]} != [[:IFS:]]# ]]; then
return 1
Expand Down Expand Up @@ -641,9 +629,7 @@ _autocomplete.complete-word.completion-widget() {
if [[ -v compstate[old_list] ]]; then
compstate[old_list]='keep'
compstate[insert]='1'
if [[ ${compstate[context]} == (command|redirect) ]]; then
compstate[insert]+=' '
fi
[[ ${compstate[context]} == (command|redirect) ]] && compstate[insert]+=' '
_autocomplete._main_complete complete-word _oldlist
else
_autocomplete._main_complete complete-word
Expand Down Expand Up @@ -694,7 +680,7 @@ _autocomplete.history-search.zle-widget() {

local FZF_COMPLETION_TRIGGER=''
local fzf_default_completion='list-expand'
local FZF_DEFAULT_OPTS="$FZF_DEFAULT_OPTS --bind=ctrl-space:abort,ctrl-k:kill-line"
local FZF_DEFAULT_OPTS="$FZF_DEFAULT_OPTS --ansi --bind=ctrl-space:abort,ctrl-k:kill-line"

zle fzf-history-widget
}
Expand All @@ -704,7 +690,7 @@ _autocomplete.expand-or-complete.zle-widget() {

local FZF_COMPLETION_TRIGGER=''
local fzf_default_completion='list-expand'
local FZF_DEFAULT_OPTS="$FZF_DEFAULT_OPTS --bind=ctrl-space:abort,ctrl-k:kill-line"
local FZF_DEFAULT_OPTS="$FZF_DEFAULT_OPTS --ansi --bind=ctrl-space:abort,ctrl-k:kill-line"

local curcontext
_autocomplete.curcontext expand-or-complete
Expand All @@ -717,10 +703,18 @@ _autocomplete.expand-or-complete.zle-widget() {
if [[ ${LBUFFER[-1]} != [[:IFS:]]# || ${RBUFFER[1]} != [[:IFS:]]# ]]; then
zle .select-in-shell-word
local lbuffer=$LBUFFER
if ! zle expand-word && [[ $lbuffer != $LBUFFER ]]; then
zle expand-word
if [[ $lbuffer != $LBUFFER ]]; then
zle .auto-suffix-remove
return 0
fi
return 0
local lword=${${(Az)LBUFFER}[-1]}
local rword=${${(Az)RBUFFER}[1]}
local word=$lword$rword
word=${${word/[\^\(\<\[\*\?]*[\*\?\)\>\]\#]}//[\^\*\?\|\#]}
LBUFFER=${LBUFFER%$lword}$word
RBUFFER=${RBUFFER#$rword}
zle -R
fi

zle fzf-completion
Expand All @@ -730,9 +724,15 @@ _autocomplete.expand-word.completion-widget() {
setopt localoptions noshortloops warncreateglobal extendedglob $_autocomplete__options

local curcontext
_autocomplete._main_complete expand-word
(( compstate[nmatches] == 1)) && compstate[insert]='1'
(( compstate[nmatches] > 0))
if [[ ${_lastcomp[completer]} == expand ]] \
&& (( _lastcomp[unambiguous_cursor] > ${#:-$PREFIX$SUFFIX} + 1 )); then
_autocomplete._main_complete expand-word _expand
compstate[insert]='unambiguous'
elif [[ $PREFIX$SUFFIX == *[\*\(\|\<\[\?\^\#]* ]]; then
_autocomplete._main_complete expand-word -
else
_autocomplete._main_complete expand-word _expand_alias _correct
fi
}

_autocomplete.curcontext() {
Expand All @@ -759,7 +759,6 @@ _autocomplete._main_complete() {
_autocomplete.handle_long_list() {
emulate -LR zsh -o noshortloops -o warncreateglobal -o extendedglob

# compstate[insert]=''
compstate[list_max]=0
_autocomplete.max_lines
local max_lines=REPLY
Expand Down

0 comments on commit 15d9f23

Please sign in to comment.