diff --git a/autosuggestions.zsh b/autosuggestions.zsh index 5983e01..196e944 100644 --- a/autosuggestions.zsh +++ b/autosuggestions.zsh @@ -13,10 +13,14 @@ source "${0:a:h}/completion-client.zsh" function { [[ -n $ZLE_DISABLE_AUTOSUGGEST ]] && return - autosuggest-ensure-server + autoload -U is-at-least + + if is-at-least 5.0.3; then + autosuggest-ensure-server + fi } -ZLE_AUTOSUGGEST_PAUSE_WIDGETS=( +ZLE_AUTOSUGGEST_SUSPEND_WIDGETS=( vi-cmd-mode vi-backward-char backward-char backward-word beginning-of-line history-search-forward history-search-backward up-line-or-history down-line-or-history @@ -34,19 +38,23 @@ autosuggest-pause() { local widget # When autosuggestions are disabled, kill the unmaterialized part RBUFFER='' - zle -A self-insert autosuggest-paused-self-insert - zle -A .magic-space magic-space - zle -A .backward-delete-char backward-delete-char - zle -A .accept-line accept-line - for widget in $ZLE_AUTOSUGGEST_PAUSE_WIDGETS; do + zle -A autosuggest-paused-self-insert self-insert + zle -A autosuggest-magic-space-orig magic-space + zle -A autosuggest-backward-delete-char-orig backward-delete-char + zle -A autosuggest-accept-line-orig accept-line + for widget in $ZLE_AUTOSUGGEST_SUSPEND_WIDGETS; do + [[ -z $widgets[$widget] ]] && continue eval "zle -A autosuggest-${widget}-orig ${widget}" done for widget in $ZLE_AUTOSUGGEST_COMPLETION_WIDGETS; do - eval "zle -A autosuggest-${widget}-orig $widget" + [[ -z $widgets[$widget] ]] && continue + eval "zle -A autosuggest-${widget}-orig ${widget}" done autosuggest-highlight-suggested-text - zle -F $ZLE_AUTOSUGGEST_CONNECTION + if [[ -n $ZLE_AUTOSUGGEST_CONNECTION ]]; then + zle -F $ZLE_AUTOSUGGEST_CONNECTION + fi } autosuggest-resume() { @@ -54,45 +62,36 @@ autosuggest-resume() { ZLE_AUTOSUGGESTING=1 local widget # Replace prediction widgets by versions that will also highlight RBUFFER - zle -N self-insert autosuggest-insert-or-space - zle -N magic-space autosuggest-insert-or-space - zle -N backward-delete-char autosuggest-backward-delete-char - zle -N accept-line autosuggest-accept-line - # Hook into some default widgets that should pause autosuggestion + zle -A autosuggest-insert-or-space self-insert + zle -A autosuggest-insert-or-space magic-space + zle -A autosuggest-backward-delete-char backward-delete-char + zle -A autosuggest-accept-line accept-line + # Hook into some default widgets that should suspend autosuggestion # automatically - for widget in $ZLE_AUTOSUGGEST_PAUSE_WIDGETS; do - eval "zle -A $widget autosuggest-${widget}-orig; \ - zle -A autosuggest-suspend $widget" + for widget in $ZLE_AUTOSUGGEST_SUSPEND_WIDGETS; do + [[ -z $widgets[$widget] ]] && continue + eval "zle -A autosuggest-suspend $widget" done - # Hook into completion widgets to handle suggestions after completions + # Hook into completion widgets to trim RBUFFER before completion for widget in $ZLE_AUTOSUGGEST_COMPLETION_WIDGETS; do - eval "zle -A $widget autosuggest-${widget}-orig; \ - zle -A autosuggest-tab $widget" + [[ -z $widgets[$widget] ]] && continue + eval "zle -A autosuggest-tab $widget" done - if [[ $BUFFER != '' ]]; then - autosuggest-request-suggestion - fi - if [[ -n $ZLE_AUTOSUGGEST_CONNECTION ]]; then # install listen for suggestions asynchronously - zle -F $ZLE_AUTOSUGGEST_CONNECTION autosuggest-pop-suggestion + zle -Fw $ZLE_AUTOSUGGEST_CONNECTION autosuggest-pop-suggestion fi } autosuggest-start() { autosuggest-resume - zle recursive-edit - integer rv=$? - autosuggest-pause - zle -A .self-insert self-insert - (( rv )) || zle accept-line - return rv } # Toggles autosuggestions on/off autosuggest-toggle() { if [[ -n $ZLE_AUTOSUGGESTING ]]; then autosuggest-pause + zle -A autosuggest-self-insert-orig self-insert else autosuggest-resume fi @@ -110,34 +109,42 @@ autosuggest-highlight-suggested-text() { } autosuggest-insert-or-space() { + setopt localoptions noshwordsplit noksharrays if [[ $LBUFFER == *$'\012'* ]] || (( PENDING )); then - # Editing a multiline buffer or pasting in a chunk of text, dont - # autosuggest - zle .$WIDGET "$@" - elif [[ ${RBUFFER[1]} == ${KEYS[-1]} ]]; then - # Same as what's typed, just move on - ((++CURSOR)) - autosuggest-highlight-suggested-text - else - LBUFFER="$LBUFFER$KEYS" - autosuggest-request-suggestion - fi -} - -autosuggest-backward-delete-char() { - if ! (( $CURSOR )); then - zle .kill-whole-line + # Editing multiline buffer or pasting a chunk of text, pause + autosuggest-suspend return fi - if [[ $LBUFFER == *$'\012'* || $LASTWIDGET != (self-insert|magic-space|backward-delete-char) ]]; then - # When editing a multiline buffer or if the last widget was e.g. a motion, - # then probably the intent is to actually edit the line, not change the - # search prefix. - LBUFFER="$LBUFFER[1,-2]" + if [[ ${RBUFFER[1]} == ${KEYS[-1]} ]]; then + # Same as what's typed, just move on + ((++CURSOR)) else - ((--CURSOR)) - zle .history-beginning-search-forward || RBUFFER='' + LBUFFER="$LBUFFER$KEYS" + if [[ $LASTWIDGET == (self-insert|magic-space|backward-delete-char) || $LASTWIDGET == (complete-word|accept-*|zle-line-init) ]]; then + if ! zle .history-beginning-search-backward; then + RBUFFER='' + if [[ ${KEYS[-1]} != ' ' ]]; then + autosuggest-send-request ${LBUFFER} + fi + fi + fi + fi + autosuggest-highlight-suggested-text +} + +autosuggest-backward-delete-char() { + if (( $#LBUFFER > 1 )); then + setopt localoptions noshwordsplit noksharrays + if [[ $LBUFFER = *$'\012'* || $LASTWIDGET != (self-insert|magic-space|backward-delete-char) ]]; then + LBUFFER="$LBUFFER[1,-2]" + else + ((--CURSOR)) + zle .history-beginning-search-forward || RBUFFER='' + fi + autosuggest-highlight-suggested-text + else + zle .kill-whole-line fi } @@ -152,10 +159,10 @@ autosuggest-accept-line() { autosuggest-paused-self-insert() { if [[ $RBUFFER == '' ]]; then # Resume autosuggestions when inserting at the end of the line - autosuggest-enable - zle autosuggest-modify + autosuggest-resume + zle self-insert else - zle .self-insert + zle autosuggest-self-insert-orig fi } @@ -187,18 +194,6 @@ autosuggest-pop-suggestion() { zle -Rc } -autosuggest-request-suggestion() { - if (( $CURSOR == 0 )) || [[ ${LBUFFER[-1]} == ' ' ]]; then - RBUFFER='' - return - fi - - [[ -n $ZLE_DISABLE_AUTOSUGGEST || $LBUFFER == '' ]] && return - zle .history-beginning-search-backward ||\ - autosuggest-first-completion ${LBUFFER} - autosuggest-highlight-suggested-text -} - autosuggest-suspend() { autosuggest-pause zle autosuggest-${WIDGET}-orig "$@" @@ -224,5 +219,25 @@ zle -N autosuggest-toggle zle -N autosuggest-start zle -N autosuggest-accept-suggested-small-word zle -N autosuggest-accept-suggested-word -zle -N autosuggest-suspend + +zle -N autosuggest-paused-self-insert +zle -N autosuggest-insert-or-space +zle -N autosuggest-backward-delete-char +zle -N autosuggest-accept-line + zle -N autosuggest-tab +zle -N autosuggest-suspend + +# Save all widgets +zle -A self-insert autosuggest-self-insert-orig +zle -A magic-space autosuggest-magic-space-orig +zle -A backward-delete-char autosuggest-backward-delete-char-orig +zle -A accept-line autosuggest-accept-line-orig +for widget in $ZLE_AUTOSUGGEST_SUSPEND_WIDGETS; do + [[ -z $widgets[$widget] ]] && continue + eval "zle -A $widget autosuggest-${widget}-orig" +done +for widget in $ZLE_AUTOSUGGEST_COMPLETION_WIDGETS; do + [[ -z $widgets[$widget] ]] && continue + eval "zle -A $widget autosuggest-${widget}-orig" +done diff --git a/completion-client.zsh b/completion-client.zsh index f67f2dd..c8cd957 100755 --- a/completion-client.zsh +++ b/completion-client.zsh @@ -9,7 +9,7 @@ autosuggest-ensure-server() { local pid_file="$server_dir/pid" local socket_path="$server_dir/socket" - if [[ ! -S $socket_path || ! -r $pid_file ]] || ! kill -0 $(<$pid_file) &> /dev/null; then + if [[ ! -d $server_dir || ! -r $pid_file ]] || ! kill -0 $(<$pid_file) &> /dev/null; then if which setsid &> /dev/null; then setsid zsh $AUTOSUGGEST_SERVER_SCRIPT $server_dir $pid_file $socket_path &! else @@ -33,9 +33,8 @@ autosuggest-server-connect() { ZLE_AUTOSUGGEST_CONNECTION=$REPLY } -autosuggest-first-completion() { +autosuggest-send-request() { [[ -z $ZLE_AUTOSUGGEST_CONNECTION ]] && return 1 setopt local_options noglob - local response print -u $ZLE_AUTOSUGGEST_CONNECTION - $1 &> /dev/null || return 1 }