Merge pull request #169 from zsh-users/develop

v0.3.3
This commit is contained in:
Eric Freese 2016-10-17 07:45:49 -06:00 committed by GitHub
commit fedc22e9bb
12 changed files with 143 additions and 34 deletions

View file

@ -1,5 +1,12 @@
# Changelog # Changelog
## v0.3.3
- Switch from $history array to fc builtin for better performance with large HISTFILEs (#164)
- Fix tilde handling when extended_glob is set (#168)
- Add config option for maximum buffer length to fetch suggestions for (#178)
- Add config option for list of widgets to ignore (#184)
- Don't fetch a new suggestion unless a modification widget actually modifies the buffer (#183)
## v0.3.2 ## v0.3.2
- Test runner now supports running specific tests and choosing zsh binary - Test runner now supports running specific tests and choosing zsh binary
- Return code from original widget is now correctly passed through (#135) - Return code from original widget is now correctly passed through (#135)

View file

@ -69,7 +69,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: Set `ZSH_AUTOSUGGEST_STRATEGY` to choose the strategy for generating suggestions. There are currently two to choose from:
- `default`: Chooses the most recent match. - `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)). - `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`.
### Widget Mapping ### Widget Mapping
@ -80,12 +80,19 @@ This plugin works by triggering custom behavior when certain [zle widgets](http:
- `ZSH_AUTOSUGGEST_ACCEPT_WIDGETS`: Widgets in this array will accept the suggestion when invoked. - `ZSH_AUTOSUGGEST_ACCEPT_WIDGETS`: Widgets in this array will accept the suggestion when invoked.
- `ZSH_AUTOSUGGEST_EXECUTE_WIDGETS`: Widgets in this array will execute the suggestion when invoked. - `ZSH_AUTOSUGGEST_EXECUTE_WIDGETS`: Widgets in this array will execute the suggestion when invoked.
- `ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS`: Widgets in this array will partially accept the suggestion when invoked. - `ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS`: Widgets in this array will partially accept the suggestion when invoked.
- `ZSH_AUTOSUGGEST_IGNORE_WIDGETS`: Widgets in this array will not trigger any custom behavior.
Widgets not in any of these lists will update the suggestion when invoked. Widgets that modify the buffer and are not found in any of these arrays will fetch a new suggestion after they are invoked.
**Note:** A widget shouldn't belong to more than one of the above arrays. **Note:** A widget shouldn't belong to more than one of the above arrays.
### Disabling suggestion for large buffers
Set `ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE` to an integer value to disable autosuggestion for large buffers. The default is unset, which means that autosuggestion will be tried for any buffer size. Recommended value is 20.
This can be useful when pasting large amount of text in the terminal, to avoid triggering autosuggestion for too long strings.
### Key Bindings ### Key Bindings
This plugin provides three widgets that you can use with `bindkey`: This plugin provides three widgets that you can use with `bindkey`:

View file

@ -1 +1 @@
v0.3.2 v0.3.3

View file

@ -47,10 +47,20 @@ _zsh_autosuggest_bind_widget() {
# Map all configured widgets to the right autosuggest widgets # Map all configured widgets to the right autosuggest widgets
_zsh_autosuggest_bind_widgets() { _zsh_autosuggest_bind_widgets() {
local widget; local widget
local ignore_widgets
ignore_widgets=(
.\*
_\*
zle-line-\*
autosuggest-\*
$ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX\*
$ZSH_AUTOSUGGEST_IGNORE_WIDGETS
)
# Find every widget we might want to bind and bind it appropriately # Find every widget we might want to bind and bind it appropriately
for widget in ${${(f)"$(builtin zle -la)"}:#(.*|_*|orig-*|autosuggest-*|$ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX*|zle-line-*|run-help|which-command|beep|set-local-history|yank)}; do for widget in ${${(f)"$(builtin zle -la)"}:#${(j:|:)~ignore_widgets}}; do
if [ ${ZSH_AUTOSUGGEST_CLEAR_WIDGETS[(r)$widget]} ]; then if [ ${ZSH_AUTOSUGGEST_CLEAR_WIDGETS[(r)$widget]} ]; then
_zsh_autosuggest_bind_widget $widget clear _zsh_autosuggest_bind_widget $widget clear
elif [ ${ZSH_AUTOSUGGEST_ACCEPT_WIDGETS[(r)$widget]} ]; then elif [ ${ZSH_AUTOSUGGEST_ACCEPT_WIDGETS[(r)$widget]} ]; then

View file

@ -47,3 +47,16 @@ ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=(
vi-forward-blank-word vi-forward-blank-word
vi-forward-blank-word-end vi-forward-blank-word-end
) )
# Widgets that should be ignored (globbing supported but must be escaped)
ZSH_AUTOSUGGEST_IGNORE_WIDGETS=(
orig-\*
beep
run-help
set-local-history
which-command
yank
)
# Max size of buffer to trigger autosuggestion. Leave undefined for no upper bound.
ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=

View file

@ -7,12 +7,5 @@
# #
_zsh_autosuggest_strategy_default() { _zsh_autosuggest_strategy_default() {
local prefix="$1" fc -lnrm "$1*" 1 2>/dev/null | head -n 1
# Get the keys of the history items that match
local -a histkeys
histkeys=(${(k)history[(r)$prefix*]})
# Echo the value of the first key
echo -E "${history[$histkeys[1]]}"
} }

View file

@ -16,6 +16,9 @@
# will be 'ls foo' rather than 'ls bar' because your most recently # will be 'ls foo' rather than 'ls bar' because your most recently
# executed command (pwd) was previously followed by 'ls foo'. # executed command (pwd) was previously followed by 'ls foo'.
# #
# 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`.
_zsh_autosuggest_strategy_match_prev_cmd() { _zsh_autosuggest_strategy_match_prev_cmd() {
local prefix="$1" local prefix="$1"

View file

@ -17,5 +17,5 @@ _zsh_autosuggest_escape_command() {
setopt localoptions EXTENDED_GLOB setopt localoptions EXTENDED_GLOB
# Escape special chars in the string (requires EXTENDED_GLOB) # Escape special chars in the string (requires EXTENDED_GLOB)
echo -E "${1//(#m)[\\()\[\]|*?]/\\$MATCH}" echo -E "${1//(#m)[\\()\[\]|*?~]/\\$MATCH}"
} }

View file

@ -15,24 +15,34 @@ _zsh_autosuggest_clear() {
_zsh_autosuggest_modify() { _zsh_autosuggest_modify() {
local -i retval local -i retval
# Save the contents of the buffer/postdisplay
local orig_buffer="$BUFFER"
local orig_postdisplay="$POSTDISPLAY"
# Clear suggestion while original widget runs # Clear suggestion while original widget runs
unset POSTDISPLAY unset POSTDISPLAY
# Original widget modifies the buffer # Original widget may modify the buffer
_zsh_autosuggest_invoke_original_widget $@ _zsh_autosuggest_invoke_original_widget $@
retval=$? retval=$?
# Don't fetch a new suggestion if the buffer hasn't changed
if [ "$BUFFER" = "$orig_buffer" ]; then
POSTDISPLAY="$orig_postdisplay"
return $retval
fi
# Get a new suggestion if the buffer is not empty after modification # Get a new suggestion if the buffer is not empty after modification
local suggestion local suggestion
if [ $#BUFFER -gt 0 ]; then if [ $#BUFFER -gt 0 ]; then
if [ -z "$ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE" -o $#BUFFER -lt "$ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE" ]; then
suggestion="$(_zsh_autosuggest_suggestion "$BUFFER")" suggestion="$(_zsh_autosuggest_suggestion "$BUFFER")"
fi fi
fi
# Add the suggestion to the POSTDISPLAY # Add the suggestion to the POSTDISPLAY
if [ -n "$suggestion" ]; then if [ -n "$suggestion" ]; then
POSTDISPLAY="${suggestion#$BUFFER}" POSTDISPLAY="${suggestion#$BUFFER}"
else
unset POSTDISPLAY
fi fi
return $retval return $retval

View file

@ -44,6 +44,12 @@ assertTildeSuggestion() {
'cd ~/something' 'cd ~/something'
} }
assertTildeSuggestionWithExtendedGlob() {
setopt local_options extended_glob
assertTildeSuggestion
}
assertParenthesesSuggestion() { assertParenthesesSuggestion() {
set_history <<-'EOF' set_history <<-'EOF'
echo "$(ls foo)" echo "$(ls foo)"
@ -87,6 +93,7 @@ testSpecialCharsForAllStrategies() {
assertBackslashSuggestion assertBackslashSuggestion
assertDoubleBackslashSuggestion assertDoubleBackslashSuggestion
assertTildeSuggestion assertTildeSuggestion
assertTildeSuggestionWithExtendedGlob
assertParenthesesSuggestion assertParenthesesSuggestion
assertSquareBracketsSuggestion assertSquareBracketsSuggestion
done done

View file

@ -9,6 +9,7 @@ oneTimeSetUp() {
setUp() { setUp() {
BUFFER='' BUFFER=''
POSTDISPLAY='' POSTDISPLAY=''
ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=''
} }
tearDown() { tearDown() {
@ -42,6 +43,35 @@ testModify() {
"$POSTDISPLAY" "$POSTDISPLAY"
} }
testModifyBufferTooLarge() {
ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE='20'
stub_and_eval \
_zsh_autosuggest_invoke_original_widget \
'BUFFER+="012345678901234567890"'
stub_and_echo \
_zsh_autosuggest_suggestion \
'012345678901234567890123456789'
_zsh_autosuggest_modify 'original-widget'
assertTrue \
'original widget not invoked' \
'stub_called _zsh_autosuggest_invoke_original_widget'
assertEquals \
'BUFFER was not modified' \
'012345678901234567890' \
"$BUFFER"
assertEquals \
'POSTDISPLAY does not contain suggestion' \
'' \
"$POSTDISPLAY"
}
testRetval() { testRetval() {
stub_and_eval \ stub_and_eval \
_zsh_autosuggest_invoke_original_widget \ _zsh_autosuggest_invoke_original_widget \

View file

@ -1,6 +1,6 @@
# Fish-like fast/unobtrusive autosuggestions for zsh. # Fish-like fast/unobtrusive autosuggestions for zsh.
# https://github.com/zsh-users/zsh-autosuggestions # https://github.com/zsh-users/zsh-autosuggestions
# v0.3.2 # v0.3.3
# Copyright (c) 2013 Thiago de Arruda # Copyright (c) 2013 Thiago de Arruda
# Copyright (c) 2016 Eric Freese # Copyright (c) 2016 Eric Freese
# #
@ -74,6 +74,19 @@ ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=(
vi-forward-blank-word-end vi-forward-blank-word-end
) )
# Widgets that should be ignored (globbing supported but must be escaped)
ZSH_AUTOSUGGEST_IGNORE_WIDGETS=(
orig-\*
beep
run-help
set-local-history
which-command
yank
)
# Max size of buffer to trigger autosuggestion. Leave undefined for no upper bound.
ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE=
#--------------------------------------------------------------------# #--------------------------------------------------------------------#
# Handle Deprecated Variables/Widgets # # Handle Deprecated Variables/Widgets #
#--------------------------------------------------------------------# #--------------------------------------------------------------------#
@ -158,10 +171,20 @@ _zsh_autosuggest_bind_widget() {
# Map all configured widgets to the right autosuggest widgets # Map all configured widgets to the right autosuggest widgets
_zsh_autosuggest_bind_widgets() { _zsh_autosuggest_bind_widgets() {
local widget; local widget
local ignore_widgets
ignore_widgets=(
.\*
_\*
zle-line-\*
autosuggest-\*
$ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX\*
$ZSH_AUTOSUGGEST_IGNORE_WIDGETS
)
# Find every widget we might want to bind and bind it appropriately # Find every widget we might want to bind and bind it appropriately
for widget in ${${(f)"$(builtin zle -la)"}:#(.*|_*|orig-*|autosuggest-*|$ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX*|zle-line-*|run-help|which-command|beep|set-local-history|yank)}; do for widget in ${${(f)"$(builtin zle -la)"}:#${(j:|:)~ignore_widgets}}; do
if [ ${ZSH_AUTOSUGGEST_CLEAR_WIDGETS[(r)$widget]} ]; then if [ ${ZSH_AUTOSUGGEST_CLEAR_WIDGETS[(r)$widget]} ]; then
_zsh_autosuggest_bind_widget $widget clear _zsh_autosuggest_bind_widget $widget clear
elif [ ${ZSH_AUTOSUGGEST_ACCEPT_WIDGETS[(r)$widget]} ]; then elif [ ${ZSH_AUTOSUGGEST_ACCEPT_WIDGETS[(r)$widget]} ]; then
@ -233,24 +256,34 @@ _zsh_autosuggest_clear() {
_zsh_autosuggest_modify() { _zsh_autosuggest_modify() {
local -i retval local -i retval
# Save the contents of the buffer/postdisplay
local orig_buffer="$BUFFER"
local orig_postdisplay="$POSTDISPLAY"
# Clear suggestion while original widget runs # Clear suggestion while original widget runs
unset POSTDISPLAY unset POSTDISPLAY
# Original widget modifies the buffer # Original widget may modify the buffer
_zsh_autosuggest_invoke_original_widget $@ _zsh_autosuggest_invoke_original_widget $@
retval=$? retval=$?
# Don't fetch a new suggestion if the buffer hasn't changed
if [ "$BUFFER" = "$orig_buffer" ]; then
POSTDISPLAY="$orig_postdisplay"
return $retval
fi
# Get a new suggestion if the buffer is not empty after modification # Get a new suggestion if the buffer is not empty after modification
local suggestion local suggestion
if [ $#BUFFER -gt 0 ]; then if [ $#BUFFER -gt 0 ]; then
if [ -z "$ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE" -o $#BUFFER -lt "$ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE" ]; then
suggestion="$(_zsh_autosuggest_suggestion "$BUFFER")" suggestion="$(_zsh_autosuggest_suggestion "$BUFFER")"
fi fi
fi
# Add the suggestion to the POSTDISPLAY # Add the suggestion to the POSTDISPLAY
if [ -n "$suggestion" ]; then if [ -n "$suggestion" ]; then
POSTDISPLAY="${suggestion#$BUFFER}" POSTDISPLAY="${suggestion#$BUFFER}"
else
unset POSTDISPLAY
fi fi
return $retval return $retval
@ -360,7 +393,7 @@ _zsh_autosuggest_escape_command() {
setopt localoptions EXTENDED_GLOB setopt localoptions EXTENDED_GLOB
# Escape special chars in the string (requires EXTENDED_GLOB) # Escape special chars in the string (requires EXTENDED_GLOB)
echo -E "${1//(#m)[\\()\[\]|*?]/\\$MATCH}" echo -E "${1//(#m)[\\()\[\]|*?~]/\\$MATCH}"
} }
#--------------------------------------------------------------------# #--------------------------------------------------------------------#
@ -371,14 +404,7 @@ _zsh_autosuggest_escape_command() {
# #
_zsh_autosuggest_strategy_default() { _zsh_autosuggest_strategy_default() {
local prefix="$1" fc -lnrm "$1*" 1 2>/dev/null | head -n 1
# Get the keys of the history items that match
local -a histkeys
histkeys=(${(k)history[(r)$prefix*]})
# Echo the value of the first key
echo -E "${history[$histkeys[1]]}"
} }
#--------------------------------------------------------------------# #--------------------------------------------------------------------#
@ -398,6 +424,9 @@ _zsh_autosuggest_strategy_default() {
# will be 'ls foo' rather than 'ls bar' because your most recently # will be 'ls foo' rather than 'ls bar' because your most recently
# executed command (pwd) was previously followed by 'ls foo'. # executed command (pwd) was previously followed by 'ls foo'.
# #
# 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`.
_zsh_autosuggest_strategy_match_prev_cmd() { _zsh_autosuggest_strategy_match_prev_cmd() {
local prefix="$1" local prefix="$1"