From ca68e0cdee8071ca46684b2eb0818878d4a0494b Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Mon, 30 Oct 2023 14:36:19 -0400 Subject: [PATCH] feat(corfu): more CAPFs and ergonomy changes Add CAPFs from cape: - `cape-dabbrev`; - `cape-elisp-block`; - `cape-file`; Fix some CAPFs via cape: - Make non-exclusive, purified and silent `pcomplete-completions-at-point`; - Make non-exclusive and non-interruptable `lsp-completion-at-point`; - Make non-exclusive `eglot-completion-at-point`; - Make non-exclusive `comint-completion-at-point`; Fix and improve keybindings: - Smart `DEL`; Add depth to CAPFs, allowing ordering to be adjustable. --- modules/completion/corfu/README.org | 21 +++++++++++++++++++-- modules/completion/corfu/config.el | 22 +++++++++++++++++++++- modules/config/default/config.el | 10 +++++++++- 3 files changed, 49 insertions(+), 4 deletions(-) diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org index 74c8043d5..252423567 100644 --- a/modules/completion/corfu/README.org +++ b/modules/completion/corfu/README.org @@ -26,6 +26,9 @@ utilities for fine-tuning. Only some of common behaviors are documented here. - +orderless :: Pull in [[doom-package:orderless]] if necessary and apply multi-component completion (still needed if [[doom-module::completion vertico]] is active). +- +dabbrev :: + Enable and configure [[doom-package:dabbrev]] as a close-to-universal CAPF + fallback. ** Packages - [[doom-package:corfu]] @@ -190,15 +193,18 @@ A few variables may be set to change behavior of this module: Enables commiting with [[RET]] when the popup is visible. Default is ~t~, may be set to ~'minibuffer~ if you want to commit both the completion and the minibuffer when active. When ~nil~, it is always passed-through. +- [[var:+corfu-buffer-scanning-size-limit]] :: + Sets the maximum buffer size to be scanned by ~cape-dabbrev~. Defaults to 1 MB. + Set this if you are having performance problems using the CAPF. ** Adding CAPFs to a mode To add other CAPFs on a mode-per-mode basis, put either of the following in your ~config.el~: #+begin_src emacs-lisp -(add-hook! some-mode (add-to-list 'completion-at-point-functions #'some-capf)) +(add-hook! some-mode (add-hook 'completion-at-point-functions #'some-capf depth t)) ;; OR, but note the different call signature -(add-hook 'some-mode-hook (lambda () (add-to-list 'completion-at-point-functions #'some-capf))) +(add-hook 'some-mode-hook (lambda () (add-hook 'completion-at-point-functions #'some-capf depth t))) #+end_src ~DEPTH~ above is an integer between -100, 100, and defaults to 0 if nil. Also @@ -221,6 +227,17 @@ all CAPFs are interactive to be called this way, in which case you can use * Troubleshooting [[doom-report:][Report an issue?]] +If you have performance issues with ~cape-dabbrev~, the first thing I recommend +doing is to look at the list of buffers Dabbrev is scanning: + +#+begin_src emacs-lisp +(dabbrev--select-buffers) ; => (# #> # ...) +(length (dabbrev--select-buffers)) ; => 37 +#+end_src + +... and modify ~dabbrev-ignored-buffer-regexps~ or ~dabbrev-ignored-buffer-modes~ +accordingly. + * Frequently asked questions /This module has no FAQs yet./ [[doom-suggest-faq:][Ask one?]] diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index 6ad3fe349..ae2e8409a 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -8,6 +8,9 @@ Possible values are: and immediatelly exit if in the minibuffer; - nil: Pass-through without inserting.") +(defvar +corfu-buffer-scanning-size-limit (* 1 1024 1024) ; 1 MB + "Size limit for a buffer to be scanned by `cape-dabbrev'.") + ;; ;;; Packages (use-package! corfu @@ -50,10 +53,27 @@ Possible values are: :init (add-hook! prog-mode (defun +corfu-add-cape-file-h () - (add-to-list 'completion-at-point-functions #'cape-file))) + (add-hook 'completion-at-point-functions #'cape-file -10 t))) (add-hook! (org-mode markdown-mode) (defun +corfu-add-cape-elisp-block-h () (add-hook 'completion-at-point-functions #'cape-elisp-block 0 t))) + ;; Enable Dabbrev completion basically everywhere as a fallback. + (when (modulep! +dabbrev) + (setq cape-dabbrev-check-other-buffers t) + ;; Set up `cape-dabbrev' options. + (defun +dabbrev-friend-buffer-p (other-buffer) + (< (buffer-size other-buffer) +corfu-buffer-scanning-size-limit)) + (add-hook! (prog-mode text-mode conf-mode comint-mode minibuffer-setup + eshell-mode) + (defun +corfu-add-cape-dabbrev-h () + (add-hook 'completion-at-point-functions #'cape-dabbrev 20 t))) + (after! dabbrev + (setq dabbrev-friend-buffer-function #'+dabbrev-friend-buffer-p + dabbrev-ignored-buffer-regexps + '("^ " + "\\(TAGS\\|tags\\|ETAGS\\|etags\\|GTAGS\\|GRTAGS\\|GPATH\\)\\(<[0-9]+>\\)?") + dabbrev-upcase-means-case-search t) + (add-to-list 'dabbrev-ignored-buffer-modes 'pdf-view-mode))) ;; Make these capfs composable. (advice-add #'lsp-completion-at-point :around #'cape-wrap-noninterruptible) diff --git a/modules/config/default/config.el b/modules/config/default/config.el index 8316284d8..e3becc12a 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -468,7 +468,13 @@ Continues comments if executed from a commented line. Consults [backtab] #'corfu-previous "TAB" #'corfu-next [tab] #'corfu-next)) - (let ((cmds-ret + (let ((cmds-del + `(menu-item "Reset completion" corfu-reset + :filter ,(lambda (cmd) + (when (and (>= corfu--index 0) + (eq corfu-preview-current 'insert)) + cmd)))) + (cmds-ret `(menu-item "Insert completion DWIM" corfu-insert :filter ,(lambda (cmd) (interactive) @@ -488,6 +494,8 @@ Continues comments if executed from a commented line. Consults (t cmd)))))) (map! :when (modulep! :completion corfu) :map corfu-map + [backspace] cmds-del + "DEL" cmds-del :gi [return] cmds-ret :gi "RET" cmds-ret))