Skip to content

Commit 3da421a

Browse files
authored
Merge pull request #456 from zsh-users/features/history-ignore
Allow configuring to ignore history entries matching a pattern
2 parents 146020d + b87a497 commit 3da421a

File tree

6 files changed

+78
-20
lines changed

6 files changed

+78
-20
lines changed

README.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -86,6 +86,12 @@ As of `v0.4.0`, suggestions can be fetched asynchronously. To enable this behavi
8686

8787
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`.
8888

89+
### Ignoring history suggestions that match a pattern
90+
91+
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.
92+
93+
**Note:** This only affects the `history` and `match_prev_cmd` suggestion strategies.
94+
8995

9096
### Key Bindings
9197

spec/strategies/history_spec.rb

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,5 +8,16 @@
88
end
99
end
1010

11+
context 'when ZSH_AUTOSUGGEST_HISTORY_IGNORE is set to a pattern' do
12+
let(:options) { ['ZSH_AUTOSUGGEST_HISTORY_IGNORE="* bar"'] }
13+
14+
it 'does not make suggestions that match the pattern' do
15+
with_history('ls foo', 'ls bar', 'echo baz') do
16+
session.send_string('ls')
17+
wait_for { session.content }.to eq('ls foo')
18+
end
19+
end
20+
end
21+
1122
include_examples 'special characters'
1223
end

spec/strategies/match_prev_cmd_spec.rb

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -3,19 +3,32 @@
33
describe 'the `match_prev_cmd` strategy' do
44
let(:options) { ['ZSH_AUTOSUGGEST_STRATEGY=match_prev_cmd'] }
55

6+
let(:history) { [
7+
'echo what',
8+
'ls foo',
9+
'echo what',
10+
'ls bar',
11+
'ls baz',
12+
'echo what'
13+
] }
14+
615
it 'suggests the last matching history entry after the previous command' do
7-
with_history(
8-
'echo what',
9-
'ls foo',
10-
'echo what',
11-
'ls bar',
12-
'ls baz',
13-
'echo what'
14-
) do
16+
with_history(*history) do
1517
session.send_string('ls')
1618
wait_for { session.content }.to eq('ls bar')
1719
end
1820
end
1921

22+
context 'when ZSH_AUTOSUGGEST_HISTORY_IGNORE is set to a pattern' do
23+
let(:options) { ['ZSH_AUTOSUGGEST_STRATEGY=match_prev_cmd', 'ZSH_AUTOSUGGEST_HISTORY_IGNORE="* bar"'] }
24+
25+
it 'does not make suggestions that match the pattern' do
26+
with_history(*history) do
27+
session.send_string('ls')
28+
wait_for { session.content }.to eq('ls foo')
29+
end
30+
end
31+
end
32+
2033
include_examples 'special characters'
2134
end

src/strategies/history.zsh

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@ _zsh_autosuggest_strategy_history() {
1010
# Reset options to defaults and enable LOCAL_OPTIONS
1111
emulate -L zsh
1212

13-
# Enable globbing flags so that we can use (#m)
13+
# Enable globbing flags so that we can use (#m) and (x~y) glob operator
1414
setopt EXTENDED_GLOB
1515

1616
# Escape backslashes and all of the glob operators so we can use
@@ -19,7 +19,14 @@ _zsh_autosuggest_strategy_history() {
1919
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
2020
local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
2121

22-
# Get the history items that match
22+
# Get the history items that match the prefix, excluding those that match
23+
# the ignore pattern
24+
local pattern="$prefix*"
25+
if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then
26+
pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)"
27+
fi
28+
29+
# Give the first history item matching the pattern as the suggestion
2330
# - (r) subscript flag makes the pattern match on values
24-
typeset -g suggestion="${history[(r)${prefix}*]}"
31+
typeset -g suggestion="${history[(r)$pattern]}"
2532
}

src/strategies/match_prev_cmd.zsh

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -24,16 +24,23 @@ _zsh_autosuggest_strategy_match_prev_cmd() {
2424
# Reset options to defaults and enable LOCAL_OPTIONS
2525
emulate -L zsh
2626

27-
# Enable globbing flags so that we can use (#m)
27+
# Enable globbing flags so that we can use (#m) and (x~y) glob operator
2828
setopt EXTENDED_GLOB
2929

3030
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
3131
local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
3232

33+
# Get the history items that match the prefix, excluding those that match
34+
# the ignore pattern
35+
local pattern="$prefix*"
36+
if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then
37+
pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)"
38+
fi
39+
3340
# Get all history event numbers that correspond to history
34-
# entries that match pattern $prefix*
41+
# entries that match the pattern
3542
local history_match_keys
36-
history_match_keys=(${(k)history[(R)$prefix*]})
43+
history_match_keys=(${(k)history[(R)$~pattern]})
3744

3845
# By default we use the first history number (most recent history entry)
3946
local histkey="${history_match_keys[1]}"

zsh-autosuggestions.zsh

Lines changed: 20 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -626,7 +626,7 @@ _zsh_autosuggest_strategy_history() {
626626
# Reset options to defaults and enable LOCAL_OPTIONS
627627
emulate -L zsh
628628

629-
# Enable globbing flags so that we can use (#m)
629+
# Enable globbing flags so that we can use (#m) and (x~y) glob operator
630630
setopt EXTENDED_GLOB
631631

632632
# Escape backslashes and all of the glob operators so we can use
@@ -635,9 +635,16 @@ _zsh_autosuggest_strategy_history() {
635635
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
636636
local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
637637

638-
# Get the history items that match
638+
# Get the history items that match the prefix, excluding those that match
639+
# the ignore pattern
640+
local pattern="$prefix*"
641+
if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then
642+
pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)"
643+
fi
644+
645+
# Give the first history item matching the pattern as the suggestion
639646
# - (r) subscript flag makes the pattern match on values
640-
typeset -g suggestion="${history[(r)${prefix}*]}"
647+
typeset -g suggestion="${history[(r)$pattern]}"
641648
}
642649

643650
#--------------------------------------------------------------------#
@@ -665,16 +672,23 @@ _zsh_autosuggest_strategy_match_prev_cmd() {
665672
# Reset options to defaults and enable LOCAL_OPTIONS
666673
emulate -L zsh
667674

668-
# Enable globbing flags so that we can use (#m)
675+
# Enable globbing flags so that we can use (#m) and (x~y) glob operator
669676
setopt EXTENDED_GLOB
670677

671678
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
672679
local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
673680

681+
# Get the history items that match the prefix, excluding those that match
682+
# the ignore pattern
683+
local pattern="$prefix*"
684+
if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then
685+
pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)"
686+
fi
687+
674688
# Get all history event numbers that correspond to history
675-
# entries that match pattern $prefix*
689+
# entries that match the pattern
676690
local history_match_keys
677-
history_match_keys=(${(k)history[(R)$prefix*]})
691+
history_match_keys=(${(k)history[(R)$~pattern]})
678692

679693
# By default we use the first history number (most recent history entry)
680694
local histkey="${history_match_keys[1]}"

0 commit comments

Comments
 (0)