Allow configuring to ignore history entries matching a pattern

Set ZSH_AUTOSUGGEST_HISTORY_IGNORE to a glob pattern to have the history
and match_prev_cmd suggestion strategies never make suggestions matching
that pattern.

For example, set to "cd *" to never suggest any `cd` commands from
history (see issues #340 and #425). Or set to "?(#c50,)" to never
suggest anything 50 characters or longer (see issue #429).
This commit is contained in:
Eric Freese 2019-06-29 21:44:29 -06:00
parent 146020d9b2
commit b87a4972c8
6 changed files with 78 additions and 20 deletions

View file

@ -86,6 +86,12 @@ As of `v0.4.0`, suggestions can be fetched asynchronously. To enable this behavi
Set `ZSH_AUTOSUGGEST_MANUAL_REBIND` (it can be set to anything) to disable automatic widget re-binding on each precmd. This can be a big boost to performance, but you'll need to handle re-binding yourself if any of the widget lists change or if you or another plugin wrap any of the autosuggest widgets. To re-bind widgets, run `_zsh_autosuggest_bind_widgets`.
### Ignoring history suggestions that match a pattern
Set `ZSH_AUTOSUGGEST_HISTORY_IGNORE` to a glob pattern to prevent offering suggestions for history entries that match the pattern. For example, set it to `"cd *"` to never suggest any `cd` commands from history. Or set to `"?(#c50,)"` to never suggest anything 50 characters or longer.
**Note:** This only affects the `history` and `match_prev_cmd` suggestion strategies.
### Key Bindings

View file

@ -8,5 +8,16 @@ describe 'the `history` suggestion strategy' do
end
end
context 'when ZSH_AUTOSUGGEST_HISTORY_IGNORE is set to a pattern' do
let(:options) { ['ZSH_AUTOSUGGEST_HISTORY_IGNORE="* bar"'] }
it 'does not make suggestions that match the pattern' do
with_history('ls foo', 'ls bar', 'echo baz') do
session.send_string('ls')
wait_for { session.content }.to eq('ls foo')
end
end
end
include_examples 'special characters'
end

View file

@ -3,19 +3,32 @@ require 'strategies/special_characters_helper'
describe 'the `match_prev_cmd` strategy' do
let(:options) { ['ZSH_AUTOSUGGEST_STRATEGY=match_prev_cmd'] }
it 'suggests the last matching history entry after the previous command' do
with_history(
let(:history) { [
'echo what',
'ls foo',
'echo what',
'ls bar',
'ls baz',
'echo what'
) do
] }
it 'suggests the last matching history entry after the previous command' do
with_history(*history) do
session.send_string('ls')
wait_for { session.content }.to eq('ls bar')
end
end
context 'when ZSH_AUTOSUGGEST_HISTORY_IGNORE is set to a pattern' do
let(:options) { ['ZSH_AUTOSUGGEST_STRATEGY=match_prev_cmd', 'ZSH_AUTOSUGGEST_HISTORY_IGNORE="* bar"'] }
it 'does not make suggestions that match the pattern' do
with_history(*history) do
session.send_string('ls')
wait_for { session.content }.to eq('ls foo')
end
end
end
include_examples 'special characters'
end

View file

@ -10,7 +10,7 @@ _zsh_autosuggest_strategy_history() {
# Reset options to defaults and enable LOCAL_OPTIONS
emulate -L zsh
# Enable globbing flags so that we can use (#m)
# Enable globbing flags so that we can use (#m) and (x~y) glob operator
setopt EXTENDED_GLOB
# Escape backslashes and all of the glob operators so we can use
@ -19,7 +19,14 @@ _zsh_autosuggest_strategy_history() {
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
# Get the history items that match
# Get the history items that match the prefix, excluding those that match
# the ignore pattern
local pattern="$prefix*"
if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then
pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)"
fi
# Give the first history item matching the pattern as the suggestion
# - (r) subscript flag makes the pattern match on values
typeset -g suggestion="${history[(r)${prefix}*]}"
typeset -g suggestion="${history[(r)$pattern]}"
}

View file

@ -24,16 +24,23 @@ _zsh_autosuggest_strategy_match_prev_cmd() {
# Reset options to defaults and enable LOCAL_OPTIONS
emulate -L zsh
# Enable globbing flags so that we can use (#m)
# Enable globbing flags so that we can use (#m) and (x~y) glob operator
setopt EXTENDED_GLOB
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
# Get the history items that match the prefix, excluding those that match
# the ignore pattern
local pattern="$prefix*"
if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then
pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)"
fi
# Get all history event numbers that correspond to history
# entries that match pattern $prefix*
# entries that match the pattern
local history_match_keys
history_match_keys=(${(k)history[(R)$prefix*]})
history_match_keys=(${(k)history[(R)$~pattern]})
# By default we use the first history number (most recent history entry)
local histkey="${history_match_keys[1]}"

View file

@ -626,7 +626,7 @@ _zsh_autosuggest_strategy_history() {
# Reset options to defaults and enable LOCAL_OPTIONS
emulate -L zsh
# Enable globbing flags so that we can use (#m)
# Enable globbing flags so that we can use (#m) and (x~y) glob operator
setopt EXTENDED_GLOB
# Escape backslashes and all of the glob operators so we can use
@ -635,9 +635,16 @@ _zsh_autosuggest_strategy_history() {
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
# Get the history items that match
# Get the history items that match the prefix, excluding those that match
# the ignore pattern
local pattern="$prefix*"
if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then
pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)"
fi
# Give the first history item matching the pattern as the suggestion
# - (r) subscript flag makes the pattern match on values
typeset -g suggestion="${history[(r)${prefix}*]}"
typeset -g suggestion="${history[(r)$pattern]}"
}
#--------------------------------------------------------------------#
@ -665,16 +672,23 @@ _zsh_autosuggest_strategy_match_prev_cmd() {
# Reset options to defaults and enable LOCAL_OPTIONS
emulate -L zsh
# Enable globbing flags so that we can use (#m)
# Enable globbing flags so that we can use (#m) and (x~y) glob operator
setopt EXTENDED_GLOB
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
# Get the history items that match the prefix, excluding those that match
# the ignore pattern
local pattern="$prefix*"
if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then
pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)"
fi
# Get all history event numbers that correspond to history
# entries that match pattern $prefix*
# entries that match the pattern
local history_match_keys
history_match_keys=(${(k)history[(R)$prefix*]})
history_match_keys=(${(k)history[(R)$~pattern]})
# By default we use the first history number (most recent history entry)
local histkey="${history_match_keys[1]}"