diff --git a/CHANGELOG.md b/CHANGELOG.md index f017be2..387071b 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,15 @@ # Changelog +## v0.5.0 +- Don't overwrite config with default values (#335) +- Support fallback strategies by supplying array to suggestion config var +- Rename "default" suggestion strategy to "history" to name it based on what it actually does +- Reset opts in some functions affected by `GLOB_SUBST` (#334) +- Support widgets starting with dashes (ex: `-a-widget`) (#337) +- Skip async tests in zsh versions less than 5.0.8 because of reliability issues +- Fix handling of newline + carriage return in async pty (#333) + + ## v0.4.3 - Avoid bell when accepting suggestions with `autosuggest-accept` (#228) - Don't fetch suggestions after [up,down]-line-or-beginning-search (#227, #241) diff --git a/INSTALL.md b/INSTALL.md index fef0f2e..d439ef9 100644 --- a/INSTALL.md +++ b/INSTALL.md @@ -16,6 +16,16 @@ 3. Start a new terminal session. +### Antigen + +1. Add the following to your `.zshrc`: + + ```sh + antigen bundle zsh-users/zsh-autosuggestions + ``` + +2. Start a new terminal session. + ### Oh My Zsh 1. Clone this repository into `$ZSH_CUSTOM/plugins` (by default `~/.oh-my-zsh/custom/plugins`) diff --git a/Makefile b/Makefile index d5d162c..b89ff04 100644 --- a/Makefile +++ b/Makefile @@ -9,6 +9,7 @@ SRC_FILES := \ $(SRC_DIR)/highlight.zsh \ $(SRC_DIR)/widgets.zsh \ $(SRC_DIR)/strategies/*.zsh \ + $(SRC_DIR)/fetch.zsh \ $(SRC_DIR)/async.zsh \ $(SRC_DIR)/start.zsh diff --git a/README.md b/README.md index 83720e6..7e3e674 100644 --- a/README.md +++ b/README.md @@ -27,7 +27,7 @@ If you invoke the `forward-word` widget, it will partially accept the suggestion ## Configuration -You may want to override the default global config variables after sourcing the plugin. Default values of these variables can be found [here](src/config.zsh). +You may want to override the default global config variables. Default values of these variables can be found [here](src/config.zsh). **Note:** If you are using Oh My Zsh, you can put this configuration in a file in the `$ZSH_CUSTOM` directory. See their comments on [overriding internals](https://github.com/robbyrussell/oh-my-zsh/wiki/Customization#overriding-internals). @@ -39,10 +39,10 @@ Set `ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE` to configure the style that the suggestion ### Suggestion Strategy -Set `ZSH_AUTOSUGGEST_STRATEGY` to choose the strategy for generating suggestions. There are currently two to choose from: +`ZSH_AUTOSUGGEST_STRATEGY` is an array that specifies how suggestions should be generated. The strategies in the array are tried successively until a suggestion is found. There are currently two built-in strategies to choose from: -- `default`: Chooses the most recent match. -- `match_prev_cmd`: Chooses the most recent match whose preceding history item matches the most recently executed command ([more info](src/strategies/match_prev_cmd.zsh)). Note that this strategy won't work as expected with ZSH options that don't preserve the history order such as `HIST_IGNORE_ALL_DUPS` or `HIST_EXPIRE_DUPS_FIRST`. +- `history`: Chooses the most recent match from history. +- `match_prev_cmd`: Like `history`, but chooses the most recent match whose preceding history item matches the most recently executed command ([more info](src/strategies/match_prev_cmd.zsh)). Note that this strategy won't work as expected with ZSH options that don't preserve the history order such as `HIST_IGNORE_ALL_DUPS` or `HIST_EXPIRE_DUPS_FIRST`. ### Widget Mapping diff --git a/VERSION b/VERSION index f87d474..b043aa6 100644 --- a/VERSION +++ b/VERSION @@ -1 +1 @@ -v0.4.3 +v0.5.0 diff --git a/spec/async_spec.rb b/spec/async_spec.rb index 0bcbaa1..152adde 100644 --- a/spec/async_spec.rb +++ b/spec/async_spec.rb @@ -1,4 +1,8 @@ context 'with asynchronous suggestions enabled' do + before do + skip 'Async mode not supported below v5.0.8' if session.zsh_version < Gem::Version.new('5.0.8') + end + let(:options) { ["ZSH_AUTOSUGGEST_USE_ASYNC="] } describe '`up-line-or-beginning-search`' do @@ -27,6 +31,45 @@ context 'with asynchronous suggestions enabled' do end end + it 'should not add extra carriage returns before newlines' do + session. + send_string('echo "'). + send_keys('escape'). + send_keys('enter'). + send_string('"'). + send_keys('enter') + + session.clear_screen + + session.send_string('echo') + wait_for { session.content }.to eq("echo \"\n\"") + end + + it 'should treat carriage returns and newlines as separate characters' do + session. + send_string('echo "'). + send_keys('C-v'). + send_keys('enter'). + send_string('foo"'). + send_keys('enter') + + session. + send_string('echo "'). + send_keys('control'). + send_keys('enter'). + send_string('bar"'). + send_keys('enter') + + session.clear_screen + + session. + send_string('echo "'). + send_keys('C-v'). + send_keys('enter') + + wait_for { session.content }.to eq('echo "^Mfoo"') + end + describe 'exiting a subshell' do it 'should not cause error messages to be printed' do session.run_command('$(exit)') diff --git a/spec/integrations/zle_input_stack_spec.rb b/spec/integrations/zle_input_stack_spec.rb index 8a2c990..12cfbc7 100644 --- a/spec/integrations/zle_input_stack_spec.rb +++ b/spec/integrations/zle_input_stack_spec.rb @@ -2,7 +2,7 @@ describe 'using `zle -U`' do let(:before_sourcing) do -> do session. - run_command('_zsh_autosuggest_strategy_test() { sleep 1; _zsh_autosuggest_strategy_default "$1" }'). + run_command('_zsh_autosuggest_strategy_test() { sleep 1; _zsh_autosuggest_strategy_history "$1" }'). run_command('foo() { zle -U - "echo hello" }; zle -N foo; bindkey ^B foo') end end diff --git a/spec/options/strategy_spec.rb b/spec/options/strategy_spec.rb index c9f01e1..58562d0 100644 --- a/spec/options/strategy_spec.rb +++ b/spec/options/strategy_spec.rb @@ -1,20 +1,55 @@ describe 'a suggestion for a given prefix' do - let(:options) { ['_zsh_autosuggest_strategy_default() { suggestion="echo foo" }'] } + let(:history_strategy) { '_zsh_autosuggest_strategy_history() { suggestion="history" }' } + let(:foobar_strategy) { '_zsh_autosuggest_strategy_foobar() { [[ "foobar baz" = $1* ]] && suggestion="foobar baz" }' } + let(:foobaz_strategy) { '_zsh_autosuggest_strategy_foobaz() { [[ "foobaz bar" = $1* ]] && suggestion="foobaz bar" }' } - it 'is determined by calling the default strategy function' do - session.send_string('e') - wait_for { session.content }.to eq('echo foo') + let(:after_sourcing) do + -> do + session.run_command(history_strategy) + end end - context 'when ZSH_AUTOSUGGEST_STRATEGY is set' do - let(:options) { [ - '_zsh_autosuggest_strategy_custom() { suggestion="echo foo" }', - 'ZSH_AUTOSUGGEST_STRATEGY=custom' - ] } + it 'by default is determined by calling the `history` strategy function' do + session.send_string('h') + wait_for { session.content }.to eq('history') + end - it 'is determined by calling the specified strategy function' do - session.send_string('e') - wait_for { session.content }.to eq('echo foo') + context 'when ZSH_AUTOSUGGEST_STRATEGY is set to an array' do + let(:after_sourcing) do + -> do + session. + run_command(foobar_strategy). + run_command(foobaz_strategy). + run_command('ZSH_AUTOSUGGEST_STRATEGY=(foobar foobaz)') + end + end + + it 'is determined by the first strategy function to return a suggestion' do + session.send_string('foo') + wait_for { session.content }.to eq('foobar baz') + + session.send_string('baz') + wait_for { session.content }.to eq('foobaz bar') + end + end + + context 'when ZSH_AUTOSUGGEST_STRATEGY is set to a string' do + let(:after_sourcing) do + -> do + session. + run_command(foobar_strategy). + run_command(foobaz_strategy). + run_command('ZSH_AUTOSUGGEST_STRATEGY="foobar foobaz"') + end + end + + it 'is determined by the first strategy function to return a suggestion' do + session.send_string('foo') + wait_for { session.content }.to eq('foobar baz') + + session.send_string('baz') + wait_for { session.content }.to eq('foobaz bar') end end end + diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 64115d2..abea917 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -6,12 +6,14 @@ RSpec.shared_context 'terminal session' do let(:term_opts) { {} } let(:session) { TerminalSession.new(term_opts) } let(:before_sourcing) { -> {} } + let(:after_sourcing) { -> {} } let(:options) { [] } around do |example| before_sourcing.call - - session.run_command((['source zsh-autosuggestions.zsh'] + options).join('; ')) + session.run_command(options.join('; ')) + session.run_command('source zsh-autosuggestions.zsh') + after_sourcing.call session.clear_screen example.run diff --git a/spec/terminal_session.rb b/spec/terminal_session.rb index 2d9468f..f91ee6c 100644 --- a/spec/terminal_session.rb +++ b/spec/terminal_session.rb @@ -18,6 +18,10 @@ class TerminalSession tmux_command("new-session -d -x #{opts[:width]} -y #{opts[:height]} '#{cmd}'") end + def zsh_version + @zsh_version ||= Gem::Version.new(`#{ZSH_BIN} -c 'echo -n $ZSH_VERSION'`) + end + def tmux_socket_name @tmux_socket_name ||= SecureRandom.hex(6) end diff --git a/src/async.zsh b/src/async.zsh index 9a0cfaa..dd54c24 100644 --- a/src/async.zsh +++ b/src/async.zsh @@ -17,9 +17,12 @@ _zsh_autosuggest_async_server() { sleep 1 # Block for long enough for the signal to come through } - # Output only newlines (not carriage return + newline) + # 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 @@ -32,7 +35,7 @@ _zsh_autosuggest_async_server() { # Run suggestion search in the background ( local suggestion - _zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "$query" + _zsh_autosuggest_fetch_suggestion "$query" echo -n -E "$suggestion"$'\0' ) & diff --git a/src/bind.zsh b/src/bind.zsh index 42a0dd0..bb41ef8 100644 --- a/src/bind.zsh +++ b/src/bind.zsh @@ -69,12 +69,14 @@ _zsh_autosuggest_bind_widget() { }" # Create the bound widget - zle -N $widget _zsh_autosuggest_bound_${bind_count}_$widget + zle -N -- $widget _zsh_autosuggest_bound_${bind_count}_$widget } # Map all configured widgets to the right autosuggest widgets _zsh_autosuggest_bind_widgets() { - local widget + emulate -L zsh + + local widget local ignore_widgets ignore_widgets=( diff --git a/src/config.zsh b/src/config.zsh index 597307f..9ac1484 100644 --- a/src/config.zsh +++ b/src/config.zsh @@ -6,15 +6,17 @@ # Color to use when highlighting suggestion # Uses format of `region_highlight` # More info: http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Zle-Widgets -ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=8' +: ${ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=8'} # Prefix to use when saving original versions of bound widgets -ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX=autosuggest-orig- +: ${ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX=autosuggest-orig-} -ZSH_AUTOSUGGEST_STRATEGY=default +# Strategies to use to fetch a suggestion +# Will try each strategy in order until a suggestion is returned +(( ! ${+ZSH_AUTOSUGGEST_STRATEGY} )) && ZSH_AUTOSUGGEST_STRATEGY=(history) # Widgets that clear the suggestion -ZSH_AUTOSUGGEST_CLEAR_WIDGETS=( +(( ! ${+ZSH_AUTOSUGGEST_CLEAR_WIDGETS} )) && ZSH_AUTOSUGGEST_CLEAR_WIDGETS=( history-search-forward history-search-backward history-beginning-search-forward @@ -29,7 +31,7 @@ ZSH_AUTOSUGGEST_CLEAR_WIDGETS=( ) # Widgets that accept the entire suggestion -ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=( +(( ! ${+ZSH_AUTOSUGGEST_ACCEPT_WIDGETS} )) && ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=( forward-char end-of-line vi-forward-char @@ -38,11 +40,11 @@ ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=( ) # Widgets that accept the entire suggestion and execute it -ZSH_AUTOSUGGEST_EXECUTE_WIDGETS=( +(( ! ${+ZSH_AUTOSUGGEST_EXECUTE_WIDGETS} )) && ZSH_AUTOSUGGEST_EXECUTE_WIDGETS=( ) # Widgets that accept the suggestion as far as the cursor moves -ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=( +(( ! ${+ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS} )) && ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=( forward-word emacs-forward-word vi-forward-word @@ -54,7 +56,7 @@ ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=( ) # Widgets that should be ignored (globbing supported but must be escaped) -ZSH_AUTOSUGGEST_IGNORE_WIDGETS=( +(( ! ${+ZSH_AUTOSUGGEST_IGNORE_WIDGETS} )) && ZSH_AUTOSUGGEST_IGNORE_WIDGETS=( orig-\* beep run-help @@ -64,8 +66,8 @@ ZSH_AUTOSUGGEST_IGNORE_WIDGETS=( yank-pop ) -# Max size of buffer to trigger autosuggestion. Leave undefined for no upper bound. -ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE= +# Max size of buffer to trigger autosuggestion. Leave null for no upper bound. +: ${ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=} # Pty name for calculating autosuggestions asynchronously -ZSH_AUTOSUGGEST_ASYNC_PTY_NAME=zsh_autosuggest_pty +: ${ZSH_AUTOSUGGEST_ASYNC_PTY_NAME=zsh_autosuggest_pty} diff --git a/src/fetch.zsh b/src/fetch.zsh new file mode 100644 index 0000000..f94e66d --- /dev/null +++ b/src/fetch.zsh @@ -0,0 +1,23 @@ + +#--------------------------------------------------------------------# +# Fetch Suggestion # +#--------------------------------------------------------------------# +# Loops through all specified strategies and returns a suggestion +# from the first strategy to provide one. +# + +_zsh_autosuggest_fetch_suggestion() { + typeset -g suggestion + local -a strategies + + # Ensure we are working with an array + strategies=(${=ZSH_AUTOSUGGEST_STRATEGY}) + + for strategy in $strategies; do + # Try to get a suggestion from this strategy + _zsh_autosuggest_strategy_$strategy "$1" + + # Break once we've found a suggestion + [[ -n "$suggestion" ]] && break + done +} diff --git a/src/strategies/default.zsh b/src/strategies/default.zsh index 0e85fb5..a2755a5 100644 --- a/src/strategies/default.zsh +++ b/src/strategies/default.zsh @@ -1,12 +1,12 @@ #--------------------------------------------------------------------# -# Default Suggestion Strategy # +# History Suggestion Strategy # #--------------------------------------------------------------------# # Suggests the most recent history item that matches the given # prefix. # -_zsh_autosuggest_strategy_default() { +_zsh_autosuggest_strategy_history() { # Reset options to defaults and enable LOCAL_OPTIONS emulate -L zsh diff --git a/src/widgets.zsh b/src/widgets.zsh index 87bb62e..6a2be4a 100644 --- a/src/widgets.zsh +++ b/src/widgets.zsh @@ -37,6 +37,8 @@ _zsh_autosuggest_clear() { # Modify the buffer and get a new suggestion _zsh_autosuggest_modify() { + emulate -L zsh + local -i retval # Only available in zsh >= 5.4 @@ -97,13 +99,15 @@ _zsh_autosuggest_fetch() { _zsh_autosuggest_async_request "$BUFFER" else local suggestion - _zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "$BUFFER" + _zsh_autosuggest_fetch_suggestion "$BUFFER" _zsh_autosuggest_suggest "$suggestion" fi } # Offer a suggestion _zsh_autosuggest_suggest() { + emulate -L zsh + local suggestion="$1" if [[ -n "$suggestion" ]] && (( $#BUFFER )); then diff --git a/zsh-autosuggestions.zsh b/zsh-autosuggestions.zsh index 1c3eab5..d8f0151 100644 --- a/zsh-autosuggestions.zsh +++ b/zsh-autosuggestions.zsh @@ -1,6 +1,6 @@ # Fish-like fast/unobtrusive autosuggestions for zsh. # https://github.com/zsh-users/zsh-autosuggestions -# v0.4.3 +# v0.5.0 # Copyright (c) 2013 Thiago de Arruda # Copyright (c) 2016-2018 Eric Freese # @@ -42,15 +42,17 @@ zmodload zsh/zpty # Color to use when highlighting suggestion # Uses format of `region_highlight` # More info: http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Zle-Widgets -ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=8' +: ${ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=8'} # Prefix to use when saving original versions of bound widgets -ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX=autosuggest-orig- +: ${ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX=autosuggest-orig-} -ZSH_AUTOSUGGEST_STRATEGY=default +# Strategies to use to fetch a suggestion +# Will try each strategy in order until a suggestion is returned +(( ! ${+ZSH_AUTOSUGGEST_STRATEGY} )) && ZSH_AUTOSUGGEST_STRATEGY=(history) # Widgets that clear the suggestion -ZSH_AUTOSUGGEST_CLEAR_WIDGETS=( +(( ! ${+ZSH_AUTOSUGGEST_CLEAR_WIDGETS} )) && ZSH_AUTOSUGGEST_CLEAR_WIDGETS=( history-search-forward history-search-backward history-beginning-search-forward @@ -65,7 +67,7 @@ ZSH_AUTOSUGGEST_CLEAR_WIDGETS=( ) # Widgets that accept the entire suggestion -ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=( +(( ! ${+ZSH_AUTOSUGGEST_ACCEPT_WIDGETS} )) && ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=( forward-char end-of-line vi-forward-char @@ -74,11 +76,11 @@ ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=( ) # Widgets that accept the entire suggestion and execute it -ZSH_AUTOSUGGEST_EXECUTE_WIDGETS=( +(( ! ${+ZSH_AUTOSUGGEST_EXECUTE_WIDGETS} )) && ZSH_AUTOSUGGEST_EXECUTE_WIDGETS=( ) # Widgets that accept the suggestion as far as the cursor moves -ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=( +(( ! ${+ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS} )) && ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=( forward-word emacs-forward-word vi-forward-word @@ -90,7 +92,7 @@ ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=( ) # Widgets that should be ignored (globbing supported but must be escaped) -ZSH_AUTOSUGGEST_IGNORE_WIDGETS=( +(( ! ${+ZSH_AUTOSUGGEST_IGNORE_WIDGETS} )) && ZSH_AUTOSUGGEST_IGNORE_WIDGETS=( orig-\* beep run-help @@ -100,11 +102,11 @@ ZSH_AUTOSUGGEST_IGNORE_WIDGETS=( yank-pop ) -# Max size of buffer to trigger autosuggestion. Leave undefined for no upper bound. -ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE= +# Max size of buffer to trigger autosuggestion. Leave null for no upper bound. +: ${ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=} # Pty name for calculating autosuggestions asynchronously -ZSH_AUTOSUGGEST_ASYNC_PTY_NAME=zsh_autosuggest_pty +: ${ZSH_AUTOSUGGEST_ASYNC_PTY_NAME=zsh_autosuggest_pty} #--------------------------------------------------------------------# # Utility Functions # @@ -206,12 +208,14 @@ _zsh_autosuggest_bind_widget() { }" # Create the bound widget - zle -N $widget _zsh_autosuggest_bound_${bind_count}_$widget + zle -N -- $widget _zsh_autosuggest_bound_${bind_count}_$widget } # Map all configured widgets to the right autosuggest widgets _zsh_autosuggest_bind_widgets() { - local widget + emulate -L zsh + + local widget local ignore_widgets ignore_widgets=( @@ -318,6 +322,8 @@ _zsh_autosuggest_clear() { # Modify the buffer and get a new suggestion _zsh_autosuggest_modify() { + emulate -L zsh + local -i retval # Only available in zsh >= 5.4 @@ -378,13 +384,15 @@ _zsh_autosuggest_fetch() { _zsh_autosuggest_async_request "$BUFFER" else local suggestion - _zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "$BUFFER" + _zsh_autosuggest_fetch_suggestion "$BUFFER" _zsh_autosuggest_suggest "$suggestion" fi } # Offer a suggestion _zsh_autosuggest_suggest() { + emulate -L zsh + local suggestion="$1" if [[ -n "$suggestion" ]] && (( $#BUFFER )); then @@ -494,13 +502,13 @@ zle -N autosuggest-disable _zsh_autosuggest_widget_disable zle -N autosuggest-toggle _zsh_autosuggest_widget_toggle #--------------------------------------------------------------------# -# Default Suggestion Strategy # +# History Suggestion Strategy # #--------------------------------------------------------------------# # Suggests the most recent history item that matches the given # prefix. # -_zsh_autosuggest_strategy_default() { +_zsh_autosuggest_strategy_history() { # Reset options to defaults and enable LOCAL_OPTIONS emulate -L zsh @@ -577,6 +585,29 @@ _zsh_autosuggest_strategy_match_prev_cmd() { typeset -g suggestion="$history[$histkey]" } +#--------------------------------------------------------------------# +# Fetch Suggestion # +#--------------------------------------------------------------------# +# Loops through all specified strategies and returns a suggestion +# from the first strategy to provide one. +# + +_zsh_autosuggest_fetch_suggestion() { + typeset -g suggestion + local -a strategies + + # Ensure we are working with an array + strategies=(${=ZSH_AUTOSUGGEST_STRATEGY}) + + for strategy in $strategies; do + # Try to get a suggestion from this strategy + _zsh_autosuggest_strategy_$strategy "$1" + + # Break once we've found a suggestion + [[ -n "$suggestion" ]] && break + done +} + #--------------------------------------------------------------------# # Async # #--------------------------------------------------------------------# @@ -595,9 +626,12 @@ _zsh_autosuggest_async_server() { sleep 1 # Block for long enough for the signal to come through } - # Output only newlines (not carriage return + newline) + # 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 @@ -610,7 +644,7 @@ _zsh_autosuggest_async_server() { # Run suggestion search in the background ( local suggestion - _zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "$query" + _zsh_autosuggest_fetch_suggestion "$query" echo -n -E "$suggestion"$'\0' ) &