Skip to content

Commit ae315de

Browse files
authored
Merge pull request #494 from zsh-users/develop
v0.6.4
2 parents d43c309 + ff298e5 commit ae315de

File tree

11 files changed

+178
-54
lines changed

11 files changed

+178
-54
lines changed

CHANGELOG.md

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,10 @@
11
# Changelog
22

3+
## v0.6.4
4+
- Fix `vi-forward-char` triggering a bell when using it to accept a suggestion (#488)
5+
- New configuration option to skip completion suggestions when buffer matches a pattern (#487)
6+
- New configuration option to ignore history entries matching a pattern (#456)
7+
38
## v0.6.3
49
- Fixed bug moving cursor to end of buffer after accepting suggestion (#453)
510

README.md

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -53,8 +53,8 @@ For more info, read the Character Highlighting section of the zsh manual: `man z
5353
`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 three built-in strategies to choose from:
5454

5555
- `history`: Chooses the most recent match from history.
56+
- `completion`: Chooses a suggestion based on what tab-completion would suggest. (requires `zpty` module)
5657
- `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`.
57-
- `completion`: (experimental) Chooses a suggestion based on what tab-completion would suggest. (requires `zpty` module)
5858

5959
For example, setting `ZSH_AUTOSUGGEST_STRATEGY=(history completion)` will first try to find a suggestion from your history, but, if it can't find a match, will find a suggestion from the completion engine.
6060

@@ -87,6 +87,18 @@ As of `v0.4.0`, suggestions can be fetched asynchronously. To enable this behavi
8787

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

90+
### Ignoring history suggestions that match a pattern
91+
92+
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.
93+
94+
**Note:** This only affects the `history` and `match_prev_cmd` suggestion strategies.
95+
96+
### Skipping completion suggestions for certain cases
97+
98+
Set `ZSH_AUTOSUGGEST_COMPLETION_IGNORE` to a glob pattern to prevent offering completion suggestions when the buffer matches that pattern. For example, set it to `"git *"` to disable completion suggestions for git subcommands.
99+
100+
**Note:** This only affects the `completion` suggestion strategy.
101+
90102

91103
### Key Bindings
92104

VERSION

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
v0.6.3
1+
v0.6.4

spec/strategies/completion_spec.rb

Lines changed: 18 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,9 @@
55
session.
66
run_command('autoload compinit && compinit').
77
run_command('_foo() { compadd bar; compadd bat }').
8-
run_command('compdef _foo baz')
8+
run_command('_num() { compadd two; compadd three }').
9+
run_command('compdef _foo baz').
10+
run_command('compdef _num one')
911
end
1012
end
1113

@@ -37,6 +39,21 @@
3739
end
3840
end
3941

42+
context 'when ZSH_AUTOSUGGEST_COMPLETION_IGNORE is set to a pattern' do
43+
let(:options) { ['ZSH_AUTOSUGGEST_STRATEGY=completion', 'ZSH_AUTOSUGGEST_COMPLETION_IGNORE="one *"'] }
44+
45+
it 'makes suggestions when the buffer does not match the pattern' do
46+
session.send_string('baz ')
47+
wait_for { session.content }.to eq('baz bar')
48+
end
49+
50+
it 'does not make suggestions when the buffer matches the pattern' do
51+
session.send_string('one t')
52+
sleep 1
53+
expect(session.content).to eq('one t')
54+
end
55+
end
56+
4057
context 'when async mode is enabled' do
4158
let(:options) { ['ZSH_AUTOSUGGEST_USE_ASYNC=true', 'ZSH_AUTOSUGGEST_STRATEGY=completion'] }
4259

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/completion.zsh

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -96,6 +96,12 @@ _zsh_autosuggest_capture_completion_async() {
9696
}
9797

9898
_zsh_autosuggest_strategy_completion() {
99+
# Reset options to defaults and enable LOCAL_OPTIONS
100+
emulate -L zsh
101+
102+
# Enable extended glob for completion ignore pattern
103+
setopt EXTENDED_GLOB
104+
99105
typeset -g suggestion
100106
local line REPLY
101107

@@ -105,6 +111,9 @@ _zsh_autosuggest_strategy_completion() {
105111
# Exit if we don't have zpty
106112
zmodload zsh/zpty 2>/dev/null || return
107113

114+
# Exit if our search string matches the ignore pattern
115+
[[ -n "$ZSH_AUTOSUGGEST_COMPLETION_IGNORE" ]] && [[ "$1" == $~ZSH_AUTOSUGGEST_COMPLETION_IGNORE ]] && return
116+
108117
# Zle will be inactive if we are in async mode
109118
if zle; then
110119
zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME _zsh_autosuggest_capture_completion_sync
@@ -122,7 +131,7 @@ _zsh_autosuggest_strategy_completion() {
122131
# versions of zsh (older than 5.3), we sometimes get extra bytes after
123132
# the second null byte, so trim those off the end.
124133
# See http://www.zsh.org/mla/workers/2015/msg03290.html
125-
suggestion="${${line#*$'\0'}%$'\0'*}"
134+
suggestion="${${(@0)line}[2]}"
126135
} always {
127136
# Destroy the pty
128137
zpty -d $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME

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]}"

src/widgets.zsh

Lines changed: 24 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@ _zsh_autosuggest_modify() {
5656
emulate -L zsh
5757

5858
# Don't fetch a new suggestion if there's more input to be read immediately
59-
if (( $PENDING > 0 )) || (( $KEYS_QUEUED_COUNT > 0 )); then
59+
if (( $PENDING > 0 || $KEYS_QUEUED_COUNT > 0 )); then
6060
POSTDISPLAY="$orig_postdisplay"
6161
return $retval
6262
fi
@@ -119,31 +119,41 @@ _zsh_autosuggest_suggest() {
119119

120120
# Accept the entire suggestion
121121
_zsh_autosuggest_accept() {
122-
local -i max_cursor_pos=$#BUFFER
122+
local -i retval max_cursor_pos=$#BUFFER
123123

124124
# When vicmd keymap is active, the cursor can't move all the way
125125
# to the end of the buffer
126126
if [[ "$KEYMAP" = "vicmd" ]]; then
127127
max_cursor_pos=$((max_cursor_pos - 1))
128128
fi
129129

130+
# If we're not in a valid state to accept a suggestion, just run the
131+
# original widget and bail out
132+
if (( $CURSOR != $max_cursor_pos || !$#POSTDISPLAY )); then
133+
_zsh_autosuggest_invoke_original_widget $@
134+
return
135+
fi
136+
130137
# Only accept if the cursor is at the end of the buffer
131-
if [[ $CURSOR = $max_cursor_pos ]]; then
132-
# Add the suggestion to the buffer
133-
BUFFER="$BUFFER$POSTDISPLAY"
138+
# Add the suggestion to the buffer
139+
BUFFER="$BUFFER$POSTDISPLAY"
134140

135-
# Remove the suggestion
136-
unset POSTDISPLAY
141+
# Remove the suggestion
142+
unset POSTDISPLAY
137143

138-
# Move the cursor to the end of the buffer
139-
if [[ "$KEYMAP" = "vicmd" ]]; then
140-
CURSOR=$(($#BUFFER - 1))
141-
else
142-
CURSOR=$#BUFFER
143-
fi
144+
# Run the original widget before manually moving the cursor so that the
145+
# cursor movement doesn't make the widget do something unexpected
146+
_zsh_autosuggest_invoke_original_widget $@
147+
retval=$?
148+
149+
# Move the cursor to the end of the buffer
150+
if [[ "$KEYMAP" = "vicmd" ]]; then
151+
CURSOR=$(($#BUFFER - 1))
152+
else
153+
CURSOR=$#BUFFER
144154
fi
145155

146-
_zsh_autosuggest_invoke_original_widget $@
156+
return $retval
147157
}
148158

149159
# Accept the entire suggestion and execute it

0 commit comments

Comments
 (0)