From 0f80f9511d6346c9dac4efa8a34f150f0bf0991a Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Sat, 26 May 2018 14:01:03 -0600 Subject: [PATCH 01/12] Fix handling of newline + carriage return in async pty (#333) --- spec/async_spec.rb | 39 +++++++++++++++++++++++++++++++++++++++ src/async.zsh | 5 ++++- zsh-autosuggestions.zsh | 5 ++++- 3 files changed, 47 insertions(+), 2 deletions(-) diff --git a/spec/async_spec.rb b/spec/async_spec.rb index 0bcbaa1..10f1a74 100644 --- a/spec/async_spec.rb +++ b/spec/async_spec.rb @@ -27,6 +27,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/src/async.zsh b/src/async.zsh index 9a0cfaa..62e3329 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 diff --git a/zsh-autosuggestions.zsh b/zsh-autosuggestions.zsh index 1c3eab5..e2e06be 100644 --- a/zsh-autosuggestions.zsh +++ b/zsh-autosuggestions.zsh @@ -595,9 +595,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 From 822a1f30e0a6712bbd48525a5047df3879c673be Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Sat, 26 May 2018 15:33:32 -0600 Subject: [PATCH 02/12] Async is less reliable in zsh versions < 5.0.8 `stty` occasionally hangs (always in CircleCI) inside the async pty. Disable the tests for now until we can figure out and fix/workaround this issue. --- spec/async_spec.rb | 4 ++++ spec/terminal_session.rb | 4 ++++ 2 files changed, 8 insertions(+) diff --git a/spec/async_spec.rb b/spec/async_spec.rb index 10f1a74..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 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 From 4097d6e0aeb3e2ec5f805ea1211e146a6cd26e13 Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Sun, 10 Jun 2018 22:39:58 -0600 Subject: [PATCH 03/12] Support widgets starting with dashes (ex: `-a-widget`) Fixes #337 --- src/bind.zsh | 2 +- zsh-autosuggestions.zsh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/src/bind.zsh b/src/bind.zsh index 42a0dd0..f538379 100644 --- a/src/bind.zsh +++ b/src/bind.zsh @@ -69,7 +69,7 @@ _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 diff --git a/zsh-autosuggestions.zsh b/zsh-autosuggestions.zsh index e2e06be..0a1f9c6 100644 --- a/zsh-autosuggestions.zsh +++ b/zsh-autosuggestions.zsh @@ -206,7 +206,7 @@ _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 From df6f6f9ff417e129701d218060edf9b8761dc963 Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Sat, 30 Jun 2018 15:38:05 -0600 Subject: [PATCH 04/12] Add install directions for Antigen --- INSTALL.md | 10 ++++++++++ 1 file changed, 10 insertions(+) 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`) From 4540304fa0a59b9054f19ede32088da6669938d1 Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Fri, 13 Jul 2018 22:16:53 -0600 Subject: [PATCH 05/12] Reset opts in some functions affected by GLOB_SUBST Should fix GitHub #334 --- src/bind.zsh | 4 +++- src/widgets.zsh | 4 ++++ zsh-autosuggestions.zsh | 8 +++++++- 3 files changed, 14 insertions(+), 2 deletions(-) diff --git a/src/bind.zsh b/src/bind.zsh index f538379..bb41ef8 100644 --- a/src/bind.zsh +++ b/src/bind.zsh @@ -74,7 +74,9 @@ _zsh_autosuggest_bind_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/widgets.zsh b/src/widgets.zsh index 87bb62e..3192d5e 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 @@ -104,6 +106,8 @@ _zsh_autosuggest_fetch() { # 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 0a1f9c6..ce302fd 100644 --- a/zsh-autosuggestions.zsh +++ b/zsh-autosuggestions.zsh @@ -211,7 +211,9 @@ _zsh_autosuggest_bind_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 +320,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 @@ -385,6 +389,8 @@ _zsh_autosuggest_fetch() { # Offer a suggestion _zsh_autosuggest_suggest() { + emulate -L zsh + local suggestion="$1" if [[ -n "$suggestion" ]] && (( $#BUFFER )); then From 62f5f14f2fd1d19b6cf5711a1c33e27892dc0cf1 Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Mon, 19 Nov 2018 15:30:35 -0700 Subject: [PATCH 06/12] default => history --- README.md | 2 +- spec/integrations/zle_input_stack_spec.rb | 2 +- spec/options/strategy_spec.rb | 2 +- src/config.zsh | 2 +- src/strategies/default.zsh | 4 ++-- zsh-autosuggestions.zsh | 6 +++--- 6 files changed, 9 insertions(+), 9 deletions(-) diff --git a/README.md b/README.md index 83720e6..6389b37 100644 --- a/README.md +++ b/README.md @@ -41,7 +41,7 @@ Set `ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE` to configure the style that the suggestion Set `ZSH_AUTOSUGGEST_STRATEGY` to choose the strategy for generating suggestions. There are currently two to choose from: -- `default`: Chooses the most recent match. +- `history`: Chooses the most recent match from history. - `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`. 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..c42c578 100644 --- a/spec/options/strategy_spec.rb +++ b/spec/options/strategy_spec.rb @@ -1,5 +1,5 @@ describe 'a suggestion for a given prefix' do - let(:options) { ['_zsh_autosuggest_strategy_default() { suggestion="echo foo" }'] } + let(:options) { ['_zsh_autosuggest_strategy_history() { suggestion="echo foo" }'] } it 'is determined by calling the default strategy function' do session.send_string('e') diff --git a/src/config.zsh b/src/config.zsh index 597307f..1a171f9 100644 --- a/src/config.zsh +++ b/src/config.zsh @@ -11,7 +11,7 @@ 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_STRATEGY=default +ZSH_AUTOSUGGEST_STRATEGY=history # Widgets that clear the suggestion ZSH_AUTOSUGGEST_CLEAR_WIDGETS=( 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/zsh-autosuggestions.zsh b/zsh-autosuggestions.zsh index ce302fd..8a1939f 100644 --- a/zsh-autosuggestions.zsh +++ b/zsh-autosuggestions.zsh @@ -47,7 +47,7 @@ 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_STRATEGY=default +ZSH_AUTOSUGGEST_STRATEGY=history # Widgets that clear the suggestion ZSH_AUTOSUGGEST_CLEAR_WIDGETS=( @@ -500,13 +500,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 From a78ea16c507f00e07c3f81349b852a90aeb53366 Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Sat, 24 Nov 2018 09:56:30 -0700 Subject: [PATCH 07/12] Support fallback strategies by setting array in config --- Makefile | 1 + README.md | 4 ++-- spec/options/strategy_spec.rb | 44 +++++++++++++++++++++++++++-------- src/async.zsh | 2 +- src/config.zsh | 4 +++- src/fetch.zsh | 23 ++++++++++++++++++ src/widgets.zsh | 2 +- zsh-autosuggestions.zsh | 31 +++++++++++++++++++++--- 8 files changed, 93 insertions(+), 18 deletions(-) create mode 100644 src/fetch.zsh 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 6389b37..a0bfa78 100644 --- a/README.md +++ b/README.md @@ -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: - `history`: Chooses the most recent match from history. -- `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`. +- `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/spec/options/strategy_spec.rb b/spec/options/strategy_spec.rb index c42c578..ae5a90f 100644 --- a/spec/options/strategy_spec.rb +++ b/spec/options/strategy_spec.rb @@ -1,20 +1,44 @@ describe 'a suggestion for a given prefix' do - let(:options) { ['_zsh_autosuggest_strategy_history() { 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(:options) { [ history_strategy ] } + + it 'by default is determined by calling the `history` strategy function' do + session.send_string('h') + wait_for { session.content }.to eq('history') end - context 'when ZSH_AUTOSUGGEST_STRATEGY is set' do + context 'when ZSH_AUTOSUGGEST_STRATEGY is set to an array' do let(:options) { [ - '_zsh_autosuggest_strategy_custom() { suggestion="echo foo" }', - 'ZSH_AUTOSUGGEST_STRATEGY=custom' + foobar_strategy, + foobaz_strategy, + 'ZSH_AUTOSUGGEST_STRATEGY=(foobar foobaz)' ] } - it 'is determined by calling the specified strategy function' do - session.send_string('e') - wait_for { session.content }.to eq('echo foo') + 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(:options) { [ + foobar_strategy, + foobaz_strategy, + 'ZSH_AUTOSUGGEST_STRATEGY="foobar foobaz"' + ] } + + 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/src/async.zsh b/src/async.zsh index 62e3329..dd54c24 100644 --- a/src/async.zsh +++ b/src/async.zsh @@ -35,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/config.zsh b/src/config.zsh index 1a171f9..b1e2c5b 100644 --- a/src/config.zsh +++ b/src/config.zsh @@ -11,7 +11,9 @@ 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_STRATEGY=history +# Strategies to use to fetch a suggestion +# Will try each strategy in order until a suggestion is returned +ZSH_AUTOSUGGEST_STRATEGY=(history) # Widgets that clear the suggestion ZSH_AUTOSUGGEST_CLEAR_WIDGETS=( 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/widgets.zsh b/src/widgets.zsh index 3192d5e..6a2be4a 100644 --- a/src/widgets.zsh +++ b/src/widgets.zsh @@ -99,7 +99,7 @@ _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 } diff --git a/zsh-autosuggestions.zsh b/zsh-autosuggestions.zsh index 8a1939f..91f3af6 100644 --- a/zsh-autosuggestions.zsh +++ b/zsh-autosuggestions.zsh @@ -47,7 +47,9 @@ 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_STRATEGY=history +# Strategies to use to fetch a suggestion +# Will try each strategy in order until a suggestion is returned +ZSH_AUTOSUGGEST_STRATEGY=(history) # Widgets that clear the suggestion ZSH_AUTOSUGGEST_CLEAR_WIDGETS=( @@ -382,7 +384,7 @@ _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 } @@ -583,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 # #--------------------------------------------------------------------# @@ -619,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' ) & From f0f1332e6b013613d339c189003e781275669fa2 Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Sat, 10 Nov 2018 13:56:31 -0700 Subject: [PATCH 08/12] Add `after_sourcing` hook for tests Is executed immediately after sourcing the plugin --- spec/options/strategy_spec.rb | 33 ++++++++++++++++++++++----------- spec/spec_helper.rb | 2 ++ 2 files changed, 24 insertions(+), 11 deletions(-) diff --git a/spec/options/strategy_spec.rb b/spec/options/strategy_spec.rb index ae5a90f..58562d0 100644 --- a/spec/options/strategy_spec.rb +++ b/spec/options/strategy_spec.rb @@ -3,7 +3,11 @@ describe 'a suggestion for a given prefix' do 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" }' } - let(:options) { [ history_strategy ] } + let(:after_sourcing) do + -> do + session.run_command(history_strategy) + end + end it 'by default is determined by calling the `history` strategy function' do session.send_string('h') @@ -11,11 +15,14 @@ describe 'a suggestion for a given prefix' do end context 'when ZSH_AUTOSUGGEST_STRATEGY is set to an array' do - let(:options) { [ - foobar_strategy, - foobaz_strategy, - 'ZSH_AUTOSUGGEST_STRATEGY=(foobar foobaz)' - ] } + 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') @@ -27,11 +34,14 @@ describe 'a suggestion for a given prefix' do end context 'when ZSH_AUTOSUGGEST_STRATEGY is set to a string' do - let(:options) { [ - foobar_strategy, - foobaz_strategy, - 'ZSH_AUTOSUGGEST_STRATEGY="foobar foobaz"' - ] } + 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') @@ -42,3 +52,4 @@ describe 'a suggestion for a given prefix' do end end end + diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index 64115d2..bfcb706 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('; ')) + after_sourcing.call session.clear_screen example.run From 9e4d3c337ff2e3e7b11502142b8c3db4924b8f70 Mon Sep 17 00:00:00 2001 From: Eric Nielsen Date: Mon, 15 Oct 2018 16:37:02 -0500 Subject: [PATCH 09/12] Don't overwrite config with default values otherwise users are obliged to set the config values *after* sourcing the plugin. They're not able to do it before. Also, re-sourcing the plugin will reset the values to the defaults again. See zimfw/zimfw#301 Fixes #335 --- README.md | 2 +- spec/spec_helper.rb | 4 ++-- src/config.zsh | 22 +++++++++++----------- zsh-autosuggestions.zsh | 22 +++++++++++----------- 4 files changed, 25 insertions(+), 25 deletions(-) diff --git a/README.md b/README.md index a0bfa78..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). diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb index bfcb706..abea917 100644 --- a/spec/spec_helper.rb +++ b/spec/spec_helper.rb @@ -11,8 +11,8 @@ RSpec.shared_context 'terminal session' do 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 diff --git a/src/config.zsh b/src/config.zsh index b1e2c5b..9ac1484 100644 --- a/src/config.zsh +++ b/src/config.zsh @@ -6,17 +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-} # Strategies to use to fetch a suggestion # Will try each strategy in order until a suggestion is returned -ZSH_AUTOSUGGEST_STRATEGY=(history) +(( ! ${+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 @@ -31,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 @@ -40,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 @@ -56,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 @@ -66,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/zsh-autosuggestions.zsh b/zsh-autosuggestions.zsh index 91f3af6..56aa80b 100644 --- a/zsh-autosuggestions.zsh +++ b/zsh-autosuggestions.zsh @@ -42,17 +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-} # Strategies to use to fetch a suggestion # Will try each strategy in order until a suggestion is returned -ZSH_AUTOSUGGEST_STRATEGY=(history) +(( ! ${+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 @@ -67,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 @@ -76,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 @@ -92,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 @@ -102,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 # From 0d994d4732ed08ca299c381e749c0e457d97073a Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Sat, 24 Nov 2018 09:44:07 -0700 Subject: [PATCH 10/12] Update changelog for v0.5.0 release --- CHANGELOG.md | 10 ++++++++++ 1 file changed, 10 insertions(+) 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) From 286656635c6b9d7a1e968fa61e60522e423e5387 Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Sat, 24 Nov 2018 09:44:46 -0700 Subject: [PATCH 11/12] v0.5.0 --- VERSION | 2 +- zsh-autosuggestions.zsh | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) 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/zsh-autosuggestions.zsh b/zsh-autosuggestions.zsh index 56aa80b..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 # From 70f36c007db30a5fe1edf2b63664088b502a729c Mon Sep 17 00:00:00 2001 From: Eric Freese Date: Sat, 24 Nov 2018 15:06:19 -0700 Subject: [PATCH 12/12] Finish renaming "default" strategy to "history" --- spec/strategies/{default_spec.rb => history_spec.rb} | 2 +- src/strategies/{default.zsh => history.zsh} | 0 2 files changed, 1 insertion(+), 1 deletion(-) rename spec/strategies/{default_spec.rb => history_spec.rb} (85%) rename src/strategies/{default.zsh => history.zsh} (100%) diff --git a/spec/strategies/default_spec.rb b/spec/strategies/history_spec.rb similarity index 85% rename from spec/strategies/default_spec.rb rename to spec/strategies/history_spec.rb index 89321f3..f8ae526 100644 --- a/spec/strategies/default_spec.rb +++ b/spec/strategies/history_spec.rb @@ -1,6 +1,6 @@ require 'strategies/special_characters_helper' -describe 'the default suggestion strategy' do +describe 'the `history` suggestion strategy' do it 'suggests the last matching history entry' do with_history('ls foo', 'ls bar', 'echo baz') do session.send_string('ls') diff --git a/src/strategies/default.zsh b/src/strategies/history.zsh similarity index 100% rename from src/strategies/default.zsh rename to src/strategies/history.zsh