mirror of
https://github.com/zsh-users/zsh-autosuggestions.git
synced 2025-04-17 11:35:31 +08:00
Add history cycling widgets
This commit is contained in:
parent
ebaf409002
commit
09b6c1659f
@ -81,6 +81,8 @@ This plugin provides a few widgets that you can use with `bindkey`:
|
|||||||
5. `autosuggest-disable`: Disables suggestions.
|
5. `autosuggest-disable`: Disables suggestions.
|
||||||
6. `autosuggest-enable`: Re-enables suggestions.
|
6. `autosuggest-enable`: Re-enables suggestions.
|
||||||
7. `autosuggest-toggle`: Toggles between enabled/disabled suggestions.
|
7. `autosuggest-toggle`: Toggles between enabled/disabled suggestions.
|
||||||
|
8. `autosuggest-next`: Suggests the next older entry from history.
|
||||||
|
9. `autosuggest-next`: Suggests the next newer entry from history.
|
||||||
|
|
||||||
For example, this would bind <kbd>ctrl</kbd> + <kbd>space</kbd> to accept the current suggestion.
|
For example, this would bind <kbd>ctrl</kbd> + <kbd>space</kbd> to accept the current suggestion.
|
||||||
|
|
||||||
|
48
spec/widgets/next_spec.rb
Normal file
48
spec/widgets/next_spec.rb
Normal file
@ -0,0 +1,48 @@
|
|||||||
|
describe 'the `autosuggest-next` widget' do
|
||||||
|
context 'when suggestions are disabled' do
|
||||||
|
before do
|
||||||
|
session.
|
||||||
|
run_command('bindkey ^B autosuggest-disable').
|
||||||
|
run_command('bindkey ^K autosuggest-next').
|
||||||
|
send_keys('C-b')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'will fetch and display a suggestion' do
|
||||||
|
with_history('echo hello', 'echo world', 'echo joe') do
|
||||||
|
session.send_string('echo h')
|
||||||
|
sleep 1
|
||||||
|
expect(session.content).to eq('echo h')
|
||||||
|
|
||||||
|
session.send_keys('C-k')
|
||||||
|
wait_for { session.content }.to eq('echo hello')
|
||||||
|
|
||||||
|
session.send_string('e')
|
||||||
|
wait_for { session.content }.to eq('echo hello')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'invoked on a populated history' do
|
||||||
|
before do
|
||||||
|
session.
|
||||||
|
run_command('bindkey ^K autosuggest-next')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'will cycle, fetch, and display a suggestion' do
|
||||||
|
with_history('echo hello', 'echo world', 'echo joe') do
|
||||||
|
session.send_string('echo')
|
||||||
|
sleep 1
|
||||||
|
expect(session.content).to eq('echo joe')
|
||||||
|
|
||||||
|
session.send_keys('C-k')
|
||||||
|
wait_for { session.content }.to eq('echo world')
|
||||||
|
|
||||||
|
session.send_keys('C-k')
|
||||||
|
wait_for { session.content }.to eq('echo hello')
|
||||||
|
|
||||||
|
session.send_keys('C-k')
|
||||||
|
wait_for { session.content }.to eq('echo hello')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
58
spec/widgets/previous_spec.rb
Normal file
58
spec/widgets/previous_spec.rb
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
describe 'the `autosuggest-previous` widget' do
|
||||||
|
context 'when suggestions are disabled' do
|
||||||
|
before do
|
||||||
|
session.
|
||||||
|
run_command('bindkey ^B autosuggest-disable').
|
||||||
|
run_command('bindkey ^J autosuggest-previous').
|
||||||
|
send_keys('C-b')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'will fetch and display a suggestion' do
|
||||||
|
with_history('echo hello', 'echo world', 'echo joe') do
|
||||||
|
session.send_string('echo h')
|
||||||
|
sleep 1
|
||||||
|
expect(session.content).to eq('echo h')
|
||||||
|
|
||||||
|
session.send_keys('C-j')
|
||||||
|
wait_for { session.content }.to eq('echo hello')
|
||||||
|
|
||||||
|
session.send_string('e')
|
||||||
|
wait_for { session.content }.to eq('echo hello')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
|
||||||
|
context 'invoked on a populated history' do
|
||||||
|
before do
|
||||||
|
session.
|
||||||
|
run_command('bindkey ^K autosuggest-next').
|
||||||
|
run_command('bindkey ^J autosuggest-previous')
|
||||||
|
end
|
||||||
|
|
||||||
|
it 'will cycle, fetch, and display a suggestion' do
|
||||||
|
with_history('echo hello', 'echo world', 'echo joe') do
|
||||||
|
session.send_string('echo')
|
||||||
|
sleep 1
|
||||||
|
expect(session.content).to eq('echo joe')
|
||||||
|
|
||||||
|
session.send_keys('C-k')
|
||||||
|
wait_for { session.content }.to eq('echo world')
|
||||||
|
|
||||||
|
session.send_keys('C-k')
|
||||||
|
wait_for { session.content }.to eq('echo hello')
|
||||||
|
|
||||||
|
session.send_keys('C-k')
|
||||||
|
wait_for { session.content }.to eq('echo hello')
|
||||||
|
|
||||||
|
session.send_keys('C-j')
|
||||||
|
wait_for { session.content }.to eq('echo world')
|
||||||
|
|
||||||
|
session.send_keys('C-j')
|
||||||
|
wait_for { session.content }.to eq('echo joe')
|
||||||
|
|
||||||
|
session.send_keys('C-j')
|
||||||
|
wait_for { session.content }.to eq('echo joe')
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
||||||
|
end
|
@ -25,15 +25,21 @@ _zsh_autosuggest_async_server() {
|
|||||||
|
|
||||||
local last_pid
|
local last_pid
|
||||||
|
|
||||||
while IFS='' read -r -d $'\0' query; do
|
while IFS='' read -r -d $'\0' input; do
|
||||||
# Kill last bg process
|
# Kill last bg process
|
||||||
kill -KILL $last_pid &>/dev/null
|
kill -KILL $last_pid &>/dev/null
|
||||||
|
|
||||||
|
# Break up the input into a list
|
||||||
|
# - (p) recognize the same escape sequences as the print builtin
|
||||||
|
# - (s) force field splitting at the separator given '\1'
|
||||||
|
local query=( ${(ps:\1:)input} )
|
||||||
|
|
||||||
# Run suggestion search in the background
|
# Run suggestion search in the background
|
||||||
(
|
(
|
||||||
local suggestion
|
local suggestion
|
||||||
_zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "$query"
|
local capped_history_index
|
||||||
echo -n -E "$suggestion"$'\0'
|
_zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "${query[1]}" "${query[2]}"
|
||||||
|
echo -n -E "$capped_history_index"$'\1'"$suggestion"$'\0'
|
||||||
) &
|
) &
|
||||||
|
|
||||||
last_pid=$!
|
last_pid=$!
|
||||||
@ -42,7 +48,7 @@ _zsh_autosuggest_async_server() {
|
|||||||
|
|
||||||
_zsh_autosuggest_async_request() {
|
_zsh_autosuggest_async_request() {
|
||||||
# Write the query to the zpty process to fetch a suggestion
|
# Write the query to the zpty process to fetch a suggestion
|
||||||
zpty -w -n $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME "${1}"$'\0'
|
zpty -w -n $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME "${1}"$'\1'"${2}"$'\0'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Called when new data is ready to be read from the pty
|
# Called when new data is ready to be read from the pty
|
||||||
@ -51,10 +57,15 @@ _zsh_autosuggest_async_request() {
|
|||||||
_zsh_autosuggest_async_response() {
|
_zsh_autosuggest_async_response() {
|
||||||
setopt LOCAL_OPTIONS EXTENDED_GLOB
|
setopt LOCAL_OPTIONS EXTENDED_GLOB
|
||||||
|
|
||||||
local suggestion
|
local raw_input
|
||||||
|
|
||||||
zpty -rt $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME suggestion '*'$'\0' 2>/dev/null
|
zpty -rt $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME raw_input '*'$'\0' 2>/dev/null
|
||||||
zle autosuggest-suggest -- "${suggestion%%$'\0'##}"
|
|
||||||
|
local input=( ${(ps:\1:)raw_input%%$'\0'##} )
|
||||||
|
local capped_history_index="${input[1]}"
|
||||||
|
local suggestion="${input[2]}"
|
||||||
|
|
||||||
|
zle autosuggest-suggest -- "${capped_history_index}" "${suggestion}"
|
||||||
}
|
}
|
||||||
|
|
||||||
_zsh_autosuggest_async_pty_create() {
|
_zsh_autosuggest_async_pty_create() {
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
#--------------------------------------------------------------------#
|
#--------------------------------------------------------------------#
|
||||||
# Default Suggestion Strategy #
|
# Default Suggestion Strategy #
|
||||||
#--------------------------------------------------------------------#
|
#--------------------------------------------------------------------#
|
||||||
# Suggests the most recent history item that matches the given
|
# Suggests the history item that matches the given prefix and history
|
||||||
# prefix.
|
# index
|
||||||
#
|
#
|
||||||
|
|
||||||
_zsh_autosuggest_strategy_default() {
|
_zsh_autosuggest_strategy_default() {
|
||||||
@ -13,13 +13,21 @@ _zsh_autosuggest_strategy_default() {
|
|||||||
# Enable globbing flags so that we can use (#m)
|
# Enable globbing flags so that we can use (#m)
|
||||||
setopt EXTENDED_GLOB
|
setopt EXTENDED_GLOB
|
||||||
|
|
||||||
|
# Extract the paramenters for this function
|
||||||
|
typeset -g capped_history_index="${1}"
|
||||||
|
local query="${2}"
|
||||||
|
|
||||||
# Escape backslashes and all of the glob operators so we can use
|
# Escape backslashes and all of the glob operators so we can use
|
||||||
# this string as a pattern to search the $history associative array.
|
# this string as a pattern to search the $history associative array.
|
||||||
# - (#m) globbing flag enables setting references for match data
|
# - (#m) globbing flag enables setting references for match data
|
||||||
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
|
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
|
||||||
local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
|
local prefix="${query//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
|
||||||
|
|
||||||
# Get the history items that match
|
# Get the history items that match
|
||||||
# - (r) subscript flag makes the pattern match on values
|
# - (R) subscript flag makes the pattern match on values
|
||||||
typeset -g suggestion="${history[(r)${prefix}*]}"
|
# - (k) returns the entry indices instead of values
|
||||||
|
local suggestions=(${(k)history[(R)$prefix*]})
|
||||||
|
|
||||||
|
(( capped_history_index > $#suggestions )) && capped_history_index=${#suggestions}
|
||||||
|
typeset -g suggestion="${history[${suggestions[${capped_history_index}]}]}"
|
||||||
}
|
}
|
||||||
|
@ -27,8 +27,12 @@ _zsh_autosuggest_strategy_match_prev_cmd() {
|
|||||||
# Enable globbing flags so that we can use (#m)
|
# Enable globbing flags so that we can use (#m)
|
||||||
setopt EXTENDED_GLOB
|
setopt EXTENDED_GLOB
|
||||||
|
|
||||||
|
# Extract the paramenters for this function
|
||||||
|
typeset -g capped_history_index="${1}"
|
||||||
|
local query="${2}"
|
||||||
|
|
||||||
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
|
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
|
||||||
local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
|
local prefix="${query//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
|
||||||
|
|
||||||
# Get all history event numbers that correspond to history
|
# Get all history event numbers that correspond to history
|
||||||
# entries that match pattern $prefix*
|
# entries that match pattern $prefix*
|
||||||
@ -36,13 +40,13 @@ _zsh_autosuggest_strategy_match_prev_cmd() {
|
|||||||
history_match_keys=(${(k)history[(R)$prefix*]})
|
history_match_keys=(${(k)history[(R)$prefix*]})
|
||||||
|
|
||||||
# By default we use the first history number (most recent history entry)
|
# By default we use the first history number (most recent history entry)
|
||||||
local histkey="${history_match_keys[1]}"
|
local histkey="${history_match_keys[capped_history_index]}"
|
||||||
|
|
||||||
# Get the previously executed command
|
# Get the previously executed command
|
||||||
local prev_cmd="$(_zsh_autosuggest_escape_command "${history[$((HISTCMD-1))]}")"
|
local prev_cmd="$(_zsh_autosuggest_escape_command "${history[$((HISTCMD-1))]}")"
|
||||||
|
|
||||||
# Iterate up to the first 200 history event numbers that match $prefix
|
# Iterate up to the first 200 history event numbers that match $prefix
|
||||||
for key in "${(@)history_match_keys[1,200]}"; do
|
for key in "${(@)history_match_keys[capped_history_index,200]}"; do
|
||||||
# Stop if we ran out of history
|
# Stop if we ran out of history
|
||||||
[[ $key -gt 1 ]] || break
|
[[ $key -gt 1 ]] || break
|
||||||
|
|
||||||
|
@ -31,6 +31,7 @@ _zsh_autosuggest_toggle() {
|
|||||||
_zsh_autosuggest_clear() {
|
_zsh_autosuggest_clear() {
|
||||||
# Remove the suggestion
|
# Remove the suggestion
|
||||||
unset POSTDISPLAY
|
unset POSTDISPLAY
|
||||||
|
history_index=1
|
||||||
|
|
||||||
_zsh_autosuggest_invoke_original_widget $@
|
_zsh_autosuggest_invoke_original_widget $@
|
||||||
}
|
}
|
||||||
@ -91,25 +92,45 @@ _zsh_autosuggest_modify() {
|
|||||||
return $retval
|
return $retval
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Navigate to the next suggestion in the suggestion list
|
||||||
|
_zsh_autosuggest_next() {
|
||||||
|
history_index=$(( history_index + 1 ))
|
||||||
|
_zsh_autosuggest_fetch
|
||||||
|
}
|
||||||
|
|
||||||
|
# Navigate to the previous suggestion in the suggestion list
|
||||||
|
_zsh_autosuggest_previous() {
|
||||||
|
(( history_index > 1 )) && history_index=$(( history_index - 1 ))
|
||||||
|
_zsh_autosuggest_fetch
|
||||||
|
}
|
||||||
|
|
||||||
# Fetch a new suggestion based on what's currently in the buffer
|
# Fetch a new suggestion based on what's currently in the buffer
|
||||||
_zsh_autosuggest_fetch() {
|
_zsh_autosuggest_fetch() {
|
||||||
|
if ! (( history_index > 0 )); then
|
||||||
|
history_index=1
|
||||||
|
fi
|
||||||
|
|
||||||
if zpty -t "$ZSH_AUTOSUGGEST_ASYNC_PTY_NAME" &>/dev/null; then
|
if zpty -t "$ZSH_AUTOSUGGEST_ASYNC_PTY_NAME" &>/dev/null; then
|
||||||
_zsh_autosuggest_async_request "$BUFFER"
|
_zsh_autosuggest_async_request ${history_index} "$BUFFER"
|
||||||
else
|
else
|
||||||
local suggestion
|
local suggestion
|
||||||
_zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "$BUFFER"
|
local capped_history_index
|
||||||
_zsh_autosuggest_suggest "$suggestion"
|
_zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY ${history_index} "$BUFFER"
|
||||||
|
_zsh_autosuggest_suggest "$capped_history_index" "$suggestion"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Offer a suggestion
|
# Offer a suggestion
|
||||||
_zsh_autosuggest_suggest() {
|
_zsh_autosuggest_suggest() {
|
||||||
local suggestion="$1"
|
local capped_history_index="$1"
|
||||||
|
local suggestion="$2"
|
||||||
|
|
||||||
if [[ -n "$suggestion" ]] && (( $#BUFFER )); then
|
if [[ -n "$suggestion" ]] && (( $#BUFFER )); then
|
||||||
POSTDISPLAY="${suggestion#$BUFFER}"
|
POSTDISPLAY="${suggestion#$BUFFER}"
|
||||||
|
history_index="${capped_history_index}"
|
||||||
else
|
else
|
||||||
unset POSTDISPLAY
|
unset POSTDISPLAY
|
||||||
|
history_index=1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -130,6 +151,7 @@ _zsh_autosuggest_accept() {
|
|||||||
|
|
||||||
# Remove the suggestion
|
# Remove the suggestion
|
||||||
unset POSTDISPLAY
|
unset POSTDISPLAY
|
||||||
|
history_index=1
|
||||||
|
|
||||||
# Move the cursor to the end of the buffer
|
# Move the cursor to the end of the buffer
|
||||||
CURSOR=${#BUFFER}
|
CURSOR=${#BUFFER}
|
||||||
@ -145,6 +167,7 @@ _zsh_autosuggest_execute() {
|
|||||||
|
|
||||||
# Remove the suggestion
|
# Remove the suggestion
|
||||||
unset POSTDISPLAY
|
unset POSTDISPLAY
|
||||||
|
history_index=1
|
||||||
|
|
||||||
# Call the original `accept-line` to handle syntax highlighting or
|
# Call the original `accept-line` to handle syntax highlighting or
|
||||||
# other potential custom behavior
|
# other potential custom behavior
|
||||||
@ -186,7 +209,7 @@ _zsh_autosuggest_partial_accept() {
|
|||||||
return $retval
|
return $retval
|
||||||
}
|
}
|
||||||
|
|
||||||
for action in clear modify fetch suggest accept partial_accept execute enable disable toggle; do
|
for action in clear modify fetch suggest accept partial_accept execute enable disable toggle next previous; do
|
||||||
eval "_zsh_autosuggest_widget_$action() {
|
eval "_zsh_autosuggest_widget_$action() {
|
||||||
local -i retval
|
local -i retval
|
||||||
|
|
||||||
@ -211,3 +234,5 @@ zle -N autosuggest-execute _zsh_autosuggest_widget_execute
|
|||||||
zle -N autosuggest-enable _zsh_autosuggest_widget_enable
|
zle -N autosuggest-enable _zsh_autosuggest_widget_enable
|
||||||
zle -N autosuggest-disable _zsh_autosuggest_widget_disable
|
zle -N autosuggest-disable _zsh_autosuggest_widget_disable
|
||||||
zle -N autosuggest-toggle _zsh_autosuggest_widget_toggle
|
zle -N autosuggest-toggle _zsh_autosuggest_widget_toggle
|
||||||
|
zle -N autosuggest-next _zsh_autosuggest_widget_next
|
||||||
|
zle -N autosuggest-previous _zsh_autosuggest_widget_previous
|
||||||
|
@ -312,6 +312,7 @@ _zsh_autosuggest_toggle() {
|
|||||||
_zsh_autosuggest_clear() {
|
_zsh_autosuggest_clear() {
|
||||||
# Remove the suggestion
|
# Remove the suggestion
|
||||||
unset POSTDISPLAY
|
unset POSTDISPLAY
|
||||||
|
history_index=1
|
||||||
|
|
||||||
_zsh_autosuggest_invoke_original_widget $@
|
_zsh_autosuggest_invoke_original_widget $@
|
||||||
}
|
}
|
||||||
@ -372,25 +373,45 @@ _zsh_autosuggest_modify() {
|
|||||||
return $retval
|
return $retval
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Navigate to the next suggestion in the suggestion list
|
||||||
|
_zsh_autosuggest_next() {
|
||||||
|
history_index=$(( history_index + 1 ))
|
||||||
|
_zsh_autosuggest_fetch
|
||||||
|
}
|
||||||
|
|
||||||
|
# Navigate to the previous suggestion in the suggestion list
|
||||||
|
_zsh_autosuggest_previous() {
|
||||||
|
(( history_index > 1 )) && history_index=$(( history_index - 1 ))
|
||||||
|
_zsh_autosuggest_fetch
|
||||||
|
}
|
||||||
|
|
||||||
# Fetch a new suggestion based on what's currently in the buffer
|
# Fetch a new suggestion based on what's currently in the buffer
|
||||||
_zsh_autosuggest_fetch() {
|
_zsh_autosuggest_fetch() {
|
||||||
|
if ! (( history_index > 0 )); then
|
||||||
|
history_index=1
|
||||||
|
fi
|
||||||
|
|
||||||
if zpty -t "$ZSH_AUTOSUGGEST_ASYNC_PTY_NAME" &>/dev/null; then
|
if zpty -t "$ZSH_AUTOSUGGEST_ASYNC_PTY_NAME" &>/dev/null; then
|
||||||
_zsh_autosuggest_async_request "$BUFFER"
|
_zsh_autosuggest_async_request ${history_index} "$BUFFER"
|
||||||
else
|
else
|
||||||
local suggestion
|
local suggestion
|
||||||
_zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "$BUFFER"
|
local capped_history_index
|
||||||
_zsh_autosuggest_suggest "$suggestion"
|
_zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY ${history_index} "$BUFFER"
|
||||||
|
_zsh_autosuggest_suggest "$capped_history_index" "$suggestion"
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
# Offer a suggestion
|
# Offer a suggestion
|
||||||
_zsh_autosuggest_suggest() {
|
_zsh_autosuggest_suggest() {
|
||||||
local suggestion="$1"
|
local capped_history_index="$1"
|
||||||
|
local suggestion="$2"
|
||||||
|
|
||||||
if [[ -n "$suggestion" ]] && (( $#BUFFER )); then
|
if [[ -n "$suggestion" ]] && (( $#BUFFER )); then
|
||||||
POSTDISPLAY="${suggestion#$BUFFER}"
|
POSTDISPLAY="${suggestion#$BUFFER}"
|
||||||
|
history_index="${capped_history_index}"
|
||||||
else
|
else
|
||||||
unset POSTDISPLAY
|
unset POSTDISPLAY
|
||||||
|
history_index=1
|
||||||
fi
|
fi
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,6 +432,7 @@ _zsh_autosuggest_accept() {
|
|||||||
|
|
||||||
# Remove the suggestion
|
# Remove the suggestion
|
||||||
unset POSTDISPLAY
|
unset POSTDISPLAY
|
||||||
|
history_index=1
|
||||||
|
|
||||||
# Move the cursor to the end of the buffer
|
# Move the cursor to the end of the buffer
|
||||||
CURSOR=${#BUFFER}
|
CURSOR=${#BUFFER}
|
||||||
@ -426,6 +448,7 @@ _zsh_autosuggest_execute() {
|
|||||||
|
|
||||||
# Remove the suggestion
|
# Remove the suggestion
|
||||||
unset POSTDISPLAY
|
unset POSTDISPLAY
|
||||||
|
history_index=1
|
||||||
|
|
||||||
# Call the original `accept-line` to handle syntax highlighting or
|
# Call the original `accept-line` to handle syntax highlighting or
|
||||||
# other potential custom behavior
|
# other potential custom behavior
|
||||||
@ -467,7 +490,7 @@ _zsh_autosuggest_partial_accept() {
|
|||||||
return $retval
|
return $retval
|
||||||
}
|
}
|
||||||
|
|
||||||
for action in clear modify fetch suggest accept partial_accept execute enable disable toggle; do
|
for action in clear modify fetch suggest accept partial_accept execute enable disable toggle next previous; do
|
||||||
eval "_zsh_autosuggest_widget_$action() {
|
eval "_zsh_autosuggest_widget_$action() {
|
||||||
local -i retval
|
local -i retval
|
||||||
|
|
||||||
@ -492,12 +515,14 @@ zle -N autosuggest-execute _zsh_autosuggest_widget_execute
|
|||||||
zle -N autosuggest-enable _zsh_autosuggest_widget_enable
|
zle -N autosuggest-enable _zsh_autosuggest_widget_enable
|
||||||
zle -N autosuggest-disable _zsh_autosuggest_widget_disable
|
zle -N autosuggest-disable _zsh_autosuggest_widget_disable
|
||||||
zle -N autosuggest-toggle _zsh_autosuggest_widget_toggle
|
zle -N autosuggest-toggle _zsh_autosuggest_widget_toggle
|
||||||
|
zle -N autosuggest-next _zsh_autosuggest_widget_next
|
||||||
|
zle -N autosuggest-previous _zsh_autosuggest_widget_previous
|
||||||
|
|
||||||
#--------------------------------------------------------------------#
|
#--------------------------------------------------------------------#
|
||||||
# Default Suggestion Strategy #
|
# Default Suggestion Strategy #
|
||||||
#--------------------------------------------------------------------#
|
#--------------------------------------------------------------------#
|
||||||
# Suggests the most recent history item that matches the given
|
# Suggests the history item that matches the given prefix and history
|
||||||
# prefix.
|
# index
|
||||||
#
|
#
|
||||||
|
|
||||||
_zsh_autosuggest_strategy_default() {
|
_zsh_autosuggest_strategy_default() {
|
||||||
@ -507,15 +532,23 @@ _zsh_autosuggest_strategy_default() {
|
|||||||
# Enable globbing flags so that we can use (#m)
|
# Enable globbing flags so that we can use (#m)
|
||||||
setopt EXTENDED_GLOB
|
setopt EXTENDED_GLOB
|
||||||
|
|
||||||
|
# Extract the paramenters for this function
|
||||||
|
typeset -g capped_history_index="${1}"
|
||||||
|
local query="${2}"
|
||||||
|
|
||||||
# Escape backslashes and all of the glob operators so we can use
|
# Escape backslashes and all of the glob operators so we can use
|
||||||
# this string as a pattern to search the $history associative array.
|
# this string as a pattern to search the $history associative array.
|
||||||
# - (#m) globbing flag enables setting references for match data
|
# - (#m) globbing flag enables setting references for match data
|
||||||
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
|
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
|
||||||
local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
|
local prefix="${query//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
|
||||||
|
|
||||||
# Get the history items that match
|
# Get the history items that match
|
||||||
# - (r) subscript flag makes the pattern match on values
|
# - (R) subscript flag makes the pattern match on values
|
||||||
typeset -g suggestion="${history[(r)${prefix}*]}"
|
# - (k) returns the entry indices instead of values
|
||||||
|
local suggestions=(${(k)history[(R)$prefix*]})
|
||||||
|
|
||||||
|
(( capped_history_index > $#suggestions )) && capped_history_index=${#suggestions}
|
||||||
|
typeset -g suggestion="${history[${suggestions[${capped_history_index}]}]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
#--------------------------------------------------------------------#
|
#--------------------------------------------------------------------#
|
||||||
@ -546,8 +579,12 @@ _zsh_autosuggest_strategy_match_prev_cmd() {
|
|||||||
# Enable globbing flags so that we can use (#m)
|
# Enable globbing flags so that we can use (#m)
|
||||||
setopt EXTENDED_GLOB
|
setopt EXTENDED_GLOB
|
||||||
|
|
||||||
|
# Extract the paramenters for this function
|
||||||
|
typeset -g capped_history_index="${1}"
|
||||||
|
local query="${2}"
|
||||||
|
|
||||||
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
|
# TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
|
||||||
local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
|
local prefix="${query//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
|
||||||
|
|
||||||
# Get all history event numbers that correspond to history
|
# Get all history event numbers that correspond to history
|
||||||
# entries that match pattern $prefix*
|
# entries that match pattern $prefix*
|
||||||
@ -555,13 +592,13 @@ _zsh_autosuggest_strategy_match_prev_cmd() {
|
|||||||
history_match_keys=(${(k)history[(R)$prefix*]})
|
history_match_keys=(${(k)history[(R)$prefix*]})
|
||||||
|
|
||||||
# By default we use the first history number (most recent history entry)
|
# By default we use the first history number (most recent history entry)
|
||||||
local histkey="${history_match_keys[1]}"
|
local histkey="${history_match_keys[capped_history_index]}"
|
||||||
|
|
||||||
# Get the previously executed command
|
# Get the previously executed command
|
||||||
local prev_cmd="$(_zsh_autosuggest_escape_command "${history[$((HISTCMD-1))]}")"
|
local prev_cmd="$(_zsh_autosuggest_escape_command "${history[$((HISTCMD-1))]}")"
|
||||||
|
|
||||||
# Iterate up to the first 200 history event numbers that match $prefix
|
# Iterate up to the first 200 history event numbers that match $prefix
|
||||||
for key in "${(@)history_match_keys[1,200]}"; do
|
for key in "${(@)history_match_keys[capped_history_index,200]}"; do
|
||||||
# Stop if we ran out of history
|
# Stop if we ran out of history
|
||||||
[[ $key -gt 1 ]] || break
|
[[ $key -gt 1 ]] || break
|
||||||
|
|
||||||
@ -603,15 +640,21 @@ _zsh_autosuggest_async_server() {
|
|||||||
|
|
||||||
local last_pid
|
local last_pid
|
||||||
|
|
||||||
while IFS='' read -r -d $'\0' query; do
|
while IFS='' read -r -d $'\0' input; do
|
||||||
# Kill last bg process
|
# Kill last bg process
|
||||||
kill -KILL $last_pid &>/dev/null
|
kill -KILL $last_pid &>/dev/null
|
||||||
|
|
||||||
|
# Break up the input into a list
|
||||||
|
# - (p) recognize the same escape sequences as the print builtin
|
||||||
|
# - (s) force field splitting at the separator given '\1'
|
||||||
|
local query=( ${(ps:\1:)input} )
|
||||||
|
|
||||||
# Run suggestion search in the background
|
# Run suggestion search in the background
|
||||||
(
|
(
|
||||||
local suggestion
|
local suggestion
|
||||||
_zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "$query"
|
local capped_history_index
|
||||||
echo -n -E "$suggestion"$'\0'
|
_zsh_autosuggest_strategy_$ZSH_AUTOSUGGEST_STRATEGY "${query[1]}" "${query[2]}"
|
||||||
|
echo -n -E "$capped_history_index"$'\1'"$suggestion"$'\0'
|
||||||
) &
|
) &
|
||||||
|
|
||||||
last_pid=$!
|
last_pid=$!
|
||||||
@ -620,7 +663,7 @@ _zsh_autosuggest_async_server() {
|
|||||||
|
|
||||||
_zsh_autosuggest_async_request() {
|
_zsh_autosuggest_async_request() {
|
||||||
# Write the query to the zpty process to fetch a suggestion
|
# Write the query to the zpty process to fetch a suggestion
|
||||||
zpty -w -n $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME "${1}"$'\0'
|
zpty -w -n $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME "${1}"$'\1'"${2}"$'\0'
|
||||||
}
|
}
|
||||||
|
|
||||||
# Called when new data is ready to be read from the pty
|
# Called when new data is ready to be read from the pty
|
||||||
@ -629,10 +672,15 @@ _zsh_autosuggest_async_request() {
|
|||||||
_zsh_autosuggest_async_response() {
|
_zsh_autosuggest_async_response() {
|
||||||
setopt LOCAL_OPTIONS EXTENDED_GLOB
|
setopt LOCAL_OPTIONS EXTENDED_GLOB
|
||||||
|
|
||||||
local suggestion
|
local raw_input
|
||||||
|
|
||||||
zpty -rt $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME suggestion '*'$'\0' 2>/dev/null
|
zpty -rt $ZSH_AUTOSUGGEST_ASYNC_PTY_NAME raw_input '*'$'\0' 2>/dev/null
|
||||||
zle autosuggest-suggest -- "${suggestion%%$'\0'##}"
|
|
||||||
|
local input=( ${(ps:\1:)raw_input%%$'\0'##} )
|
||||||
|
local capped_history_index="${input[1]}"
|
||||||
|
local suggestion="${input[2]}"
|
||||||
|
|
||||||
|
zle autosuggest-suggest -- "${capped_history_index}" "${suggestion}"
|
||||||
}
|
}
|
||||||
|
|
||||||
_zsh_autosuggest_async_pty_create() {
|
_zsh_autosuggest_async_pty_create() {
|
||||||
|
Loading…
Reference in New Issue
Block a user