configs-all 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (227) hide show
  1. package/.claude/settings.local.json +3 -0
  2. package/CLAUDE.md +94 -0
  3. package/README.md +424 -0
  4. package/TERMINAL_SHORTCUTS.md +96 -0
  5. package/WINDOWS_COMPATIBILITY.md +85 -0
  6. package/WINDOWS_MCP_SETUP.md +133 -0
  7. package/apps/RectangleConfig.plist +0 -0
  8. package/apps/Synergy +84 -0
  9. package/apps/iStat Menus Settings.ismp7 +0 -0
  10. package/claude/CLAUDE.md +228 -0
  11. package/claude/commands/changelog.md +36 -0
  12. package/claude/commands/commit.md +29 -0
  13. package/claude/commands/context.md +112 -0
  14. package/claude/commands/dash.md +37 -0
  15. package/claude/commands/deploy-check.md +37 -0
  16. package/claude/commands/deps.md +26 -0
  17. package/claude/commands/duplo.md +56 -0
  18. package/claude/commands/explain.md +43 -0
  19. package/claude/commands/fix-and-test.md +46 -0
  20. package/claude/commands/game-debug.md +66 -0
  21. package/claude/commands/games.md +53 -0
  22. package/claude/commands/go.md +147 -0
  23. package/claude/commands/guard.md +102 -0
  24. package/claude/commands/handoff.md +66 -0
  25. package/claude/commands/incident.md +144 -0
  26. package/claude/commands/init.md +78 -0
  27. package/claude/commands/k8s-debug.md +31 -0
  28. package/claude/commands/lint.md +27 -0
  29. package/claude/commands/merge-all.md +115 -0
  30. package/claude/commands/merge.md +129 -0
  31. package/claude/commands/mikpc.md +54 -0
  32. package/claude/commands/morning.md +72 -0
  33. package/claude/commands/partymode.md +105 -0
  34. package/claude/commands/plans.md +88 -0
  35. package/claude/commands/pr.md +41 -0
  36. package/claude/commands/prep.md +132 -0
  37. package/claude/commands/push-sync.md +82 -0
  38. package/claude/commands/push.md +34 -0
  39. package/claude/commands/research.md +73 -0
  40. package/claude/commands/retro.md +95 -0
  41. package/claude/commands/review-pr.md +96 -0
  42. package/claude/commands/review.md +41 -0
  43. package/claude/commands/scaffold-agent.md +45 -0
  44. package/claude/commands/setup.md +92 -0
  45. package/claude/commands/ship-prod.md +97 -0
  46. package/claude/commands/ship.md +82 -0
  47. package/claude/commands/simplify.md +42 -0
  48. package/claude/commands/spike.md +110 -0
  49. package/claude/commands/status.md +37 -0
  50. package/claude/commands/sync.md +72 -0
  51. package/claude/commands/test.md +29 -0
  52. package/claude/commands/triage.md +72 -0
  53. package/claude/desktop/claude_desktop_config.json +9 -0
  54. package/claude/hooks.json +15 -0
  55. package/claude/mcp-servers.duplo.json +8 -0
  56. package/claude/mcp-servers.json +62 -0
  57. package/claude/scripts/psdebug.ps1 +7 -0
  58. package/claude/settings.json +38 -0
  59. package/claude/settings.local.json +4 -0
  60. package/claude/statusline-command.sh +94 -0
  61. package/claude/templates/CLAUDE-k8s-devops.md +58 -0
  62. package/claude/templates/CLAUDE-python-agent.md +47 -0
  63. package/claude/templates/CLAUDE-typescript-frontend.md +50 -0
  64. package/docker/ai-stack/docker-compose.yml +76 -0
  65. package/docker/ai-stack/searxng/limiter.toml +3 -0
  66. package/docker/ai-stack/searxng/settings.yml +39 -0
  67. package/docker/cli/config.json.template +15 -0
  68. package/docker/cli/daemon.json +9 -0
  69. package/docker/cli/features.json +3 -0
  70. package/docker/mcp/catalog.json +9 -0
  71. package/docker/mcp/catalogs/docker-mcp.yaml +15107 -0
  72. package/docker/mcp/config.yaml +0 -0
  73. package/docker/mcp/registry.yaml +37 -0
  74. package/docker/mcp/tools.yaml +0 -0
  75. package/docs/context/.gitkeep +0 -0
  76. package/docs/context/2026-03-02-configs.md +142 -0
  77. package/docs/handoff/.gitkeep +0 -0
  78. package/docs/incidents/.gitkeep +0 -0
  79. package/docs/plans/2026-02-28-autonomous-command-suite-design.md +250 -0
  80. package/docs/plans/2026-02-28-autonomous-command-suite.md +682 -0
  81. package/docs/plans/2026-03-01-ai-stack-split-architecture.md +72 -0
  82. package/docs/plans/2026-03-02-ai-stack-expansion.md +33 -0
  83. package/docs/plans/2026-03-02-merge-commands-design.md +58 -0
  84. package/docs/plans/2026-03-02-merge-commands.md +354 -0
  85. package/docs/research/.gitkeep +0 -0
  86. package/docs/research/2026-03-02-configs-repo-architecture.md +152 -0
  87. package/docs/retros/.gitkeep +0 -0
  88. package/docs/retros/2026-03-01-ai-stack-split-architecture.md +38 -0
  89. package/docs/spikes/.gitkeep +0 -0
  90. package/gh/config.yml +16 -0
  91. package/gh/hosts.yml +5 -0
  92. package/gh/main.json +103 -0
  93. package/ghostty/config +90 -0
  94. package/git/config/base.gitconfig +46 -0
  95. package/git/config/chiefmikey.gitconfig +11 -0
  96. package/git/config/personal.gitconfig +10 -0
  97. package/git/config/work.gitconfig +14 -0
  98. package/ide/cursor/extensions.txt +111 -0
  99. package/ide/cursor/keybindings.json +307 -0
  100. package/ide/cursor/mcp.json +92 -0
  101. package/ide/cursor/settings.json +544 -0
  102. package/ide/vscode/extensions.txt +120 -0
  103. package/ide/vscode/insiders/extensions.txt +119 -0
  104. package/ide/vscode/insiders/keybindings.json +294 -0
  105. package/ide/vscode/insiders/settings.json +518 -0
  106. package/ide/vscode/keybindings.json +294 -0
  107. package/ide/vscode/settings.json +526 -0
  108. package/ide/vscode/vscode/extensions.txt +43 -0
  109. package/iterm/Mikey Pro.json +951 -0
  110. package/iterm/com.googlecode.iterm2.plist +5549 -0
  111. package/iterm/font/MesloLGS NF Bold Italic.ttf +0 -0
  112. package/iterm/font/MesloLGS NF Bold.ttf +0 -0
  113. package/iterm/font/MesloLGS NF Italic.ttf +0 -0
  114. package/iterm/font/MesloLGS NF Regular.ttf +0 -0
  115. package/package.json +15 -0
  116. package/scripts/ai/deploy-ai-stack.sh +119 -0
  117. package/scripts/ai/fix-ai-proxy.service +12 -0
  118. package/scripts/ai/fix-ai-proxy.sh +25 -0
  119. package/scripts/brew/search/brew-search-results.sh +19 -0
  120. package/scripts/brew/search/brew-search.sh +34 -0
  121. package/scripts/brew/upgrade/brew-upgrade-autoupdate.sh +5 -0
  122. package/scripts/brew/upgrade/brew-upgrade-full-auto.sh +89 -0
  123. package/scripts/brew/upgrade/brew-upgrade-full.sh +159 -0
  124. package/scripts/docker/cleanup/docker-cleanup-manage.sh +163 -0
  125. package/scripts/docker/cleanup/docker-cleanup.cron +12 -0
  126. package/scripts/docker/cleanup/docker-cleanup.sh +280 -0
  127. package/scripts/docker/install/README.md +23 -0
  128. package/scripts/docker/install/docker-al2.sh +7 -0
  129. package/scripts/docker/install/docker-compose-al2.sh +15 -0
  130. package/scripts/gh/auth/auth.sh +12 -0
  131. package/scripts/gh/config/gh-config.sh +3 -0
  132. package/scripts/gh/gist/gh-gist-create.sh +29 -0
  133. package/scripts/gh/gist/gh-gist-delete.sh +1 -0
  134. package/scripts/gh/gist/gh-gist-edit.sh +8 -0
  135. package/scripts/gh/gpg-key/gh-gpg-key-add.sh +3 -0
  136. package/scripts/gh/install/install.sh +7 -0
  137. package/scripts/gh/label/gh-label-clone.sh +0 -0
  138. package/scripts/gh/label/gh-label-create.sh +0 -0
  139. package/scripts/gh/label/gh-label-delete.sh +0 -0
  140. package/scripts/gh/label/gh-label-edit.sh +0 -0
  141. package/scripts/gh/label/gh-label-list.sh +0 -0
  142. package/scripts/gh/secret/gh-secret-delete.sh +24 -0
  143. package/scripts/gh/secret/gh-secret-set.sh +70 -0
  144. package/scripts/gh/ssh-key/gh-ssh-key-add.sh +8 -0
  145. package/scripts/git/add/git-add.sh +3 -0
  146. package/scripts/git/auth/README.md +11 -0
  147. package/scripts/git/auth/https.sh +20 -0
  148. package/scripts/git/auth/ssh-mac.sh +41 -0
  149. package/scripts/git/branch-delete/git-branch-delete.sh +16 -0
  150. package/scripts/git/checkout/git-checkout-stash.sh +32 -0
  151. package/scripts/git/temp/git-temp-pull.sh +6 -0
  152. package/scripts/git/temp/git-temp-push.sh +5 -0
  153. package/scripts/install/fresh.zsh +34 -0
  154. package/scripts/install/full-install.zsh +193 -0
  155. package/scripts/linux/codedeploy/README.md +19 -0
  156. package/scripts/linux/codedeploy/linux-codedeploy-al2.sh +13 -0
  157. package/scripts/linux/codedeploy/linux-codedeploy-index.sh +16 -0
  158. package/scripts/linux/codedeploy/linux-codedeploy-ubuntu.sh +14 -0
  159. package/scripts/linux/coredns/README.md +17 -0
  160. package/scripts/linux/coredns/linux-coredns-al2.sh +29 -0
  161. package/scripts/linux/wifi/01-netconf.yaml +21 -0
  162. package/scripts/linux/wifi/wifi-ubuntu.sh +17 -0
  163. package/scripts/mac/dock-sort/mac-dock-sort.sh +87 -0
  164. package/scripts/mac/dropbox-ignore/mac-dropbox-ignore.sh +12 -0
  165. package/scripts/mac/sudo-askpass/mac-sudo-askpass.sh +50 -0
  166. package/scripts/mac/sudo-askpass/setup-sudo-password.sh +49 -0
  167. package/scripts/mac/upgrade/mac-upgrade.sh +21 -0
  168. package/scripts/mac/vpn/mac-vpn.sh +4 -0
  169. package/scripts/mcp/aws-mcp-wrapper.ps1 +97 -0
  170. package/scripts/mcp/aws-mcp-wrapper.sh +53 -0
  171. package/scripts/mcp/duplo-mcp-wrapper.sh +31 -0
  172. package/scripts/mcp/filesystem-mcp-wrapper.ps1 +43 -0
  173. package/scripts/mcp/filesystem-mcp-wrapper.sh +34 -0
  174. package/scripts/mcp/git-mcp-wrapper.ps1 +42 -0
  175. package/scripts/mcp/git-mcp-wrapper.sh +33 -0
  176. package/scripts/mcp/github-mcp-wrapper.ps1 +43 -0
  177. package/scripts/mcp/github-mcp-wrapper.sh +19 -0
  178. package/scripts/mcp/kubernetes-mcp-wrapper.ps1 +22 -0
  179. package/scripts/mcp/kubernetes-mcp-wrapper.sh +16 -0
  180. package/scripts/mcp/mcp-launcher.ps1 +56 -0
  181. package/scripts/mcp/mcp-launcher.sh +71 -0
  182. package/scripts/mcp/mongodb-mcp-wrapper.ps1 +26 -0
  183. package/scripts/mcp/mongodb-mcp-wrapper.sh +17 -0
  184. package/scripts/mcp/notion-mcp-wrapper.ps1 +23 -0
  185. package/scripts/mcp/notion-mcp-wrapper.sh +14 -0
  186. package/scripts/mcp/postgres-mcp-wrapper.ps1 +23 -0
  187. package/scripts/mcp/postgres-mcp-wrapper.sh +16 -0
  188. package/scripts/npm/ncu/npm-ncu.sh +24 -0
  189. package/scripts/npm/upgrade/npm-upgrade.sh +51 -0
  190. package/scripts/qmk/build_reviung41.sh +28 -0
  191. package/scripts/qmk/sync_unicorne.sh +44 -0
  192. package/scripts/sync/README.md +64 -0
  193. package/scripts/sync/config-common.zsh +882 -0
  194. package/scripts/sync/pull-configs.ps1 +33 -0
  195. package/scripts/sync/pull-configs.zsh +278 -0
  196. package/scripts/sync/push-configs.ps1 +91 -0
  197. package/scripts/sync/push-configs.zsh +384 -0
  198. package/shell/alias/alias-d.zsh +333 -0
  199. package/shell/alias/alias.zsh +36 -0
  200. package/shell/alias/categories/development.zsh +157 -0
  201. package/shell/alias/categories/environment.zsh +13 -0
  202. package/shell/alias/categories/git.zsh +40 -0
  203. package/shell/alias/categories/github-functions.zsh +459 -0
  204. package/shell/alias/categories/network.zsh +46 -0
  205. package/shell/alias/categories/path.zsh +46 -0
  206. package/shell/alias/categories/system.zsh +78 -0
  207. package/shell/alias/categories/wolfe-server.zsh +11 -0
  208. package/shell/powershell/Microsoft.PowerShell_profile.ps1 +208 -0
  209. package/shell/zsh/.p10k.zsh +1832 -0
  210. package/shell/zsh/.zshrc +87 -0
  211. package/shell/zsh/config/completion.zsh +31 -0
  212. package/shell/zsh/config/functions.zsh +31 -0
  213. package/shell/zsh/config/keybindings.zsh +13 -0
  214. package/shell/zsh/config/options.zsh +56 -0
  215. package/shell/zsh/config/plugins.zsh +83 -0
  216. package/shell/zsh/config/variables.zsh +191 -0
  217. package/shell/zsh/powerlevel10k.zsh-theme +83 -0
  218. package/shell/zsh/zsh-autosuggestions.zsh +871 -0
  219. package/ssh/config +46 -0
  220. package/ssh/config.duplo +21 -0
  221. package/ssh/config.mikpc +35 -0
  222. package/ssh/personal_signing.pub +1 -0
  223. package/templates/.envrc.example +34 -0
  224. package/templates/.envrc.quickstart +17 -0
  225. package/wezterm/wezterm.lua +249 -0
  226. package/wsl/.wslconfig +3 -0
  227. package/wsl/wsl.conf +18 -0
