diff --git a/README.md b/README.md
index abf4790..a72ea01 100644
--- a/README.md
+++ b/README.md
@@ -70,6 +70,7 @@ This plugin works by triggering custom behavior when certain [zle widgets](http:
- `ZSH_AUTOSUGGEST_CLEAR_WIDGETS`: Widgets in this array will clear the suggestion when invoked.
- `ZSH_AUTOSUGGEST_ACCEPT_WIDGETS`: Widgets in this array will accept the suggestion when invoked.
+- `ZSH_AUTOSUGGEST_EXECUTE_WIDGETS`: Widgets in this array will execute the suggestion when invoked.
- `ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS`: Widgets in this array will partially accept the suggestion when invoked.
Widgets not in any of these lists will update the suggestion when invoked.
@@ -79,10 +80,11 @@ Widgets not in any of these lists will update the suggestion when invoked.
### Key Bindings
-This plugin provides two widgets that you can use with `bindkey`:
+This plugin provides three widgets that you can use with `bindkey`:
1. `autosuggest-accept`: Accepts the current suggestion.
-2. `autosuggest-clear`: Clears the current suggestion.
+2. `autosuggest-execute`: Accepts and executes the current suggestion.
+3. `autosuggest-clear`: Clears the current suggestion.
For example, this would bind ctrl + space to accept the current suggestion.
diff --git a/script/test.zsh b/script/test.zsh
index 45f3dbc..ba563a6 100755
--- a/script/test.zsh
+++ b/script/test.zsh
@@ -177,6 +177,29 @@ testWidgetFunctionAcceptCursorNotAtEnd() {
"$POSTDISPLAY"
}
+testWidgetFunctionExecute() {
+ BUFFER="ec"
+ POSTDISPLAY="ho hello"
+
+ stub _zsh_autosuggest_invoke_original_widget
+
+ _zsh_autosuggest_execute
+
+ assertTrue \
+ "accept-line not invoked" \
+ "stub_called_with _zsh_autosuggest_invoke_original_widget 'accept-line'"
+
+ assertEquals \
+ "BUFFER was not modified" \
+ "echo hello" \
+ "$BUFFER"
+
+ assertEquals \
+ "POSTDISPLAY was not cleared" \
+ "" \
+ "$POSTDISPLAY"
+}
+
testWidgetFunctionPartialAcceptCursorMovesOutOfBuffer() {
BUFFER="ec"
POSTDISPLAY="ho hello"
@@ -281,6 +304,32 @@ testWidgetClear() {
"stub_called _zsh_autosuggest_highlight_apply"
}
+testWidgetExecute() {
+ stub _zsh_autosuggest_highlight_reset
+ stub _zsh_autosuggest_execute
+ stub _zsh_autosuggest_highlight_apply
+
+ # Call the function pointed to by the widget since we can't call
+ # the widget itself when zle is not active
+ ${widgets[autosuggest-execute]#*:} "original-widget"
+
+ assertTrue \
+ "autosuggest-execute widget does not exist" \
+ "zle -l autosuggest-execute"
+
+ assertTrue \
+ "highlight_reset was not called" \
+ "stub_called _zsh_autosuggest_highlight_reset"
+
+ assertTrue \
+ "widget function was not called" \
+ "stub_called _zsh_autosuggest_execute"
+
+ assertTrue \
+ "highlight_apply was not called" \
+ "stub_called _zsh_autosuggest_highlight_apply"
+}
+
testEscapeCommandPrefix() {
assertEquals \
"Did not escape single backslash" \
diff --git a/src/bind.zsh b/src/bind.zsh
index cc020de..030c6cf 100644
--- a/src/bind.zsh
+++ b/src/bind.zsh
@@ -55,6 +55,8 @@ _zsh_autosuggest_bind_widgets() {
_zsh_autosuggest_bind_widget $widget clear
elif [ ${ZSH_AUTOSUGGEST_ACCEPT_WIDGETS[(r)$widget]} ]; then
_zsh_autosuggest_bind_widget $widget accept
+ elif [ ${ZSH_AUTOSUGGEST_EXECUTE_WIDGETS[(r)$widget]} ]; then
+ _zsh_autosuggest_bind_widget $widget execute
elif [ ${ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS[(r)$widget]} ]; then
_zsh_autosuggest_bind_widget $widget partial_accept
else
diff --git a/src/config.zsh b/src/config.zsh
index b5a0f02..ae34f82 100644
--- a/src/config.zsh
+++ b/src/config.zsh
@@ -32,6 +32,10 @@ ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=(
vi-end-of-line
)
+# Widgets that accept the entire suggestion and execute it
+ZSH_AUTOSUGGEST_EXECUTE_WIDGETS=(
+)
+
# Widgets that accept the suggestion as far as the cursor moves
ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=(
forward-word
diff --git a/src/widgets.zsh b/src/widgets.zsh
index 1537b8a..925a5e2 100644
--- a/src/widgets.zsh
+++ b/src/widgets.zsh
@@ -47,6 +47,19 @@ _zsh_autosuggest_accept() {
_zsh_autosuggest_invoke_original_widget $@
}
+# Accept the entire suggestion and execute it
+_zsh_autosuggest_execute() {
+ # Add the suggestion to the buffer
+ BUFFER="$BUFFER$POSTDISPLAY"
+
+ # Remove the suggestion
+ unset POSTDISPLAY
+
+ # Call the original `accept-line` to handle syntax highlighting or
+ # other potential custom behavior
+ _zsh_autosuggest_invoke_original_widget "accept-line"
+}
+
# Partially accept the suggestion
_zsh_autosuggest_partial_accept() {
# Save the contents of the buffer so we can restore later if needed
@@ -71,7 +84,7 @@ _zsh_autosuggest_partial_accept() {
fi
}
-for action in clear modify accept partial_accept; do
+for action in clear modify accept partial_accept execute; do
eval "_zsh_autosuggest_widget_$action() {
_zsh_autosuggest_highlight_reset
_zsh_autosuggest_$action \$@
@@ -81,3 +94,4 @@ done
zle -N autosuggest-accept _zsh_autosuggest_widget_accept
zle -N autosuggest-clear _zsh_autosuggest_widget_clear
+zle -N autosuggest-execute _zsh_autosuggest_widget_execute
diff --git a/zsh-autosuggestions.zsh b/zsh-autosuggestions.zsh
index 552bbdf..cd8ad5a 100644
--- a/zsh-autosuggestions.zsh
+++ b/zsh-autosuggestions.zsh
@@ -58,6 +58,10 @@ ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=(
vi-end-of-line
)
+# Widgets that accept the entire suggestion and execute it
+ZSH_AUTOSUGGEST_EXECUTE_WIDGETS=(
+)
+
# Widgets that accept the suggestion as far as the cursor moves
ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=(
forward-word
@@ -159,6 +163,8 @@ _zsh_autosuggest_bind_widgets() {
_zsh_autosuggest_bind_widget $widget clear
elif [ ${ZSH_AUTOSUGGEST_ACCEPT_WIDGETS[(r)$widget]} ]; then
_zsh_autosuggest_bind_widget $widget accept
+ elif [ ${ZSH_AUTOSUGGEST_EXECUTE_WIDGETS[(r)$widget]} ]; then
+ _zsh_autosuggest_bind_widget $widget execute
elif [ ${ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS[(r)$widget]} ]; then
_zsh_autosuggest_bind_widget $widget partial_accept
else
@@ -252,6 +258,19 @@ _zsh_autosuggest_accept() {
_zsh_autosuggest_invoke_original_widget $@
}
+# Accept the entire suggestion and execute it
+_zsh_autosuggest_execute() {
+ # Add the suggestion to the buffer
+ BUFFER="$BUFFER$POSTDISPLAY"
+
+ # Remove the suggestion
+ unset POSTDISPLAY
+
+ # Call the original `accept-line` to handle syntax highlighting or
+ # other potential custom behavior
+ _zsh_autosuggest_invoke_original_widget "accept-line"
+}
+
# Partially accept the suggestion
_zsh_autosuggest_partial_accept() {
# Save the contents of the buffer so we can restore later if needed
@@ -276,7 +295,7 @@ _zsh_autosuggest_partial_accept() {
fi
}
-for action in clear modify accept partial_accept; do
+for action in clear modify accept partial_accept execute; do
eval "_zsh_autosuggest_widget_$action() {
_zsh_autosuggest_highlight_reset
_zsh_autosuggest_$action \$@
@@ -286,6 +305,7 @@ done
zle -N autosuggest-accept _zsh_autosuggest_widget_accept
zle -N autosuggest-clear _zsh_autosuggest_widget_clear
+zle -N autosuggest-execute _zsh_autosuggest_widget_execute
#--------------------------------------------------------------------#
# Suggestion #