|
|
@ -374,7 +374,7 @@ _zsh_autosuggest_modify() { |
|
|
|
|
|
|
|
# Fetch a new suggestion based on what's currently in the buffer |
|
|
|
_zsh_autosuggest_fetch() { |
|
|
|
if zpty -t "$ZSH_AUTOSUGGEST_ASYNC_PTY_NAME" &>/dev/null; then |
|
|
|
if [[ -n "${ZSH_AUTOSUGGEST_USE_ASYNC+x}" ]]; then |
|
|
|
_zsh_autosuggest_async_request "$BUFFER" |
|
|
|
else |
|
|
|
local suggestion |
|
|
@ -581,109 +581,35 @@ _zsh_autosuggest_strategy_match_prev_cmd() { |
|
|
|
# Async # |
|
|
|
#--------------------------------------------------------------------# |
|
|
|
|
|
|
|
# Zpty process is spawned running this function |
|
|
|
_zsh_autosuggest_async_server() { |
|
|
|
emulate -R zsh |
|
|
|
|
|
|
|
# There is a bug in zpty module (fixed in zsh/master) by which a |
|
|
|
# zpty that exits will kill all zpty processes that were forked |
|
|
|
# before it. Here we set up a zsh exit hook to SIGKILL the zpty |
|
|
|
# process immediately, before it has a chance to kill any other |
|
|
|
# zpty processes. |
|
|
|
zshexit() { |
|
|
|
kill -KILL $$ |
|
|
|
sleep 1 # Block for long enough for the signal to come through |
|
|
|
} |
|
|
|
|
|
|
|
# Don't add any extra carriage returns |
|
|
|
stty -onlcr |
|
|
|
|
|
|
|
# Don't translate carriage returns to newlines |
|
|
|
stty -icrnl |
|
|
|
|
|
|
|
# Silence any error messages |
|
|
|
exec 2>/dev/null |
|
|
|
|
|
|
|
local last_pid |
|
|
|
|
|
|
|
while IFS='' read -r -d $'\0' query; do |
|
|
|
# Kill last bg process |
|
|
|
kill -KILL $last_pid &>/dev/null |
|
|
|
_zsh_autosuggest_async_request() { |
|
|
|
typeset -g _ZSH_AUTOSUGGEST_ASYNC_FD |
|
|
|
|
|
|
|
# Run suggestion search in the background |
|
|
|
( |
|
|
|
local suggestion |
|
|
|
_zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "$query" |
|
|
|
echo -n -E "$suggestion"$'\0' |
|
|
|
) & |
|
|
|
# Close the last fd to invalidate old suggestions |
|
|
|
if [[ -n "$_ZSH_AUTOSUGGEST_ASYNC_FD" ]] && { true <&$_ZSH_AUTOSUGGEST_ASYNC_FD } 2>/dev/null; then |
|
|
|
exec {_ZSH_AUTOSUGGEST_ASYNC_FD}<&- |
|
|
|
fi |
|
|
|
|
|
|
|
last_pid=$! |
|
|
|
done |
|
|
|
} |
|
|
|
# Fork a process to fetch a suggestion and open a pipe to read from it |
|
|
|
exec {_ZSH_AUTOSUGGEST_ASYNC_FD}< <( |
|
|
|
local suggestion |
|
|
|
_zsh_autosuggest_fetch_suggestion "$1" |
|
|
|
echo -nE "$suggestion" |
|
|
|
) |
|
|
|
|
|
|
|
_zsh_autosuggest_async_request() { |
|
|
|
# Write the query to the zpty process to fetch a suggestion |
|
|
|
zpty -w -n $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME "${1}"$'\0' |
|
|
|
# When the fd is readable, call the response handler |
|
|
|
zle -F "$_ZSH_AUTOSUGGEST_ASYNC_FD" _zsh_autosuggest_async_response |
|
|
|
} |
|
|
|
|
|
|
|
# Called when new data is ready to be read from the pty |
|
|
|
# Called when new data is ready to be read from the pipe |
|
|
|
# First arg will be fd ready for reading |
|
|
|
# Second arg will be passed in case of error |
|
|
|
_zsh_autosuggest_async_response() { |
|
|
|
setopt LOCAL_OPTIONS EXTENDED_GLOB |
|
|
|
|
|
|
|
local suggestion |
|
|
|
|
|
|
|
zpty -rt $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME suggestion '*'$'\0' 2>/dev/null |
|
|
|
zle autosuggest-suggest -- "${suggestion%%$'\0'##}" |
|
|
|
} |
|
|
|
|
|
|
|
_zsh_autosuggest_async_pty_create() { |
|
|
|
# With newer versions of zsh, REPLY stores the fd to read from |
|
|
|
typeset -h REPLY |
|
|
|
# Read everything from the fd and give it as a suggestion |
|
|
|
zle autosuggest-suggest -- "$(<&$1)" |
|
|
|
|
|
|
|
# If we won't get a fd back from zpty, try to guess it |
|
|
|
if (( ! $_ZSH_AUTOSUGGEST_ZPTY_RETURNS_FD )); then |
|
|
|
integer -l zptyfd |
|
|
|
exec {zptyfd}>&1 # Open a new file descriptor (above 10). |
|
|
|
exec {zptyfd}>&- # Close it so it's free to be used by zpty. |
|
|
|
fi |
|
|
|
|
|
|
|
# Fork a zpty process running the server function |
|
|
|
zpty -b $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME _zsh_autosuggest_async_server |
|
|
|
|
|
|
|
# Store the fd so we can remove the handler later |
|
|
|
if (( REPLY )); then |
|
|
|
_ZSH_AUTOSUGGEST_PTY_FD=$REPLY |
|
|
|
else |
|
|
|
_ZSH_AUTOSUGGEST_PTY_FD=$zptyfd |
|
|
|
fi |
|
|
|
|
|
|
|
# Set up input handler from the zpty |
|
|
|
zle -F $_ZSH_AUTOSUGGEST_PTY_FD _zsh_autosuggest_async_response |
|
|
|
} |
|
|
|
|
|
|
|
_zsh_autosuggest_async_pty_destroy() { |
|
|
|
# Remove the input handler |
|
|
|
zle -F $_ZSH_AUTOSUGGEST_PTY_FD &>/dev/null |
|
|
|
|
|
|
|
# Destroy the zpty |
|
|
|
zpty -d $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME &>/dev/null |
|
|
|
} |
|
|
|
|
|
|
|
_zsh_autosuggest_async_pty_recreate() { |
|
|
|
_zsh_autosuggest_async_pty_destroy |
|
|
|
_zsh_autosuggest_async_pty_create |
|
|
|
} |
|
|
|
|
|
|
|
_zsh_autosuggest_async_start() { |
|
|
|
typeset -g _ZSH_AUTOSUGGEST_PTY_FD |
|
|
|
|
|
|
|
_zsh_autosuggest_feature_detect_zpty_returns_fd |
|
|
|
_zsh_autosuggest_async_pty_recreate |
|
|
|
|
|
|
|
# We recreate the pty to get a fresh list of history events |
|
|
|
add-zsh-hook precmd _zsh_autosuggest_async_pty_recreate |
|
|
|
# Remove the handler and close the fd |
|
|
|
zle -F "$1" |
|
|
|
exec {1}<&- |
|
|
|
} |
|
|
|
|
|
|
|
#--------------------------------------------------------------------# |
|
|
@ -701,10 +627,6 @@ _zsh_autosuggest_start() { |
|
|
|
# zsh-syntax-highlighting widgets. This also allows modifications |
|
|
|
# to the widget list variables to take effect on the next precmd. |
|
|
|
add-zsh-hook precmd _zsh_autosuggest_bind_widgets |
|
|
|
|
|
|
|
if [[ -n "${ZSH_AUTOSUGGEST_USE_ASYNC+x}" ]]; then |
|
|
|
_zsh_autosuggest_async_start |
|
|
|
fi |
|
|
|
} |
|
|
|
|
|
|
|
# Start the autosuggestion widgets on the next precmd |
|
|
|