mirror of
https://github.com/zsh-users/zsh-autosuggestions.git
synced 2024-11-25 10:01:05 +01:00
Add match_prev_cmd strategy.
A new suggestion strategy 'match_prev_cmd' is available. This is a bit more context aware variaton on the default strategy. The suggestion will be: - The newest history entry that matches the current prefix, AND - Whose preceding history entry also matches the previously executed command. See src/strategies/match_prev_cmd.zsh for an example.
This commit is contained in:
parent
976acc708c
commit
73f774bd5d
4 changed files with 232 additions and 0 deletions
122
script/test-strategy-match-prev-cmd.zsh
Executable file
122
script/test-strategy-match-prev-cmd.zsh
Executable file
|
@ -0,0 +1,122 @@
|
||||||
|
#!/usr/bin/env zsh
|
||||||
|
|
||||||
|
SCRIPT_DIR=$(dirname "$0")
|
||||||
|
TEST_DIR=$SCRIPT_DIR/../test
|
||||||
|
DIST_DIR=$SCRIPT_DIR/../
|
||||||
|
|
||||||
|
# Use stub.sh for stubbing/mocking
|
||||||
|
source $TEST_DIR/stub-1.0.2.sh
|
||||||
|
|
||||||
|
source $DIST_DIR/zsh-autosuggestions.zsh
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------#
|
||||||
|
# Match Previous Command Suggestion Strategy #
|
||||||
|
#--------------------------------------------------------------------#
|
||||||
|
|
||||||
|
TMPHIST_FILE=/tmp/zsh-autosuggestions-test-tmp-hist
|
||||||
|
|
||||||
|
HISTSIZE=0 # Clear history
|
||||||
|
HISTSIZE=100
|
||||||
|
|
||||||
|
cat > $TMPHIST_FILE <<-EOH
|
||||||
|
one
|
||||||
|
two
|
||||||
|
three
|
||||||
|
four
|
||||||
|
five
|
||||||
|
six
|
||||||
|
seven
|
||||||
|
eight
|
||||||
|
nine
|
||||||
|
ten
|
||||||
|
eleven
|
||||||
|
EOH
|
||||||
|
echo >> $TMPHIST_FILE
|
||||||
|
|
||||||
|
fc -R $TMPHIST_FILE
|
||||||
|
|
||||||
|
rm $TMPHIST_FILE
|
||||||
|
|
||||||
|
ZSH_AUTOSUGGEST_STRATEGY=match_prev_cmd
|
||||||
|
|
||||||
|
testNoMatchPrevIsOne() {
|
||||||
|
stub_and_echo _zsh_autosuggest_prev_command "one"
|
||||||
|
|
||||||
|
assertEquals \
|
||||||
|
"Did not pick correct suggestion for prefix 'garbage' after 'one'" \
|
||||||
|
"" \
|
||||||
|
"$(_zsh_autosuggest_suggestion garbage)"
|
||||||
|
}
|
||||||
|
|
||||||
|
testMatchPrevIsOne() {
|
||||||
|
stub_and_echo _zsh_autosuggest_prev_command "one"
|
||||||
|
|
||||||
|
assertEquals \
|
||||||
|
"Did not pick correct suggestion for prefix 'o' after 'one'" \
|
||||||
|
"one" \
|
||||||
|
"$(_zsh_autosuggest_suggestion o)"
|
||||||
|
|
||||||
|
assertEquals \
|
||||||
|
"Did not pick correct suggestion for prefix 't' after 'one'" \
|
||||||
|
"two" \
|
||||||
|
"$(_zsh_autosuggest_suggestion t)"
|
||||||
|
|
||||||
|
assertEquals \
|
||||||
|
"Did not pick correct suggestion for prefix 'th' after 'one'" \
|
||||||
|
"three" \
|
||||||
|
"$(_zsh_autosuggest_suggestion th)"
|
||||||
|
|
||||||
|
assertEquals \
|
||||||
|
"Did not pick correct suggestion for prefix 'f' after 'one'" \
|
||||||
|
"five" \
|
||||||
|
"$(_zsh_autosuggest_suggestion f)"
|
||||||
|
|
||||||
|
assertEquals \
|
||||||
|
"Did not pick correct suggestion for prefix 'fo' after 'one" \
|
||||||
|
"four" \
|
||||||
|
"$(_zsh_autosuggest_suggestion fo)"
|
||||||
|
}
|
||||||
|
|
||||||
|
testNoMatchPrevIsTwo() {
|
||||||
|
stub_and_echo _zsh_autosuggest_prev_command "two"
|
||||||
|
|
||||||
|
assertEquals \
|
||||||
|
"Did not pick correct suggestion for prefix 'garbage' after 'two'" \
|
||||||
|
"" \
|
||||||
|
"$(_zsh_autosuggest_suggestion garbage)"
|
||||||
|
}
|
||||||
|
|
||||||
|
testMatchPrevIsTwo() {
|
||||||
|
stub_and_echo _zsh_autosuggest_prev_command "two"
|
||||||
|
|
||||||
|
assertEquals \
|
||||||
|
"Did not pick correct suggestion for prefix 'o' after 'two'" \
|
||||||
|
"one" \
|
||||||
|
"$(_zsh_autosuggest_suggestion o)"
|
||||||
|
|
||||||
|
assertEquals \
|
||||||
|
"Did not pick correct suggestion for prefix 't' after 'two'" \
|
||||||
|
"three" \
|
||||||
|
"$(_zsh_autosuggest_suggestion t)"
|
||||||
|
|
||||||
|
assertEquals \
|
||||||
|
"Did not pick correct suggestion for prefix 'tw' after 'two'" \
|
||||||
|
"two" \
|
||||||
|
"$(_zsh_autosuggest_suggestion tw)"
|
||||||
|
|
||||||
|
assertEquals \
|
||||||
|
"Did not pick correct suggestion for prefix 'f' after 'two'" \
|
||||||
|
"five" \
|
||||||
|
"$(_zsh_autosuggest_suggestion f)"
|
||||||
|
|
||||||
|
assertEquals \
|
||||||
|
"Did not pick correct suggestion for prefix 'fo' after 'two" \
|
||||||
|
"four" \
|
||||||
|
"$(_zsh_autosuggest_suggestion fo)"
|
||||||
|
}
|
||||||
|
|
||||||
|
setopt shwordsplit
|
||||||
|
SHUNIT_PARENT=$0
|
||||||
|
|
||||||
|
source $TEST_DIR/shunit2-2.1.6/src/shunit2
|
||||||
|
|
50
src/strategies/match_prev_cmd.zsh
Normal file
50
src/strategies/match_prev_cmd.zsh
Normal file
|
@ -0,0 +1,50 @@
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------#
|
||||||
|
# Match Previous Command Suggestion Strategy #
|
||||||
|
#--------------------------------------------------------------------#
|
||||||
|
# Suggests the most recent history item that matches the given
|
||||||
|
# prefix, and whose preceding history item also matches the most
|
||||||
|
# recently executed command.
|
||||||
|
#
|
||||||
|
# For example, if your have just executed:
|
||||||
|
# pwd
|
||||||
|
# ls foo
|
||||||
|
# ls bar
|
||||||
|
# pwd
|
||||||
|
# And then you start typing 'ls', then the suggestion will be 'ls foo',
|
||||||
|
# rather than 'ls bar', as your most recently executed command (pwd)
|
||||||
|
# was followed by 'ls foo' on it's previous invocation.
|
||||||
|
#
|
||||||
|
|
||||||
|
_zsh_autosuggest_strategy_match_prev_cmd() {
|
||||||
|
local prefix="$(_zsh_autosuggest_escape_command_prefix "$1")"
|
||||||
|
|
||||||
|
# Get all history event numbers that correspond to history
|
||||||
|
# entries that match pattern $prefix*
|
||||||
|
local history_match_keys
|
||||||
|
history_match_keys=(${(k)history[(R)$prefix*]})
|
||||||
|
|
||||||
|
# By default we use the first history number (most recent history entry)
|
||||||
|
local histkey="${history_match_keys[1]}"
|
||||||
|
|
||||||
|
# Get the previously executed command
|
||||||
|
local prev_cmd="$(_zsh_autosuggest_prev_command)"
|
||||||
|
prev_cmd="$(_zsh_autosuggest_escape_command_prefix $prev_cmd)"
|
||||||
|
|
||||||
|
# Iterate up to the first 200 history event numbers that match $prefix
|
||||||
|
for key in "${(@)history_match_keys[1,200]}"; do
|
||||||
|
# Stop if we ran out of history
|
||||||
|
[[ $key -gt 1 ]] || break
|
||||||
|
|
||||||
|
# See if the history entry preceding the suggestion matches the
|
||||||
|
# previous command, and use it if it does
|
||||||
|
if [[ "${history[$((key - 1))]}" == $prev_cmd ]]; then
|
||||||
|
histkey="$key"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Echo the matched history entry
|
||||||
|
echo -E "$history[$histkey]"
|
||||||
|
}
|
||||||
|
|
|
@ -19,3 +19,8 @@ _zsh_autosuggest_escape_command_prefix() {
|
||||||
# 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}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Get the previously executed command (hookable for testing)
|
||||||
|
_zsh_autosuggest_prev_command() {
|
||||||
|
echo -E "${history[$((HISTCMD-1))]}"
|
||||||
|
}
|
||||||
|
|
|
@ -330,6 +330,11 @@ _zsh_autosuggest_escape_command_prefix() {
|
||||||
echo -E "${1//(#m)[\\()\[\]|*?]/\\$MATCH}"
|
echo -E "${1//(#m)[\\()\[\]|*?]/\\$MATCH}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Get the previously executed command (hookable for testing)
|
||||||
|
_zsh_autosuggest_prev_command() {
|
||||||
|
echo -E "${history[$((HISTCMD-1))]}"
|
||||||
|
}
|
||||||
|
|
||||||
#--------------------------------------------------------------------#
|
#--------------------------------------------------------------------#
|
||||||
# Default Suggestion Strategy #
|
# Default Suggestion Strategy #
|
||||||
#--------------------------------------------------------------------#
|
#--------------------------------------------------------------------#
|
||||||
|
@ -347,6 +352,56 @@ _zsh_autosuggest_strategy_default() {
|
||||||
echo -E "${history[$histkey]}"
|
echo -E "${history[$histkey]}"
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#--------------------------------------------------------------------#
|
||||||
|
# Match Previous Command Suggestion Strategy #
|
||||||
|
#--------------------------------------------------------------------#
|
||||||
|
# Suggests the most recent history item that matches the given
|
||||||
|
# prefix, and whose preceding history item also matches the most
|
||||||
|
# recently executed command.
|
||||||
|
#
|
||||||
|
# For example, if your have just executed:
|
||||||
|
# pwd
|
||||||
|
# ls foo
|
||||||
|
# ls bar
|
||||||
|
# pwd
|
||||||
|
# And then you start typing 'ls', then the suggestion will be 'ls foo',
|
||||||
|
# rather than 'ls bar', as your most recently executed command (pwd)
|
||||||
|
# was followed by 'ls foo' on it's previous invocation.
|
||||||
|
#
|
||||||
|
|
||||||
|
_zsh_autosuggest_strategy_match_prev_cmd() {
|
||||||
|
local prefix="$(_zsh_autosuggest_escape_command_prefix "$1")"
|
||||||
|
|
||||||
|
# Get all history event numbers that correspond to history
|
||||||
|
# entries that match pattern $prefix*
|
||||||
|
local history_match_keys
|
||||||
|
history_match_keys=(${(k)history[(R)$prefix*]})
|
||||||
|
|
||||||
|
# By default we use the first history number (most recent history entry)
|
||||||
|
local histkey="${history_match_keys[1]}"
|
||||||
|
|
||||||
|
# Get the previously executed command
|
||||||
|
local prev_cmd="$(_zsh_autosuggest_prev_command)"
|
||||||
|
prev_cmd="$(_zsh_autosuggest_escape_command_prefix $prev_cmd)"
|
||||||
|
|
||||||
|
# Iterate up to the first 200 history event numbers that match $prefix
|
||||||
|
for key in "${(@)history_match_keys[1,200]}"; do
|
||||||
|
# Stop if we ran out of history
|
||||||
|
[[ $key -gt 1 ]] || break
|
||||||
|
|
||||||
|
# See if the history entry preceding the suggestion matches the
|
||||||
|
# previous command, and use it if it does
|
||||||
|
if [[ "${history[$((key - 1))]}" == $prev_cmd ]]; then
|
||||||
|
histkey="$key"
|
||||||
|
break
|
||||||
|
fi
|
||||||
|
done
|
||||||
|
|
||||||
|
# Echo the matched history entry
|
||||||
|
echo -E "$history[$histkey]"
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
#--------------------------------------------------------------------#
|
#--------------------------------------------------------------------#
|
||||||
# Start #
|
# Start #
|
||||||
#--------------------------------------------------------------------#
|
#--------------------------------------------------------------------#
|
||||||
|
|
Loading…
Reference in a new issue