From 4cca26ec84e764b077175ae20c54c8d673061fc2 Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Fri, 18 May 2018 15:05:45 -0600 Subject: [PATCH] Modify completion code to better fit our needs Only need the first completion result --- src/strategies/completion.zsh | 124 ++++++++++++--------------------- zsh-autosuggestions.zsh | 125 ++++++++++++---------------------- 2 files changed, 85 insertions(+), 164 deletions(-) diff --git a/src/strategies/completion.zsh b/src/strategies/completion.zsh index db948a0..aa87673 100644 --- a/src/strategies/completion.zsh +++ b/src/strategies/completion.zsh @@ -9,114 +9,74 @@ _zsh_autosuggest_capture_completion() { zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME zsh -f -i - # line buffer for pty output local line setopt rcquotes () { - zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME source $1 - repeat 4; do - zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line - [[ $line == ok* ]] && return - done - echo 'error initializing.' >&2 - exit 2 + # Initialize the pty env, blocking until null byte is seen + zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME "source $1" + zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0' } =( <<< ' - # no prompt! - PROMPT= - # load completion system + exec 2>/dev/null # Silence any error messages + autoload compinit compinit -d ~/.zcompdump_autosuggestions - # never run a command - bindkey ''^M'' undefined - bindkey ''^J'' undefined - bindkey ''^I'' complete-word - # send a line with null-byte at the end before and after completions are output - null-line () { - echo -E - $''\0'' - } - compprefuncs=( null-line ) - comppostfuncs=( null-line exit ) - # never group stuff! + + # Exit as soon as completion is finished + comppostfuncs=( exit ) + + # Never group stuff! zstyle '':completion:*'' list-grouped false - # don''t insert tab when attempting completion on empty line - zstyle '':completion:*'' insert-tab false + # no list separator, this saves some stripping later on zstyle '':completion:*'' list-separator '''' + # we use zparseopts zmodload zsh/zutil + # override compadd (this our hook) compadd () { - # check if any of -O, -A or -D are given + # Just delegate and leave if any of -O, -A or -D are given if [[ ${@[1,(i)(-|--)]} == *-(O|A|D)\ * ]]; then - # if that is the case, just delegate and leave builtin compadd "$@" return $? fi - # ok, this concerns us! - # echo -E - got this: "$@" - # be careful with namespacing here, we don''t want to mess with stuff that - # should be passed to compadd! - typeset -a __hits __dscr __tmp - # do we have a description parameter? - # note we don''t use zparseopts here because of combined option parameters - # with arguments like -default- confuse it. - if (( $@[(I)-d] )); then # kind of a hack, $+@[(r)-d] doesn''t work because of line noise overload - # next param after -d - __tmp=${@[$[${@[(i)-d]}+1]]} - # description can be given as an array parameter name, or inline () array - if [[ $__tmp == \(* ]]; then - eval "__dscr=$__tmp" - else - __dscr=( "${(@P)__tmp}" ) - fi - fi - # capture completions by injecting -A parameter into the compadd call. - # this takes care of matching for us. - builtin compadd -A __hits -D __dscr "$@" - # JESUS CHRIST IT TOOK ME FOREVER TO FIGURE OUT THIS OPTION WAS SET AND WAS MESSING WITH MY SHIT HERE + setopt localoptions norcexpandparam extendedglob - # extract prefixes and suffixes from compadd call. we can''t do zsh''s cool + + typeset -a __hits + + # Capture completions by injecting -A parameter into the compadd call. + # This takes care of matching for us. + builtin compadd -A __hits "$@" + + # Exit if no completion results + [[ -n $__hits ]] || return + + # Extract prefixes and suffixes from compadd call. we can''t do zsh''s cool # -r remove-func magic, but it''s better than nothing. typeset -A apre hpre hsuf asuf zparseopts -E P:=apre p:=hpre S:=asuf s:=hsuf - # append / to directories? we are only emulating -f in a half-assed way - # here, but it''s better than nothing. - integer dirsuf=0 - # don''t be fooled by -default- >.> - if [[ -z $hsuf && "${${@//-default-/}% -# *}" == *-[[:alnum:]]#f* ]]; then - dirsuf=1 - fi - # just drop - [[ -n $__hits ]] || return - # this is the point where we have all matches in $__hits and all - # descriptions in $__dscr! - # display all matches - local dsuf dscr - for i in {1..$#__hits}; do - # add a dir suffix? - (( dirsuf )) && [[ -d $__hits[$i] ]] && dsuf=/ || dsuf= - # description to be displayed afterwards - (( $#__dscr >= $i )) && dscr=" -- ${${__dscr[$i]}##$__hits[$i] #}" || dscr= - echo -E - $IPREFIX$apre$hpre$__hits[$i]$dsuf$hsuf$asuf - done - } - # signal success! - echo ok') + # Print the first match + echo -nE - $''\0''$IPREFIX$apre$hpre$__hits[1]$dsuf$hsuf$asuf$''\0'' + } + + # Signal setup completion by sending null byte + echo $''\0'' + ') + + # Send the string and a tab to trigger completion zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME "$*"$'\t' - integer tog=0 - # read from the pty, and parse linewise - while zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME; do :; done | while IFS= read -r line; do - if [[ $line == *$'\0\r' ]]; then - (( tog++ )) && return 0 || continue - fi - # display between toggles - (( tog )) && echo -E - $line - done + # Read up to the start of the first result + zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0' - return 2 + # Read the first result + zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0' + + # Print it, removing the trailing null byte + echo -E - ${line%$'\0'} } _zsh_autosuggest_strategy_completion() { diff --git a/zsh-autosuggestions.zsh b/zsh-autosuggestions.zsh index 41336a7..a2134da 100644 --- a/zsh-autosuggestions.zsh +++ b/zsh-autosuggestions.zsh @@ -506,114 +506,75 @@ zle -N autosuggest-toggle _zsh_autosuggest_widget_toggle _zsh_autosuggest_capture_completion() { zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME zsh -f -i - # line buffer for pty output local line setopt rcquotes () { - zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME source $1 - repeat 4; do - zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line - [[ $line == ok* ]] && return - done - echo 'error initializing.' >&2 - exit 2 + # Setup, blocking until null byte to signal completion + zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME "source $1" + zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0' } =( <<< ' - # no prompt! - PROMPT= - # load completion system + exec 2>/dev/null # Silence any error messages + autoload compinit compinit -d ~/.zcompdump_autosuggestions - # never run a command - bindkey ''^M'' undefined - bindkey ''^J'' undefined - bindkey ''^I'' complete-word - # send a line with null-byte at the end before and after completions are output - null-line () { - echo -E - $''\0'' - } - compprefuncs=( null-line ) - comppostfuncs=( null-line exit ) - # never group stuff! + + # Exit as soon as completion is finished + comppostfuncs=( exit ) + + # Never group stuff! zstyle '':completion:*'' list-grouped false - # don''t insert tab when attempting completion on empty line - zstyle '':completion:*'' insert-tab false + # no list separator, this saves some stripping later on zstyle '':completion:*'' list-separator '''' + # we use zparseopts zmodload zsh/zutil + # override compadd (this our hook) compadd () { - # check if any of -O, -A or -D are given + # Just delegate and leave if any of -O, -A or -D are given if [[ ${@[1,(i)(-|--)]} == *-(O|A|D)\ * ]]; then - # if that is the case, just delegate and leave builtin compadd "$@" return $? fi - # ok, this concerns us! - # echo -E - got this: "$@" - # be careful with namespacing here, we don''t want to mess with stuff that - # should be passed to compadd! - typeset -a __hits __dscr __tmp - # do we have a description parameter? - # note we don''t use zparseopts here because of combined option parameters - # with arguments like -default- confuse it. - if (( $@[(I)-d] )); then # kind of a hack, $+@[(r)-d] doesn''t work because of line noise overload - # next param after -d - __tmp=${@[$[${@[(i)-d]}+1]]} - # description can be given as an array parameter name, or inline () array - if [[ $__tmp == \(* ]]; then - eval "__dscr=$__tmp" - else - __dscr=( "${(@P)__tmp}" ) - fi - fi - # capture completions by injecting -A parameter into the compadd call. - # this takes care of matching for us. - builtin compadd -A __hits -D __dscr "$@" - # JESUS CHRIST IT TOOK ME FOREVER TO FIGURE OUT THIS OPTION WAS SET AND WAS MESSING WITH MY SHIT HERE + setopt localoptions norcexpandparam extendedglob - # extract prefixes and suffixes from compadd call. we can''t do zsh''s cool + + typeset -a __hits + + # Capture completions by injecting -A parameter into the compadd call. + # This takes care of matching for us. + builtin compadd -A __hits "$@" + + # Exit if no completion results + [[ -n $__hits ]] || return + + # Extract prefixes and suffixes from compadd call. we can''t do zsh''s cool # -r remove-func magic, but it''s better than nothing. typeset -A apre hpre hsuf asuf zparseopts -E P:=apre p:=hpre S:=asuf s:=hsuf - # append / to directories? we are only emulating -f in a half-assed way - # here, but it''s better than nothing. - integer dirsuf=0 - # don''t be fooled by -default- >.> - if [[ -z $hsuf && "${${@//-default-/}% -# *}" == *-[[:alnum:]]#f* ]]; then - dirsuf=1 - fi - # just drop - [[ -n $__hits ]] || return - # this is the point where we have all matches in $__hits and all - # descriptions in $__dscr! - # display all matches - local dsuf dscr - for i in {1..$#__hits}; do - # add a dir suffix? - (( dirsuf )) && [[ -d $__hits[$i] ]] && dsuf=/ || dsuf= - # description to be displayed afterwards - (( $#__dscr >= $i )) && dscr=" -- ${${__dscr[$i]}##$__hits[$i] #}" || dscr= - echo -E - $IPREFIX$apre$hpre$__hits[$i]$dsuf$hsuf$asuf - done - } - # signal success! - echo ok') + # Print the first match + echo -nE - $''\0''$IPREFIX$apre$hpre$__hits[1]$dsuf$hsuf$asuf$''\0'' + } + + # Signal setup completion by sending null byte + echo $''\0'' + ') + + + # Send the string and a tab to trigger completion zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME "$*"$'\t' - integer tog=0 - # read from the pty, and parse linewise - while zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME; do :; done | while IFS= read -r line; do - if [[ $line == *$'\0\r' ]]; then - (( tog++ )) && return 0 || continue - fi - # display between toggles - (( tog )) && echo -E - $line - done + # Read up to the start of the first result + zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0' - return 2 + # Read the first result + zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0' + + # Print it, removing the trailing null byte + echo -E - ${line%$'\0'} } _zsh_autosuggest_strategy_completion() {