Add zsh-autosuggestion
[zsh.git] / .zsh / external / zsh-autosuggestions / src / widgets.zsh
1
2 #--------------------------------------------------------------------#
3 # Autosuggest Widget Implementations #
4 #--------------------------------------------------------------------#
5
6 # Clear the suggestion
7 _zsh_autosuggest_clear() {
8 # Remove the suggestion
9 unset POSTDISPLAY
10
11 _zsh_autosuggest_invoke_original_widget $@
12 }
13
14 # Modify the buffer and get a new suggestion
15 _zsh_autosuggest_modify() {
16 local -i retval
17
18 # Save the contents of the buffer/postdisplay
19 local orig_buffer="$BUFFER"
20 local orig_postdisplay="$POSTDISPLAY"
21
22 # Clear suggestion while original widget runs
23 unset POSTDISPLAY
24
25 # Original widget may modify the buffer
26 _zsh_autosuggest_invoke_original_widget $@
27 retval=$?
28
29 # Don't fetch a new suggestion if the buffer hasn't changed
30 if [ "$BUFFER" = "$orig_buffer" ]; then
31 POSTDISPLAY="$orig_postdisplay"
32 return $retval
33 fi
34
35 # Get a new suggestion if the buffer is not empty after modification
36 local suggestion
37 if [ $#BUFFER -gt 0 ]; then
38 if [ -z "$ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE" -o $#BUFFER -lt "$ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE" ]; then
39 suggestion="$(_zsh_autosuggest_suggestion "$BUFFER")"
40 fi
41 fi
42
43 # Add the suggestion to the POSTDISPLAY
44 if [ -n "$suggestion" ]; then
45 POSTDISPLAY="${suggestion#$BUFFER}"
46 fi
47
48 return $retval
49 }
50
51 # Accept the entire suggestion
52 _zsh_autosuggest_accept() {
53 local -i max_cursor_pos=$#BUFFER
54
55 # When vicmd keymap is active, the cursor can't move all the way
56 # to the end of the buffer
57 if [ "$KEYMAP" = "vicmd" ]; then
58 max_cursor_pos=$((max_cursor_pos - 1))
59 fi
60
61 # Only accept if the cursor is at the end of the buffer
62 if [ $CURSOR -eq $max_cursor_pos ]; then
63 # Add the suggestion to the buffer
64 BUFFER="$BUFFER$POSTDISPLAY"
65
66 # Remove the suggestion
67 unset POSTDISPLAY
68
69 # Move the cursor to the end of the buffer
70 CURSOR=${#BUFFER}
71 fi
72
73 _zsh_autosuggest_invoke_original_widget $@
74 }
75
76 # Accept the entire suggestion and execute it
77 _zsh_autosuggest_execute() {
78 # Add the suggestion to the buffer
79 BUFFER="$BUFFER$POSTDISPLAY"
80
81 # Remove the suggestion
82 unset POSTDISPLAY
83
84 # Call the original `accept-line` to handle syntax highlighting or
85 # other potential custom behavior
86 _zsh_autosuggest_invoke_original_widget "accept-line"
87 }
88
89 # Partially accept the suggestion
90 _zsh_autosuggest_partial_accept() {
91 local -i retval
92
93 # Save the contents of the buffer so we can restore later if needed
94 local original_buffer="$BUFFER"
95
96 # Temporarily accept the suggestion.
97 BUFFER="$BUFFER$POSTDISPLAY"
98
99 # Original widget moves the cursor
100 _zsh_autosuggest_invoke_original_widget $@
101 retval=$?
102
103 # If we've moved past the end of the original buffer
104 if [ $CURSOR -gt $#original_buffer ]; then
105 # Set POSTDISPLAY to text right of the cursor
106 POSTDISPLAY="$RBUFFER"
107
108 # Clip the buffer at the cursor
109 BUFFER="$LBUFFER"
110 else
111 # Restore the original buffer
112 BUFFER="$original_buffer"
113 fi
114
115 return $retval
116 }
117
118 for action in clear modify accept partial_accept execute; do
119 eval "_zsh_autosuggest_widget_$action() {
120 local -i retval
121
122 _zsh_autosuggest_highlight_reset
123
124 _zsh_autosuggest_$action \$@
125 retval=\$?
126
127 _zsh_autosuggest_highlight_apply
128
129 return \$retval
130 }"
131 done
132
133 zle -N autosuggest-accept _zsh_autosuggest_widget_accept
134 zle -N autosuggest-clear _zsh_autosuggest_widget_clear
135 zle -N autosuggest-execute _zsh_autosuggest_widget_execute