mirror of
				https://github.com/zsh-users/zsh-autosuggestions.git
				synced 2024-05-11 05:54:57 +00:00 
			
		
		
		
	
		
			
				
	
	
		
			280 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
			
		
		
	
	
			280 lines
		
	
	
		
			8.0 KiB
		
	
	
	
		
			Bash
		
	
	
	
	
	
# Fish-like autosuggestions for zsh. Some of the code was based on the code
 | 
						|
# for 'predict-on'
 | 
						|
#
 | 
						|
# ```zsh
 | 
						|
# zle-line-init() {
 | 
						|
#		autosuggest-enable
 | 
						|
# }
 | 
						|
# zle -N zle-line-init
 | 
						|
# ```
 | 
						|
zmodload zsh/net/socket
 | 
						|
 | 
						|
source "${0:a:h}/completion-client.zsh"
 | 
						|
 | 
						|
# configuration variables
 | 
						|
AUTOSUGGESTION_HIGHLIGHT_COLOR='fg=8'
 | 
						|
AUTOSUGGESTION_HIGHLIGHT_CURSOR=1
 | 
						|
 | 
						|
function {
 | 
						|
	if [[ -n $ZLE_DISABLE_AUTOSUGGEST ]]; then
 | 
						|
		ZSH_HIGHLIGHT_HIGHLIGHTERS=()
 | 
						|
		return
 | 
						|
	fi
 | 
						|
	autoload -U is-at-least
 | 
						|
 | 
						|
	if is-at-least 5.0.3; then
 | 
						|
		autosuggest-ensure-server
 | 
						|
	fi
 | 
						|
}
 | 
						|
 | 
						|
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
 | 
						|
history-beginning-search-forward history-beginning-search-backward
 | 
						|
down-line-or-history history-substring-search-up history-substring-search-down
 | 
						|
backward-kill-word
 | 
						|
)
 | 
						|
 | 
						|
ZLE_AUTOSUGGEST_COMPLETION_WIDGETS=(
 | 
						|
complete-word expand-or-complete expand-or-complete-prefix list-choices
 | 
						|
menu-complete reverse-menu-complete menu-expand-or-complete menu-select
 | 
						|
accept-and-menu-complete
 | 
						|
)
 | 
						|
 | 
						|
ZLE_AUTOSUGGEST_ACCEPT_WIDGETS=(
 | 
						|
vi-forward-char forward-char vi-forward-word forward-word vi-add-eol
 | 
						|
vi-add-next vi-forward-blank-word end-of-line
 | 
						|
)
 | 
						|
 | 
						|
autosuggest-pause() {
 | 
						|
	[[ -z $ZLE_AUTOSUGGESTING ]] && return
 | 
						|
	unset ZLE_AUTOSUGGESTING
 | 
						|
	local widget
 | 
						|
	# When autosuggestions are disabled, kill the unmaterialized part
 | 
						|
	RBUFFER=''
 | 
						|
	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_ACCEPT_WIDGETS $ZLE_AUTOSUGGEST_SUSPEND_WIDGETS $ZLE_AUTOSUGGEST_COMPLETION_WIDGETS; do
 | 
						|
		[[ -z $widgets[$widget] || -z $widgets[autosuggest-${widget}-orig] ]] &&\
 | 
						|
		 	continue
 | 
						|
		eval "zle -A autosuggest-${widget}-orig ${widget}"
 | 
						|
	done
 | 
						|
	autosuggest-highlight-suggested-text
 | 
						|
 | 
						|
	if [[ -n $ZLE_AUTOSUGGEST_CONNECTION ]]; then
 | 
						|
		zle -F $ZLE_AUTOSUGGEST_CONNECTION
 | 
						|
	fi
 | 
						|
}
 | 
						|
 | 
						|
