1 ;;; capf-autosuggest.el --- History autosuggestions for comint and eshell -*- lexical-binding: t; -*-
3 ;; Copyright (C) 2021 Free Software Foundation, Inc.
5 ;; Filename: capf-autosuggest.el
6 ;; Author: jakanakaevangeli <jakanakaevangeli@chiru.no>
9 ;; Package-Requires: ((emacs "25.1"))
10 ;; URL: https://repo.or.cz/emacs-capf-autosuggest.git
12 ;; This file is part of GNU Emacs.
14 ;; This program is free software: you can redistribute it and/or modify
15 ;; it under the terms of the GNU General Public License as published by
16 ;; the Free Software Foundation, either version 3 of the License, or
17 ;; (at your option) any later version.
19 ;; This program is distributed in the hope that it will be useful,
20 ;; but WITHOUT ANY WARRANTY; without even the implied warranty of
21 ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
22 ;; GNU General Public License for more details.
24 ;; You should have received a copy of the GNU General Public License
25 ;; along with this program. If not, see <http://www.gnu.org/licenses/>.
29 ;; capf-autosuggest lets you preview the most recent matching history element,
30 ;; similar to zsh-autosuggestions or fish. It works in eshell and in modes
31 ;; derived from comint-mode, for example M-x shell and M-x run-python.
33 ;; As you type, the history auto-suggestion is shown as an overlay after point.
34 ;; Type [C-e] to insert text from this overlay or [M-f] to only insert a word
35 ;; from this overlay. [C-n] is a shorthand for [C-e] followed by [RET]: it
36 ;; inserts text from the overlay and sends it to the process.
40 ;; To install capf-autosuggest, type
41 ;; M-x package-install RET capf-autosuggest RET.
43 ;; Enable it with M-x capf-autosuggest-mode. It is best to add the following
44 ;; elisp snippet to your Emacs init file to enable `capf-autosuggest-mode'
45 ;; automatically for every comint and eshell buffer:
47 ;; (add-hook 'comint-mode-hook #'capf-autosuggest-mode)
48 ;; (add-hook 'eshell-mode-hook #'capf-autosuggest-mode)
52 ;; Use `capf-autosuggest-define-partial-accept-cmd' to make a command that can
53 ;; move point into an auto-suggested overlay.
55 ;; Example: to make [C-M-f] (forward-sexp) movable into suggested text, put the
56 ;; following into your Emacs init file:
58 ;; (with-eval-after-load 'capf-autosuggest
59 ;; (capf-autosuggest-define-partial-accept-cmd
60 ;; movable-forward-sexp forward-sexp)
61 ;; (define-key capf-autosuggest-active-mode-map
62 ;; [remap forward-sexp] #'movable-forward-sexp))
64 ;; By default, [C-n] (next-line) will accept the currently displayed suggestion
65 ;; and send input to shell/eshell. To disable this behaviour or enable it for
66 ;; other commands such as [C-c C-n] or [M-n], see the customization group
71 ;; capf-autosuggest provides a minor mode, capf-autosuggest-mode, that lets you
72 ;; preview the first completion candidate for in-buffer completion as an
73 ;; overlay. Instead of using the default hook `completion-at-point-functions',
74 ;; it uses its own hook `capf-autosuggest-capf-functions'. However, by
75 ;; default, this hook contains a function that reads the default hook, but only
76 ;; if point is at end of line, because an auto-suggested overlay can be
77 ;; annoying in the middle of a line. If you want, you can try enabling this
78 ;; minor mode in an ordinary buffer for previewing tab completion candidates at
81 ;; A completion-at-point function for comint and eshell history is also
82 ;; provided. Because it is less useful for tab completion and more useful for
83 ;; auto-suggestion preview, it is a member of
84 ;; `capf-autosuggest-capf-functions', which doesn't interfere with tab
85 ;; completion. By default, if there are no matches for history completion and
86 ;; point is at end of line, we fall back to previewing the default tab
87 ;; completion candidates, as described in the previous paragraph.
89 ;; You can customize this behaviour by customizing
90 ;; `capf-autosuggest-capf-functions'. For example, you could add
91 ;; `capf-autosuggest-orig-capf' to enable auto-suggestions of tab completion
92 ;; candidates in the middle of a line.
96 ;; There is also esh-autosuggest[1] with similar functionality. Differences:
97 ;; it is simpler and more concise, however it depends on company. It optionally
98 ;; allows having a delay and it is implemented only for eshell.
100 ;; [1]: http://github.com/dieggsy/esh-autosuggest
102 ;;;; Bugs, suggestions and patches can be sent to
104 ;; bugs-doseganje (at) groups.io
106 ;; and can be viewed at https://groups.io/g/bugs-doseganje/topics. As this
107 ;; package is stored in GNU ELPA, non-trivial patches require copyright
108 ;; assignment to the FSF, see info node "(emacs) Copyright Assignment".
117 (defvar comint-input-ring
)
118 (defvar comint-accum-marker
)
119 (defvar comint-use-prompt-regexp
)
120 (defvar eshell-history-ring
)
121 (defvar eshell-last-output-end
)
122 (declare-function eshell-bol
"esh-mode")
123 (declare-function comint-previous-matching-input-from-input
"comint")
124 (declare-function comint-after-pmark-p
"comint")
125 (declare-function comint-send-input
"comint")
126 (declare-function eshell-previous-matching-input-from-input
"em-hist")
127 (declare-function eshell-send-input
"esh-mode")
128 (declare-function eshell-interactive-process
"esh-cmd")
129 (declare-function eshell-next-prompt
"em-prompt")
130 (declare-function eshell-next-input
"em-hist")
131 (declare-function eshell-next-matching-input-from-input
"em-hist")
133 (defgroup capf-autosuggest nil
134 "Show completion at point as an overlay."
136 :prefix
"capf-autosuggest-"
138 '(url-link "https://github.com/jakanakaevangeli/emacs-capf-autosuggest"))
140 ;;; Auto-suggestion overlay
142 (defface capf-autosuggest-face
'((t :inherit file-name-shadow
))
143 "Face used for auto suggestions.")
145 (defvar capf-autosuggest-capf-functions
146 '(capf-autosuggest-history-capf capf-autosuggest-orig-if-at-eol-capf
)
147 "`completion-at-point-functions', used by capf-autosuggest.
148 It is used instead of the standard
149 `completion-at-point-functions', but the default value contains
150 `capf-autosuggest-orig-if-at-eol-capf' which searches the
151 standard capf functions, if point is at the end of line.")
153 (defvar-local capf-autosuggest--overlay nil
)
154 (defvar-local capf-autosuggest--str
"")
155 (defvar-local capf-autosuggest--tick nil
)
156 (defvar-local capf-autosuggest--region
'(nil)
157 "Region of `completion-at-point'.")
159 (defun capf-autosuggest-orig-capf (&optional capf-functions
)
160 "A capf that chooses from hook variable CAPF-FUNCTIONS.
161 CAPF-FUNCTIONS defaults to `completion-at-point-functions'.
162 Don't add this function to `completion-at-point-functions', as it
163 will result in an infinite loop. It is usually added to
164 `capf-autosuggest-capf-functions', making it search the standard
166 (cdr (run-hook-wrapped (or capf-functions
'completion-at-point-functions
)
167 #'completion--capf-wrapper
'all
)))
169 (defun capf-autosuggest-orig-if-at-eol-capf ()
170 "`capf-autosuggest-orig-capf' if at the end of line.
171 Otherwise, return nil."
173 (capf-autosuggest-orig-capf)))
175 (defvar capf-autosuggest-active-mode
)
177 (defun capf-autosuggest--post-h ()
178 "Create an auto-suggest overlay."
179 (when capf-autosuggest-active-mode
180 ;; `identity' is used to generate slightly faster byte-code
181 (pcase-let ((`(,beg .
,end
) (identity capf-autosuggest--region
)))
182 (unless (and (< beg
(point) end
)
183 (eq (buffer-modified-tick) capf-autosuggest--tick
))
184 (capf-autosuggest-active-mode -
1))))
186 (unless capf-autosuggest-active-mode
187 (pcase (let* ((catch-sym (make-symbol "cirf-catch"))
188 ;; `pcomplete-completions-at-point' may illegally use
189 ;; `completion-in-region' itself instead of returning a
190 ;; collection. Let's try to outsmart it.
191 (completion-in-region-function
192 (lambda (start end collection predicate
)
194 (list start end collection
:predicate predicate
))))
197 ;; With `corfu-mode' enabled, `completion--capf-wrapper' is
198 ;; advised to use completion styles instead of simple prefix
199 ;; completion for non-:exclusive criteria, making it more
200 ;; accurate, but also quite slower. In our case, we are only
201 ;; interested in prefix matching and speed, so we enable only
202 ;; the simple and fast `emacs21' prefix matching completion
204 (completion-styles '(emacs21))
205 (completion-category-overrides nil
))
209 ;; `ielm-complete-filename' may illegaly move point
211 (capf-autosuggest-orig-capf
212 'capf-autosuggest-capf-functions
))))
213 ((buffer-read-only quit
) t
)))
214 (`(,beg
,end
,table .
,plist
)
215 (let* ((pred (plist-get plist
:predicate
))
216 (string (buffer-substring-no-properties beg end
))
217 ;; See `completion-emacs21-all-completions'
218 (base (car (completion-boundaries string table pred
""))))
220 ;; Use `all-completions' rather than `completion-all-completions'
221 ;; to bypass completion styles and strictly match only on prefix.
222 ;; This makes sense here as we only use the string without the
223 ;; prefix for the overlay.
224 ((completions (all-completions string table pred
))
225 ;; `all-completions' may return strings that don't strictly
226 ;; match on our prefix. Ignore them.
227 ((string-prefix-p (substring string base
) (car completions
)))
228 (str (substring (car completions
) (- end beg base
)))
231 (setq capf-autosuggest--region
(cons beg end
)
232 capf-autosuggest--str
(copy-sequence str
)
233 capf-autosuggest--tick
(buffer-modified-tick))
234 (move-overlay capf-autosuggest--overlay end end
)
235 ;; Make sure the overlay after-string doesn't start or end with a
236 ;; newline, otherwise it can behave badly with cursor placement
237 (when (eq ?
\n (aref str
0))
238 (setq str
(concat " " str
))
240 (when (eq ?
\n (aref str
(1- len
)))
241 (setq str
(concat str
(propertize " " 'display
"")))
243 (put-text-property 0 1 'cursor len str
)
244 (put-text-property 0 len
'face
'capf-autosuggest-face str
)
245 (overlay-put capf-autosuggest--overlay
'after-string str
)
246 (capf-autosuggest-active-mode)))))))
249 (define-minor-mode capf-autosuggest-mode
250 "Auto-suggest first completion at point with an overlay."
251 :group
'capf-autosuggest
252 (if capf-autosuggest-mode
254 (when capf-autosuggest--overlay
255 (capf-autosuggest-active-mode-deactivate))
256 (setq capf-autosuggest--overlay
(make-overlay (point) (point) nil t t
))
257 (add-hook 'post-command-hook
#'capf-autosuggest--post-h nil t
)
258 (add-hook 'change-major-mode-hook
259 #'capf-autosuggest-active-mode-deactivate nil t
))
260 (remove-hook 'change-major-mode-hook
261 #'capf-autosuggest-active-mode-deactivate t
)
262 (remove-hook 'post-command-hook
#'capf-autosuggest--post-h t
)
263 (capf-autosuggest-active-mode -
1)))
265 ;;; Various commands and menu-items
268 (defmacro capf-autosuggest-define-partial-accept-cmd
(name command
)
269 "Define a command NAME.
270 It will call COMMAND interactively, allowing it to move point
271 into an auto-suggested overlay. COMMAND must not modify buffer.
272 NAME must not be called if variable
273 `capf-autosuggest-active-mode' is inactive. NAME is suitable for
274 binding in `capf-autosuggest-active-mode-map'."
276 "`%s', possibly moving point into an auto-suggested overlay."
278 (unless (< (length doc
) 80)
280 Execute command, possibly moving point into an auto-suggested overlay.
282 and make it possible for this command to enter an auo-suggested overlay."
287 (capf-autosuggest-call-partial-accept-cmd #',command
))))
289 (defun capf-autosuggest-call-partial-accept-cmd (command)
290 "Call COMMAND interactively, stepping into auto-suggested overlay.
291 Temporarily convert the overlay to buffer text and call COMMAND
292 interactively. Afterwards, the added text is deleted, but only
293 the portion after point. Additionally, if point is outside of
294 the added text, the whole text is deleted."
296 (setq beg
(overlay-start capf-autosuggest--overlay
))
297 (capf-autosuggest-active-mode -
1)
298 (with-silent-modifications
299 (catch 'cancel-atomic-change
303 (insert-and-inherit capf-autosuggest--str
)
305 (call-interactively command
)
308 (setq text
(buffer-substring beg
(point))))
309 (throw 'cancel-atomic-change nil
))))
317 (declare-function evil-forward-char
"ext:evil-commands" nil t
)
318 (declare-function evil-end-of-line
"ext:evil-commands" nil t
)
319 (declare-function evil-end-of-visual-line
"ext:evil-commands" nil t
)
320 (declare-function evil-end-of-line-or-visual-line
"ext:evil-commands" nil t
)
321 (declare-function evil-middle-of-visual-line
"ext:evil-commands" nil t
)
322 (declare-function evil-last-non-blank
"ext:evil-commands" nil t
)
323 (declare-function evil-forward-word-begin
"ext:evil-commands" nil t
)
324 (declare-function evil-forward-word-end
"ext:evil-commands" nil t
)
325 (declare-function evil-forward-WORD-begin
"ext:evil-commands" nil t
)
326 (declare-function evil-forward-WORD-end
"ext:evil-commands" nil t
)
328 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-forward-word forward-word
)
329 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-forward-char forward-char
)
330 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-forward-sexp forward-sexp
)
331 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-end-of-line end-of-line
)
332 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-move-end-of-line move-end-of-line
)
333 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-end-of-visual-line end-of-visual-line
)
334 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-forward-char evil-forward-char
)
335 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-end-of-line evil-end-of-line
)
336 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-end-of-visual-line evil-end-of-visual-line
)
337 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-end-of-line-or-visual-line evil-end-of-line-or-visual-line
)
338 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-middle-of-visual-line evil-middle-of-visual-line
)
339 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-last-non-blank evil-last-non-blank
)
340 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-forward-word-begin evil-forward-word-begin
)
341 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-forward-word-end evil-forward-word-end
)
342 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-forward-WORD-begin evil-forward-WORD-begin
)
343 (capf-autosuggest-define-partial-accept-cmd capf-autosuggest-evil-forward-WORD-end evil-forward-WORD-end
)
345 (defun capf-autosuggest-accept ()
346 "Accept current auto-suggestion.
347 Do not call this command if variable `capf-autosuggest-active-mode' is
350 (when capf-autosuggest-active-mode
351 (goto-char (overlay-start capf-autosuggest--overlay
))
352 (insert-and-inherit capf-autosuggest--str
)))
354 (defun capf-autosuggest-comint-previous-matching-input-from-input (n)
355 "Like `comint-previous-matching-input-from-input'.
356 If N is positive, the command isn't repeated and point is at
357 auto-suggested overlay, increase argument N by 1. This is done
358 in order to skip the history element already shown by the overlay."
360 (and (not (memq last-command
'(comint-previous-matching-input-from-input
361 comint-next-matching-input-from-input
)))
363 (= (point) (overlay-start capf-autosuggest--overlay
))
365 (comint-previous-matching-input-from-input n
)
366 (setq this-command
#'comint-previous-matching-input-from-input
))
368 (defun capf-autosuggest-eshell-previous-matching-input-from-input (n)
369 "Like `eshell-previous-matching-input-from-input'.
370 If N is positive, the command isn't repeated and point is at
371 auto-suggested overlay, increase argument N by 1. This is done
372 in order to skip the history element already shown by the overlay."
374 (and (not (memq last-command
'(eshell-previous-matching-input-from-input
375 eshell-next-matching-input-from-input
)))
377 (= (point) (overlay-start capf-autosuggest--overlay
))
379 (eshell-previous-matching-input-from-input n
)
380 (setq this-command
#'eshell-previous-matching-input-from-input
))
382 (defcustom capf-autosuggest-dwim-next-line t
383 "Whether `next-line' can accept and send current suggestion.
384 If t and point is on last line, `next-line' will accept the
385 current suggestion and send it to the process as input."
387 (defcustom capf-autosuggest-dwim-next-prompt nil
388 "Whether next-prompt commands can send current suggestion.
389 If t and point is after the last prompt, `comint-next-prompt' and
390 `eshell-next-prompt' will accept the current suggestion and send
391 it to the process as input."
393 (defcustom capf-autosuggest-dwim-next-input nil
394 "Whether next-input commands can send current suggestion.
395 If t and previous command wasn't a history command
396 \(next/previous-input or
397 previous/next-matching-input-from-input), `comint-next-input' and
398 `eshell-next-input' will accept the current suggestion and send
399 it to the process as input."
401 (defcustom capf-autosuggest-dwim-next-matching-input-from-input nil
402 "Whether next-input commands can send current suggestion.
403 If t and previous command wasn't a history matching command
404 \(previous or next-matching-input-from-input),
405 `comint-next-matching-input-from-input' and
406 `eshell-next-matching-input-from-input' will accept the current
407 suggestion and send it to the process as input."
410 (defun capf-autosuggest--accept-and-remapping (cmd)
411 "Return a command that will accept input and run CMD."
412 ;; Avoid infinite recursion when searching for the command remapping
413 (let ((capf-autosuggest-active-mode nil
))
414 (setq cmd
(or (command-remapping cmd
) cmd
)))
417 (capf-autosuggest-accept)
420 (setq this-command cmd
)
421 (call-interactively cmd
)))
423 (defvar capf-autosuggest-active-mode-map
424 (let ((map (make-sparse-keymap)))
425 (define-key map
[remap forward-word
] #'capf-autosuggest-forward-word
)
426 (define-key map
[remap forward-char
] #'capf-autosuggest-forward-char
)
427 (define-key map
[remap forward-sexp
] #'capf-autosuggest-forward-sexp
)
428 (define-key map
[remap end-of-line
] #'capf-autosuggest-end-of-line
)
429 (define-key map
[remap move-end-of-line
] #'capf-autosuggest-move-end-of-line
)
430 (define-key map
[remap end-of-visual-line
] #'capf-autosuggest-end-of-visual-line
)
432 (define-key map
[remap evil-forward-char
] #'capf-autosuggest-evil-forward-char
)
433 (define-key map
[remap evil-end-of-line
] #'capf-autosuggest-evil-end-of-line
)
434 (define-key map
[remap evil-end-of-visual-line
] #'capf-autosuggest-evil-end-of-visual-line
)
435 (define-key map
[remap evil-end-of-line-or-visual-line
] #'capf-autosuggest-evil-end-of-line-or-visual-line
)
436 (define-key map
[remap evil-middle-of-visual-line
] #'capf-autosuggest-evil-middle-of-visual-line
)
437 (define-key map
[remap evil-last-non-blank
] #'capf-autosuggest-evil-last-non-blank
)
438 (define-key map
[remap evil-forward-word-begin
] #'capf-autosuggest-evil-forward-word-begin
)
439 (define-key map
[remap evil-forward-word-end
] #'capf-autosuggest-evil-forward-word-end
)
440 (define-key map
[remap evil-forward-WORD-begin
] #'capf-autosuggest-evil-forward-WORD-begin
)
441 (define-key map
[remap evil-forward-WORD-end
] #'capf-autosuggest-evil-forward-WORD-end
)
443 (define-key map
[remap eshell-previous-matching-input-from-input
]
444 #'capf-autosuggest-eshell-previous-matching-input-from-input
)
445 (define-key map
[remap comint-previous-matching-input-from-input
]
446 #'capf-autosuggest-comint-previous-matching-input-from-input
)
448 (define-key map
[remap next-line
]
449 (list 'menu-item
"" nil
:filter
451 (and capf-autosuggest-dwim-next-line
452 (looking-at-p "[^\n]*\n?\\'")
455 ((derived-mode-p 'comint-mode
) #'comint-send-input
)
456 ((derived-mode-p 'eshell-mode
) #'eshell-send-input
)
457 ((minibufferp) #'exit-minibuffer
)))
458 (capf-autosuggest--accept-and-remapping cmd
)))))
459 (define-key map
[remap comint-next-prompt
]
460 (list 'menu-item
"" #'comint-send-input
:filter
462 (and capf-autosuggest-dwim-next-prompt
463 (comint-after-pmark-p)
464 (capf-autosuggest--accept-and-remapping cmd
)))))
465 (define-key map
[remap eshell-next-prompt
]
466 (list 'menu-item
"" #'eshell-send-input
:filter
468 (and capf-autosuggest-dwim-next-prompt
469 (>= (point) eshell-last-output-end
)
470 (capf-autosuggest--accept-and-remapping cmd
)))))
471 (define-key map
[remap comint-next-input
]
472 (list 'menu-item
"" #'comint-send-input
:filter
474 (and capf-autosuggest-dwim-next-input
475 (not (memq last-command
476 '(comint-next-matching-input-from-input
477 comint-previous-matching-input-from-input
478 comint-next-input comint-previous-input
)))
479 (capf-autosuggest--accept-and-remapping cmd
)))))
480 (define-key map
[remap eshell-next-input
]
481 (list 'menu-item
"" #'eshell-send-input
:filter
483 (and capf-autosuggest-dwim-next-input
484 (not (memq last-command
485 '(eshell-next-matching-input-from-input
486 eshell-previous-matching-input-from-input
487 eshell-next-input eshell-previous-input
)))
488 (capf-autosuggest--accept-and-remapping cmd
)))))
489 (define-key map
[remap comint-next-matching-input-from-input
]
490 (list 'menu-item
"" #'comint-send-input
:filter
492 (and capf-autosuggest-dwim-next-matching-input-from-input
493 (not (memq last-command
494 '(comint-next-matching-input-from-input
495 comint-previous-matching-input-from-input
)))
496 (capf-autosuggest--accept-and-remapping cmd
)))))
497 (define-key map
[remap eshell-next-matching-input-from-input
]
498 (list 'menu-item
"" #'eshell-send-input
:filter
500 (and capf-autosuggest-dwim-next-matching-input-from-input
501 (not (memq last-command
502 '(eshell-previous-matching-input-from-input
503 eshell-next-matching-input-from-input
)))
504 (capf-autosuggest--accept-and-remapping cmd
)))))
506 "Keymap active when an auto-suggestion is shown.")
508 (define-minor-mode capf-autosuggest-active-mode
509 "Active when auto-suggested overlay is shown."
510 :group
'capf-autosuggest
511 (unless capf-autosuggest-active-mode
512 (delete-overlay capf-autosuggest--overlay
)))
514 (defun capf-autosuggest-active-mode-deactivate ()
515 "Deactivate `capf-autosuggest-active-mode'."
516 (capf-autosuggest-active-mode -
1))
518 ;;; History completion functions
521 (defun capf-autosuggest-history-capf ()
522 "Completion-at-point function for history.
523 Supports `comint-mode', `eshell-mode' and the minibuffer. In
524 comint end eshell, it is applicable only if point is after the
527 This function is useful for inclusion in
528 `capf-autosuggest-capf-functions'."
530 ((derived-mode-p 'comint-mode
)
531 (capf-autosuggest-comint-capf))
532 ((derived-mode-p 'eshell-mode
)
533 (capf-autosuggest-eshell-capf))
535 (capf-autosuggest-minibuffer-capf))))
537 (defun capf-autosuggest-comint-capf ()
538 "Completion-at-point function for comint input history.
539 Is only applicable if point is after the last prompt."
540 (let ((ring comint-input-ring
)
542 (or (and (setq beg comint-accum-marker
)
543 (setq beg
(marker-position beg
)))
544 (and (setq beg
(get-buffer-process (current-buffer)))
545 (setq beg
(marker-position (process-mark beg
)))))
547 ;; Return nil to allow possible further capf functions
549 ((< (point) beg
) nil
)
550 ((<= (setq end
(if comint-use-prompt-regexp
554 ;; Return non-nil but empty completion table to block possible further
556 (list (point) (point) nil
))
557 ((and (ring-p ring
) (not (ring-empty-p ring
)))
558 (list beg end
(capf-autosuggest--completion-table ring
)
561 (defun capf-autosuggest-eshell-capf ()
562 "Completion-at-point function for eshell input history.
563 Is only applicable if point is after the last prompt."
564 (let ((ring eshell-history-ring
)
565 (beg (save-excursion (eshell-bol) (point)))
568 ((< (point) eshell-last-output-end
) nil
)
569 ((< (point) beg
) nil
)
570 ((and (= end beg
) (eshell-interactive-process))
571 (list (point) (point) nil
))
572 ((and (ring-p ring
) (not (ring-empty-p ring
)))
573 (list beg end
(capf-autosuggest--completion-table ring
)
576 (defun capf-autosuggest--completion-table (ring)
577 "Return a completion table to complete on RING."
578 (let ((ring-elems t
))
579 (lambda (input predicate action
)
580 (when (eq ring-elems t
)
581 (setq ring-elems
(ring-elements ring
)))
582 (complete-with-action action ring-elems input predicate
))))
584 (defun capf-autosuggest-minibuffer-capf ()
585 "Completion-at-point function for minibuffer history."
586 (let ((hist minibuffer-history-variable
)
588 (when (and (not (eq t hist
))
589 (setq hist
(symbol-value hist
)))
590 (when (eq minibuffer-history-sexp-flag
(minibuffer-depth))
591 (setq should-prin1 t
))
592 (list (minibuffer-prompt-end)
595 (lambda (input predicate action
)
597 (setq hist
(mapcar #'prin1-to-string hist
)
599 (complete-with-action action hist input predicate
))
603 (provide 'capf-autosuggest
)
604 ;;; capf-autosuggest.el ends here