1 ;;; capf-autosuggest.el --- History autosuggestions for comint and eshell -*- lexical-binding: t; -*-
3 ;; Filename: capf-autosuggest.el
4 ;; Description: History autosuggestions for comint and eshell
5 ;; Author: jakanakaevangeli <jakanakaevangeli@chiru.no>
8 ;; URL: https://github.com/jakanakaevangeli/emacs-capf-autosuggest
10 ;; This file is not part of GNU Emacs.
12 ;; This program is free software: you can redistribute it and/or modify
13 ;; it under the terms of the GNU General Public License as published by
14 ;; the Free Software Foundation, either version 3 of the License, or
15 ;; (at your option) any later version.
17 ;; This program is distributed in the hope that it will be useful,
18 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
19 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
20 ;; GNU General Public License for more details.
22 ;; You should have received a copy of the GNU General Public License
23 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
27 ;; capf-autosuggest lets you preview the most recent matching history element,
28 ;; similar to zsh-autosuggestions or fish. It works in eshell and in modes
29 ;; derived from comint-mode, for example M-x shell and M-x run-python.
33 ;; Add the following to your Emacs init file:
35 ;; (add-to-list 'load-path "/path/to/emacs-capf-autosuggest")
36 ;; (require 'capf-autosuggest)
37 ;; (add-hook 'comint-mode-hook #'capf-autosuggest-setup-comint)
38 ;; (add-hook 'eshell-mode-hook #'capf-autosuggest-setup-eshell)
42 ;; Use `capf-autosuggest-define-partial-accept-cmd' to make a command that can
43 ;; move point into an auto-suggested layer.
45 ;; Example: to make C-M-f (forward-sexp) movable into suggested text, put the
46 ;; following into you init file:
48 ;; (with-eval-after-load 'capf-autosuggest
49 ;; (capf-autosuggest-define-partial-accept-cmd
50 ;; movable-forward-sexp forward-sexp)
51 ;; (define-key capf-autosuggest-active-mode-map [remap forward-sexp]
52 ;; #'movable-forward-sexp))
54 ;; By default, C-n (next-line) will accept the currently displayed suggestion
55 ;; and send input to shell/eshell. See the customization group
56 ;; capf-autosuggest do disable this behaviour or enable it for other commands,
57 ;; such as C-c C-n or M-n.
61 ;; capf-autosuggest provides a minor mode, capf-autosuggest-mode, that lets you
62 ;; preview the first completion candidate for in-buffer completion as an
63 ;; overlay. Instead of using the default hook `completion-at-point-functions',
64 ;; it uses its own hook `capf-autosuggest-capf-functions'. However, by
65 ;; default, this hook contains a function that reads the default hook, but only
66 ;; if point is at end of line, because an auto-suggested overlay can be
67 ;; annoying in the middle of a line. If you want, you can try enabling this
68 ;; minor mode in an ordinary buffer for previewing tab completion candidates at
71 ;; completion-at-point functions for comint and eshell history are also
72 ;; provided. Because they are less useful for tab completion and more useful
73 ;; for auto-suggestion preview, they should be added to
74 ;; `capf-autosuggest-capf-functions', which doesn't interfere with tab
75 ;; completion. The setup functions mentioned in "Installation" paragraph add
76 ;; them to this hook locally. By default, if there are no matches for history
77 ;; completion and point is at end of line, we fall back to previewing the
78 ;; default tab completion candidates, as described in the previous paragraph.
80 ;; You can customize this behaviour by customizing
81 ;; `capf-autosuggest-capf-functions'. For example, you could add
82 ;; `capf-autosuggest-orig-capf' to enable auto-suggestions of tab completion
83 ;; candidates in the middle of a line.
87 ;; There is also esh-autosuggest[1] with similar functionality. Differences:
88 ;; it is simpler and more concise, however it depends on company. It optionally
89 ;; allows having a delay and it is implemented only for eshell.
91 ;; [1]: http://github.com/dieggsy/esh-autosuggest
100 (defvar comint-input-ring
)
101 (defvar comint-accum-marker
)
102 (defvar comint-use-prompt-regexp
)
103 (defvar eshell-history-ring
)
104 (defvar eshell-last-output-end
)
105 (declare-function eshell-bol
"esh-mode")
106 (declare-function comint-previous-matching-input-from-input
"comint")
107 (declare-function eshell-previous-matching-input-from-input
"em-hist")
108 (declare-function eshell-send-input
"esh-mode")
109 (declare-function eshell-interactive-process
"esh-cmd")
110 (declare-function eshell-next-prompt
"em-prompt")
111 (declare-function eshell-next-input
"em-hist")
112 (declare-function eshell-next-matching-input-from-input
"em-hist")
114 (defgroup capf-autosuggest nil
115 "Show completion-at-point as an overlay."
117 :prefix
"capf-autosuggest-"
119 '(url-link "https://github.com/jakanakaevangeli/emacs-capf-autosuggest"))
121 ;;; Auto-suggestion overlay
123 (defface capf-autosuggest-face
'((t :inherit file-name-shadow
))
124 "Face used for auto suggestions.")
126 (defvar capf-autosuggest-capf-functions
'(capf-autosuggest-orig-if-at-eol-capf)
127 "`completion-at-point-functions', used by capf-autosuggest.
128 It is used instead of the standard
129 `completion-at-point-functions', but the default value contains
130 `capf-autosuggest-orig-if-at-eol-capf' which searches the
131 standard capf functions, if point is at the end of line.")
133 (defvar capf-autosuggest-all-completions-only-one nil
134 "Non-nil if only the first result of `all-completions' is of interest.
135 capf-autosuggest binds this to t around calls to
136 `all-completions'. A dynamic completion table can take this as a
137 hint to only return a list of one element for optimization.")
139 (defvar-local capf-autosuggest--overlay nil
)
140 (defvar-local capf-autosuggest--str
"")
141 (defvar-local capf-autosuggest--tick nil
)
142 (defvar-local capf-autosuggest--region
'(nil)
143 "Region of `completion-at-point'.")
145 (defun capf-autosuggest-orig-capf (&optional capf-functions
)
146 "A capf that chooses from hook variable CAPF-FUNCTIONS.
147 CAPF-FUNCTIONS defaults to `completion-at-point-functions'.
148 Don't add this function to `completion-at-point-functions', as
149 this will result in an infinite loop. Useful for adding to
150 `capf-autosuggest-capf-functions', making it search the standard
152 (cdr (run-hook-wrapped (or capf-functions
'completion-at-point-functions
)
153 #'completion--capf-wrapper
'all
)))
155 (defun capf-autosuggest-orig-if-at-eol-capf ()
156 "`capf-autosuggest-orig-capf' if at the end of line.
157 Otherwise, return nil."
159 (capf-autosuggest-orig-capf)))
161 (defvar capf-autosuggest-active-mode
)
163 (defun capf-autosuggest--post-h ()
164 "Create an auto-suggest overlay."
165 (when capf-autosuggest-active-mode
166 ;; `identity' is used to generate slightly faster byte-code
167 (pcase-let ((`(,beg .
,end
) (identity capf-autosuggest--region
)))
168 (unless (and (< beg
(point) end
)
169 (eq (buffer-modified-tick) capf-autosuggest--tick
))
170 (capf-autosuggest-active-mode -
1))))
172 (unless capf-autosuggest-active-mode
173 (pcase (let* ((catch-sym (make-symbol "cirf-catch"))
174 ;; `pcomplete-completions-at-point' may illegally use
175 ;; `completion-in-region' itself instead of returning a
176 ;; collection. Let's try to outsmart it.
177 (completion-in-region-function
178 (lambda (start end collection predicate
)
180 (list start end collection
:predicate predicate
))))
181 (buffer-read-only t
))
184 (capf-autosuggest-orig-capf 'capf-autosuggest-capf-functions
))
185 (buffer-read-only t
)))
186 (`(,beg
,end
,table .
,plist
)
187 (let* ((pred (plist-get plist
:predicate
))
188 (string (buffer-substring-no-properties beg end
))
189 ;; See `completion-emacs21-all-completions'
190 (base (car (completion-boundaries string table pred
""))))
193 (let ((capf-autosuggest-all-completions-only-one t
))
194 ;; Use `all-completions' rather than
195 ;; `completion-all-completions' to bypass completion styles
196 ;; and strictly match only on prefix. This makes sense here
197 ;; as we only use the string without the prefix for the
199 (all-completions string table pred
)))
200 ;; `all-completions' may return strings that don't strictly
201 ;; match on our prefix. Ignore them.
202 ((string-prefix-p (substring string base
) (car completions
)))
203 (str (substring (car completions
) (- end beg base
)))
206 (setq capf-autosuggest--region
(cons beg end
)
207 capf-autosuggest--str
(copy-sequence str
)
208 capf-autosuggest--tick
(buffer-modified-tick))
209 (move-overlay capf-autosuggest--overlay end end
)
210 ;; Make sure the overlay after-string doesn't start or end with a
211 ;; newline, otherwise it can behave badly with cursor placement
212 (when (eq ?
\n (aref str
0))
213 (setq str
(concat " " str
))
215 (when (eq ?
\n (aref str
(1- len
)))
216 (setq str
(concat str
(propertize " " 'display
"")))
218 (put-text-property 0 1 'cursor len str
)
219 (put-text-property 0 len
'face
'capf-autosuggest-face str
)
220 (overlay-put capf-autosuggest--overlay
'after-string str
)
221 (capf-autosuggest-active-mode)))))))
224 (define-minor-mode capf-autosuggest-mode
225 "Auto-suggest first completion at point with an overlay."
226 :group
'capf-autosuggest
227 (if capf-autosuggest-mode
229 (setq capf-autosuggest--overlay
(make-overlay (point) (point) nil t t
))
230 (add-hook 'post-command-hook
#'capf-autosuggest--post-h nil t
)
231 (add-hook 'change-major-mode-hook
232 #'capf-autosuggest-active-mode-deactivate nil t
))
233 (remove-hook 'change-major-mode-hook
234 #'capf-autosuggest-active-mode-deactivate t
)
235 (remove-hook 'post-command-hook
#'capf-autosuggest--post-h t
)
236 (capf-autosuggest-active-mode -
1)))
238 ;;; Various commands and menu-items
241 (defmacro capf-autosuggest-define-partial-accept-cmd
(name command
)
242 "Define a command NAME.
243 It will call COMMAND interactively, allowing it to move point
244 into an auto-suggested overlay. COMMAND must not modify buffer.
245 NAME must not be called if variable
246 `capf-autosuggest-active-mode' is inactive. NAME is suitable for
247 binding in `capf-autosuggest-active-mode-map'."
249 ,(format "`%s', possibly moving point into an auto-suggested overlay."
252 (capf-autosuggest-call-partial-accept-cmd #',command
)))
254 (defun capf-autosuggest-call-partial-accept-cmd (command)
255 "Call COMMAND interactively, stepping into auto-suggested overlay.
256 Temporarily convert the overlay to buffer text and call COMMAND
257 interactively. Afterwards, the added text is deleted, but only
258 the portion after point. Additionally, if point is outside of
259 the added text, the whole text is deleted."
261 (with-silent-modifications
262 (catch 'cancel-atomic-change
265 (goto-char (overlay-start capf-autosuggest--overlay
))
267 (insert-and-inherit capf-autosuggest--str
)
269 (call-interactively command
)
272 (setq text
(buffer-substring beg
(point))))
273 (throw 'cancel-atomic-change nil
))))
281 (declare-function evil-forward-char
"ext:evil-commands" nil t
)
282 (declare-function evil-end-of-line
"ext:evil-commands" nil t
)
283 (declare-function evil-end-of-visual-line
"ext:evil-commands" nil t
)
284 (declare-function evil-end-of-line-or-visual-line
"ext:evil-commands" nil t
)
285 (declare-function evil-middle-of-visual-line
"ext:evil-commands" nil t
)
286 (declare-function evil-last-non-blank
"ext:evil-commands" nil t
)
287 (declare-function evil-forward-word-begin
"ext:evil-commands" nil t
)
288 (declare-function evil-forward-word-end
"ext:evil-commands" nil t
)
289 (declare-function evil-forward-WORD-begin
"ext:evil-commands" nil t
)
290 (declare-function evil-forward-WORD-end
"ext:evil-commands" nil t
)
292 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-forward-word forward-word
)
293 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-forward-char forward-char
)
294 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-forward-sexp forward-sexp
)
295 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-end-of-line end-of-line
)
296 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-move-end-of-line move-end-of-line
)
297 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-end-of-visual-line end-of-visual-line
)
298 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-forward-char evil-forward-char
)
299 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-end-of-line evil-end-of-line
)
300 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-end-of-visual-line evil-end-of-visual-line
)
301 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-end-of-line-or-visual-line evil-end-of-line-or-visual-line
)
302 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-middle-of-visual-line evil-middle-of-visual-line
)
303 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-last-non-blank evil-last-non-blank
)
304 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-forward-word-begin evil-forward-word-begin
)
305 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-forward-word-end evil-forward-word-end
)
306 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-forward-WORD-begin evil-forward-WORD-begin
)
307 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-forward-WORD-end evil-forward-WORD-end
)
309 (defun capf-autosuggest-accept ()
310 "Accept current auto-suggestion.
311 Do not call this command if variable `capf-autosuggest-active-mode' is
314 (capf-autosuggest-call-partial-accept-cmd
317 (goto-char (overlay-start capf-autosuggest--overlay
)))))
319 (defun capf-autosuggest-comint-previous-matching-input-from-input (n)
320 "Like `comint-previous-matching-input-from-input'.
321 If N is positive, the command isn't repeated and point is at
322 auto-suggested overlay, increase argument N by 1. This is done
323 in order to skip the history element already shown by the overlay."
325 (and (not (memq last-command
'(comint-previous-matching-input-from-input
326 comint-next-matching-input-from-input
)))
328 (= (point) (overlay-start capf-autosuggest--overlay
))
330 (comint-previous-matching-input-from-input n
)
331 (setq this-command
#'comint-previous-matching-input-from-input
))
333 (defun capf-autosuggest-eshell-previous-matching-input-from-input (n)
334 "Like `eshell-previous-matching-input-from-input'.
335 If N is positive, the command isn't repeated and point is at
336 auto-suggested overlay, increase argument N by 1. This is done
337 in order to skip the history element already shown by the overlay."
339 (and (not (memq last-command
'(eshell-previous-matching-input-from-input
340 eshell-next-matching-input-from-input
)))
342 (= (point) (overlay-start capf-autosuggest--overlay
))
344 (eshell-previous-matching-input-from-input n
)
345 (setq this-command
#'eshell-previous-matching-input-from-input
))
347 (defun capf-autosuggest-comint-send-input ()
348 "`capf-autosuggest-accept' and `comint-send-input'."
350 (capf-autosuggest-accept)
351 (call-interactively (or (command-remapping #'comint-send-input
)
352 #'comint-send-input
))
353 (setq this-command
#'comint-send-input
))
355 (defun capf-autosuggest-eshell-send-input ()
356 "`capf-autosuggest-accept' and `eshell-send-input'."
358 (capf-autosuggest-accept)
359 (call-interactively (or (command-remapping #'eshell-send-input
)
360 #'eshell-send-input
))
361 (setq this-command
#'eshell-send-input
))
363 (defun capf-autosuggest-minibuffer-send-input ()
364 "`capf-autosuggest-accept' and `exit-minibuffer'."
366 (capf-autosuggest-accept)
367 (call-interactively (or (command-remapping #'exit-minibuffer
)
369 (setq this-command
#'exit-minibuffer
))
371 (defcustom capf-autosuggest-dwim-next-line t
372 "Whether `next-line' can accept and send current suggestion.
373 If t and point is on last line, `next-line' will accept the
374 current suggestion and send input."
376 (defcustom capf-autosuggest-dwim-next-prompt nil
377 "Whether next-prompt commands can send current suggestion.
378 If t and point is after the last prompt, `comint-next-prompt' and
379 `eshell-next-prompt' will accept the current suggestion and send
382 (defcustom capf-autosuggest-dwim-next-input nil
383 "Whether next-input commands can send current suggestion.
384 If t and previous command wasn't a history command
385 (next/previous-input or previous/next-matching-input-from-input),
386 `comint-next-input' and `eshell-next-input' will accept the
387 current suggestion and send input."
389 (defcustom capf-autosuggest-dwim-next-matching-input-from-input nil
390 "Whether next-input commands can send current suggestion.
391 If t and previous command wasn't a history matching command
392 (previous or next-matching-input-from-input),
393 `comint-next-matching-input-from-input' and
394 `eshell-next-matching-input-from-input' will accept the current
395 suggestion and send input."
398 (defvar capf-autosuggest-active-mode-map
399 (let ((map (make-sparse-keymap)))
400 (define-key map
[remap forward-word
] #'capf-autosuggest-forward-word
)
401 (define-key map
[remap forward-char
] #'capf-autosuggest-forward-char
)
402 (define-key map
[remap forward-sexp
] #'capf-autosuggest-forward-sexp
)
403 (define-key map
[remap end-of-line
] #'capf-autosuggest-end-of-line
)
404 (define-key map
[remap move-end-of-line
] #'capf-autosuggest-move-end-of-line
)
405 (define-key map
[remap end-of-visual-line
] #'capf-autosuggest-end-of-visual-line
)
407 (define-key map
[remap evil-forward-char
] #'capf-autosuggest-evil-forward-char
)
408 (define-key map
[remap evil-end-of-line
] #'capf-autosuggest-evil-end-of-line
)
409 (define-key map
[remap evil-end-of-visual-line
] #'capf-autosuggest-evil-end-of-visual-line
)
410 (define-key map
[remap evil-end-of-line-or-visual-line
] #'capf-autosuggest-evil-end-of-line-or-visual-line
)
411 (define-key map
[remap evil-middle-of-visual-line
] #'capf-autosuggest-evil-middle-of-visual-line
)
412 (define-key map
[remap evil-last-non-blank
] #'capf-autosuggest-evil-last-non-blank
)
413 (define-key map
[remap evil-forward-word-begin
] #'capf-autosuggest-evil-forward-word-begin
)
414 (define-key map
[remap evil-forward-word-end
] #'capf-autosuggest-evil-forward-word-end
)
415 (define-key map
[remap evil-forward-WORD-begin
] #'capf-autosuggest-evil-forward-WORD-begin
)
416 (define-key map
[remap evil-forward-WORD-end
] #'capf-autosuggest-evil-forward-WORD-end
)
418 (define-key map
[remap eshell-previous-matching-input-from-input
]
419 #'capf-autosuggest-eshell-previous-matching-input-from-input
)
420 (define-key map
[remap comint-previous-matching-input-from-input
]
421 #'capf-autosuggest-comint-previous-matching-input-from-input
)
423 (define-key map
[remap next-line
]
424 (list 'menu-item
"" #'next-line
:filter
426 (if (and capf-autosuggest-dwim-next-line
427 (looking-at-p "[^\n]*\n?\\'"))
429 ((derived-mode-p 'comint-mode
) #'capf-autosuggest-comint-send-input
)
430 ((derived-mode-p 'eshell-mode
) #'capf-autosuggest-eshell-send-input
)
431 ((minibufferp) #'capf-autosuggest-minibuffer-send-input
)
434 (define-key map
[remap comint-next-prompt
]
435 (list 'menu-item
"" #'comint-next-prompt
:filter
437 (if (and capf-autosuggest-dwim-next-prompt
438 (comint-after-pmark-p))
439 #'capf-autosuggest-comint-send-input
441 (define-key map
[remap eshell-next-prompt
]
442 (list 'menu-item
"" #'eshell-next-prompt
:filter
444 (if (and capf-autosuggest-dwim-next-prompt
445 (>= (point) eshell-last-output-end
))
446 #'capf-autosuggest-comint-send-input
448 (define-key map
[remap comint-next-input
]
449 (list 'menu-item
"" #'comint-next-input
:filter
451 (if (or (not capf-autosuggest-dwim-next-input
)
453 '(comint-next-matching-input-from-input
454 comint-previous-matching-input-from-input
455 comint-next-input comint-previous-input
)))
457 #'capf-autosuggest-comint-send-input
))))
458 (define-key map
[remap eshell-next-input
]
459 (list 'menu-item
"" #'eshell-next-input
:filter
461 (if (or (not capf-autosuggest-dwim-next-input
)
463 '(eshell-next-matching-input-from-input
464 eshell-previous-matching-input-from-input
465 eshell-next-input eshell-previous-input
)))
467 #'capf-autosuggest-eshell-send-input
))))
468 (define-key map
[remap comint-next-matching-input-from-input
]
469 (list 'menu-item
"" #'comint-next-matching-input-from-input
:filter
471 (if (or (not capf-autosuggest-dwim-next-matching-input-from-input
)
473 '(comint-next-matching-input-from-input
474 comint-previous-matching-input-from-input
)))
476 #'capf-autosuggest-comint-send-input
))))
477 (define-key map
[remap eshell-next-matching-input-from-input
]
478 (list 'menu-item
"" #'eshell-next-matching-input-from-input
:filter
480 (if (or (not capf-autosuggest-dwim-next-matching-input-from-input
)
482 '(eshell-previous-matching-input-from-input
483 eshell-next-matching-input-from-input
)))
485 #'capf-autosuggest-eshell-send-input
))))
487 "Keymap active when an auto-suggestion is shown.")
489 (define-minor-mode capf-autosuggest-active-mode
490 "Active when auto-suggested overlay is shown."
491 :group
'capf-autosuggest
492 (unless capf-autosuggest-active-mode
493 (delete-overlay capf-autosuggest--overlay
)))
495 (defun capf-autosuggest-active-mode-deactivate ()
496 "Deactivate `capf-autosuggest-active-mode'."
497 (capf-autosuggest-active-mode -
1))
499 ;;;; History completion function
502 (defun capf-autosuggest-comint-capf ()
503 "Completion-at-point function for comint input history.
504 Is only applicable if point is after the last prompt."
505 (let ((ring comint-input-ring
)
507 (or (and (setq beg comint-accum-marker
)
508 (setq beg
(marker-position beg
)))
509 (and (setq beg
(get-buffer-process (current-buffer)))
510 (setq beg
(marker-position (process-mark beg
)))))
512 ;; Return nil to allow possible further capf functions
514 ((< (point) beg
) nil
)
515 ((<= (setq end
(if comint-use-prompt-regexp
519 ;; Return non-nil but empty completion table to block possible further
521 (list (point) (point) nil
))
522 ((and (ring-p ring
) (not (ring-empty-p ring
)))
523 (list beg end
(capf-autosuggest--completion-table ring
)
526 (defun capf-autosuggest-eshell-capf ()
527 "Completion-at-point function for eshell input history.
528 Is only applicable if point is after the last prompt."
529 (let ((ring eshell-history-ring
)
530 (beg (save-excursion (eshell-bol) (point)))
533 ((< (point) eshell-last-output-end
) nil
)
534 ((< (point) beg
) nil
)
535 ((and (= end beg
) (eshell-interactive-process))
536 (list (point) (point) nil
))
537 ((and (ring-p ring
) (not (ring-empty-p ring
)))
538 (list beg end
(capf-autosuggest--completion-table ring
)
541 (defun capf-autosuggest--completion-table (ring)
542 "Return a completion table to complete on RING."
546 (lambda (input predicate action
)
550 with only-one
= capf-autosuggest-all-completions-only-one
551 with regexps
= completion-regexp-list
552 for i below
(ring-size ring
)
553 for elem
= (ring-ref ring i
)
554 if
(string-prefix-p input elem
)
555 if
(cl-loop for regex in regexps
556 always
(string-match-p regex elem
))
557 if
(or (null predicate
)
558 (funcall predicate elem
))
563 (complete-with-action
564 nil
(let ((capf-autosuggest-all-completions-only-one nil
))
565 (funcall self input predicate t
))
568 (and (ring-member ring input
)
570 (funcall predicate input
))
571 (cl-loop for regex in completion-regexp-list
572 always
(string-match-p regex input
))))
573 (t (complete-with-action
574 action
(ring-elements ring
) input predicate
)))))))
577 (defun capf-autosuggest-setup-comint ()
578 "Setup capf-autosuggest for history suggestion in comint."
579 (capf-autosuggest-mode)
580 (add-hook 'capf-autosuggest-capf-functions
#'capf-autosuggest-comint-capf nil t
))
583 (defun capf-autosuggest-setup-eshell ()
584 "Setup capf-autosuggest for history suggestion in eshell."
585 (capf-autosuggest-mode)
586 (add-hook 'capf-autosuggest-capf-functions
#'capf-autosuggest-eshell-capf nil t
))
589 (defun capf-autosuggest-setup-minibuffer ()
590 "Setup capf-autosuggest for history suggestion in the minibuffer."
591 (let ((hist minibuffer-history-variable
)
593 (when (and (not (eq t hist
))
594 (setq hist
(symbol-value hist
)))
595 (when (eq minibuffer-history-sexp-flag
(minibuffer-depth))
596 (setq should-prin1 t
))
597 (capf-autosuggest-mode)
598 (add-hook 'capf-autosuggest-capf-functions
601 (setq hist
(mapcar #'prin1-to-string hist
)
603 (list (minibuffer-prompt-end)
609 (provide 'capf-autosuggest
)
610 ;;; capf-autosuggest.el ends here