autosuggest-resume() {
 | 
						|
	[[ -n $ZLE_AUTOSUGGESTING ]] && return
 | 
						|
	ZLE_AUTOSUGGESTING=1
 | 
						|
	local widget
 | 
						|
	# Replace prediction widgets by versions that will also highlight RBUFFER
 | 
						|
	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_ACCEPT_WIDGETS; do
 | 
						|
		[[ -z $widgets[$widget] ]] && continue
 | 
						|
		eval "zle -A autosuggest-accept-suggestion $widget"
 | 
						|
	done
 | 
						|
	for widget in $ZLE_AUTOSUGGEST_SUSPEND_WIDGETS; do
 | 
						|
		[[ -z $widgets[$widget] ]] && continue
 | 
						|
		eval "zle -A autosuggest-suspend $widget"
 | 
						|
	done
 | 
						|
	# Hook into completion widgets to trim RBUFFER before completion
 | 
						|
	for widget in $ZLE_AUTOSUGGEST_COMPLETION_WIDGETS; do
 | 
						|
		[[ -z $widgets[$widget] ]] && continue
 | 
						|
		eval "zle -A autosuggest-tab $widget"
 | 
						|
	done
 | 
						|
	if [[ -n $ZLE_AUTOSUGGEST_CONNECTION ]]; then
 | 
						|
		# install listen for suggestions asynchronously
 | 
						|
		zle -Fw $ZLE_AUTOSUGGEST_CONNECTION autosuggest-pop-suggestion
 | 
						|
	fi
 | 
						|
}
 | 
						|
 | 
						|
