;;; corfu-auto.el --- Auto completion -*- lexical-binding: t -*- ;; Copyright (C) 2021-2026 Free Software Foundation, Inc. ;; Author: Daniel Mendler ;; Maintainer: Daniel Mendler ;; Created: 2022 ;; Version: 2.8 ;; Package-Requires: ((emacs "29.1") (compat "30") (corfu "2.8")) ;; URL: https://github.com/minad/corfu ;; This file is part of GNU Emacs. ;; This program is free software: you can redistribute it and/or modify ;; it under the terms of the GNU General Public License as published by ;; the Free Software Foundation, either version 3 of the License, or ;; (at your option) any later version. ;; This program is distributed in the hope that it will be useful, ;; but WITHOUT ANY WARRANTY; without even the implied warranty of ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ;; GNU General Public License for more details. ;; You should have received a copy of the GNU General Public License ;; along with this program. If not, see . ;;; Commentary: ;; Automatically show the popup if `corfu-auto' is non-nil. ;;; Code: (require 'corfu) (defcustom corfu-auto-trigger "" "Characters which trigger auto completion. If a trigger character is detected `corfu-auto-prefix' is ignored." :type 'string :group 'corfu) (defcustom corfu-auto-prefix 3 "Minimum length of prefix for auto completion. The completion backend can override this with :company-prefix-length. It is not recommended to use a small prefix length (below 2), since this will create high load for Emacs. See also `corfu-auto-delay' and `corfu-auto-trigger'." :type 'natnum :group 'corfu) (defcustom corfu-auto-delay 0.2 "Delay for auto completion. It is not recommended to use a short delay or even 0, since this will create high load for Emacs, in particular if executing the completion backend is costly. Instead of reducing the delay too much, try `corfu-auto-trigger' to trigger immediate completion after certain characters." :type 'float :group 'corfu) (defcustom corfu-auto-commands '("self-insert-command\\'" "delete-backward-char\\'" "\\`backward-delete-char" c-electric-colon c-electric-lt-gt c-electric-slash c-scope-operator) "Commands which initiate auto completion. The list can contain either command symbols or regular expressions." :type '(repeat (choice regexp symbol)) :group 'corfu) (defvar corfu-auto--timer (timer-create) "Auto completion timer.") (defun corfu-auto--complete-deferred (&optional tick) "Initiate auto completion if TICK did not change." (corfu--protect (lambda () (when (and (not completion-in-region-mode) (or (not tick) (equal tick (corfu-auto--tick)))) (pcase (while-no-input ;; Interruptible Capf query (run-hook-wrapped 'completion-at-point-functions #'corfu--capf-wrapper (unless (seq-contains-p corfu-auto-trigger last-command-event) corfu-auto-prefix))) (`(,fun ,beg ,end ,table . ,plist) (pcase-let* ((completion-in-region-mode-predicate (lambda () (when-let* ((newbeg (car-safe (funcall fun)))) (= newbeg beg)))) (completion-extra-properties plist) (pred (plist-get plist :predicate)) (state (plist-get plist :corfu--state)) (`(,str . ,pt) (alist-get 'corfu--input state)) (cands (alist-get 'corfu--candidates state))) ;; Bail out immediately for exactly matching candidates ;; if no further completion is possible. (when (or (eq corfu-on-exact-match 'show) (not (equal cands (list str))) (consp (corfu--try-completion str table pred pt))) (corfu--setup beg end table pred) (corfu--exhibit))))))))) (defun corfu-auto--post-command () "Post command hook which initiates auto completion." (corfu--protect (lambda () (cancel-timer corfu-auto--timer) (when (and (not completion-in-region-mode) (not defining-kbd-macro) (not buffer-read-only) (corfu--match-symbol-p corfu-auto-commands this-command) (corfu--popup-support-p)) (if (or (<= corfu-auto-delay 0) (seq-contains-p corfu-auto-trigger last-command-event)) (corfu-auto--complete-deferred) ;; Do not use `timer-set-idle-time' since this leads to ;; unpredictable pauses, in particular with `flyspell-mode'. (timer-set-time corfu-auto--timer (timer-relative-time nil corfu-auto-delay)) (timer-set-function corfu-auto--timer #'corfu-auto--complete-deferred (list (corfu-auto--tick))) (timer-activate corfu-auto--timer)))))) (defun corfu-auto--tick () "Return the current tick/status of the buffer. Auto completion is only performed if the tick did not change." (list (selected-window) (current-buffer) (buffer-chars-modified-tick) (point))) (provide 'corfu-auto) ;;; corfu-auto.el ends here