@@ -0,0 +1,871 @@
1
+ # Fish-like fast/unobtrusive autosuggestions for zsh.
2
+ # https://github.com/zsh-users/zsh-autosuggestions
3
+ # v0.7.1
4
+ # Copyright (c) 2013 Thiago de Arruda
5
+ # Copyright (c) 2016-2021 Eric Freese
6
+ #
7
+ # Permission is hereby granted, free of charge, to any person
8
+ # obtaining a copy of this software and associated documentation
9
+ # files (the "Software"), to deal in the Software without
10
+ # restriction, including without limitation the rights to use,
11
+ # copy, modify, merge, publish, distribute, sublicense, and/or sell
12
+ # copies of the Software, and to permit persons to whom the
13
+ # Software is furnished to do so, subject to the following
14
+ # conditions:
15
+ #
16
+ # The above copyright notice and this permission notice shall be
17
+ # included in all copies or substantial portions of the Software.
18
+ #
19
+ # THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20
+ # EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES
21
+ # OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22
+ # NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT
23
+ # HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY,
24
+ # WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
25
+ # FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR
26
+ # OTHER DEALINGS IN THE SOFTWARE.
27
+
28
+ #--------------------------------------------------------------------#
29
+ # Global Configuration Variables #
30
+ #--------------------------------------------------------------------#
31
+
32
+ # Color to use when highlighting suggestion
33
+ # Uses format of `region_highlight`
34
+ # More info: http://zsh.sourceforge.net/Doc/Release/Zsh-Line-Editor.html#Zle-Widgets
35
+ (( ! ${+ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE} )) &&
36
+ typeset -g ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE='fg=8'
37
+
38
+ # Prefix to use when saving original versions of bound widgets
39
+ (( ! ${+ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX} )) &&
40
+ typeset -g ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX=autosuggest-orig-
41
+
42
+ # Strategies to use to fetch a suggestion
43
+ # Will try each strategy in order until a suggestion is returned
44
+ (( ! ${+ZSH_AUTOSUGGEST_STRATEGY} )) && {
45
+ typeset -ga ZSH_AUTOSUGGEST_STRATEGY
46
+ ZSH_AUTOSUGGEST_STRATEGY=(history)
47
+ }
48
+
49
+ # Widgets that clear the suggestion
50
+ (( ! ${+ZSH_AUTOSUGGEST_CLEAR_WIDGETS} )) && {
51
+ typeset -ga ZSH_AUTOSUGGEST_CLEAR_WIDGETS
52
+ ZSH_AUTOSUGGEST_CLEAR_WIDGETS=(
53
+ history-search-forward
54
+ history-search-backward
55
+ history-beginning-search-forward
56
+ history-beginning-search-backward
57
+ history-beginning-search-forward-end
58
+ history-beginning-search-backward-end
59
+ history-substring-search-up
60
+ history-substring-search-down
61
+ up-line-or-beginning-search
62
+ down-line-or-beginning-search
63
+ up-line-or-history
64
+ down-line-or-history
65
+ accept-line
66
+ copy-earlier-word
67
+ )
68
+ }
69
+
70
+ # Widgets that accept the entire suggestion
71
+ (( ! ${+ZSH_AUTOSUGGEST_ACCEPT_WIDGETS} )) && {
72
+ typeset -ga ZSH_AUTOSUGGEST_ACCEPT_WIDGETS
73
+ ZSH_AUTOSUGGEST_ACCEPT_WIDGETS=(
74
+ forward-char
75
+ end-of-line
76
+ vi-forward-char
77
+ vi-end-of-line
78
+ vi-add-eol
79
+ )
80
+ }
81
+
82
+ # Widgets that accept the entire suggestion and execute it
83
+ (( ! ${+ZSH_AUTOSUGGEST_EXECUTE_WIDGETS} )) && {
84
+ typeset -ga ZSH_AUTOSUGGEST_EXECUTE_WIDGETS
85
+ ZSH_AUTOSUGGEST_EXECUTE_WIDGETS=(
86
+ )
87
+ }
88
+
89
+ # Widgets that accept the suggestion as far as the cursor moves
90
+ (( ! ${+ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS} )) && {
91
+ typeset -ga ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS
92
+ ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS=(
93
+ forward-word
94
+ emacs-forward-word
95
+ vi-forward-word
96
+ vi-forward-word-end
97
+ vi-forward-blank-word
98
+ vi-forward-blank-word-end
99
+ vi-find-next-char
100
+ vi-find-next-char-skip
101
+ )
102
+ }
103
+
104
+ # Widgets that should be ignored (globbing supported but must be escaped)
105
+ (( ! ${+ZSH_AUTOSUGGEST_IGNORE_WIDGETS} )) && {
106
+ typeset -ga ZSH_AUTOSUGGEST_IGNORE_WIDGETS
107
+ ZSH_AUTOSUGGEST_IGNORE_WIDGETS=(
108
+ orig-\*
109
+ beep
110
+ run-help
111
+ set-local-history
112
+ which-command
113
+ yank
114
+ yank-pop
115
+ zle-\*
116
+ )
117
+ }
118
+
119
+ # Pty name for capturing completions for completion suggestion strategy
120
+ (( ! ${+ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME} )) &&
121
+ typeset -g ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME=zsh_autosuggest_completion_pty
122
+
123
+ #--------------------------------------------------------------------#
124
+ # Utility Functions #
125
+ #--------------------------------------------------------------------#
126
+
127
+ _zsh_autosuggest_escape_command() {
128
+ setopt localoptions EXTENDED_GLOB
129
+
130
+ # Escape special chars in the string (requires EXTENDED_GLOB)
131
+ echo -E "${1//(#m)[\"\'\\()\[\]|*?~]/\\$MATCH}"
132
+ }
133
+
134
+ #--------------------------------------------------------------------#
135
+ # Widget Helpers #
136
+ #--------------------------------------------------------------------#
137
+
138
+ _zsh_autosuggest_incr_bind_count() {
139
+ typeset -gi bind_count=$((_ZSH_AUTOSUGGEST_BIND_COUNTS[$1]+1))
140
+ _ZSH_AUTOSUGGEST_BIND_COUNTS[$1]=$bind_count
141
+ }
142
+
143
+ # Bind a single widget to an autosuggest widget, saving a reference to the original widget
144
+ _zsh_autosuggest_bind_widget() {
145
+ typeset -gA _ZSH_AUTOSUGGEST_BIND_COUNTS
146
+
147
+ local widget=$1
148
+ local autosuggest_action=$2
149
+ local prefix=$ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX
150
+
151
+ local -i bind_count
152
+
153
+ # Save a reference to the original widget
154
+ case $widgets[$widget] in
155
+ # Already bound
156
+ user:_zsh_autosuggest_(bound|orig)_*)
157
+ bind_count=$((_ZSH_AUTOSUGGEST_BIND_COUNTS[$widget]))
158
+ ;;
159
+
160
+ # User-defined widget
161
+ user:*)
162
+ _zsh_autosuggest_incr_bind_count $widget
163
+ zle -N $prefix$bind_count-$widget ${widgets[$widget]#*:}
164
+ ;;
165
+
166
+ # Built-in widget
167
+ builtin)
168
+ _zsh_autosuggest_incr_bind_count $widget
169
+ eval "_zsh_autosuggest_orig_${(q)widget}() { zle .${(q)widget} }"
170
+ zle -N $prefix$bind_count-$widget _zsh_autosuggest_orig_$widget
171
+ ;;
172
+
173
+ # Completion widget
174
+ completion:*)
175
+ _zsh_autosuggest_incr_bind_count $widget
176
+ eval "zle -C $prefix$bind_count-${(q)widget} ${${(s.:.)widgets[$widget]}[2,3]}"
177
+ ;;
178
+ esac
179
+
180
+ # Pass the original widget's name explicitly into the autosuggest
181
+ # function. Use this passed in widget name to call the original
182
+ # widget instead of relying on the $WIDGET variable being set
183
+ # correctly. $WIDGET cannot be trusted because other plugins call
184
+ # zle without the `-w` flag (e.g. `zle self-insert` instead of
185
+ # `zle self-insert -w`).
186
+ eval "_zsh_autosuggest_bound_${bind_count}_${(q)widget}() {
187
+ _zsh_autosuggest_widget_$autosuggest_action $prefix$bind_count-${(q)widget} \$@
188
+ }"
189
+
190
+ # Create the bound widget
191
+ zle -N -- $widget _zsh_autosuggest_bound_${bind_count}_$widget
192
+ }
193
+
194
+ # Map all configured widgets to the right autosuggest widgets
195
+ _zsh_autosuggest_bind_widgets() {
196
+ emulate -L zsh
197
+
198
+ local widget
199
+ local ignore_widgets
200
+
201
+ ignore_widgets=(
202
+ .\*
203
+ _\*
204
+ ${_ZSH_AUTOSUGGEST_BUILTIN_ACTIONS/#/autosuggest-}
205
+ $ZSH_AUTOSUGGEST_ORIGINAL_WIDGET_PREFIX\*
206
+ $ZSH_AUTOSUGGEST_IGNORE_WIDGETS
207
+ )
208
+
209
+ # Find every widget we might want to bind and bind it appropriately
210
+ for widget in ${${(f)"$(builtin zle -la)"}:#${(j:|:)~ignore_widgets}}; do
211
+ if [[ -n ${ZSH_AUTOSUGGEST_CLEAR_WIDGETS[(r)$widget]} ]]; then
212
+ _zsh_autosuggest_bind_widget $widget clear
213
+ elif [[ -n ${ZSH_AUTOSUGGEST_ACCEPT_WIDGETS[(r)$widget]} ]]; then
214
+ _zsh_autosuggest_bind_widget $widget accept
215
+ elif [[ -n ${ZSH_AUTOSUGGEST_EXECUTE_WIDGETS[(r)$widget]} ]]; then
216
+ _zsh_autosuggest_bind_widget $widget execute
217
+ elif [[ -n ${ZSH_AUTOSUGGEST_PARTIAL_ACCEPT_WIDGETS[(r)$widget]} ]]; then
218
+ _zsh_autosuggest_bind_widget $widget partial_accept
219
+ else
220
+ # Assume any unspecified widget might modify the buffer
221
+ _zsh_autosuggest_bind_widget $widget modify
222
+ fi
223
+ done
224
+ }
225
+
226
+ # Given the name of an original widget and args, invoke it, if it exists
227
+ _zsh_autosuggest_invoke_original_widget() {
228
+ # Do nothing unless called with at least one arg
229
+ (( $# )) || return 0
230
+
231
+ local original_widget_name="$1"
232
+
233
+ shift
234
+
235
+ if (( ${+widgets[$original_widget_name]} )); then
236
+ zle $original_widget_name -- $@
237
+ fi
238
+ }
239
+
240
+ #--------------------------------------------------------------------#
241
+ # Highlighting #
242
+ #--------------------------------------------------------------------#
243
+
244
+ # If there was a highlight, remove it
245
+ _zsh_autosuggest_highlight_reset() {
246
+ typeset -g _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT
247
+
248
+ if [[ -n "$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT" ]]; then
249
+ region_highlight=("${(@)region_highlight:#$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT}")
250
+ unset _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT
251
+ fi
252
+ }
253
+
254
+ # If there's a suggestion, highlight it
255
+ _zsh_autosuggest_highlight_apply() {
256
+ typeset -g _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT
257
+
258
+ if (( $#POSTDISPLAY )); then
259
+ typeset -g _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT="$#BUFFER $(($#BUFFER + $#POSTDISPLAY)) $ZSH_AUTOSUGGEST_HIGHLIGHT_STYLE"
260
+ region_highlight+=("$_ZSH_AUTOSUGGEST_LAST_HIGHLIGHT")
261
+ else
262
+ unset _ZSH_AUTOSUGGEST_LAST_HIGHLIGHT
263
+ fi
264
+ }
265
+
266
+ #--------------------------------------------------------------------#
267
+ # Autosuggest Widget Implementations #
268
+ #--------------------------------------------------------------------#
269
+
270
+ # Disable suggestions
271
+ _zsh_autosuggest_disable() {
272
+ typeset -g _ZSH_AUTOSUGGEST_DISABLED
273
+ _zsh_autosuggest_clear
274
+ }
275
+
276
+ # Enable suggestions
277
+ _zsh_autosuggest_enable() {
278
+ unset _ZSH_AUTOSUGGEST_DISABLED
279
+
280
+ if (( $#BUFFER )); then
281
+ _zsh_autosuggest_fetch
282
+ fi
283
+ }
284
+
285
+ # Toggle suggestions (enable/disable)
286
+ _zsh_autosuggest_toggle() {
287
+ if (( ${+_ZSH_AUTOSUGGEST_DISABLED} )); then
288
+ _zsh_autosuggest_enable
289
+ else
290
+ _zsh_autosuggest_disable
291
+ fi
292
+ }
293
+
294
+ # Clear the suggestion
295
+ _zsh_autosuggest_clear() {
296
+ # Remove the suggestion
297
+ POSTDISPLAY=
298
+
299
+ _zsh_autosuggest_invoke_original_widget $@
300
+ }
301
+
302
+ # Modify the buffer and get a new suggestion
303
+ _zsh_autosuggest_modify() {
304
+ local -i retval
305
+
306
+ # Only available in zsh >= 5.4
307
+ local -i KEYS_QUEUED_COUNT
308
+
309
+ # Save the contents of the buffer/postdisplay
310
+ local orig_buffer="$BUFFER"
311
+ local orig_postdisplay="$POSTDISPLAY"
312
+
313
+ # Clear suggestion while waiting for next one
314
+ POSTDISPLAY=
315
+
316
+ # Original widget may modify the buffer
317
+ _zsh_autosuggest_invoke_original_widget $@
318
+ retval=$?
319
+
320
+ emulate -L zsh
321
+
322
+ # Don't fetch a new suggestion if there's more input to be read immediately
323
+ if (( $PENDING > 0 || $KEYS_QUEUED_COUNT > 0 )); then
324
+ POSTDISPLAY="$orig_postdisplay"
325
+ return $retval
326
+ fi
327
+
328
+ # Optimize if manually typing in the suggestion or if buffer hasn't changed
329
+ if [[ "$BUFFER" = "$orig_buffer"* && "$orig_postdisplay" = "${BUFFER:$#orig_buffer}"* ]]; then
330
+ POSTDISPLAY="${orig_postdisplay:$(($#BUFFER - $#orig_buffer))}"
331
+ return $retval
332
+ fi
333
+
334
+ # Bail out if suggestions are disabled
335
+ if (( ${+_ZSH_AUTOSUGGEST_DISABLED} )); then
336
+ return $?
337
+ fi
338
+
339
+ # Get a new suggestion if the buffer is not empty after modification
340
+ if (( $#BUFFER > 0 )); then
341
+ if [[ -z "$ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE" ]] || (( $#BUFFER <= $ZSH_AUTOSUGGEST_BUFFER_MAX_SIZE )); then
342
+ _zsh_autosuggest_fetch
343
+ fi
344
+ fi
345
+
346
+ return $retval
347
+ }
348
+
349
+ # Fetch a new suggestion based on what's currently in the buffer
350
+ _zsh_autosuggest_fetch() {
351
+ if (( ${+ZSH_AUTOSUGGEST_USE_ASYNC} )); then
352
+ _zsh_autosuggest_async_request "$BUFFER"
353
+ else
354
+ local suggestion
355
+ _zsh_autosuggest_fetch_suggestion "$BUFFER"
356
+ _zsh_autosuggest_suggest "$suggestion"
357
+ fi
358
+ }
359
+
360
+ # Offer a suggestion
361
+ _zsh_autosuggest_suggest() {
362
+ emulate -L zsh
363
+
364
+ local suggestion="$1"
365
+
366
+ if [[ -n "$suggestion" ]] && (( $#BUFFER )); then
367
+ POSTDISPLAY="${suggestion#$BUFFER}"
368
+ else
369
+ POSTDISPLAY=
370
+ fi
371
+ }
372
+
373
+ # Accept the entire suggestion
374
+ _zsh_autosuggest_accept() {
375
+ local -i retval max_cursor_pos=$#BUFFER
376
+
377
+ # When vicmd keymap is active, the cursor can't move all the way
378
+ # to the end of the buffer
379
+ if [[ "$KEYMAP" = "vicmd" ]]; then
380
+ max_cursor_pos=$((max_cursor_pos - 1))
381
+ fi
382
+
383
+ # If we're not in a valid state to accept a suggestion, just run the
384
+ # original widget and bail out
385
+ if (( $CURSOR != $max_cursor_pos || !$#POSTDISPLAY )); then
386
+ _zsh_autosuggest_invoke_original_widget $@
387
+ return
388
+ fi
389
+
390
+ # Only accept if the cursor is at the end of the buffer
391
+ # Add the suggestion to the buffer
392
+ BUFFER="$BUFFER$POSTDISPLAY"
393
+
394
+ # Remove the suggestion
395
+ POSTDISPLAY=
396
+
397
+ # Run the original widget before manually moving the cursor so that the
398
+ # cursor movement doesn't make the widget do something unexpected
399
+ _zsh_autosuggest_invoke_original_widget $@
400
+ retval=$?
401
+
402
+ # Move the cursor to the end of the buffer
403
+ if [[ "$KEYMAP" = "vicmd" ]]; then
404
+ CURSOR=$(($#BUFFER - 1))
405
+ else
406
+ CURSOR=$#BUFFER
407
+ fi
408
+
409
+ return $retval
410
+ }
411
+
412
+ # Accept the entire suggestion and execute it
413
+ _zsh_autosuggest_execute() {
414
+ # Add the suggestion to the buffer
415
+ BUFFER="$BUFFER$POSTDISPLAY"
416
+
417
+ # Remove the suggestion
418
+ POSTDISPLAY=
419
+
420
+ # Call the original `accept-line` to handle syntax highlighting or
421
+ # other potential custom behavior
422
+ _zsh_autosuggest_invoke_original_widget "accept-line"
423
+ }
424
+
425
+ # Partially accept the suggestion
426
+ _zsh_autosuggest_partial_accept() {
427
+ local -i retval cursor_loc
428
+
429
+ # Save the contents of the buffer so we can restore later if needed
430
+ local original_buffer="$BUFFER"
431
+
432
+ # Temporarily accept the suggestion.
433
+ BUFFER="$BUFFER$POSTDISPLAY"
434
+
435
+ # Original widget moves the cursor
436
+ _zsh_autosuggest_invoke_original_widget $@
437
+ retval=$?
438
+
439
+ # Normalize cursor location across vi/emacs modes
440
+ cursor_loc=$CURSOR
441
+ if [[ "$KEYMAP" = "vicmd" ]]; then
442
+ cursor_loc=$((cursor_loc + 1))
443
+ fi
444
+
445
+ # If we've moved past the end of the original buffer
446
+ if (( $cursor_loc > $#original_buffer )); then
447
+ # Set POSTDISPLAY to text right of the cursor
448
+ POSTDISPLAY="${BUFFER[$(($cursor_loc + 1)),$#BUFFER]}"
449
+
450
+ # Clip the buffer at the cursor
451
+ BUFFER="${BUFFER[1,$cursor_loc]}"
452
+ else
453
+ # Restore the original buffer
454
+ BUFFER="$original_buffer"
455
+ fi
456
+
457
+ return $retval
458
+ }
459
+
460
+ () {
461
+ typeset -ga _ZSH_AUTOSUGGEST_BUILTIN_ACTIONS
462
+
463
+ _ZSH_AUTOSUGGEST_BUILTIN_ACTIONS=(
464
+ clear
465
+ fetch
466
+ suggest
467
+ accept
468
+ execute
469
+ enable
470
+ disable
471
+ toggle
472
+ )
473
+
474
+ local action
475
+ for action in $_ZSH_AUTOSUGGEST_BUILTIN_ACTIONS modify partial_accept; do
476
+ eval "_zsh_autosuggest_widget_$action() {
477
+ local -i retval
478
+
479
+ _zsh_autosuggest_highlight_reset
480
+
481
+ _zsh_autosuggest_$action \$@
482
+ retval=\$?
483
+
484
+ _zsh_autosuggest_highlight_apply
485
+
486
+ zle -R
487
+
488
+ return \$retval
489
+ }"
490
+ done
491
+
492
+ for action in $_ZSH_AUTOSUGGEST_BUILTIN_ACTIONS; do
493
+ zle -N autosuggest-$action _zsh_autosuggest_widget_$action
494
+ done
495
+ }
496
+
497
+ #--------------------------------------------------------------------#
498
+ # Completion Suggestion Strategy #
499
+ #--------------------------------------------------------------------#
500
+ # Fetches a suggestion from the completion engine
501
+ #
502
+
503
+ _zsh_autosuggest_capture_postcompletion() {
504
+ # Always insert the first completion into the buffer
505
+ compstate[insert]=1
506
+
507
+ # Don't list completions
508
+ unset 'compstate[list]'
509
+ }
510
+
511
+ _zsh_autosuggest_capture_completion_widget() {
512
+ # Add a post-completion hook to be called after all completions have been
513
+ # gathered. The hook can modify compstate to affect what is done with the
514
+ # gathered completions.
515
+ local -a +h comppostfuncs
516
+ comppostfuncs=(_zsh_autosuggest_capture_postcompletion)
517
+
518
+ # Only capture completions at the end of the buffer
519
+ CURSOR=$#BUFFER
520
+
521
+ # Run the original widget wrapping `.complete-word` so we don't
522
+ # recursively try to fetch suggestions, since our pty is forked
523
+ # after autosuggestions is initialized.
524
+ zle -- ${(k)widgets[(r)completion:.complete-word:_main_complete]}
525
+
526
+ if is-at-least 5.0.3; then
527
+ # Don't do any cr/lf transformations. We need to do this immediately before
528
+ # output because if we do it in setup, onlcr will be re-enabled when we enter
529
+ # vared in the async code path. There is a bug in zpty module in older versions
530
+ # where the tty is not properly attached to the pty slave, resulting in stty
531
+ # getting stopped with a SIGTTOU. See zsh-workers thread 31660 and upstream
532
+ # commit f75904a38
533
+ stty -onlcr -ocrnl -F /dev/tty
534
+ fi
535
+
536
+ # The completion has been added, print the buffer as the suggestion
537
+ echo -nE - $'\0'$BUFFER$'\0'
538
+ }
539
+
540
+ zle -N autosuggest-capture-completion _zsh_autosuggest_capture_completion_widget
541
+
542
+ _zsh_autosuggest_capture_setup() {
543
+ # There is a bug in zpty module in older zsh versions by which a
544
+ # zpty that exits will kill all zpty processes that were forked
545
+ # before it. Here we set up a zsh exit hook to SIGKILL the zpty
546
+ # process immediately, before it has a chance to kill any other
547
+ # zpty processes.
548
+ if ! is-at-least 5.4; then
549
+ zshexit() {
550
+ # The zsh builtin `kill` fails sometimes in older versions
551
+ # https://unix.stackexchange.com/a/477647/156673
552
+ kill -KILL $$ 2>&- || command kill -KILL $$
553
+
554
+ # Block for long enough for the signal to come through
555
+ sleep 1
556
+ }
557
+ fi
558
+
559
+ # Try to avoid any suggestions that wouldn't match the prefix
560
+ zstyle ':completion:*' matcher-list ''
561
+ zstyle ':completion:*' path-completion false
562
+ zstyle ':completion:*' max-errors 0 not-numeric
563
+
564
+ bindkey '^I' autosuggest-capture-completion
565
+ }
566
+
567
+ _zsh_autosuggest_capture_completion_sync() {
568
+ _zsh_autosuggest_capture_setup
569
+
570
+ zle autosuggest-capture-completion
571
+ }
572
+
573
+ _zsh_autosuggest_capture_completion_async() {
574
+ _zsh_autosuggest_capture_setup
575
+
576
+ zmodload zsh/parameter 2>/dev/null || return # For `$functions`
577
+
578
+ # Make vared completion work as if for a normal command line
579
+ # https://stackoverflow.com/a/7057118/154703
580
+ autoload +X _complete
581
+ functions[_original_complete]=$functions[_complete]
582
+ function _complete() {
583
+ unset 'compstate[vared]'
584
+ _original_complete "$@"
585
+ }
586
+
587
+ # Open zle with buffer set so we can capture completions for it
588
+ vared 1
589
+ }
590
+
591
+ _zsh_autosuggest_strategy_completion() {
592
+ # Reset options to defaults and enable LOCAL_OPTIONS
593
+ emulate -L zsh
594
+
595
+ # Enable extended glob for completion ignore pattern
596
+ setopt EXTENDED_GLOB
597
+
598
+ typeset -g suggestion
599
+ local line REPLY
600
+
601
+ # Exit if we don't have completions
602
+ whence compdef >/dev/null || return
603
+
604
+ # Exit if we don't have zpty
605
+ zmodload zsh/zpty 2>/dev/null || return
606
+
607
+ # Exit if our search string matches the ignore pattern
608
+ [[ -n "$ZSH_AUTOSUGGEST_COMPLETION_IGNORE" ]] && [[ "$1" == $~ZSH_AUTOSUGGEST_COMPLETION_IGNORE ]] && return
609
+
610
+ # Zle will be inactive if we are in async mode
611
+ if zle; then
612
+ zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME _zsh_autosuggest_capture_completion_sync
613
+ else
614
+ zpty $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME _zsh_autosuggest_capture_completion_async "\$1"
615
+ zpty -w $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME $'\t'
616
+ fi
617
+
618
+ {
619
+ # The completion result is surrounded by null bytes, so read the
620
+ # content between the first two null bytes.
621
+ zpty -r $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME line '*'$'\0''*'$'\0'
622
+
623
+ # Extract the suggestion from between the null bytes. On older
624
+ # versions of zsh (older than 5.3), we sometimes get extra bytes after
625
+ # the second null byte, so trim those off the end.
626
+ # See http://www.zsh.org/mla/workers/2015/msg03290.html
627
+ suggestion="${${(@0)line}[2]}"
628
+ } always {
629
+ # Destroy the pty
630
+ zpty -d $ZSH_AUTOSUGGEST_COMPLETIONS_PTY_NAME
631
+ }
632
+ }
633
+
634
+ #--------------------------------------------------------------------#
635
+ # History Suggestion Strategy #
636
+ #--------------------------------------------------------------------#
637
+ # Suggests the most recent history item that matches the given
638
+ # prefix.
639
+ #
640
+
641
+ _zsh_autosuggest_strategy_history() {
642
+ # Reset options to defaults and enable LOCAL_OPTIONS
643
+ emulate -L zsh
644
+
645
+ # Enable globbing flags so that we can use (#m) and (x~y) glob operator
646
+ setopt EXTENDED_GLOB
647
+
648
+ # Escape backslashes and all of the glob operators so we can use
649
+ # this string as a pattern to search the $history associative array.
650
+ # - (#m) globbing flag enables setting references for match data
651
+ # TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
652
+ local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
653
+
654
+ # Get the history items that match the prefix, excluding those that match
655
+ # the ignore pattern
656
+ local pattern="$prefix*"
657
+ if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then
658
+ pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)"
659
+ fi
660
+
661
+ # Give the first history item matching the pattern as the suggestion
662
+ # - (r) subscript flag makes the pattern match on values
663
+ typeset -g suggestion="${history[(r)$pattern]}"
664
+ }
665
+
666
+ #--------------------------------------------------------------------#
667
+ # Match Previous Command Suggestion Strategy #
668
+ #--------------------------------------------------------------------#
669
+ # Suggests the most recent history item that matches the given
670
+ # prefix and whose preceding history item also matches the most
671
+ # recently executed command.
672
+ #
673
+ # For example, suppose your history has the following entries:
674
+ # - pwd
675
+ # - ls foo
676
+ # - ls bar
677
+ # - pwd
678
+ #
679
+ # Given the history list above, when you type 'ls', the suggestion
680
+ # will be 'ls foo' rather than 'ls bar' because your most recently
681
+ # executed command (pwd) was previously followed by 'ls foo'.
682
+ #
683
+ # Note that this strategy won't work as expected with ZSH options that don't
684
+ # preserve the history order such as `HIST_IGNORE_ALL_DUPS` or
685
+ # `HIST_EXPIRE_DUPS_FIRST`.
686
+
687
+ _zsh_autosuggest_strategy_match_prev_cmd() {
688
+ # Reset options to defaults and enable LOCAL_OPTIONS
689
+ emulate -L zsh
690
+
691
+ # Enable globbing flags so that we can use (#m) and (x~y) glob operator
692
+ setopt EXTENDED_GLOB
693
+
694
+ # TODO: Use (b) flag when we can drop support for zsh older than v5.0.8
695
+ local prefix="${1//(#m)[\\*?[\]<>()|^~#]/\\$MATCH}"
696
+
697
+ # Get the history items that match the prefix, excluding those that match
698
+ # the ignore pattern
699
+ local pattern="$prefix*"
700
+ if [[ -n $ZSH_AUTOSUGGEST_HISTORY_IGNORE ]]; then
701
+ pattern="($pattern)~($ZSH_AUTOSUGGEST_HISTORY_IGNORE)"
702
+ fi
703
+
704
+ # Get all history event numbers that correspond to history
705
+ # entries that match the pattern
706
+ local history_match_keys
707
+ history_match_keys=(${(k)history[(R)$~pattern]})
708
+
709
+ # By default we use the first history number (most recent history entry)
710
+ local histkey="${history_match_keys[1]}"
711
+
712
+ # Get the previously executed command
713
+ local prev_cmd="$(_zsh_autosuggest_escape_command "${history[$((HISTCMD-1))]}")"
714
+
715
+ # Iterate up to the first 200 history event numbers that match $prefix
716
+ for key in "${(@)history_match_keys[1,200]}"; do
717
+ # Stop if we ran out of history
718
+ [[ $key -gt 1 ]] || break
719
+
720
+ # See if the history entry preceding the suggestion matches the
721
+ # previous command, and use it if it does
722
+ if [[ "${history[$((key - 1))]}" == "$prev_cmd" ]]; then
723
+ histkey="$key"
724
+ break
725
+ fi
726
+ done
727
+
728
+ # Give back the matched history entry
729
+ typeset -g suggestion="$history[$histkey]"
730
+ }
731
+
732
+ #--------------------------------------------------------------------#
733
+ # Fetch Suggestion #
734
+ #--------------------------------------------------------------------#
735
+ # Loops through all specified strategies and returns a suggestion
736
+ # from the first strategy to provide one.
737
+ #
738
+
739
+ _zsh_autosuggest_fetch_suggestion() {
740
+ typeset -g suggestion
741
+ local -a strategies
742
+ local strategy
743
+
744
+ # Ensure we are working with an array
745
+ strategies=(${=ZSH_AUTOSUGGEST_STRATEGY})
746
+
747
+ for strategy in $strategies; do
748
+ # Try to get a suggestion from this strategy
749
+ _zsh_autosuggest_strategy_$strategy "$1"
750
+
751
+ # Ensure the suggestion matches the prefix
752
+ [[ "$suggestion" != "$1"* ]] && unset suggestion
753
+
754
+ # Break once we've found a valid suggestion
755
+ [[ -n "$suggestion" ]] && break
756
+ done
757
+ }
758
+
759
+ #--------------------------------------------------------------------#
760
+ # Async #
761
+ #--------------------------------------------------------------------#
762
+
763
+ _zsh_autosuggest_async_request() {
764
+ zmodload zsh/system 2>/dev/null # For `$sysparams`
765
+
766
+ typeset -g _ZSH_AUTOSUGGEST_ASYNC_FD _ZSH_AUTOSUGGEST_CHILD_PID
767
+
768
+ # If we've got a pending request, cancel it
769
+ if [[ -n "$_ZSH_AUTOSUGGEST_ASYNC_FD" ]] && { true <&$_ZSH_AUTOSUGGEST_ASYNC_FD } 2>/dev/null; then
770
+ # Close the file descriptor and remove the handler
771
+ builtin exec {_ZSH_AUTOSUGGEST_ASYNC_FD}<&-
772
+ zle -F $_ZSH_AUTOSUGGEST_ASYNC_FD
773
+
774
+ # We won't know the pid unless the user has zsh/system module installed
775
+ if [[ -n "$_ZSH_AUTOSUGGEST_CHILD_PID" ]]; then
776
+ # Zsh will make a new process group for the child process only if job
777
+ # control is enabled (MONITOR option)
778
+ if [[ -o MONITOR ]]; then
779
+ # Send the signal to the process group to kill any processes that may
780
+ # have been forked by the suggestion strategy
781
+ kill -TERM -$_ZSH_AUTOSUGGEST_CHILD_PID 2>/dev/null
782
+ else
783
+ # Kill just the child process since it wasn't placed in a new process
784
+ # group. If the suggestion strategy forked any child processes they may
785
+ # be orphaned and left behind.
786
+ kill -TERM $_ZSH_AUTOSUGGEST_CHILD_PID 2>/dev/null
787
+ fi
788
+ fi
789
+ fi
790
+
791
+ # Fork a process to fetch a suggestion and open a pipe to read from it
792
+ builtin exec {_ZSH_AUTOSUGGEST_ASYNC_FD}< <(
793
+ # Tell parent process our pid
794
+ echo $sysparams[pid]
795
+
796
+ # Fetch and print the suggestion
797
+ local suggestion
798
+ _zsh_autosuggest_fetch_suggestion "$1"
799
+ echo -nE "$suggestion"
800
+ )
801
+
802
+ # There's a weird bug here where ^C stops working unless we force a fork
803
+ # See https://github.com/zsh-users/zsh-autosuggestions/issues/364
804
+ autoload -Uz is-at-least
805
+ is-at-least 5.8 || command true
806
+
807
+ # Read the pid from the child process
808
+ read _ZSH_AUTOSUGGEST_CHILD_PID <&$_ZSH_AUTOSUGGEST_ASYNC_FD
809
+
810
+ # When the fd is readable, call the response handler
811
+ zle -F "$_ZSH_AUTOSUGGEST_ASYNC_FD" _zsh_autosuggest_async_response
812
+ }
813
+
814
+ # Called when new data is ready to be read from the pipe
815
+ # First arg will be fd ready for reading
816
+ # Second arg will be passed in case of error
817
+ _zsh_autosuggest_async_response() {
818
+ emulate -L zsh
819
+
820
+ local suggestion
821
+
822
+ if [[ -z "$2" || "$2" == "hup" ]]; then
823
+ # Read everything from the fd and give it as a suggestion
824
+ IFS='' read -rd '' -u $1 suggestion
825
+ zle autosuggest-suggest -- "$suggestion"
826
+
827
+ # Close the fd
828
+ builtin exec {1}<&-
829
+ fi
830
+
831
+ # Always remove the handler
832
+ zle -F "$1"
833
+ _ZSH_AUTOSUGGEST_ASYNC_FD=
834
+ }
835
+
836
+ #--------------------------------------------------------------------#
837
+ # Start #
838
+ #--------------------------------------------------------------------#
839
+
840
+ # Start the autosuggestion widgets
841
+ _zsh_autosuggest_start() {
842
+ # By default we re-bind widgets on every precmd to ensure we wrap other
843
+ # wrappers. Specifically, highlighting breaks if our widgets are wrapped by
844
+ # zsh-syntax-highlighting widgets. This also allows modifications to the
845
+ # widget list variables to take effect on the next precmd. However this has
846
+ # a decent performance hit, so users can set ZSH_AUTOSUGGEST_MANUAL_REBIND
847
+ # to disable the automatic re-binding.
848
+ if (( ${+ZSH_AUTOSUGGEST_MANUAL_REBIND} )); then
849
+ add-zsh-hook -d precmd _zsh_autosuggest_start
850
+ fi
851
+
852
+ _zsh_autosuggest_bind_widgets
853
+ }
854
+
855
+ # Mark for auto-loading the functions that we use
856
+ autoload -Uz add-zsh-hook is-at-least
857
+
858
+ # Automatically enable asynchronous mode in newer versions of zsh. Disable for
859
+ # older versions because there is a bug when using async mode where ^C does not
860
+ # work immediately after fetching a suggestion.
861
+ # See https://github.com/zsh-users/zsh-autosuggestions/issues/364
862
+ if is-at-least 5.0.8; then
863
+ typeset -g ZSH_AUTOSUGGEST_USE_ASYNC=
864
+ fi
865
+
866
+ # Bind keys
867
+ bindkey 'fl' autosuggest-execute
868
+
869
+ # Start the autosuggestion widgets on the next precmd
870
+ add-zsh-hook precmd _zsh_autosuggest_start
871
+