autosuggest-start() {
 | 
						|
	if [[ -z $ZLE_DISABLE_AUTOSUGGEST && -n $functions[_zsh_highlight] ]]; then
 | 
						|
            if [[ ${ZSH_HIGHLIGHT_HIGHLIGHTERS[(i)autosuggest]} -gt ${#ZSH_HIGHLIGHT_HIGHLIGHTERS}  ]];then
 | 
						|
                ZSH_HIGHLIGHT_HIGHLIGHTERS+=(autosuggest)
 | 
						|
            fi
 | 
						|
	fi
 | 
						|
	autosuggest-resume
 | 
						|
}
 | 
						|
 | 
						|
# 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
 | 
						|
}
 | 
						|
 | 
						|
autosuggest-highlight-suggested-text() {
 | 
						|
	if (( $+functions[_zsh_highlight_buffer_modified] > 0 )); then
 | 
						|
		_zsh_highlight
 | 
						|
	else
 | 
						|
		region_highlight=()
 | 
						|
		_zsh_highlight_autosuggest_highlighter
 | 
						|
	fi
 | 
						|
}
 | 
						|
 | 
						|
_zsh_highlight_autosuggest_highlighter_predicate() {
 | 
						|
	[[ -n $ZLE_AUTOSUGGESTING ]] && (( $#RBUFFER > 0 ))
 | 
						|
}
 | 
						|
 | 
						|
_zsh_highlight_autosuggest_highlighter() {
 | 
						|
	region_highlight+=("$(( $CURSOR + $AUTOSUGGESTION_HIGHLIGHT_CURSOR )) $(( $CURSOR + $#RBUFFER )) $AUTOSUGGESTION_HIGHLIGHT_COLOR")
 | 
						|
}
 | 
						|
 | 
						|
autosuggest-insert-or-space() {
 | 
						|
  setopt localoptions noshwordsplit noksharrays
 | 
						|
	if [[ $LBUFFER == *$'\012'* ]] || (( PENDING )); then
 | 
						|
		# Editing multiline buffer or pasting a chunk of text, pause
 | 
						|
		autosuggest-suspend
 | 
						|
		return
 | 
						|
	fi
 | 
						|
 | 
						|
	if [[ ${RBUFFER[1]} == ${KEYS[-1]} ]]; then
 | 
						|
		# Same as what's typed, just move on
 | 
						|
		((++CURSOR))
 | 
						|
		autosuggest-invalidate-highlight-cache
 | 
						|
	else
 | 
						|
		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))
 | 
						|
			autosuggest-invalidate-highlight-cache
 | 
						|
      zle .history-beginning-search-forward || RBUFFER=''
 | 
						|
    fi
 | 
						|
		autosuggest-highlight-suggested-text
 | 
						|
	else
 | 
						|
		zle .kill-whole-line
 | 
						|
	fi
 | 
						|
}
 | 
						|
 | 
						|
# When autosuggesting, ignore RBUFFER which corresponds to the 'unmaterialized'
 | 
						|
# section when the user accepts the line
 | 
						|
autosuggest-accept-line() {
 | 
						|
	RBUFFER=''
 | 
						|
	if ! (( $+functions[_zsh_highlight_buffer_modified] )); then
 | 
						|
		# Only clear the colors if the user doesn't have zsh-highlight installed
 | 
						|
		region_highlight=()
 | 
						|
	fi
 | 
						|
	zle .accept-line
 | 
						|
}
 | 
						|
 | 
						|
autosuggest-paused-self-insert() {
 | 
						|
	if [[ $RBUFFER == '' ]]; then
 | 
						|
		# Resume autosuggestions when inserting at the end of the line
 | 
						|
		autosuggest-resume
 | 
						|
		zle self-insert
 | 
						|
	else
 | 
						|
		zle autosuggest-self-insert-orig
 | 
						|
	fi
 | 
						|
}
 | 
						|
 | 
						|
autosuggest-pop-suggestion() {
 | 
						|
	local words last_word suggestion
 | 
						|
	if ! IFS= read -r -u $ZLE_AUTOSUGGEST_CONNECTION suggestion; then
 | 
						|
		# server closed the connection, stop listenting
 | 
						|
		zle -F $ZLE_AUTOSUGGEST_CONNECTION
 | 
						|
		unset ZLE_AUTOSUGGEST_CONNECTION
 | 
						|
		return
 | 
						|
	fi
 | 
						|
	if [[ -n $suggestion ]]; then
 | 
						|
		local prefix=${suggestion%$'\2'*}
 | 
						|
		suggestion=${suggestion#*$'\2'}
 | 
						|
		# only use the suggestion if the prefix is still compatible with
 | 
						|
		# the suggestion(prefix should be contained in LBUFFER)
 | 
						|
		if [[ ${LBUFFER#$prefix*} != ${LBUFFER} ]]; then
 | 
						|
			words=(${(z)LBUFFER})
 | 
						|
			last_word=${words[-1]}
 | 
						|
			suggestion=${suggestion:$#last_word}
 | 
						|
			RBUFFER="$suggestion"
 | 
						|
			autosuggest-highlight-suggested-text
 | 
						|
		else
 | 
						|
			RBUFFER=''
 | 
						|
		fi
 | 
						|
	else
 | 
						|
		RBUFFER=''
 | 
						|
	fi
 | 
						|
	zle -Rc
 | 
						|
}
 | 
						|
 | 
						|
autosuggest-suspend() {
 | 
						|
	autosuggest-pause
 | 
						|
	zle autosuggest-${WIDGET}-orig "$@"
 | 
						|
}
 | 
						|
 | 
						|
autosuggest-tab() {
 | 
						|
	RBUFFER=''
 | 
						|
	zle autosuggest-${WIDGET}-orig "$@"
 | 
						|
	autosuggest-highlight-suggested-text
 | 
						|
}
 | 
						|
 | 
						|
autosuggest-accept-suggestion() {
 | 
						|
        if [[ AUTOSUGGESTION_ACCEPT_RIGHT_ARROW -eq 1 && "$WIDGET" == 'forward-char' ]]; then
 | 
						|
	  zle autosuggest-end-of-line-orig "$@"
 | 
						|
        else
 | 
						|
	  zle autosuggest-${WIDGET}-orig "$@"
 | 
						|
        fi
 | 
						|
	if [[ -n $ZLE_AUTOSUGGESTING ]]; then
 | 
						|
		autosuggest-invalidate-highlight-cache
 | 
						|
		autosuggest-highlight-suggested-text
 | 
						|
	fi
 | 
						|
}
 | 
						|
 | 
						|
autosuggest-invalidate-highlight-cache() {
 | 
						|
	# invalidate the buffer for zsh-syntax-highlighting
 | 
						|
	_ZSH_HIGHLIGHT_PRIOR_BUFFER=''
 | 
						|
}
 | 
						|
 | 
						|
zle -N autosuggest-toggle
 | 
						|
zle -N autosuggest-start
 | 
						|
zle -N autosuggest-accept-suggested-small-word
 | 
						|
zle -N autosuggest-accept-suggested-word
 | 
						|
 | 
						|
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
 | 
						|
zle -N autosuggest-accept-suggestion
 | 
						|
 | 
						|
# 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_ACCEPT_WIDGETS} ${ZLE_AUTOSUGGEST_SUSPEND_WIDGETS} ${ZLE_AUTOSUGGEST_COMPLETION_WIDGETS}; do
 | 
						|
	[[ -z $widgets[$widget] ]] && continue
 | 
						|
	eval "zle -A $widget autosuggest-${widget}-orig"
 | 
						|
done
 |