From 7018cb45fbd4019214b4ee1a046ce94c4cb5e6ae Mon Sep 17 00:00:00 2001 From: Dev380 <49997896+Dev380@users.noreply.github.com> Date: Sat, 9 Mar 2024 21:54:06 -0800 Subject: [PATCH 01/49] fix(vertico): disable minor mode highlight duly Minor mode highlights did not disable as long as the mode was enabled. Amend: #7706 --- modules/completion/vertico/config.el | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modules/completion/vertico/config.el b/modules/completion/vertico/config.el index 89f30a5c1..0d52ab950 100644 --- a/modules/completion/vertico/config.el +++ b/modules/completion/vertico/config.el @@ -371,7 +371,8 @@ orderless." (if (or (eq sym major-mode) (and (memq sym minor-mode-list) - (boundp sym))) + (boundp sym) + (symbol-value sym))) (add-face-text-property 0 (length cmd) 'font-lock-constant-face 'append cmd))) cmd)) From aad8ec1895714f4fec6abfe444c9a69b4ee8f308 Mon Sep 17 00:00:00 2001 From: minh Date: Sun, 10 Mar 2024 11:52:34 +0700 Subject: [PATCH 02/49] feat(java): java.el takes java-ts-mode into account allow +java-current-package and +java-current-class functions to operate on java-ts-mode (the java tree-sitter mode) not just java-mode. --- modules/lang/java/autoload/java.el | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/modules/lang/java/autoload/java.el b/modules/lang/java/autoload/java.el index ed0ebddcd..82fc4a7f1 100644 --- a/modules/lang/java/autoload/java.el +++ b/modules/lang/java/autoload/java.el @@ -44,8 +44,9 @@ It does this by ignoring everything before the nearest package root (see root)." (cond ((doom-special-buffer-p (current-buffer)) "{PackageName}") - ((not (eq major-mode 'java-mode)) - (user-error "Not in java-mode")) + ((and (not (eq major-mode 'java-mode)) + (not (eq major-mode 'java-ts-mode)) + (user-error "Not in java-mode or java-ts-mode"))) ((when-let (project-root (doom-project-root)) (let* ((project-root (file-truename project-root)) (file-path @@ -73,8 +74,9 @@ root)." "Get the class name for the current file." (cond ((doom-special-buffer-p (current-buffer)) "{ClassName}") - ((not (eq major-mode 'java-mode)) - (user-error "Not in java-mode")) + ((and (not (eq major-mode 'java-mode)) + (not (eq major-mode 'java-ts-mode)) + (user-error "Not in java-mode or java-ts-mode"))) (buffer-file-name (file-name-sans-extension (file-name-base (buffer-file-name)))) ((user-error "Can't deduce the class name")))) From 79429ecc562893b77be257013f8150eb51005cc1 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 5 Mar 2024 02:29:18 -0500 Subject: [PATCH 03/49] fix(nim): swap nimfmt with nimpretty Nim 2.x+ comes with its own formatter (nimpretty). Close: #7578 Co-authored-by: pietrangelo --- modules/lang/nim/README.org | 4 ++-- modules/lang/nim/config.el | 2 +- modules/lang/nim/doctor.el | 5 ++--- 3 files changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/lang/nim/README.org b/modules/lang/nim/README.org index 166e0f6da..774d38a60 100644 --- a/modules/lang/nim/README.org +++ b/modules/lang/nim/README.org @@ -52,8 +52,8 @@ Alternatively, nim is usually available through your OS's package manager: - openSUSE: ~$ zypper install nim~ ** Formatter - -Formatting is handled using the [[doom-module::editor format]] module via [[https://github.com/FedericoCeratto/nimfmt#installation][nimfmt]]. +Formatting is handled using the [[doom-module::editor format]] module via nimpretty +(included with Nim). * TODO Usage #+begin_quote diff --git a/modules/lang/nim/config.el b/modules/lang/nim/config.el index ddaf986f3..231f29262 100644 --- a/modules/lang/nim/config.el +++ b/modules/lang/nim/config.el @@ -12,7 +12,7 @@ nimsuggest isn't installed." (when (and nimsuggest-path (file-executable-p nimsuggest-path)) (nimsuggest-mode)))) - (set-formatter! 'nmfmt '("nimfmt" filepath) :modes '(nim-mode)) + (set-formatter! 'nmfmt '("nimpretty" filepath) :modes '(nim-mode)) (when (featurep :system 'windows) ;; TODO File PR/report upstream (https://github.com/nim-lang/nim-mode) diff --git a/modules/lang/nim/doctor.el b/modules/lang/nim/doctor.el index 32980d7ed..f9927b6b6 100644 --- a/modules/lang/nim/doctor.el +++ b/modules/lang/nim/doctor.el @@ -1,4 +1,3 @@ - ;;; lang/nim/doctor.el (unless (executable-find "nimsuggest") @@ -8,5 +7,5 @@ (warn! "Could not find nim executable; build commands will be disabled.")) (when (modulep! :editor format) - (unless (executable-find "nimfmt") - (warn! "Could not find nimfmt. Formatting will be disabled."))) + (unless (executable-find "nimpretty") + (warn! "Could not find nimpretty. Formatting will be disabled."))) From d4434887281f87be8a6aefdc50a7360df4571328 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 5 Mar 2024 02:31:00 -0500 Subject: [PATCH 04/49] bump: :lang nim nim-lang/nim-mode@1338e5b0d5e1 -> nim-lang/nim-mode@625cc023bd75 --- modules/lang/nim/packages.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/lang/nim/packages.el b/modules/lang/nim/packages.el index 30993cbcc..0f4d4c71f 100644 --- a/modules/lang/nim/packages.el +++ b/modules/lang/nim/packages.el @@ -3,7 +3,7 @@ ;;; requires nim nimsuggest nimble -(package! nim-mode :pin "1338e5b0d5e111ad932efb77d3cad680cc3b86c9") +(package! nim-mode :pin "625cc023bd75a741b7d4e629e5bec3a52f45b4be") (when (and (modulep! :checkers syntax) (not (modulep! :checkers syntax +flymake))) From 2bce9dbc1ad1e84641625a8d7d794f9644d58b21 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 5 Mar 2024 15:57:31 -0500 Subject: [PATCH 05/49] fix: doom-incremental-first-idle-timer: type error when nil If the user uses the doom-load-packages-incrementally function directly, and has set doom-incremental-first-idle-timer set to nil, it will throw a type error. Close: #7710 --- lisp/doom-start.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/lisp/doom-start.el b/lisp/doom-start.el index 5a68dd036..e52624bcf 100644 --- a/lisp/doom-start.el +++ b/lisp/doom-start.el @@ -199,7 +199,7 @@ in daemon sessions (they are loaded immediately at startup).") (defvar doom-incremental-first-idle-timer (if (daemonp) 0 2.0) "How long (in idle seconds) until incremental loading starts. -Set this to nil to disable incremental loading. +Set this to nil to disable incremental loading at startup. Set this to 0 to load all incrementally deferred packages immediately at `emacs-startup-hook'.") @@ -222,7 +222,7 @@ intervals." (condition-case-unless-debug e (and (or (null (setq idle-time (current-idle-time))) - (< (float-time idle-time) doom-incremental-first-idle-timer) + (< (float-time idle-time) (or doom-incremental-first-idle-timer 0.0)) (not (while-no-input (doom-log "start:iloader: Loading %s (%d left)" req (length packages)) From f1c1efe420afffdec8557dd7bf0e1782158bfc12 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Wed, 6 Mar 2024 00:26:17 -0500 Subject: [PATCH 06/49] refactor(biblio): move 3rd party modes to use-package blocks This makes load-order more predictable for users wanting to modify the side-effects of citar-org-roam-mode or citar-embark-mode. I.e. (after! citar-org-roam ...) (after! citar-embark ...) Instead of: (after! (citar org-roam) ...) (after! (citar embark) ...) Ref: #7712 Co-authored-by: hpfr --- modules/tools/biblio/config.el | 20 ++++++++++++++------ 1 file changed, 14 insertions(+), 6 deletions(-) diff --git a/modules/tools/biblio/config.el b/modules/tools/biblio/config.el index 61caf6677..970990d27 100644 --- a/modules/tools/biblio/config.el +++ b/modules/tools/biblio/config.el @@ -29,12 +29,6 @@ org-cite-activate-processor 'citar) :config - (after! embark - (citar-embark-mode)) - - (after! org-roam - (citar-org-roam-mode)) - (when (modulep! :completion vertico +icons) (defvar citar-indicator-files-icons (citar-indicator-create @@ -81,6 +75,20 @@ ;; ;;; Third-party +(use-package! citar-embark + :defer t + :init + (after! (citar embark) + (citar-embark-mode))) + + +(use-package! citar-org-roam + :defer t + :init + (after! (citar org-roam) + (citar-org-roam-mode))) + + (use-package! bibtex-completion :when (or (modulep! :completion ivy) (modulep! :completion helm)) From 3820ead9e3b029abb2e09289d4b875e25cdea332 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Mar 2024 00:38:13 -0500 Subject: [PATCH 07/49] tweak(markdown): disable wiki links & math highlights by default These two features are relatively expensive and shouldn't be enabled as a global default. --- modules/lang/markdown/config.el | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/modules/lang/markdown/config.el b/modules/lang/markdown/config.el index 9461635c9..cad315f38 100644 --- a/modules/lang/markdown/config.el +++ b/modules/lang/markdown/config.el @@ -18,9 +18,7 @@ capture, the end position, and the output buffer.") (use-package! markdown-mode :mode ("/README\\(?:\\.md\\)?\\'" . gfm-mode) :init - (setq markdown-enable-math t ; syntax highlighting for latex fragments - markdown-enable-wiki-links t - markdown-italic-underscore t + (setq markdown-italic-underscore t markdown-asymmetric-header t markdown-gfm-additional-languages '("sh") markdown-make-gfm-checkboxes-buttons t From 3b405c8d8146553a1faad664e529c1ed0f841fa8 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Mar 2024 20:42:02 -0400 Subject: [PATCH 08/49] fix(lib): only use alpha-background on pgtk builds Fix: #7721 --- lisp/lib/ui.el | 21 ++++++++++++--------- 1 file changed, 12 insertions(+), 9 deletions(-) diff --git a/lisp/lib/ui.el b/lisp/lib/ui.el index ea553c1d1..d2d01e5e3 100644 --- a/lisp/lib/ui.el +++ b/lisp/lib/ui.el @@ -175,15 +175,18 @@ Use `winner-undo' to undo this. Alternatively, use "Interactively change the current frame's opacity. OPACITY is an integer between 0 to 100, inclusive." - (interactive - (list (read-number "Opacity (0-100): " - (or (frame-parameter - nil (if (> emacs-major-version 28) - 'alpha-background 'alpha)) - 100)))) - (set-frame-parameter nil (if (> emacs-major-version 28) - 'alpha-background 'alpha) - opacity)) + (interactive '(interactive)) + (let* ((parameter + (if (eq window-system 'pgtk) + 'alpha-background + 'alpha)) + (opacity + (if (eq opacity 'interactive) + (read-number "Opacity (0-100): " + (or (frame-parameter nil parameter) + 100)) + opacity))) + (set-frame-parameter nil parameter opacity))) (defvar doom--narrowed-base-buffer nil) ;;;###autoload From 198fe82b6d4989b7fdffb810e97371c44fa4dbcb Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Mar 2024 20:43:52 -0400 Subject: [PATCH 09/49] feat(lib): backport find-sibling-file I will slowly phase out projectile in favor of project.el, starting with projectile-find-other-file, which -- as of Emacs 29 -- has a native alternative: `find-sibling-file`. Ref: doomemacs/community#1 --- lisp/lib/files.el | 72 ++++++++++++++++++++++++ modules/config/default/+evil-bindings.el | 2 +- modules/editor/evil/+commands.el | 2 +- modules/lang/cc/config.el | 2 + modules/lang/web/+css.el | 8 +-- 5 files changed, 77 insertions(+), 9 deletions(-) diff --git a/lisp/lib/files.el b/lisp/lib/files.el index 2ffcc8c1e..088463293 100644 --- a/lisp/lib/files.el +++ b/lisp/lib/files.el @@ -527,5 +527,77 @@ If FORCE-P, overwrite the destination file if it exists, without confirmation." (recentf-save-list) (message "Removed %S from `recentf-list'" (abbreviate-file-name file))) + +;; +;;; Backports + +;; Introduced in Emacs 29. +;;;###autoload +(eval-when! (not (fboundp 'find-sibling-file)) + (defvar find-sibling-rules nil) + + (defun find-sibling-file (file) + "Visit a \"sibling\" file of FILE. +When called interactively, FILE is the currently visited file. + +The \"sibling\" file is defined by the `find-sibling-rules' variable." + (interactive (progn + (unless buffer-file-name + (user-error "Not visiting a file")) + (list buffer-file-name))) + (unless find-sibling-rules + (user-error "The `find-sibling-rules' variable has not been configured")) + (let ((siblings (find-sibling-file-search (expand-file-name file) + find-sibling-rules))) + (cond + ((null siblings) + (user-error "Couldn't find any sibling files")) + ((length= siblings 1) + (find-file (car siblings))) + (t + (let ((relatives (mapcar (lambda (sibling) + (file-relative-name + sibling (file-name-directory file))) + siblings))) + (find-file + (completing-read (format-prompt "Find file" (car relatives)) + relatives nil t nil nil (car relatives)))))))) + + (defun find-sibling-file-search (file &optional rules) + "Return a list of FILE's \"siblings\". +RULES should be a list on the form defined by `find-sibling-rules' (which +see), and if nil, defaults to `find-sibling-rules'." + (let ((results nil)) + (pcase-dolist (`(,match . ,expansions) (or rules find-sibling-rules)) + ;; Go through the list and find matches. + (when (string-match match file) + (let ((match-data (match-data))) + (dolist (expansion expansions) + (let ((start 0)) + ;; Expand \\1 forms in the expansions. + (while (string-match "\\\\\\([&0-9]+\\)" expansion start) + (let ((index (string-to-number (match-string 1 expansion)))) + (setq start (match-end 0) + expansion + (replace-match + (substring file + (elt match-data (* index 2)) + (elt match-data (1+ (* index 2)))) + t t expansion))))) + ;; Then see which files we have that are matching. (And + ;; expand from the end of the file's match, since we might + ;; be doing a relative match.) + (let ((default-directory (substring file 0 (car match-data)))) + ;; Keep the first matches first. + (setq results + (nconc + results + (mapcar #'expand-file-name + (file-expand-wildcards expansion nil t))))))))) + ;; Delete the file itself (in case it matched), and remove + ;; duplicates, in case we have several expansions and some match + ;; the same subsets of files. + (delete file (delete-dups results))))) + (provide 'doom-lib '(files)) ;;; files.el ends here diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index c79c078f6..fd2487410 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -677,7 +677,7 @@ :desc "Configure project" "g" #'projectile-configure-project :desc "Invalidate project cache" "i" #'projectile-invalidate-cache :desc "Kill project buffers" "k" #'projectile-kill-buffers - :desc "Find other file" "o" #'projectile-find-other-file + :desc "Find sibling file" "o" #'find-sibling-file :desc "Switch project" "p" #'projectile-switch-project :desc "Find recent project files" "r" #'projectile-recentf :desc "Run project" "R" #'projectile-run-project diff --git a/modules/editor/evil/+commands.el b/modules/editor/evil/+commands.el index 7c05694bc..05bb798c2 100644 --- a/modules/editor/evil/+commands.el +++ b/modules/editor/evil/+commands.el @@ -52,7 +52,7 @@ (evil-ex-define-cmd "pop[up]" #'+popup/buffer) ;;; Project navigation -(evil-ex-define-cmd "a" #'projectile-find-other-file) +(evil-ex-define-cmd "a" #'find-sibling-file) (evil-ex-define-cmd "cd" #'+evil:cd) (evil-ex-define-cmd "pwd" #'+evil:pwd) diff --git a/modules/lang/cc/config.el b/modules/lang/cc/config.el index 81514b2a9..9b1c2acc3 100644 --- a/modules/lang/cc/config.el +++ b/modules/lang/cc/config.el @@ -78,6 +78,8 @@ This is ignored by ccls.") :return "return" :yield "#require") + (add-to-list 'find-sibling-rules '("/\\([^/]+\\)\\.c\\(c\\|pp\\)\\'" "\\1.\\(h\\|hh\\|hpp\\)")) + (when (modulep! +tree-sitter) (add-hook! '(c-mode-local-vars-hook c++-mode-local-vars-hook) diff --git a/modules/lang/web/+css.el b/modules/lang/web/+css.el index fdcc4c744..144670d42 100644 --- a/modules/lang/web/+css.el +++ b/modules/lang/web/+css.el @@ -8,13 +8,7 @@ be aligned. If set to `nil', disable all the above behaviors.") -(after! projectile - (pushnew! projectile-other-file-alist - '("css" "scss" "sass" "less" "styl") - '("scss" "css") - '("sass" "css") - '("less" "css") - '("styl" "css"))) +(add-to-list 'find-sibling-rules '("/\\([^/]+\\)\\.\\(\\(s[ac]\\|le\\)ss\\|styl\\)\\'" "\\1\\.css")) ;; From 43870bf8318f6471c4ce5e14565c9f0a3fb6e368 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Sun, 10 Mar 2024 23:50:14 -0400 Subject: [PATCH 10/49] fix(editorconfig): prevent changes to tab-width in org-mode - Add another measure for preventing changes to tab-width in org-mode. The hook introduced in 2757a97 runs too early and could be overwritten by editorconfig. - Fix the hook in 2757a97 to run much later, ensuring (as a last resort) no other packages can overwrite tab-width either. Amend: 2757a97a30e7 Ref: #7670 --- modules/lang/org/config.el | 7 ++++++- modules/tools/editorconfig/config.el | 16 +++++++++++++--- 2 files changed, 19 insertions(+), 4 deletions(-) diff --git a/modules/lang/org/config.el b/modules/lang/org/config.el index f88057bf3..549f38c10 100644 --- a/modules/lang/org/config.el +++ b/modules/lang/org/config.el @@ -1438,7 +1438,12 @@ between the two." ;; HACK: Somehow, users/packages still find a way to modify tab-width in ;; org-mode. Since org-mode treats a non-standerd tab-width as an error ;; state, I use this hook to makes it much harder to change by accident. - (add-hook! 'org-mode-hook :depth 110 (setq-local tab-width 8)) + (add-hook! 'org-mode-hook + (add-hook! 'after-change-major-mode-hook :local + ;; The second check is necessary, in case of `org-edit-src-code' which + ;; clones a buffer and changes its major-mode. + (when (derived-mode-p 'org-mode) + (setq tab-width 8)))) ;; Save target buffer after archiving a node. (setq org-archive-subtree-save-file-p t) diff --git a/modules/tools/editorconfig/config.el b/modules/tools/editorconfig/config.el index e6d52b3c5..5fb5bfa87 100644 --- a/modules/tools/editorconfig/config.el +++ b/modules/tools/editorconfig/config.el @@ -48,6 +48,16 @@ extension, try to guess one." (defun +editorconfig-disable-indent-detection-h (props) "Inhibit `dtrt-indent' if an explicit indent_style and indent_size is specified by editorconfig." - (when (or (gethash 'indent_style props) - (gethash 'indent_size props)) - (setq doom-inhibit-indent-detection 'editorconfig))))) + (when (and (not doom-inhibit-indent-detection) + (or (gethash 'indent_style props) + (gethash 'indent_size props))) + (setq doom-inhibit-indent-detection 'editorconfig))) + ;; I use a hook over `editorconfig-exclude-modes' because the option + ;; inhibits all settings, and I only want to inhibit indent_size. Plus modes + ;; in that option won't apply to derived modes, so we'd have to add *all* + ;; possible org-mode derivatives to it. + (defun +editorconfig-unset-tab-width-in-org-mode-h (props) + "A tab-width != 8 is an error state in org-mode, so prevent changing it." + (when (and (gethash 'indent_size props) + (derived-mode-p 'org-mode)) + (setq tab-width 8))))) From 41e81f67a73bb6d042c83a02f5c9ac3125306fd5 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Mar 2024 00:26:19 -0400 Subject: [PATCH 11/49] refactor(editorconfig): remove unused advice editorconfig-call-editorconfig-exec was renamed+redesigned upstream. The advice can no longer be trivially repurposed, so I'm removing it. Ref: editorconfig/editorconfig-emacs@f8f1a899dfc2 --- modules/tools/editorconfig/config.el | 30 ---------------------------- 1 file changed, 30 deletions(-) diff --git a/modules/tools/editorconfig/config.el b/modules/tools/editorconfig/config.el index 5fb5bfa87..f98078c97 100644 --- a/modules/tools/editorconfig/config.el +++ b/modules/tools/editorconfig/config.el @@ -1,21 +1,5 @@ ;;; tools/editorconfig/config.el -*- lexical-binding: t; -*- -;; editorconfig cannot procure the correct settings for extension-less files. -;; Executable scripts with a shebang line, for example. So why not use Emacs' -;; major mode to drop editorconfig a hint? This is accomplished by temporarily -;; appending an extension to `buffer-file-name' when we talk to editorconfig. -(defvar +editorconfig-mode-alist - '((emacs-lisp-mode . "el") - (js2-mode . "js") - (perl-mode . "pl") - (php-mode . "php") - (python-mode . "py") - (ruby-mode . "rb") - (sh-mode . "sh")) - "An alist mapping major modes to extensions. Used by -`doom--editorconfig-smart-detection-a' to give editorconfig filetype hints.") - - ;; Handles whitespace (tabs/spaces) settings externally. This way projects can ;; specify their own formatting rules. (use-package! editorconfig @@ -30,20 +14,6 @@ (add-to-list 'editorconfig-exclude-regexps "\\.\\(zip\\|\\(doc\\|xls\\|ppt\\)x\\)\\'") - (defadvice! +editorconfig--smart-detection-a (fn) - "Retrieve the properties for the current file. If it doesn't have an -extension, try to guess one." - :around #'editorconfig-call-editorconfig-exec - (let ((buffer-file-name - (if (and (not (bound-and-true-p org-src-mode)) - (file-name-extension buffer-file-name)) - buffer-file-name - (format "%s%s" (buffer-file-name (buffer-base-buffer)) - (if-let (ext (alist-get major-mode +editorconfig-mode-alist)) - (concat "." ext) - ""))))) - (funcall fn))) - (add-hook! 'editorconfig-after-apply-functions (defun +editorconfig-disable-indent-detection-h (props) "Inhibit `dtrt-indent' if an explicit indent_style and indent_size is From dec058fabb5ed188f712a90cfd987616ade3676a Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Mar 2024 00:37:17 -0400 Subject: [PATCH 12/49] fix(treemacs): treemacs-nerd-icons load order w/ +lsp lsp-treemacs changes the default Treemacs theme, so treemacs-nerd-icons needs to be loaded after it, if it's installed/enabled. Fix: #7519 Fix: doomemacs/themes#801 Ref: emacs-lsp/lsp-treemacs#89 --- modules/ui/treemacs/config.el | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/modules/ui/treemacs/config.el b/modules/ui/treemacs/config.el index 9f3febb6a..211e1f3bc 100644 --- a/modules/ui/treemacs/config.el +++ b/modules/ui/treemacs/config.el @@ -44,7 +44,12 @@ This must be set before `treemacs' has loaded.") (use-package! treemacs-nerd-icons - :after treemacs + :defer t + ;; HACK: Because `lsp-treemacs' mutates Treemacs' default theme, and + ;; `treemacs-nerd-icons' reads from it to populate its nerd-icons theme, + ;; load order is important to ensure they don't step on each other's toes. + :init (with-eval-after-load (if (modulep! +lsp) 'lsp-treemacs 'treemacs) + (require 'treemacs-nerd-icons)) :config (treemacs-load-theme "nerd-icons")) From 6c1aa0fb621a912a1a7eaed4f5db30a821d97327 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Mar 2024 00:41:00 -0400 Subject: [PATCH 13/49] bump: :tools editorconfig editorconfig/editorconfig-emacs@4b81a5992858 -> editorconfig/editorconfig-emacs@c3666c093f3a --- modules/tools/editorconfig/packages.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/modules/tools/editorconfig/packages.el b/modules/tools/editorconfig/packages.el index 022f9f75f..db1f0ecf0 100644 --- a/modules/tools/editorconfig/packages.el +++ b/modules/tools/editorconfig/packages.el @@ -3,4 +3,4 @@ (package! editorconfig :recipe (:nonrecursive t) - :pin "4b81a5992858cbf03bcd7ed6ef31e4be0b55a7c1") + :pin "c3666c093f3a2a80fb42e513bf0a10d597497c18") From 7f484f7010298d300d69fd0f70c5245e74949462 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Mar 2024 00:42:17 -0400 Subject: [PATCH 14/49] refactor: remove explain-pause-mode Tools like these will be moved to a benchmark module later (or perhaps to `:lang emacs-lisp`). For the time being, it only takes up extra space that few users use. --- lisp/lib/debug.el | 3 --- lisp/packages.el | 4 ---- 2 files changed, 7 deletions(-) diff --git a/lisp/lib/debug.el b/lisp/lib/debug.el index 741e59ff3..792acb758 100644 --- a/lisp/lib/debug.el +++ b/lisp/lib/debug.el @@ -59,9 +59,6 @@ symbol and CDR is the value to set it to when `doom-debug-mode' is activated.") (let ((enabled doom-debug-mode)) (doom-log "debug: enabled!") (mapc #'doom-debug--set-var doom-debug-variables) - (when (called-interactively-p 'any) - (when (fboundp 'explain-pause-mode) - (explain-pause-mode (if enabled +1 -1)))) ;; Watch for changes in `doom-debug-variables', or when packages load (and ;; potentially define one of `doom-debug-variables'), in case some of them ;; aren't defined when `doom-debug-mode' is first loaded. diff --git a/lisp/packages.el b/lisp/packages.el index 11bd02520..dd908a10d 100644 --- a/lisp/packages.el +++ b/lisp/packages.el @@ -4,10 +4,6 @@ ;; doom.el (package! auto-minor-mode :pin "17cfa1b54800fdef2975c0c0531dad34846a5065") (package! gcmh :pin "0089f9c3a6d4e9a310d0791cf6fa8f35642ecfd9") -(package! explain-pause-mode - :recipe (:host github - :repo "lastquestion/explain-pause-mode") - :pin "2356c8c3639cbeeb9751744dbe737267849b4b51") ;; doom-packages.el (package! straight From c6063de4399411e45a06e8ac14249b323419ae6c Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Mar 2024 00:47:13 -0400 Subject: [PATCH 15/49] nit: revise and reformat comments --- early-init.el | 6 +++--- lisp/doom-keybinds.el | 6 +++--- lisp/doom-lib.el | 14 +++++++------- lisp/doom-start.el | 24 +++++++++++++----------- lisp/doom.el | 18 ++++++++++++------ 5 files changed, 38 insertions(+), 30 deletions(-) diff --git a/early-init.el b/early-init.el index 922972c02..bc6032b42 100644 --- a/early-init.el +++ b/early-init.el @@ -106,9 +106,9 @@ ;; this early -- I remove `.so' from `load-suffixes' and pass the ;; `must-suffix' arg to `load'. See the docs of `load' for details. (if (let ((load-suffixes '(".elc" ".el"))) - ;; I avoid `load's NOERROR argument because other, legitimate errors - ;; (like permission or IO errors) should not be suppressed or - ;; interpreted as "this is not a Doom config". + ;; I avoid `load's NOERROR argument because it suppresses other, + ;; legitimate errors (like permission or IO errors), which gets + ;; incorrectly interpreted as "this is not a Doom config". (condition-case _ ;; Load the heart of Doom Emacs. (load (expand-file-name "lisp/doom" user-emacs-directory) diff --git a/lisp/doom-keybinds.el b/lisp/doom-keybinds.el index f6ff2a99a..210432fc5 100644 --- a/lisp/doom-keybinds.el +++ b/lisp/doom-keybinds.el @@ -46,12 +46,12 @@ and Emacs states, and for non-evil users.") ;; HACK: Emacs cannot distinguish between C-i from TAB. This is largely a ;; byproduct of its history in the terminal, which can't distinguish them -;; either, however, when GUIs came about Emacs greated separate input events +;; either, however, when GUIs came about Emacs created separate input events ;; for more contentious keys like TAB and RET. Therefore [return] != RET, ;; [tab] != TAB, and [backspace] != DEL. ;; -;; In the same vein, this keybind adds a [C-i] event, so users can bind to it. -;; Otherwise, it falls back to regular C-i keybinds. +;; In the same vein, this keybind adds a [C-i] event, so users can bind to it +;; independently of TAB. Otherwise, it falls back to keys bound to C-i. (define-key key-translation-map [?\C-i] (cmd! (if (let ((keys (this-single-command-raw-keys))) (and keys diff --git a/lisp/doom-lib.el b/lisp/doom-lib.el index c33edede1..9f996d3e7 100644 --- a/lisp/doom-lib.el +++ b/lisp/doom-lib.el @@ -303,9 +303,9 @@ TRIGGER-HOOK is a list of quoted hooks and/or sharp-quoted functions." (error "file!: cannot deduce the current file path"))) (defmacro dir! () - "Return the directory of the file this macro was called." - (let (file-name-handler-alist) - (file-name-directory (macroexpand '(file!))))) + "Return the directory of the file in which this macro was called." + (let (file-name-handler-alist) + (file-name-directory (macroexpand '(file!))))) ;; REVIEW Should I deprecate this? The macro's name is so long... (defalias 'letenv! 'with-environment-variables) @@ -883,16 +883,16 @@ testing advice (when combined with `rotate-text'). (dolist (target (cdr targets)) (advice-remove target #',symbol))))) + +;; +;;; Backports + (defmacro defbackport! (type symbol &rest body) "Backport a function/macro/alias from later versions of Emacs." (declare (indent defun) (doc-string 4)) (unless (fboundp (doom-unquote symbol)) `(,type ,symbol ,@body))) - -;; -;;; Backports - ;; `format-spec' wasn't autoloaded until 28.1 (defbackport! autoload 'format-spec "format-spec") diff --git a/lisp/doom-start.el b/lisp/doom-start.el index e52624bcf..2c25a3421 100644 --- a/lisp/doom-start.el +++ b/lisp/doom-start.el @@ -100,13 +100,15 @@ ;;; Disable UI elements early ;; PERF,UI: Doom strives to be keyboard-centric, so I consider these UI elements -;; clutter. Initializing them also costs a morsel of startup time. Whats more, -;; the menu bar exposes functionality that Doom doesn't endorse. Perhaps one -;; day Doom will support these, but today is not that day. -;; +;; clutter. Initializing them also costs a morsel of startup time. What's +;; more, the menu bar exposes functionality that Doom doesn't endorse. Perhaps +;; one day Doom will support these, but today is not that day. By disabling +;; them early, we save Emacs some time. + ;; HACK: I intentionally avoid calling `menu-bar-mode', `tool-bar-mode', and -;; `scroll-bar-mode' because they do extra work to manipulate frame variables -;; that isn't necessary this early in the startup process. +;; `scroll-bar-mode' because their manipulation of frame parameters can +;; trigger/queue a superfluous (and expensive, depending on the window system) +;; frame redraw at startup. (push '(menu-bar-lines . 0) default-frame-alist) (push '(tool-bar-lines . 0) default-frame-alist) (push '(vertical-scroll-bars) default-frame-alist) @@ -119,7 +121,7 @@ ;; non-application window -- which means it doesn't automatically capture ;; focus when it is started, among other things, so enable the menu-bar for ;; GUI frames, but keep it disabled in terminal frames because there it -;; activates an ugly, in-frame menu bar. +;; unavoidably activates an ugly, in-frame menu bar. (eval-when! doom--system-macos-p (add-hook! '(window-setup-hook after-make-frame-functions) (defun doom-restore-menu-bar-in-gui-frames-h (&optional frame) @@ -136,7 +138,7 @@ ;; a step too opinionated. (setq default-input-method nil) ;; ...And the clipboard on Windows could be in a wider encoding (UTF-16), so -;; leave Emacs to its own devices. +;; leave Emacs to its own devices there. (eval-when! (not doom--system-windows-p) (setq selection-coding-system 'utf-8)) @@ -180,7 +182,7 @@ (defvar doom-incremental-packages '(t) "A list of packages to load incrementally after startup. Any large packages here may cause noticeable pauses, so it's recommended you break them up into -sub-packages. For example, `org' is comprised of many packages, and can be +sub-packages. For example, `org' is comprised of many packages, and might be broken up into: (doom-load-packages-incrementally @@ -192,7 +194,7 @@ broken up into: This is already done by the lang/org module, however. If you want to disable incremental loading altogether, either remove -`doom-load-packages-incrementally-h' from `emacs-startup-hook' or set +`doom-load-packages-incrementally-h' from `doom-after-init-hook' or set `doom-incremental-first-idle-timer' to nil. Incremental loading does not occur in daemon sessions (they are loaded immediately at startup).") @@ -201,7 +203,7 @@ in daemon sessions (they are loaded immediately at startup).") Set this to nil to disable incremental loading at startup. Set this to 0 to load all incrementally deferred packages immediately at -`emacs-startup-hook'.") +`doom-after-init-hook'.") (defvar doom-incremental-idle-timer 0.75 "How long (in idle seconds) in between incrementally loading packages.") diff --git a/lisp/doom.el b/lisp/doom.el index 5f9835224..65924d1ec 100644 --- a/lisp/doom.el +++ b/lisp/doom.el @@ -59,9 +59,13 @@ ;; - On first switched-to buffer: `doom-first-buffer-hook' ;; - On first opened file: `doom-first-file-hook' ;; -;; This is Doom's heart, where I define all its major constants and variables, -;; set only its sanest global defaults, employ its hackiest (and least -;; offensive) optimizations, and load the minimum for all Doom sessions. +;; This file is Doom's heart, where I define all its major constants and +;; variables, set only its sanest global defaults, employ its hackiest (and +;; least offensive) optimizations, and load the minimum needed for all Doom +;; sessions, interactive or otherwise. +;; +;; See doom-start.el for initialization intended solely for interactive +;; sessions, and doom-cli.el for non-interactive sessions. ;; ;;; Code: @@ -110,7 +114,8 @@ ;;; Custom features & global constants ;; Doom has its own features that its modules, CLI, and user extensions can ;; announce, and don't belong in `features', so they are stored here, which can -;; include information about the external system environment. +;; include information about the external system environment. Module-specific +;; features are kept elsewhere, however. (defconst doom-features (pcase system-type ('darwin '(macos bsd)) @@ -410,8 +415,9 @@ users).") ;; PERF: Shave seconds off startup time by starting the scratch buffer in ;; `fundamental-mode', rather than, say, `org-mode' or `text-mode', which - ;; pull in a ton of packages. `doom/open-scratch-buffer' provides a better - ;; scratch buffer anyway. + ;; pull in a ton of packages. This buffer is created whether or not we're + ;; in an interactive session. Plus, `doom/open-scratch-buffer' provides a + ;; better scratch buffer, so keep the initial one blank. (setq initial-major-mode 'fundamental-mode initial-scratch-message nil) From e27d9b35d3a42e22951edcfbdaa63526f4b9c7b2 Mon Sep 17 00:00:00 2001 From: Tim Ruffing Date: Sun, 11 Feb 2024 03:49:35 +0100 Subject: [PATCH 16/49] fix(popup): fix finding of major side window Fix: #7647 Amend: #7598 --- modules/ui/popup/autoload/popup.el | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) diff --git a/modules/ui/popup/autoload/popup.el b/modules/ui/popup/autoload/popup.el index ba90d642f..aa31fac2a 100644 --- a/modules/ui/popup/autoload/popup.el +++ b/modules/ui/popup/autoload/popup.el @@ -512,17 +512,24 @@ Accepts the same arguments as `display-buffer-in-side-window'. You must set (and (eq (window-parameter window 'window-side) side) (eq (window-parameter window 'window-vslot) vslot))) nil)) - ;; As opposed to the `window-side' property, the `window-vslot' - ;; property is set only on a single live window and never on internal + ;; As opposed to the `window-side' property, our `window-vslot' + ;; parameter is set only on a single live window and never on internal ;; windows. Moreover, as opposed to `window-with-parameter' (as used ;; by the original `display-buffer-in-side-window'), ;; `get-window-with-predicate' only returns live windows anyway. In ;; any case, we will have missed the major side window and got a ;; child instead if the major side window happens to be an internal - ;; window. In that case, the major side window is the parent of the - ;; live window. + ;; window with multiple children. In that case, all childen should + ;; have the same `window-vslot' parameter, and the major side window + ;; is the parent of the live window. + (prev (and live (window-prev-sibling live))) + (next (and live (window-next-sibling live))) + (prev-vslot (and prev (window-parameter prev 'window-vslot))) + (next-vslot (and next (window-parameter next 'window-vslot))) (major (and live - (if (window-next-sibling live) (window-parent live) live))) + (if (or (eq prev-vslot vslot) (eq next-vslot vslot)) + (window-parent live) + live))) (reversed (window--sides-reverse-on-frame-p (selected-frame))) (windows (cond ((window-live-p major) @@ -614,6 +621,7 @@ Accepts the same arguments as `display-buffer-in-side-window'. You must set (setq window (ignore-errors (split-window prev-window nil prev-side)))))) (set-window-parameter window 'window-slot slot) + (set-window-parameter window 'window-vslot vslot) (with-current-buffer buffer (setq window--sides-shown t)) (window--display-buffer From 4be265ead73e587a9cc2e86f01e103728c5eaf20 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Mar 2024 02:50:33 -0400 Subject: [PATCH 17/49] fix: doom-incremental-first-idle-timer: type error when nil (part 2) Amend: 2bce9dbc1ad1 Ref: #7710 --- lisp/doom-start.el | 14 +++++++++----- 1 file changed, 9 insertions(+), 5 deletions(-) diff --git a/lisp/doom-start.el b/lisp/doom-start.el index 2c25a3421..c5b1d46b2 100644 --- a/lisp/doom-start.el +++ b/lisp/doom-start.el @@ -211,9 +211,13 @@ Set this to 0 to load all incrementally deferred packages immediately at (defun doom-load-packages-incrementally (packages &optional now) "Registers PACKAGES to be loaded incrementally. -If NOW is non-nil, load PACKAGES incrementally, in `doom-incremental-idle-timer' -intervals." - (let ((gc-cons-threshold most-positive-fixnum)) +If NOW is non-nil, PACKAGES will be marked for incremental loading next time +Emacs is idle for `doom-incremental-first-idle-timer' seconds (falls back to +`doom-incremental-idle-timer'), then in `doom-incremental-idle-timer' intervals +afterwards." + (let* ((gc-cons-threshold most-positive-fixnum) + (first-idle-timer (or doom-incremental-first-idle-timer + doom-incremental-idle-timer))) (if (not now) (cl-callf append doom-incremental-packages packages) (while packages @@ -224,7 +228,7 @@ intervals." (condition-case-unless-debug e (and (or (null (setq idle-time (current-idle-time))) - (< (float-time idle-time) (or doom-incremental-first-idle-timer 0.0)) + (< (float-time idle-time) first-idle-timer) (not (while-no-input (doom-log "start:iloader: Loading %s (%d left)" req (length packages)) @@ -244,7 +248,7 @@ intervals." (doom-log "start:iloader: Finished!") (run-at-time (if idle-time doom-incremental-idle-timer - doom-incremental-first-idle-timer) + first-idle-timer) nil #'doom-load-packages-incrementally packages t) (setq packages nil)))))))) From 61327bf77770d815d71ba84a872a2da3d8fd4a53 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Mar 2024 03:24:44 -0400 Subject: [PATCH 18/49] refactor(lib): use doom-region-{beginning,end} --- lisp/lib/ui.el | 18 ++++++------------ 1 file changed, 6 insertions(+), 12 deletions(-) diff --git a/lisp/lib/ui.el b/lisp/lib/ui.el index d2d01e5e3..f564248e4 100644 --- a/lisp/lib/ui.el +++ b/lisp/lib/ui.el @@ -198,12 +198,9 @@ narrowing doesn't affect other windows displaying the same buffer. Call `doom/widen-indirectly-narrowed-buffer' to undo it (incrementally). Inspired from http://demonastery.org/2013/04/emacs-evil-narrow-region/" - (interactive - (list (or (bound-and-true-p evil-visual-beginning) (region-beginning)) - (or (bound-and-true-p evil-visual-end) (region-end)))) - (unless (region-active-p) - (setq beg (line-beginning-position) - end (line-end-position))) + (interactive (if (region-active-p) + (list (doom-region-beginning) (doom-region-end)) + (list (bol) (eol)))) (deactivate-mark) (let ((orig-buffer (current-buffer))) (with-current-buffer (switch-to-buffer (clone-indirect-buffer nil nil)) @@ -242,12 +239,9 @@ If the current buffer is not an indirect buffer, it is `widen'ed." ;;;###autoload (defun doom/toggle-narrow-buffer (beg end) "Narrow the buffer to BEG END. If narrowed, widen it." - (interactive - (list (or (bound-and-true-p evil-visual-beginning) (region-beginning)) - (or (bound-and-true-p evil-visual-end) (region-end)))) + (interactive (if (region-active-p) + (list (doom-region-beginning) (doom-region-end)) + (list (bol) (eol)))) (if (buffer-narrowed-p) (widen) - (unless (region-active-p) - (setq beg (line-beginning-position) - end (line-end-position))) (narrow-to-region beg end))) From 559171575e7685463ae6608b6c37caf7c234f89d Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Mar 2024 03:26:01 -0400 Subject: [PATCH 19/49] refactor(lib): doom-region-end: extract marker --- lisp/lib/text.el | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/lisp/lib/text.el b/lisp/lib/text.el index 60a56b47e..cef1a098b 100644 --- a/lisp/lib/text.el +++ b/lisp/lib/text.el @@ -88,10 +88,11 @@ Uses `evil-visual-beginning' if available." "Return end position of selection. Uses `evil-visual-end' if available." (declare (side-effect-free t)) - (if (and (bound-and-true-p evil-local-mode) - (evil-visual-state-p)) - evil-visual-end - (region-end))) + (or (and (bound-and-true-p evil-local-mode) + (evil-visual-state-p) + (markerp evil-visual-end) + (marker-position evil-visual-end)) + (region-end))) ;;;###autoload (defun doom-thing-at-point-or-region (&optional thing prompt) From a0a1babc0d24e34909fbe6801edbe8388a022b98 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Mar 2024 03:27:38 -0400 Subject: [PATCH 20/49] fix(cli): silence output from site-lisp Some site files will forcibly undo `inhibit-message` or set `force-load-messages`. This ensures site lisp files don't make unnecessary noise at startup. --- lisp/doom-cli.el | 32 ++++++++++++++++---------------- 1 file changed, 16 insertions(+), 16 deletions(-) diff --git a/lisp/doom-cli.el b/lisp/doom-cli.el index 25c4e1216..7d5bff2f7 100644 --- a/lisp/doom-cli.el +++ b/lisp/doom-cli.el @@ -25,22 +25,22 @@ ;; HACK: Load `cl' and site files manually to prevent polluting logs and ;; stdout with deprecation and/or file load messages. - (let ((inhibit-message (not init-file-debug))) - (require 'cl nil t) - (unless site-run-file - (let ((site-run-file "site-start") - (tail load-path) - (lispdir (expand-file-name "../lisp" data-directory)) - dir) - (while tail - (setq dir (car tail)) - (let ((default-directory dir)) - (load (expand-file-name "subdirs.el") t inhibit-message t)) - (unless (string-prefix-p lispdir dir) - (let ((default-directory dir)) - (load (expand-file-name "leim-list.el") t inhibit-message t))) - (setq tail (cdr tail))) - (load site-run-file t inhibit-message)))) + (quiet! + (require 'cl nil t) + (unless site-run-file + (let ((site-run-file "site-start") + (tail load-path) + (lispdir (expand-file-name "../lisp" data-directory)) + dir) + (while tail + (setq dir (car tail)) + (let ((default-directory dir)) + (load (expand-file-name "subdirs.el") t inhibit-message t)) + (unless (string-prefix-p lispdir dir) + (let ((default-directory dir)) + (load (expand-file-name "leim-list.el") t inhibit-message t))) + (setq tail (cdr tail))) + (load site-run-file t inhibit-message)))) (setq-default ;; PERF: Don't generate superfluous files when writing temp buffers. From 1db96a1fdb76a9ab245a298db701880eeba8fe7d Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Mar 2024 03:44:41 -0400 Subject: [PATCH 21/49] docs(web): correct type, mention JS comment hack, remove superfluous notice close: #7388 --- modules/lang/web/README.org | 10 ++++------ 1 file changed, 4 insertions(+), 6 deletions(-) diff --git a/modules/lang/web/README.org b/modules/lang/web/README.org index 4418f522b..53ff8e32c 100644 --- a/modules/lang/web/README.org +++ b/modules/lang/web/README.org @@ -6,7 +6,7 @@ * Description :unfold: This module adds support for various web languages, including HTML5, CSS, SASS/SCSS, Pug/Jade/Slim, and HAML, as well as various web frameworks, like -ReactJS, Wordpress, Jekyll, Phaser, AngularJS, Djano, and more. +ReactJS, Wordpress, Jekyll, Phaser, AngularJS, Django, and more. ** Maintainers - @hlissner @@ -41,6 +41,9 @@ ReactJS, Wordpress, Jekyll, Phaser, AngularJS, Djano, and more. 󱌣 This module's hacks haven't been documented yet. [[doom-contrib-module:][Document them?]] #+end_quote +- Fixes ~//~ line commenting in JSX and Javascript files (if you aren't using + :lang javascript for some reason) + ** TODO Changelog # This section will be machine generated. Don't edit it by hand. /This module does not have a changelog yet./ @@ -49,13 +52,8 @@ ReactJS, Wordpress, Jekyll, Phaser, AngularJS, Djano, and more. [[id:01cffea4-3329-45e2-a892-95a384ab2338][Enable this module in your ~doom!~ block.]] ** Formatter - Formatting is handled using the [[doom-module::editor format]] module via [[https://prettier.io/docs/en/install.html][prettier]]. -#+begin_quote - 󱌣 /No installation steps have been documented./ [[doom-contrib-module:][Document them?]] -#+end_quote - * TODO Usage #+begin_quote 󱌣 This module has no usage documentation yet. [[doom-contrib-module:][Write some?]] From 68682ac01269f2ba55b51f368901cf6735d7c24a Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Mar 2024 03:55:04 -0400 Subject: [PATCH 22/49] fix(ruby): ruby REPL w/ robe set-repl-handler! handlers have to return a buffer. Close: #7450 Co-authored-by: Zetagon --- modules/lang/ruby/autoload.el | 6 ++++++ modules/lang/ruby/config.el | 2 +- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/modules/lang/ruby/autoload.el b/modules/lang/ruby/autoload.el index 70f3e68ff..47e5b1f73 100644 --- a/modules/lang/ruby/autoload.el +++ b/modules/lang/ruby/autoload.el @@ -13,3 +13,9 @@ open." (when (processp process) (kill-process (get-buffer-process inf-buffer)) (kill-buffer inf-buffer))))))) + +;;;###autoload +(defun +ruby-robe-repl-handler () + "Start Robe and open a REPL (for `set-repl-handler!')." + (robe-start) + (robe-inf-buffer)) diff --git a/modules/lang/ruby/config.el b/modules/lang/ruby/config.el index 61f2d46d1..31cc15c4b 100644 --- a/modules/lang/ruby/config.el +++ b/modules/lang/ruby/config.el @@ -48,7 +48,7 @@ (bound-and-true-p lsp--buffer-deferred) (robe-mode +1)))) :config - (set-repl-handler! 'ruby-mode #'robe-start) + (set-repl-handler! 'ruby-mode #'+ruby-robe-repl-handler) (set-company-backend! 'ruby-mode 'company-robe 'company-dabbrev-code) (set-lookup-handlers! 'ruby-mode :definition #'robe-jump From b3822557044ba21c8823bc209ac584e922028916 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Mon, 11 Mar 2024 03:30:10 -0400 Subject: [PATCH 23/49] release(modules): 24.03.0-dev Ref: 2b39e4136850 --- lisp/doom.el | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lisp/doom.el b/lisp/doom.el index 65924d1ec..885e31f29 100644 --- a/lisp/doom.el +++ b/lisp/doom.el @@ -201,7 +201,7 @@ "Current version of Doom Emacs core.") ;; DEPRECATED: Remove these when the modules are moved out of core. -(defconst doom-modules-version "24.02.0-pre" +(defconst doom-modules-version "24.03.0-pre" "Current version of Doom Emacs.") (defvar doom-init-time nil From a0344ffc3ad7844075f6b0bc53c5130545d5a1d5 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Mon, 11 Mar 2024 03:01:48 -0500 Subject: [PATCH 24/49] fix(mu4e): advice for new mu4e release mu4e-quit now takes an optional argument, BURY, which is a boolean that determines whether to bury the buffer or kill it. This commit updates the advice to reflect this change. --- modules/email/mu4e/autoload/mu-lock.el | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/modules/email/mu4e/autoload/mu-lock.el b/modules/email/mu4e/autoload/mu-lock.el index 14cf1b01d..6f1a111cd 100644 --- a/modules/email/mu4e/autoload/mu-lock.el +++ b/modules/email/mu4e/autoload/mu-lock.el @@ -35,9 +35,9 @@ If STRICT only accept an unset lock file." (when (or strict (/= (emacs-pid) pid)) t)))) ;;;###autoload -(defun +mu4e-lock-file-delete-maybe () +(defun +mu4e-lock-file-delete-maybe (&optional bury) "Check `+mu4e-lock-file', and delete it if this process is responsible for it." - (when (+mu4e-lock-available) + (when (and (+mu4e-lock-available) (not bury)) (delete-file +mu4e-lock-file) (file-notify-rm-watch +mu4e-lock--request-watcher))) From 5532c68e53db9dc936251f30539c865d14bc452c Mon Sep 17 00:00:00 2001 From: Luigi Sartor Piucco Date: Sat, 24 Sep 2022 17:33:32 -0300 Subject: [PATCH 25/49] module: add :completion corfu This commit's primary goal is allowing use of [minad/corfu](https://github.com/minad/corfu) as an alternative to [company](https://github.com/company-mode/company-mode). It introduces a module under :completion for this purpose, plus some conditionals on other relevant modules to toggle functionality like lsp back-ends and [minad/cape](https://github.com/minad/cape) capfs for certain modes. Other optional or miscellaneous features include: - Support for displaying the completion's documentation on a secondary popup; - Support for terminal display if :os tty; - Support for icons if +icons; - Support for tab-and-go completion if +tng; --- modules/completion/corfu/README.org | 155 +++++++++++++++++++++++++++ modules/completion/corfu/autoload.el | 10 ++ modules/completion/corfu/config.el | 114 ++++++++++++++++++++ modules/completion/corfu/packages.el | 11 ++ modules/tools/lsp/+lsp.el | 5 +- 5 files changed, 294 insertions(+), 1 deletion(-) create mode 100644 modules/completion/corfu/README.org create mode 100644 modules/completion/corfu/autoload.el create mode 100644 modules/completion/corfu/config.el create mode 100644 modules/completion/corfu/packages.el diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org new file mode 100644 index 000000000..f300bde8c --- /dev/null +++ b/modules/completion/corfu/README.org @@ -0,0 +1,155 @@ +#+title: :completion corfu +#+subtitle: Complete with cap(f), cape and a flying feather +#+created: September 9, 2022 +#+since: 3.0.0 (#7002) + +* Description :unfold: +This module provides code completion, powered by [[doom-package:corfu]]. + +It is recommended to enable either this or [[doom-module::completion company]], in +case you desire pre-configured auto-completion. Corfu is much lighter weight and +focused, plus it's built on native Emacs functionality, whereas company is heavy +and highly non-native, but has some extra features and more maturity. + +** Maintainers +- [[doom-user:][@LuigiPiucco]] + +[[doom-contrib-maintainer:][Become a maintainer?]] + +** Module flags +- +icons :: + Display icons beside completion suggestions. +- +tng :: + Known as Tab'n'Go to Company users, changes behavior to invoke completion on + [[kbd:][TAB]]. When Corfu is active, [[kbd:][TAB]] and [[kbd:][S-TAB]] will navigate the completion + candidates. Arrow keys and evil-style movement are still supported. +- +orderless :: + Pull in [[doom-package:orderless]] if necessary and apply multi-component + completion (still needed if [[doom-module::completion vertico]] is active). + +** Packages +- [[doom-package:corfu]] +- [[doom-package:cape]] +- [[doom-package:nerd-icons-corfu]] if [[doom-module::completion corfu +icons]] +- [[doom-package:orderless]] if [[doom-module::completion corfu +orderless]] +- [[doom-package:corfu-terminal]] if [[doom-module::os tty]] + +** Hacks +/No hacks documented for this module./ + +** TODO Changelog +# This section will be machine generated. Don't edit it by hand. +/This module does not have a changelog yet./ + +* Installation +Enable this module in your ~doom!~ block. + +This module has no direct requirements, but some languages may have their own +requirements to fulfill before you get code completion in them (and some +languages may lack code completion support altogether). Run ~$ doom doctor~ to +find out if you're missing any dependencies. Note that Corfu may have support +for completions in languages that have no development intelligence, since it +supports generic, context insensitive candidates such as file names or recurring +words. + +* TODO Usage +#+begin_quote + 🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]] +#+end_quote + +** Code completion +By default, completion gets triggered after typing 2 non-space consecutive +characters, or by means of the [[kbd:][C-SPC]] keybinding at any moment. While the popup +is visible, the following relevant keys are available: + +| Keybind | Description | +|----------+------------------------------------------------------------------| +| [[kbd:][]] | Go to next candidate | +| [[kbd:][]] | Go to previous candidate | +| [[kbd:][C-n]] | Go to next candidate | +| [[kbd:][C-p]] | Go to previous candidate | +| [[kbd:][C-j]] | (evil) Go to next candidate | +| [[kbd:][C-k]] | (evil) Go to previous candidate | +| [[kbd:][C-]] | Go to next doc line | +| [[kbd:][C-]] | Go to previous doc line | +| [[kbd:][C-S-n]] | Go to next doc line | +| [[kbd:][C-S-p]] | Go to previous doc line | +| [[kbd:][C-S-j]] | (evil) Go to next doc line | +| [[kbd:][C-S-k]] | (evil) Go to previous doc line | +| [[kbd:][C-h]] | Toggle documentation (if available) | +| [[kbd:][M-m]] | Export to minibuffer (if [[doom-module::completion vertico]]) | +| [[kbd:][M-S-j]] | (evil) Export to minibuffer (if [[doom-module::completion vertico]]) | +| [[kbd:][RET]] | Insert candidate | +| [[kbd:][SPC]] | (after wildcard) Reset completion | +| [[kbd:][DEL]] | Reset completion | +| [[kbd:][C-SPC]] | Complete (unless [[doom-module::completion corfu +tng]]) | +| [[kbd:][C-SPC]] | (when completing) Insert separator DWIM (see below) | + +If you prefer a [[kbd:][TAB]]-centric completion style, enable the [[doom-module::completion +corfu +tng]] flag so that, instead, you trigger completion with [[kbd:][TAB]], getting the +following additional binds: + +| Keybind | Description | +|---------+-----------------------------------------------| +| [[kbd:][TAB]] | Complete | +| [[kbd:][TAB]] | (when completing) Go to next candidate | +| [[kbd:][S-TAB]] | (when completing) Go to previous candidate | + +** Searching with multiple keywords +If the [[doom-module::completion corfu +orderless]] flag is enabled, users can +perform code completion with multiple search keywords by use of space as the +separator. More information can be found [[https://github.com/oantolin/orderless#company][here]]. Pressing [[kdb:][C-SPC]] again while +completing inserts a space as separator. This allows searching with +space-separated terms; each piece will match individually and in any order, with +smart casing. Pressing just [[kbd:][SPC]] acts as normal and quits completion, so that +when typing sentences it doesn't try to complete the whole sentence instead of +just the word. + +Additionally, for users of evil and regular corfu style, [[kdb:][C-SPC]] is smart +regarding your state. In normal-like states, enter insert then start corfu; in +visual-like states, perform [[help:evil-change][evil-change]] (which leaves you in insert state) then +start corfu; in insert-like states, start corfu immediatelly. + +** Exporting to the minibuffer (requires [[doom-module::completion vertico]]) +When using the [[doom-module::completion vertico]] module, which pulls in the +[[doom-package:consult]] package, the entries shown in the completion popup can be +exported to a consult minibuffer, giving access to all the manipulations the +Vertico suite allows. For instance, one could use this to export with +[[doom-package:embark]] via [[kbd:][C-c C-l]] and get a buffer with all candidates. + +* Configuration +A few variables may be set to change behavior of this module: + +- [[var:corfu-auto-delay]] :: + Number of seconds till completion occurs automatically. Defaults to 0.1. +- [[var:corfu-auto-prefix]] :: + Number of characters till auto-completion starts to happen. Defaults to 2. +- [[var:corfu-on-exact-match]] :: + Configures behavior for exact matches. Its default is nil, and it's + recommended to leave it at that. Otherwise, single matches on snippet keys + expand immediately. + +** 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)) +;; OR, but note the different call signature +(add-hook 'some-mode-hook (lambda () (add-to-list 'completion-at-point-functions #'some-capf))) +#+end_src + +~DEPTH~ above is an integer between -100, 100, and defaults to 0 of omitted. Also +see ~add-hook!~'s documentation for additional ways to call it. ~add-hook~ only +accepts the quoted arguments form above. + +* Troubleshooting +[[doom-report:][Report an issue?]] + +* Frequently asked questions +/This module has no FAQs yet./ [[doom-suggest-faq:][Ask one?]] + +* TODO Appendix +#+begin_quote + 🔨 This module has no appendix yet. [[doom-contrib-module:][Write one?]] +#+end_quote diff --git a/modules/completion/corfu/autoload.el b/modules/completion/corfu/autoload.el new file mode 100644 index 000000000..c34cb8232 --- /dev/null +++ b/modules/completion/corfu/autoload.el @@ -0,0 +1,10 @@ +;;; completion/corfu/autoload.el -*- lexical-binding: t; -*- + +;;;###autoload +(defun +corfu-move-to-minibuffer () + ;; Taken from corfu's README. + ;; TODO: extend this to other completion front-ends. + (interactive) + (let ((completion-extra-properties corfu--extra) + (completion-cycle-threshold completion-cycling)) + (apply #'consult-completion-in-region completion-in-region--data))) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el new file mode 100644 index 000000000..3aea1cf0c --- /dev/null +++ b/modules/completion/corfu/config.el @@ -0,0 +1,114 @@ +;;; completion/corfu/config.el -*- lexical-binding: t; -*- + +;; +;;; Packages +(use-package! corfu + :hook (doom-first-input . global-corfu-mode) + :config + (setq corfu-auto t + corfu-auto-delay 0.1 + corfu-auto-prefix 2 + global-corfu-modes '((not + erc-mode + circe-mode + help-mode + gud-mode + vterm-mode) + t) + corfu-cycle t + corfu-separator (when (modulep! +orderless) ?\s) + corfu-preselect 'valid + corfu-count 16 + corfu-max-width 120 + corfu-preview-current 'insert + corfu-on-exact-match nil + corfu-quit-at-boundary (if (modulep! +orderless) 'separator t) + corfu-quit-no-match (if (modulep! +orderless) 'separator t) + ;; In the case of +tng, TAB should be smart regarding completion; + ;; However, it should otherwise behave like normal, whatever normal was. + tab-always-indent (if (modulep! +tng) 'complete tab-always-indent)) + (add-to-list 'completion-category-overrides `(lsp-capf (styles ,@completion-styles))) + + (map! :map corfu-mode-map + :e "C-M-i" #'completion-at-point + :i "C-SPC" #'completion-at-point + :n "C-SPC" (cmd! (call-interactively #'evil-insert-state) + (call-interactively #'completion-at-point)) + :v "C-SPC" (cmd! (call-interactively #'evil-change) + (call-interactively #'completion-at-point))) + (map! :unless (modulep! :editor evil) + :map corfu-mode-map + "C-M-i" #'completion-at-point) + + (after! evil + (add-hook 'evil-insert-state-exit-hook #'corfu-quit)) + + (when (modulep! +icons) + (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) + + (map! :map corfu-map + [return] #'corfu-insert + "RET" #'corfu-insert) + (when (modulep! +orderless) + (map! :map corfu-map + "C-SPC" #'corfu-insert-separator)) + (when (modulep! +tng) + (map! :map corfu-map + [tab] #'corfu-next + [backtab] #'corfu-previous + "TAB" #'corfu-next + "S-TAB" #'corfu-previous) + (let ((cmds-del (cmds! (and (modulep! +tng) + (> corfu--index -1) + (eq corfu-preview-current 'insert)) + #'corfu-reset))) + (map! :map corfu-map + [backspace] cmds-del + "DEL" cmds-del))) + + (after! vertico + (map! :map corfu-map + "M-m" #'+corfu-move-to-minibuffer + (:when (modulep! :editor evil) + "M-J" #'+corfu-move-to-minibuffer)))) + +(use-package! cape + :defer t + :init + (add-hook! prog-mode + (defun +corfu-add-cape-file-h () + (add-to-list 'completion-at-point-functions #'cape-file))) + (add-hook! (org-mode markdown-mode) + (defun +corfu-add-cape-elisp-block-h () + (add-to-list 'completion-at-point-functions #'cape-elisp-block))) + (advice-add #'lsp-completion-at-point :around #'cape-wrap-noninterruptible)) + +(use-package! corfu-terminal + :when (not (display-graphic-p)) + :hook ((corfu-mode . corfu-terminal-mode))) + +;; +;;; Extensions + +(use-package! corfu-history + :hook ((corfu-mode . corfu-history-mode)) + :config + (after! savehist (add-to-list 'savehist-additional-variables 'corfu-history))) + + +(use-package! corfu-popupinfo + :hook ((corfu-mode . corfu-popupinfo-mode)) + :config + (setq corfu-popupinfo-delay '(0.5 . 1.0)) + (map! :map corfu-map + "C-" #'corfu-popupinfo-scroll-down + "C-" #'corfu-popupinfo-scroll-up + "C-S-p" #'corfu-popupinfo-scroll-down + "C-S-n" #'corfu-popupinfo-scroll-up + "C-h" #'corfu-popupinfo-toggle) + (map! :when (modulep! :editor evil) + :map corfu-popupinfo-map + ;; Reversed because popupinfo assumes opposite of what feels intuitive + ;; with evil. + "C-S-k" #'corfu-popupinfo-scroll-down + "C-S-j" #'corfu-popupinfo-scroll-up)) diff --git a/modules/completion/corfu/packages.el b/modules/completion/corfu/packages.el new file mode 100644 index 000000000..1620fcf99 --- /dev/null +++ b/modules/completion/corfu/packages.el @@ -0,0 +1,11 @@ +;; -*- no-byte-compile: t; -*- +;;; completion/corfu/packages.el + +(package! corfu :pin "24dccafeea114b1aec7118f2a8405b46aa0051e0") +(package! cape :pin "18a30f48bb8754421cb10dad99e0a406173d4551") +(when (modulep! +icons) + (package! nerd-icons-corfu :pin "7077bb76fefc15aed967476406a19dc5c2500b3c")) +(when (modulep! +orderless) + (package! orderless :pin "b24748093b00b37c3a572c4909f61c08fa27504f")) +(when (modulep! :os tty) + (package! corfu-terminal :pin "501548c3d51f926c687e8cd838c5865ec45d03cc")) diff --git a/modules/tools/lsp/+lsp.el b/modules/tools/lsp/+lsp.el index 5ae4a417d..96361aae4 100644 --- a/modules/tools/lsp/+lsp.el +++ b/modules/tools/lsp/+lsp.el @@ -138,8 +138,11 @@ server getting expensively restarted when reverting buffers." " ")) (add-to-list 'global-mode-string '(t (:eval lsp-modeline-icon)) - 'append)))))) + 'append))))) + (when (modulep! :completion corfu) + (setq lsp-completion-provider :none) + (add-hook 'lsp-mode-hook #'lsp-completion-mode))) (use-package! lsp-ui :hook (lsp-mode . lsp-ui-mode) From 8ed223c98efa86ecc87d86e9b89fcf8627d77ef4 Mon Sep 17 00:00:00 2001 From: Luigi Sartor Piucco Date: Wed, 26 Jul 2023 19:57:21 -0300 Subject: [PATCH 26/49] feat(corfu): add snippets Yasnippet is now properly integrated! A previosly-unset default has now been given to `corfu-on-exact-match`. With snippets, it causes immediate expansion upon single match by default, so we set it to nil and recommend against changing it in the README. --- modules/completion/corfu/README.org | 3 ++- modules/completion/corfu/config.el | 8 ++++++++ modules/completion/corfu/packages.el | 2 ++ 3 files changed, 12 insertions(+), 1 deletion(-) diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org index f300bde8c..534aa04a2 100644 --- a/modules/completion/corfu/README.org +++ b/modules/completion/corfu/README.org @@ -33,6 +33,7 @@ and highly non-native, but has some extra features and more maturity. - [[doom-package:nerd-icons-corfu]] if [[doom-module::completion corfu +icons]] - [[doom-package:orderless]] if [[doom-module::completion corfu +orderless]] - [[doom-package:corfu-terminal]] if [[doom-module::os tty]] +- [[doom-package:yasnippet-capf]] if [[doom-module::editor snippets]] ** Hacks /No hacks documented for this module./ @@ -50,7 +51,7 @@ languages may lack code completion support altogether). Run ~$ doom doctor~ to find out if you're missing any dependencies. Note that Corfu may have support for completions in languages that have no development intelligence, since it supports generic, context insensitive candidates such as file names or recurring -words. +words. Snippets may also appear in the candidate list if available. * TODO Usage #+begin_quote diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index 3aea1cf0c..3aa9ce71c 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -83,6 +83,14 @@ (add-to-list 'completion-at-point-functions #'cape-elisp-block))) (advice-add #'lsp-completion-at-point :around #'cape-wrap-noninterruptible)) +(use-package! yasnippet-capf + :when (modulep! :editor snippets) + :defer t + :init + (add-hook! 'yas-minor-mode-hook + (defun +corfu-add-yasnippet-capf-h () + (add-hook 'completion-at-point-functions #'yasnippet-capf 30 t)))) + (use-package! corfu-terminal :when (not (display-graphic-p)) :hook ((corfu-mode . corfu-terminal-mode))) diff --git a/modules/completion/corfu/packages.el b/modules/completion/corfu/packages.el index 1620fcf99..ec9edc23f 100644 --- a/modules/completion/corfu/packages.el +++ b/modules/completion/corfu/packages.el @@ -9,3 +9,5 @@ (package! orderless :pin "b24748093b00b37c3a572c4909f61c08fa27504f")) (when (modulep! :os tty) (package! corfu-terminal :pin "501548c3d51f926c687e8cd838c5865ec45d03cc")) +(when (modulep! :editor snippets) + (package! yasnippet-capf :pin "a0a6b1c2bb6decdad5cf9b74202f0042f494a6ab")) From 948f2b77053646a251fc83dd890412da347b7e80 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Mon, 30 Oct 2023 14:36:19 -0400 Subject: [PATCH 27/49] feat(corfu): more CAPFs and ergonomy changes Add various CAPFs from cape: - `cape-dabbrev`; - `cape-emoji`; - `cape-dict`; Fixed 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`/`backspace` for `+tng`; - Smart `RET`; Add depth to CAPFs, allowing ordering to be adjustable. Enable in minibuffer. --- modules/completion/corfu/README.org | 64 ++++++++++++++++--------- modules/completion/corfu/config.el | 73 +++++++++++++++++++++++++++-- 2 files changed, 113 insertions(+), 24 deletions(-) diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org index 534aa04a2..64935940e 100644 --- a/modules/completion/corfu/README.org +++ b/modules/completion/corfu/README.org @@ -26,6 +26,14 @@ and highly non-native, but has some extra features and more maturity. - +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. +- +dict :: + Enable and configure dictionary completion for text modes and related regions + in programming modes. +- +emoji :: + Enable and configure emoji completion via the emoji input method. ** Packages - [[doom-package:corfu]] @@ -63,26 +71,25 @@ By default, completion gets triggered after typing 2 non-space consecutive characters, or by means of the [[kbd:][C-SPC]] keybinding at any moment. While the popup is visible, the following relevant keys are available: -| Keybind | Description | -|----------+------------------------------------------------------------------| -| [[kbd:][]] | Go to next candidate | -| [[kbd:][]] | Go to previous candidate | -| [[kbd:][C-n]] | Go to next candidate | -| [[kbd:][C-p]] | Go to previous candidate | -| [[kbd:][C-j]] | (evil) Go to next candidate | -| [[kbd:][C-k]] | (evil) Go to previous candidate | -| [[kbd:][C-]] | Go to next doc line | -| [[kbd:][C-]] | Go to previous doc line | -| [[kbd:][C-S-n]] | Go to next doc line | -| [[kbd:][C-S-p]] | Go to previous doc line | -| [[kbd:][C-S-j]] | (evil) Go to next doc line | -| [[kbd:][C-S-k]] | (evil) Go to previous doc line | -| [[kbd:][C-h]] | Toggle documentation (if available) | +| Keybind | Description | +|----------+---------------------------------------------------------| +| [[kbd:][]] | Go to next candidate | +| [[kbd:][]] | Go to previous candidate | +| [[kbd:][C-n]] | Go to next candidate | +| [[kbd:][C-p]] | Go to previous candidate | +| [[kbd:][C-j]] | (evil) Go to next candidate | +| [[kbd:][C-k]] | (evil) Go to previous candidate | +| [[kbd:][C-]] | Go to next doc line | +| [[kbd:][C-]] | Go to previous doc line | +| [[kbd:][C-S-n]] | Go to next doc line | +| [[kbd:][C-S-p]] | Go to previous doc line | +| [[kbd:][C-S-j]] | (evil) Go to next doc line | +| [[kbd:][C-S-k]] | (evil) Go to previous doc line | +| [[kbd:][C-h]] | Toggle documentation (if available) | | [[kbd:][M-m]] | Export to minibuffer (if [[doom-module::completion vertico]]) | -| [[kbd:][M-S-j]] | (evil) Export to minibuffer (if [[doom-module::completion vertico]]) | -| [[kbd:][RET]] | Insert candidate | -| [[kbd:][SPC]] | (after wildcard) Reset completion | -| [[kbd:][DEL]] | Reset completion | +| [[kbd:][M-j]] | (evil) Export to minibuffer (if [[doom-module::completion vertico]]) | +| [[kbd:][RET]] | Insert candidate | +| [[kbd:][SPC]] | Quit autocompletion after a wildcard or pass-through | | [[kbd:][C-SPC]] | Complete (unless [[doom-module::completion corfu +tng]]) | | [[kbd:][C-SPC]] | (when completing) Insert separator DWIM (see below) | @@ -95,6 +102,7 @@ following additional binds: | [[kbd:][TAB]] | Complete | | [[kbd:][TAB]] | (when completing) Go to next candidate | | [[kbd:][S-TAB]] | (when completing) Go to previous candidate | +| [[kbd:][DEL]] | (when completing) Reset completion DWIM-style | ** Searching with multiple keywords If the [[doom-module::completion corfu +orderless]] flag is enabled, users can @@ -129,15 +137,18 @@ A few variables may be set to change behavior of this module: Configures behavior for exact matches. Its default is nil, and it's recommended to leave it at that. Otherwise, single matches on snippet keys expand immediately. +- [[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 of omitted. Also @@ -147,6 +158,17 @@ accepts the quoted arguments form above. * 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 3aa9ce71c..a8ca47fd8 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -1,5 +1,8 @@ ;;; completion/corfu/config.el -*- lexical-binding: t; -*- +(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 @@ -17,7 +20,7 @@ t) corfu-cycle t corfu-separator (when (modulep! +orderless) ?\s) - corfu-preselect 'valid + corfu-preselect (if (modulep! +tng) 'prompt 'valid) corfu-count 16 corfu-max-width 120 corfu-preview-current 'insert @@ -40,6 +43,13 @@ :map corfu-mode-map "C-M-i" #'completion-at-point) + (add-hook! 'minibuffer-setup-hook + (defun +corfu-enable-in-minibuffer () + "Enable Corfu in the minibuffer if `completion-at-point' is bound." + (when (where-is-internal #'completion-at-point (list (current-local-map))) + (setq-local corfu-echo-delay nil) + (corfu-mode +1)))) + (after! evil (add-hook 'evil-insert-state-exit-hook #'corfu-quit)) @@ -77,10 +87,67 @@ :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-to-list 'completion-at-point-functions #'cape-elisp-block))) + (add-hook 'completion-at-point-functions #'cape-elisp-block 0 t))) + ;; Enable Dabbrev completion basically everywhere as a fallback. + (when (modulep! +dabbrev) + ;; Set up `cape-dabbrev' options. + (defun +dabbrev-friend-buffer-p (other-buffer) + (< (buffer-size other-buffer) +corfu-buffer-scanning-size-limit)) + (after! dabbrev + (setq cape-dabbrev-check-other-buffers t + 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) + + (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))))) + ;; Complete emojis :). + (when (and (modulep! +emoji) (> emacs-major-version 28)) + (add-hook! (prog-mode conf-mode) + (defun +corfu-add-cape-emoji-h () + (add-hook 'completion-at-point-functions + (cape-capf-inside-faces + (cape-capf-prefix-length #'cape-emoji 1) + ;; Only call inside comments and docstrings. + 'tree-sitter-hl-face:doc 'font-lock-doc-face + 'font-lock-comment-face 'tree-sitter-hl-face:comment) + 10 t))) + (add-hook! text-mode + (defun +corfu-add-cape-emoji-text-h () + (add-hook 'completion-at-point-functions + (cape-capf-prefix-length #'cape-emoji 1) 10 t)))) + ;; Enable dictionary-based autocompletion. + (when (modulep! +dict) + (add-hook! (prog-mode conf-mode) + (defun +corfu-add-cape-dict-h () + (add-hook 'completion-at-point-functions + (cape-capf-inside-faces + ;; Only call inside comments and docstrings. + #'cape-dict 'tree-sitter-hl-face:doc 'font-lock-doc-face + 'font-lock-comment-face 'tree-sitter-hl-face:comment) + 40 t))) + (add-hook! text-mode + (defun +corfu-add-cape-dict-text-h () + (add-hook 'completion-at-point-functions #'cape-dict 40 t)))) + + ;; Make these capfs composable. + (advice-add #'comint-completion-at-point :around #'cape-wrap-nonexclusive) + (advice-add #'eglot-completion-at-point :around #'cape-wrap-nonexclusive) + (advice-add #'lsp-completion-at-point :around #'cape-wrap-nonexclusive) + (advice-add #'pcomplete-completions-at-point :around #'cape-wrap-nonexclusive) + ;; From the `cape' readme. Without this, Eshell autocompletion is broken on + ;; Emacs28. + (when (< emacs-major-version 29) + (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-silent) + (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify)) (advice-add #'lsp-completion-at-point :around #'cape-wrap-noninterruptible)) (use-package! yasnippet-capf From 8ef4ce631118c0d32e2a1b63978ba9a214f6dd44 Mon Sep 17 00:00:00 2001 From: Luigi Sartor Piucco Date: Sun, 29 Oct 2023 14:31:13 -0300 Subject: [PATCH 28/49] feat(corfu,vertico): use equal orderless config This removes the old `&` separator for Vertico (does anyone use that instead of just space?) in favor of escapable space and unifies orderless config with Corfu. Also implements smart separator insert/escape/reset on `C-SPC` Co-authored-by: Liam Hupfer --- modules/completion/corfu/README.org | 39 +++++++++++++++------------- modules/completion/corfu/autoload.el | 15 +++++++++++ modules/completion/corfu/config.el | 33 +++++++++++------------ modules/completion/vertico/config.el | 2 +- 4 files changed, 54 insertions(+), 35 deletions(-) diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org index 64935940e..fe9b09ee0 100644 --- a/modules/completion/corfu/README.org +++ b/modules/completion/corfu/README.org @@ -71,25 +71,25 @@ By default, completion gets triggered after typing 2 non-space consecutive characters, or by means of the [[kbd:][C-SPC]] keybinding at any moment. While the popup is visible, the following relevant keys are available: -| Keybind | Description | -|----------+---------------------------------------------------------| -| [[kbd:][]] | Go to next candidate | -| [[kbd:][]] | Go to previous candidate | -| [[kbd:][C-n]] | Go to next candidate | -| [[kbd:][C-p]] | Go to previous candidate | -| [[kbd:][C-j]] | (evil) Go to next candidate | -| [[kbd:][C-k]] | (evil) Go to previous candidate | -| [[kbd:][C-]] | Go to next doc line | -| [[kbd:][C-]] | Go to previous doc line | -| [[kbd:][C-S-n]] | Go to next doc line | -| [[kbd:][C-S-p]] | Go to previous doc line | -| [[kbd:][C-S-j]] | (evil) Go to next doc line | -| [[kbd:][C-S-k]] | (evil) Go to previous doc line | -| [[kbd:][C-h]] | Toggle documentation (if available) | +| Keybind | Description | +|----------+------------------------------------------------------------------| +| [[kbd:][]] | Go to next candidate | +| [[kbd:][]] | Go to previous candidate | +| [[kbd:][C-n]] | Go to next candidate | +| [[kbd:][C-p]] | Go to previous candidate | +| [[kbd:][C-j]] | (evil) Go to next candidate | +| [[kbd:][C-k]] | (evil) Go to previous candidate | +| [[kbd:][C-]] | Go to next doc line | +| [[kbd:][C-]] | Go to previous doc line | +| [[kbd:][C-S-n]] | Go to next doc line | +| [[kbd:][C-S-p]] | Go to previous doc line | +| [[kbd:][C-S-j]] | (evil) Go to next doc line | +| [[kbd:][C-S-k]] | (evil) Go to previous doc line | +| [[kbd:][C-h]] | Toggle documentation (if available) | | [[kbd:][M-m]] | Export to minibuffer (if [[doom-module::completion vertico]]) | | [[kbd:][M-j]] | (evil) Export to minibuffer (if [[doom-module::completion vertico]]) | -| [[kbd:][RET]] | Insert candidate | -| [[kbd:][SPC]] | Quit autocompletion after a wildcard or pass-through | +| [[kbd:][RET]] | Insert candidate | +| [[kbd:][SPC]] | Quit autocompletion after a wildcard or pass-through | | [[kbd:][C-SPC]] | Complete (unless [[doom-module::completion corfu +tng]]) | | [[kbd:][C-SPC]] | (when completing) Insert separator DWIM (see below) | @@ -112,7 +112,10 @@ completing inserts a space as separator. This allows searching with space-separated terms; each piece will match individually and in any order, with smart casing. Pressing just [[kbd:][SPC]] acts as normal and quits completion, so that when typing sentences it doesn't try to complete the whole sentence instead of -just the word. +just the word. Pressing [[kdb:][C-SPC]] with point after a separator escapes it with a +backslash, including the space in the search term, and pressing it with an +already escaped separator before point deletes it. Thus, you can cycle back if +you accidentaly press more than needed. Additionally, for users of evil and regular corfu style, [[kdb:][C-SPC]] is smart regarding your state. In normal-like states, enter insert then start corfu; in diff --git a/modules/completion/corfu/autoload.el b/modules/completion/corfu/autoload.el index c34cb8232..618aae42d 100644 --- a/modules/completion/corfu/autoload.el +++ b/modules/completion/corfu/autoload.el @@ -8,3 +8,18 @@ (let ((completion-extra-properties corfu--extra) (completion-cycle-threshold completion-cycling)) (apply #'consult-completion-in-region completion-in-region--data))) + +;;;###autoload +(defun +corfu-smart-sep-toggle-escape () + "Insert `corfu-separator' or toggle escape if it's already there." + (interactive) + (cond ((and (char-equal (char-before) corfu-separator) + (char-equal (char-before (1- (point))) ?\\)) + (save-excursion (delete-char -2))) + ((char-equal (char-before) corfu-separator) + (save-excursion (backward-char 1) + (insert-char ?\\))) + (t + ;; Without this corfu quits immediately. + (setq this-command #'corfu-insert-separator) + (call-interactively #'corfu-insert-separator)))) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index a8ca47fd8..0710b838e 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -56,26 +56,27 @@ (when (modulep! +icons) (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) - (map! :map corfu-map - [return] #'corfu-insert - "RET" #'corfu-insert) - (when (modulep! +orderless) + (let ((cmds-del (cmds! (and (modulep! +tng) + (> corfu--index -1) + (eq corfu-preview-current 'insert)) + #'corfu-reset))) (map! :map corfu-map - "C-SPC" #'corfu-insert-separator)) - (when (modulep! +tng) - (map! :map corfu-map - [tab] #'corfu-next - [backtab] #'corfu-previous - "TAB" #'corfu-next - "S-TAB" #'corfu-previous) - (let ((cmds-del (cmds! (and (modulep! +tng) - (> corfu--index -1) - (eq corfu-preview-current 'insert)) - #'corfu-reset))) - (map! :map corfu-map + [return] #'corfu-insert + "RET" #'corfu-insert + (:when (modulep! +orderless) + " " #'+corfu-smart-sep-toggle-escape) + (:when (modulep! +tng) + [tab] #'corfu-next + [backtab] #'corfu-previous + "TAB" #'corfu-next + "S-TAB" #'corfu-previous [backspace] cmds-del "DEL" cmds-del))) + (when (modulep! +orderless) + (after! orderless + (setq orderless-component-separator #'orderless-escapable-split-on-space))) + (after! vertico (map! :map corfu-map "M-m" #'+corfu-move-to-minibuffer diff --git a/modules/completion/vertico/config.el b/modules/completion/vertico/config.el index 0d52ab950..3f2bf3f30 100644 --- a/modules/completion/vertico/config.el +++ b/modules/completion/vertico/config.el @@ -107,7 +107,7 @@ orderless." ;; find-file etc. completion-category-overrides '((file (styles +vertico-basic-remote orderless partial-completion))) orderless-style-dispatchers '(+vertico-orderless-dispatch) - orderless-component-separator "[ &]") + orderless-component-separator #'orderless-escapable-split-on-space) ;; ...otherwise find-file gets different highlighting than other commands (set-face-attribute 'completions-first-difference nil :inherit nil)) From 7bbef948546758d9b3123e1e521b5992497db262 Mon Sep 17 00:00:00 2001 From: Luigi Sartor Piucco Date: Mon, 11 Dec 2023 19:12:54 -0300 Subject: [PATCH 29/49] fix(corfu): move binds to `:config default` Bindings were moved to the `:config default` module and some keys were adjusted to match Company/other modules. The changes were documented in the README. --- modules/completion/corfu/README.org | 88 +++++++++++++++++------ modules/completion/corfu/config.el | 50 +------------ modules/config/default/+emacs-bindings.el | 9 ++- modules/config/default/+evil-bindings.el | 44 ++++++++++-- modules/config/default/config.el | 33 +++++++++ 5 files changed, 150 insertions(+), 74 deletions(-) diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org index fe9b09ee0..e9354f8a2 100644 --- a/modules/completion/corfu/README.org +++ b/modules/completion/corfu/README.org @@ -71,27 +71,26 @@ By default, completion gets triggered after typing 2 non-space consecutive characters, or by means of the [[kbd:][C-SPC]] keybinding at any moment. While the popup is visible, the following relevant keys are available: -| Keybind | Description | -|----------+------------------------------------------------------------------| -| [[kbd:][]] | Go to next candidate | -| [[kbd:][]] | Go to previous candidate | -| [[kbd:][C-n]] | Go to next candidate | -| [[kbd:][C-p]] | Go to previous candidate | -| [[kbd:][C-j]] | (evil) Go to next candidate | -| [[kbd:][C-k]] | (evil) Go to previous candidate | -| [[kbd:][C-]] | Go to next doc line | -| [[kbd:][C-]] | Go to previous doc line | -| [[kbd:][C-S-n]] | Go to next doc line | -| [[kbd:][C-S-p]] | Go to previous doc line | -| [[kbd:][C-S-j]] | (evil) Go to next doc line | -| [[kbd:][C-S-k]] | (evil) Go to previous doc line | -| [[kbd:][C-h]] | Toggle documentation (if available) | -| [[kbd:][M-m]] | Export to minibuffer (if [[doom-module::completion vertico]]) | -| [[kbd:][M-j]] | (evil) Export to minibuffer (if [[doom-module::completion vertico]]) | -| [[kbd:][RET]] | Insert candidate | -| [[kbd:][SPC]] | Quit autocompletion after a wildcard or pass-through | -| [[kbd:][C-SPC]] | Complete (unless [[doom-module::completion corfu +tng]]) | -| [[kbd:][C-SPC]] | (when completing) Insert separator DWIM (see below) | +| Keybind | Description | +|----------+-----------------------------------------------------------| +| [[kbd:][]] | Go to next candidate | +| [[kbd:][]] | Go to previous candidate | +| [[kbd:][C-n]] | Go to next candidate | +| [[kbd:][C-p]] | Go to previous candidate | +| [[kbd:][C-j]] | (evil) Go to next candidate | +| [[kbd:][C-k]] | (evil) Go to previous candidate | +| [[kbd:][C-]] | Go to next doc line | +| [[kbd:][C-]] | Go to previous doc line | +| [[kbd:][C-S-n]] | Go to next doc line | +| [[kbd:][C-S-p]] | Go to previous doc line | +| [[kbd:][C-S-j]] | (evil) Go to next doc line | +| [[kbd:][C-S-k]] | (evil) Go to previous doc line | +| [[kbd:][C-h]] | Toggle documentation (if available) | +| [[kbd:][C-S-s]] | Export to minibuffer (if [[doom-module::completion vertico]]) | +| [[kbd:][RET]] | Insert candidate | +| [[kbd:][SPC]] | Quit autocompletion or pass-through after a wildcard | +| [[kbd:][C-SPC]] | Complete (unless [[doom-module::completion corfu +tng]]) | +| [[kbd:][C-SPC]] | (when completing) Insert separator DWIM (see below) | If you prefer a [[kbd:][TAB]]-centric completion style, enable the [[doom-module::completion corfu +tng]] flag so that, instead, you trigger completion with [[kbd:][TAB]], getting the @@ -129,9 +128,42 @@ exported to a consult minibuffer, giving access to all the manipulations the Vertico suite allows. For instance, one could use this to export with [[doom-package:embark]] via [[kbd:][C-c C-l]] and get a buffer with all candidates. +** Manually call generic CAPFs +Completion at point functions have the property that, when called interactively +via their symbol, they work as a call to ~completion-at-point~ where +[[var:completion-at-point-functions]] is bound to that CAPF alone. This allows to +assign generic functions to a binding and call as needed, leaving the default +value used for most completion tasks much leaner (thus, faster and easier to +look through). This module provides some such bindings for Evil users (see the +table below), and you're free map your own of course. Emacs users have to map it +themselves for now, due to the author's lack of knowledge on ergonomic +equivalents to the Evil ones. If you have suggestions, though, we'd be happy to +know! + +| Keybind | Description | +|---------+---------------------------------| +| [[kbd:][C-x]] [[kbd:][C-l]] | (insert-state) ~cape-line~ | +| [[kbd:][C-x]] [[kbd:][C-k]] | (insert-state) ~cape-keyword~ | +| [[kbd:][C-x]] [[kbd:][C-f]] | (insert-state) ~cape-file~ | +| [[kbd:][C-x]] [[kbd:][s]] | (insert-state) ~cape-dict~ | +| [[kbd:][C-x]] [[kbd:][C-s]] | (insert-state) ~yasnippet-capf~ | +| [[kbd:][C-x]] [[kbd:][C-n]] | (insert-state) ~cape-dabbrev~ | +| [[kbd:][C-x]] [[kbd:][C-p]] | (insert-state) ~cape-history~ | + * Configuration A few variables may be set to change behavior of this module: +- [[var:completion-at-point-functions]] :: + This is not a module/package variable, but a builtin Emacs one. Even so, it's + very important to how Corfu works, so we document it here. It contains a list + of functions that are called in turn to generate completion candidates. The + regular (non-lexical) value should contain few entries and they should + generally be context aware, so as to predict what you need. Additional + functions can be added as you get into more and more specific contexts. Also, + there may be cases where you know beforehand the kind of candidate needed, and + want to enable only that one. For this, the variable may be lexically bound to + the correct value, or you may call the CAPF interactively if a single function + is all you need. - [[var:corfu-auto-delay]] :: Number of seconds till completion occurs automatically. Defaults to 0.1. - [[var:corfu-auto-prefix]] :: @@ -158,6 +190,20 @@ To add other CAPFs on a mode-per-mode basis, put either of the following in your see ~add-hook!~'s documentation for additional ways to call it. ~add-hook~ only accepts the quoted arguments form above. +** Adding CAPFs to a key +To add other CAPFs to keys, adapt the snippet below into your ~config.el~: +#+begin_src emacs-lisp +;; For binding inside `corfu-mode-map'. Line 1 ensures the binding only exists +;; after some-mode-hook runs. Line 2 is needed only if the binding can't leak +;; into other Corfu buffers. When neither of the above make sense, the `map!' +;; call is enough. +(add-hook! some-mode ; Only needed if the binding is mode-specific + (make-local-variable 'corfu-mode-map) + (map! :map corfu-mode-map + :prefix "C-x" ; C-x is usually used as prefix, but it's not required + "e" #'cape-emoji)) ; Evil users probably want :i to avoid this in other states +#+end_src + * Troubleshooting [[doom-report:][Report an issue?]] diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index 0710b838e..d4bad1f24 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -32,17 +32,6 @@ tab-always-indent (if (modulep! +tng) 'complete tab-always-indent)) (add-to-list 'completion-category-overrides `(lsp-capf (styles ,@completion-styles))) - (map! :map corfu-mode-map - :e "C-M-i" #'completion-at-point - :i "C-SPC" #'completion-at-point - :n "C-SPC" (cmd! (call-interactively #'evil-insert-state) - (call-interactively #'completion-at-point)) - :v "C-SPC" (cmd! (call-interactively #'evil-change) - (call-interactively #'completion-at-point))) - (map! :unless (modulep! :editor evil) - :map corfu-mode-map - "C-M-i" #'completion-at-point) - (add-hook! 'minibuffer-setup-hook (defun +corfu-enable-in-minibuffer () "Enable Corfu in the minibuffer if `completion-at-point' is bound." @@ -56,32 +45,9 @@ (when (modulep! +icons) (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) - (let ((cmds-del (cmds! (and (modulep! +tng) - (> corfu--index -1) - (eq corfu-preview-current 'insert)) - #'corfu-reset))) - (map! :map corfu-map - [return] #'corfu-insert - "RET" #'corfu-insert - (:when (modulep! +orderless) - " " #'+corfu-smart-sep-toggle-escape) - (:when (modulep! +tng) - [tab] #'corfu-next - [backtab] #'corfu-previous - "TAB" #'corfu-next - "S-TAB" #'corfu-previous - [backspace] cmds-del - "DEL" cmds-del))) - (when (modulep! +orderless) (after! orderless - (setq orderless-component-separator #'orderless-escapable-split-on-space))) - - (after! vertico - (map! :map corfu-map - "M-m" #'+corfu-move-to-minibuffer - (:when (modulep! :editor evil) - "M-J" #'+corfu-move-to-minibuffer)))) + (setq orderless-component-separator #'orderless-escapable-split-on-space)))) (use-package! cape :defer t @@ -175,16 +141,4 @@ (use-package! corfu-popupinfo :hook ((corfu-mode . corfu-popupinfo-mode)) :config - (setq corfu-popupinfo-delay '(0.5 . 1.0)) - (map! :map corfu-map - "C-" #'corfu-popupinfo-scroll-down - "C-" #'corfu-popupinfo-scroll-up - "C-S-p" #'corfu-popupinfo-scroll-down - "C-S-n" #'corfu-popupinfo-scroll-up - "C-h" #'corfu-popupinfo-toggle) - (map! :when (modulep! :editor evil) - :map corfu-popupinfo-map - ;; Reversed because popupinfo assumes opposite of what feels intuitive - ;; with evil. - "C-S-k" #'corfu-popupinfo-scroll-down - "C-S-j" #'corfu-popupinfo-scroll-up)) + (setq corfu-popupinfo-delay '(0.5 . 1.0))) diff --git a/modules/config/default/+emacs-bindings.el b/modules/config/default/+emacs-bindings.el index 7aa4dfc41..2402e7885 100644 --- a/modules/config/default/+emacs-bindings.el +++ b/modules/config/default/+emacs-bindings.el @@ -511,7 +511,7 @@ "C-x C-b" #'ibuffer "C-x K" #'doom/kill-this-buffer-in-all-windows - ;;; company-mode + ;;; completion (in-buffer) (:when (modulep! :completion company) "C-;" #'+company/complete (:after company @@ -537,6 +537,13 @@ "C-p" #'company-search-repeat-backward "C-s" (cmd! (company-search-abort) (company-filter-candidates)))) + (:when (modulep! :completion corfu) + :after corfu + (:map corfu-mode-map + "C-M-i" #'completion-at-point) + (:map corfu-popupinfo-map + "C-S-h" #'corfu-popupinfo-toggle)) + ;;; ein notebooks (:after ein:notebook-multilang :map ein:notebook-multilang-mode-map diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index fd2487410..b86e58800 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -43,7 +43,10 @@ #'yas-expand (and (bound-and-true-p company-mode) (modulep! :completion company +tng)) - #'company-indent-or-complete-common) + #'company-indent-or-complete-common + (and (bound-and-true-p corfu-mode) + (modulep! :completion corfu +tng)) + #'completion-at-point) :m [tab] (cmds! (and (modulep! :editor snippets) (evil-visual-state-p) (or (eq evil-visual-selection 'line) @@ -127,7 +130,7 @@ ;; ;;; Module keybinds -;;; :completion +;;; :completion (in-buffer) (map! (:when (modulep! :completion company) :i "C-@" (cmds! (not (minibufferp)) #'company-complete-common) :i "C-SPC" (cmds! (not (minibufferp)) #'company-complete-common) @@ -156,7 +159,39 @@ "C-s" #'company-filter-candidates [escape] #'company-search-abort))) - (:when (modulep! :completion ivy) + (:when (modulep! :completion corfu) + (:after corfu + (:map corfu-mode-map + :e "C-M-i" #'completion-at-point + (:prefix "C-x" + :i "C-l" #'cape-line + :i "C-k" #'cape-keyword + :i "C-f" #'cape-file + :i "s" #'cape-dict + :i "C-s" #'yasnippet-capf + :i "C-n" #'cape-dabbrev + :i "C-p" #'cape-history) + (:unless (modulep! :completion corfu +tng) + :i "C-SPC" #'completion-at-point + :n "C-SPC" (cmd! (call-interactively #'evil-insert-state) + (call-interactively #'completion-at-point)) + :v "C-SPC" (cmd! (call-interactively #'evil-change) + (call-interactively #'completion-at-point)))) + (:map corfu-map + "C-u" (cmd! (let (corfu-cycle) + (funcall-interactively #'corfu-next (- corfu-count)))) + "C-d" (cmd! (let (corfu-cycle) + (funcall-interactively #'corfu-next corfu-count))))) + (:after corfu-popupinfo + :map corfu-popupinfo-map + ;; Reversed because popupinfo assumes opposite of what feels intuitive + ;; with evil. + "C-S-k" #'corfu-popupinfo-scroll-down + "C-S-j" #'corfu-popupinfo-scroll-up + "C-h" #'corfu-popupinfo-toggle))) + +;;; :completion (separate) +(map! (:when (modulep! :completion ivy) (:after ivy :map ivy-minibuffer-map "C-SPC" #'ivy-call-and-recenter ; preview file @@ -169,7 +204,8 @@ [C-return] #'+ivy/git-grep-other-window-action)) (:when (modulep! :completion helm) - (:after helm :map helm-map + (:after helm + :map helm-map [remap next-line] #'helm-next-line [remap previous-line] #'helm-previous-line [left] #'left-char diff --git a/modules/config/default/config.el b/modules/config/default/config.el index e67adf1e3..b8b8f2c91 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -458,6 +458,39 @@ Continues comments if executed from a commented line. Consults '(evil-ex-completion-map))) "C-s" command)) + (map! :when (modulep! :completion corfu) + :after corfu + (:map corfu-map + [return] #'corfu-insert + "RET" #'corfu-insert + "C-S-s" #'+corfu-move-to-minibuffer + "C-p" #'corfu-previous + "C-n" #'corfu-next + (:when (modulep! :completion corfu +orderless) + [remap completion-at-point] #'+corfu-smart-sep-toggle-escape) + (:when (modulep! :completion corfu +tng) + [tab] #'corfu-next + "TAB" #'corfu-next + [backtab] #'corfu-previous + "S-TAB" #'corfu-previous)) + (:after corfu-popupinfo + :map corfu-popupinfo-map + "C-" #'corfu-popupinfo-scroll-down + "C-" #'corfu-popupinfo-scroll-up + "C-S-p" #'corfu-popupinfo-scroll-down + "C-S-n" #'corfu-popupinfo-scroll-up + "C-S-u" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-down corfu-popupinfo-min-height)) + "C-S-d" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-up corfu-popupinfo-min-height)))) + + (when-let ((cmds-del (and (modulep! :completion corfu +tng) + '(menu-item "Reset completion" corfu-reset + :enable (and (> corfu--index -1) + (eq corfu-preview-current 'insert)))))) + (map! :after corfu + :map corfu-map + [backspace] cmds-del + "DEL" cmds-del)) + ;; Smarter C-a/C-e for both Emacs and Evil. C-a will jump to indentation. ;; Pressing it again will send you to the true bol. Same goes for C-e, except ;; it will ignore comments+trailing whitespace before jumping to eol. From d666dcd71323d21fa035f7ee8aded99c17e2ccf6 Mon Sep 17 00:00:00 2001 From: Luigi Sartor Piucco Date: Thu, 21 Dec 2023 12:07:39 -0300 Subject: [PATCH 30/49] feat(corfu): impl smart confirm in minibuffer An issue when using corfu in the minibuffer was the need for pressing RET twice, since the first only inserts the completion. This commit aliviates that by providing C-RET to ignore completion and conclude the minibuffer imediately and S-RET to insert completion then conclude. --- modules/completion/corfu/README.org | 23 +++++++++++++++++++++++ modules/completion/corfu/autoload.el | 8 ++++++++ modules/config/default/config.el | 8 ++++++-- 3 files changed, 37 insertions(+), 2 deletions(-) diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org index e9354f8a2..39633da9f 100644 --- a/modules/completion/corfu/README.org +++ b/modules/completion/corfu/README.org @@ -103,6 +103,29 @@ following additional binds: | [[kbd:][S-TAB]] | (when completing) Go to previous candidate | | [[kbd:][DEL]] | (when completing) Reset completion DWIM-style | +*** Completion in the minibuffer +In the minibuffer, sometimes autocompletion can interfere with your goal; +Imagine you're composing a search pattern incrementally, and you find what you +want early, with only half the word. You then press [[kbd:RET]]. If completion +kicked in as you typed, you may lose the match, since it will complete the +first candidate. On the other hand, if you were paying attention to the +suggestions and selecting one appropriate, that's desired behavior, and you may +even desire to modify the prompt further (if you were composing a command +instead, you may want to extend it after the candidate). To allow better +control, there are 3 confirm bindings when Corfu appears in the minibuffer: + +| Keybind | Description | +|-----------+--------------------------------------------------------------------| +| [[kbd:RET]] | Accept the candidate only | +| [[kbd:C-RET]] | Confirm the current prompt only | +| [[kbd:S-RET]] | Accept the candidate then immediately confirm the completed prompt | + +- Use [[kbd:RET]] when you want to continue composing after completing; +- Use [[kbd:C-RET]] when you already have the desired string, and completing would + break it; +- Use [[kbd:S-RET]] when you know the composition will be finished after completion + (thus avoiding the need to type [[kbd:RET]] twice); + ** Searching with multiple keywords If the [[doom-module::completion corfu +orderless]] flag is enabled, users can perform code completion with multiple search keywords by use of space as the diff --git a/modules/completion/corfu/autoload.el b/modules/completion/corfu/autoload.el index 618aae42d..841802596 100644 --- a/modules/completion/corfu/autoload.el +++ b/modules/completion/corfu/autoload.el @@ -1,5 +1,13 @@ ;;; completion/corfu/autoload.el -*- lexical-binding: t; -*- +;;;###autoload +(defun +corfu-complete-and-exit-minibuffer () + (interactive) + (if (>= corfu--index 0) + (corfu-complete) + (corfu-insert)) + (exit-minibuffer)) + ;;;###autoload (defun +corfu-move-to-minibuffer () ;; Taken from corfu's README. diff --git a/modules/config/default/config.el b/modules/config/default/config.el index b8b8f2c91..1108190f9 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -480,8 +480,12 @@ Continues comments if executed from a commented line. Consults "C-S-p" #'corfu-popupinfo-scroll-down "C-S-n" #'corfu-popupinfo-scroll-up "C-S-u" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-down corfu-popupinfo-min-height)) - "C-S-d" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-up corfu-popupinfo-min-height)))) - + "C-S-d" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-up corfu-popupinfo-min-height))) + (:map corfu-map + "C-" '(menu-item "Conclude the minibuffer" exit-minibuffer + :enable (minibufferp nil t)) + "S-" '(menu-item "Insert completion and conclude" +corfu-complete-and-exit-minibuffer + :enable (minibufferp nil t)))) (when-let ((cmds-del (and (modulep! :completion corfu +tng) '(menu-item "Reset completion" corfu-reset :enable (and (> corfu--index -1) From 956b85310c73d2c24d738a07fe1d7840d8e6e3e1 Mon Sep 17 00:00:00 2001 From: Luigi Sartor Piucco Date: Sun, 4 Feb 2024 17:17:13 -0300 Subject: [PATCH 31/49] feat(corfu): general move-to-minibuffer impl We previously implemented only consult/vertico as a target for export, now we have all of them. It was necessary to use case-by-case conditions, unfortunately, because other UIs have subtle quirks that prevent a single generalized approach to work. Ivy is almost compliant, but it needs beg and end to not be markers. Helm doesn't replace `completion-in-region-function`, it expects to go around the default `completion--in-region`, so a small addition was made to its module, because we weren't doing that. This was likely an oversight due to the non-standard usage. This was fixed here because we need it working for this feature. Ido doesn't implement `completion-in-region` and its `completing-read` is retricted to a list of strings as table, so it's treated the same as absence of a framework, because it lacks the needed features. --- modules/completion/corfu/README.org | 11 +++++------ modules/completion/corfu/autoload.el | 28 +++++++++++++++++++++++----- modules/completion/corfu/config.el | 2 ++ modules/completion/helm/config.el | 1 + 4 files changed, 31 insertions(+), 11 deletions(-) diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org index 39633da9f..642d83cb2 100644 --- a/modules/completion/corfu/README.org +++ b/modules/completion/corfu/README.org @@ -144,12 +144,11 @@ regarding your state. In normal-like states, enter insert then start corfu; in visual-like states, perform [[help:evil-change][evil-change]] (which leaves you in insert state) then start corfu; in insert-like states, start corfu immediatelly. -** Exporting to the minibuffer (requires [[doom-module::completion vertico]]) -When using the [[doom-module::completion vertico]] module, which pulls in the -[[doom-package:consult]] package, the entries shown in the completion popup can be -exported to a consult minibuffer, giving access to all the manipulations the -Vertico suite allows. For instance, one could use this to export with -[[doom-package:embark]] via [[kbd:][C-c C-l]] and get a buffer with all candidates. +** Exporting to the minibuffer +The entries shown in the completion popup can be exported to a ~completing-read~ +minibuffer, giving access to all the manipulations that suite allows. Using +Vertico for instance, one could use this to export with [[doom-package:embark]] via +[[kbd:][C-c C-l]] and get a buffer with all candidates. ** Manually call generic CAPFs Completion at point functions have the property that, when called interactively diff --git a/modules/completion/corfu/autoload.el b/modules/completion/corfu/autoload.el index 841802596..195c49c4c 100644 --- a/modules/completion/corfu/autoload.el +++ b/modules/completion/corfu/autoload.el @@ -10,12 +10,30 @@ ;;;###autoload (defun +corfu-move-to-minibuffer () - ;; Taken from corfu's README. - ;; TODO: extend this to other completion front-ends. + "Move the current list of candidates to your choice of minibuffer completion UI." (interactive) - (let ((completion-extra-properties corfu--extra) - (completion-cycle-threshold completion-cycling)) - (apply #'consult-completion-in-region completion-in-region--data))) + (pcase completion-in-region--data + (`(,beg ,end ,table ,pred ,extras) + (let ((completion-extra-properties extras) + completion-cycle-threshold completion-cycling) + (cond ((and (modulep! :completion vertico) + (fboundp #'consult-completion-in-region)) + (consult-completion-in-region beg end table pred)) + ((and (modulep! :completion ivy) + (fboundp #'ivy-completion-in-region)) + (ivy-completion-in-region (marker-position beg) (marker-position end) table pred)) + ;; Helm is special and wants to _wrap_ `completion--in-region' + ;; instead of replacing it in `completion-in-region-function'. + ((and (modulep! :completion helm) + (fboundp #'helm--completion-in-region) + (advice-member-p #'helm--completion-in-region #'completion--in-region)) + ;; Important: `completion-in-region-function' is set to corfu at + ;; this moment, so `completion-in-region' (single -) doesn't work. + (completion--in-region beg end table pred)) + ;; Ido doesn't implement `completion-in-region', and its + ;; `completing-read' only accepts a plain list of strings as table, + ;; so there's not much we can do with it. + (t (error "No minibuffer completion UI available for moving to!"))))))) ;;;###autoload (defun +corfu-smart-sep-toggle-escape () diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index d4bad1f24..41e54d945 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -32,6 +32,8 @@ tab-always-indent (if (modulep! +tng) 'complete tab-always-indent)) (add-to-list 'completion-category-overrides `(lsp-capf (styles ,@completion-styles))) + (add-to-list 'corfu-continue-commands #'+corfu-move-to-minibuffer) + (add-hook! 'minibuffer-setup-hook (defun +corfu-enable-in-minibuffer () "Enable Corfu in the minibuffer if `completion-at-point' is bound." diff --git a/modules/completion/helm/config.el b/modules/completion/helm/config.el index 7f983f872..109c182fa 100644 --- a/modules/completion/helm/config.el +++ b/modules/completion/helm/config.el @@ -24,6 +24,7 @@ Can be negative.") (use-package! helm-mode :hook (doom-first-input . helm-mode) :config + (advice-add #'completion--in-region :around #'helm--completion-in-region) ;; helm is too heavy for `find-file-at-point' (add-to-list 'helm-completing-read-handlers-alist (cons #'find-file-at-point nil))) From a2e76be3a9a899c295b7cb1f6dd93cdd65bdddce Mon Sep 17 00:00:00 2001 From: Luigi Sartor Piucco Date: Sun, 4 Feb 2024 18:19:04 -0300 Subject: [PATCH 32/49] bump: :completion corfu minad/corfu@24dccafeea11 -> minad/corfu@b48d3017a477 minad/cape@18a30f48bb87 -> minad/cape@bfde79ed4403 elken/yasnippet-capf@a0a6b1c2bb6d -> elken/yasnippet-capf@db12b55cd08b --- modules/completion/corfu/packages.el | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/modules/completion/corfu/packages.el b/modules/completion/corfu/packages.el index ec9edc23f..05f2d9b98 100644 --- a/modules/completion/corfu/packages.el +++ b/modules/completion/corfu/packages.el @@ -1,8 +1,8 @@ ;; -*- no-byte-compile: t; -*- ;;; completion/corfu/packages.el -(package! corfu :pin "24dccafeea114b1aec7118f2a8405b46aa0051e0") -(package! cape :pin "18a30f48bb8754421cb10dad99e0a406173d4551") +(package! corfu :pin "b48d3017a47706198e04440cc1b3483bdf646771") +(package! cape :pin "bfde79ed440343c0dbf0f64cfe7913c1efbe3f83") (when (modulep! +icons) (package! nerd-icons-corfu :pin "7077bb76fefc15aed967476406a19dc5c2500b3c")) (when (modulep! +orderless) @@ -10,4 +10,4 @@ (when (modulep! :os tty) (package! corfu-terminal :pin "501548c3d51f926c687e8cd838c5865ec45d03cc")) (when (modulep! :editor snippets) - (package! yasnippet-capf :pin "a0a6b1c2bb6decdad5cf9b74202f0042f494a6ab")) + (package! yasnippet-capf :pin "db12b55cd08b614cbba134008566e48d7faf660e")) From b54c64bc21f8d0aafea998a0c801c7dabd58df05 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Sat, 17 Feb 2024 10:44:00 -0600 Subject: [PATCH 33/49] fix(corfu): load minibuffer-setup-hook earlier This way Corfu can be lazily-loaded by the minibuffer-setup-hook. --- modules/completion/corfu/config.el | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index 41e54d945..c3190fe71 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -7,6 +7,13 @@ ;;; Packages (use-package! corfu :hook (doom-first-input . global-corfu-mode) + :init + (add-hook! 'minibuffer-setup-hook + (defun +corfu-enable-in-minibuffer () + "Enable Corfu in the minibuffer if `completion-at-point' is bound." + (when (where-is-internal #'completion-at-point (list (current-local-map))) + (setq-local corfu-echo-delay nil) + (corfu-mode +1)))) :config (setq corfu-auto t corfu-auto-delay 0.1 @@ -34,12 +41,6 @@ (add-to-list 'corfu-continue-commands #'+corfu-move-to-minibuffer) - (add-hook! 'minibuffer-setup-hook - (defun +corfu-enable-in-minibuffer () - "Enable Corfu in the minibuffer if `completion-at-point' is bound." - (when (where-is-internal #'completion-at-point (list (current-local-map))) - (setq-local corfu-echo-delay nil) - (corfu-mode +1)))) (after! evil (add-hook 'evil-insert-state-exit-hook #'corfu-quit)) From 0ea6968f74d156df81cbbbaf2522b1e5989f5b93 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Sat, 17 Feb 2024 10:45:49 -0600 Subject: [PATCH 34/49] refactor(corfu): unwrap add-hook from after! block add-hook handles void variables so there is no need to wrap it in an after! block. This also makes it easier for the user to remove the hook. --- modules/completion/corfu/config.el | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index c3190fe71..b59d5e2fe 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -42,8 +42,7 @@ (add-to-list 'corfu-continue-commands #'+corfu-move-to-minibuffer) - (after! evil - (add-hook 'evil-insert-state-exit-hook #'corfu-quit)) + (add-hook 'evil-insert-state-exit-hook #'corfu-quit) (when (modulep! +icons) (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) From f3729174bdb1942db4854b1ded62bd5975763d30 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Sat, 17 Feb 2024 10:47:35 -0600 Subject: [PATCH 35/49] feat(corfu): update minibuffer hints manually In the scenario where we exit the minibuffer using C-RET or S-RET, we need this advice to ensure that visual hints are updated before exiting. --- modules/completion/corfu/config.el | 21 ++++++++++++++++++++- 1 file changed, 20 insertions(+), 1 deletion(-) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index b59d5e2fe..ab17c7dbb 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -49,7 +49,26 @@ (when (modulep! +orderless) (after! orderless - (setq orderless-component-separator #'orderless-escapable-split-on-space)))) + (setq orderless-component-separator #'orderless-escapable-split-on-space))) + + ;; If you want to update the visual hints after completing minibuffer commands + ;; with Corfu and exiting, you have to do it manually. + (defadvice! +corfu--insert-before-exit-minibuffer-a () + :before #'exit-minibuffer + (when (or (and (frame-live-p corfu--frame) + (frame-visible-p corfu--frame)) + (and (featurep 'corfu-terminal) + (popon-live-p corfu-terminal--popon))) + (when (member isearch-lazy-highlight-timer timer-idle-list) + (apply (timer--function isearch-lazy-highlight-timer) + (timer--args isearch-lazy-highlight-timer))) + (when (member (bound-and-true-p anzu--update-timer) timer-idle-list) + (apply (timer--function anzu--update-timer) + (timer--args anzu--update-timer))) + (when (member (bound-and-true-p evil--ex-search-update-timer) + timer-idle-list) + (apply (timer--function evil--ex-search-update-timer) + (timer--args evil--ex-search-update-timer)))))) (use-package! cape :defer t From 42f48ace691525a38e8937adbdba0edd1f540692 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Sat, 17 Feb 2024 10:50:17 -0600 Subject: [PATCH 36/49] fix(corfu): bind cape-dabbrev eagerly Set up cape-dabbrev in completion-at-point-functions before dabbrev is loaded. --- modules/completion/corfu/config.el | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index ab17c7dbb..94c992045 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -84,6 +84,10 @@ ;; 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 cape-dabbrev-check-other-buffers t dabbrev-friend-buffer-function #'+dabbrev-friend-buffer-p @@ -91,12 +95,7 @@ '("^ " "\\(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) - - (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))))) + (add-to-list 'dabbrev-ignored-buffer-modes 'pdf-view-mode))) ;; Complete emojis :). (when (and (modulep! +emoji) (> emacs-major-version 28)) (add-hook! (prog-mode conf-mode) From fa1979d97fbda04ba8c508fe2419ec18376fa9f4 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Sat, 17 Feb 2024 10:52:57 -0600 Subject: [PATCH 37/49] feat(config): make C-x corfu bindings optional For someone like me that uses the vanilla emacs commands bound to C-x C-p, C-x C-n, etc, I prefer to set the completion keybindings manually. --- modules/completion/corfu/config.el | 3 +++ modules/config/default/+evil-bindings.el | 17 +++++++++-------- 2 files changed, 12 insertions(+), 8 deletions(-) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index 94c992045..e8805ce2b 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -3,6 +3,9 @@ (defvar +corfu-buffer-scanning-size-limit (* 1 1024 1024) ; 1 MB "Size limit for a buffer to be scanned by `cape-dabbrev'.") +(defvar +corfu-want-C-x-bindings t + "Whether `C-x' is a completion prefix in Evil insert state.") + ;; ;;; Packages (use-package! corfu diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index b86e58800..7b868f1c6 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -163,14 +163,15 @@ (:after corfu (:map corfu-mode-map :e "C-M-i" #'completion-at-point - (:prefix "C-x" - :i "C-l" #'cape-line - :i "C-k" #'cape-keyword - :i "C-f" #'cape-file - :i "s" #'cape-dict - :i "C-s" #'yasnippet-capf - :i "C-n" #'cape-dabbrev - :i "C-p" #'cape-history) + (:when +corfu-want-C-x-bindings + (:prefix "C-x" + :i "C-l" #'cape-line + :i "C-k" #'cape-keyword + :i "C-f" #'cape-file + :i "s" #'cape-dict + :i "C-s" #'yasnippet-capf + :i "C-n" #'cape-dabbrev + :i "C-p" #'cape-history)) (:unless (modulep! :completion corfu +tng) :i "C-SPC" #'completion-at-point :n "C-SPC" (cmd! (call-interactively #'evil-insert-state) From d25e15072ddd6c63f167c5e55d9a5711527b184e Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Sat, 17 Feb 2024 10:55:19 -0600 Subject: [PATCH 38/49] fix(corfu): bind tng tab commands to insert state These commands were being shadowed by the other Corfu commands previously. --- modules/config/default/config.el | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/modules/config/default/config.el b/modules/config/default/config.el index 1108190f9..81203f6ea 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -469,10 +469,10 @@ Continues comments if executed from a commented line. Consults (:when (modulep! :completion corfu +orderless) [remap completion-at-point] #'+corfu-smart-sep-toggle-escape) (:when (modulep! :completion corfu +tng) - [tab] #'corfu-next - "TAB" #'corfu-next - [backtab] #'corfu-previous - "S-TAB" #'corfu-previous)) + :gi [tab] #'corfu-next + :gi "TAB" #'corfu-next + :gi [backtab] #'corfu-previous + :gi "S-TAB" #'corfu-previous)) (:after corfu-popupinfo :map corfu-popupinfo-map "C-" #'corfu-popupinfo-scroll-down From 881c45bd057cd71242bee513d7f9e2dcc4a015ca Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Mon, 19 Feb 2024 18:19:00 -0600 Subject: [PATCH 39/49] doc(corfu): document +corfu-want-C-x-bindings --- modules/completion/corfu/README.org | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org index 642d83cb2..4842da058 100644 --- a/modules/completion/corfu/README.org +++ b/modules/completion/corfu/README.org @@ -195,8 +195,11 @@ A few variables may be set to change behavior of this module: recommended to leave it at that. Otherwise, single matches on snippet keys expand immediately. - [[var:+corfu-buffer-scanning-size-limit]] :: - Sets the maximum buffer size to be scanned by ~cape-dabbrev~. Defaults to 1 + 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. +- [[var:+corfu-want-C-x-bindings]] :: + Enables autocompletion backends to be bound under the ~C-x~ prefix. This + overrides some built-in Emacs keybindings. ** Adding CAPFs to a mode To add other CAPFs on a mode-per-mode basis, put either of the following in your From 16c4daee520745dcb834ef6f6f62dc6f0432d5b1 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Mon, 19 Feb 2024 23:44:58 -0600 Subject: [PATCH 40/49] feat(config): add smart-ret for corfu This commit makes RET in Corfu quit auto-completion and passthrough to the underlying keymap if no completion is selected. --- modules/config/default/config.el | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/modules/config/default/config.el b/modules/config/default/config.el index 81203f6ea..fbb1e1575 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -461,8 +461,6 @@ Continues comments if executed from a commented line. Consults (map! :when (modulep! :completion corfu) :after corfu (:map corfu-map - [return] #'corfu-insert - "RET" #'corfu-insert "C-S-s" #'+corfu-move-to-minibuffer "C-p" #'corfu-previous "C-n" #'corfu-next @@ -489,11 +487,19 @@ Continues comments if executed from a commented line. Consults (when-let ((cmds-del (and (modulep! :completion corfu +tng) '(menu-item "Reset completion" corfu-reset :enable (and (> corfu--index -1) - (eq corfu-preview-current 'insert)))))) - (map! :after corfu + (eq corfu-preview-current 'insert))))) + (cmds-ret '(menu-item "Insert completion" corfu-insert + :filter (lambda (cmd) + (if (eq corfu--index -1) + (corfu-quit) + cmd))))) + (map! :when (modulep! :completion corfu) + :after corfu :map corfu-map [backspace] cmds-del - "DEL" cmds-del)) + "DEL" cmds-del + :ig [return] cmds-ret + :ig "RET" cmds-ret)) ;; Smarter C-a/C-e for both Emacs and Evil. C-a will jump to indentation. ;; Pressing it again will send you to the true bol. Same goes for C-e, except From 14f350a3da47ff861135a9ff962bd04e3b0c7958 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Tue, 20 Feb 2024 08:23:00 -0600 Subject: [PATCH 41/49] fix(corfu): move orderless conf out of corfu block --- modules/completion/corfu/config.el | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index e8805ce2b..ab2d8313b 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -17,6 +17,9 @@ (when (where-is-internal #'completion-at-point (list (current-local-map))) (setq-local corfu-echo-delay nil) (corfu-mode +1)))) + (when (modulep! +orderless) + (after! orderless + (setq orderless-component-separator #'orderless-escapable-split-on-space))) :config (setq corfu-auto t corfu-auto-delay 0.1 @@ -50,10 +53,6 @@ (when (modulep! +icons) (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) - (when (modulep! +orderless) - (after! orderless - (setq orderless-component-separator #'orderless-escapable-split-on-space))) - ;; If you want to update the visual hints after completing minibuffer commands ;; with Corfu and exiting, you have to do it manually. (defadvice! +corfu--insert-before-exit-minibuffer-a () From a1ba1593fc537990f2da74b25ad45d6d9af15a85 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Wed, 21 Feb 2024 16:51:11 -0600 Subject: [PATCH 42/49] fix(corfu): complete after colon in lispy --- modules/completion/corfu/config.el | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index ab2d8313b..08b469e6b 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -44,6 +44,7 @@ ;; However, it should otherwise behave like normal, whatever normal was. tab-always-indent (if (modulep! +tng) 'complete tab-always-indent)) (add-to-list 'completion-category-overrides `(lsp-capf (styles ,@completion-styles))) + (add-to-list 'corfu-auto-commands #'lispy-colon) (add-to-list 'corfu-continue-commands #'+corfu-move-to-minibuffer) From b96778497b8faeb337d68f932f31c7410a955f78 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Fri, 23 Feb 2024 10:19:55 -0600 Subject: [PATCH 43/49] fix(corfu): use :filter instead of :enable --- modules/config/default/config.el | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/modules/config/default/config.el b/modules/config/default/config.el index fbb1e1575..0fa77681d 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -481,13 +481,16 @@ Continues comments if executed from a commented line. Consults "C-S-d" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-up corfu-popupinfo-min-height))) (:map corfu-map "C-" '(menu-item "Conclude the minibuffer" exit-minibuffer - :enable (minibufferp nil t)) - "S-" '(menu-item "Insert completion and conclude" +corfu-complete-and-exit-minibuffer - :enable (minibufferp nil t)))) + :filter (lambda (cmd) (when (minibufferp nil t) cmd))) + "S-" '(menu-item "Insert completion and conclude" + +corfu-complete-and-exit-minibuffer + :filter (lambda (cmd) (when (minibufferp nil t) cmd))))) (when-let ((cmds-del (and (modulep! :completion corfu +tng) '(menu-item "Reset completion" corfu-reset - :enable (and (> corfu--index -1) - (eq corfu-preview-current 'insert))))) + :filter (lambda (cmd) + (when (and (>= corfu--index 0) + (eq corfu-preview-current 'insert)) + cmd))))) (cmds-ret '(menu-item "Insert completion" corfu-insert :filter (lambda (cmd) (if (eq corfu--index -1) From d0127025a0a3e8773fd92356c457bbb7f81d37fb Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Fri, 23 Feb 2024 10:53:11 -0600 Subject: [PATCH 44/49] fix(corfu): improve detection of comments Due to https://github.com/minad/cape/pull/109, we cannot rely on only faces to detect comments. --- modules/completion/corfu/autoload.el | 15 +++++++++++++++ modules/completion/corfu/config.el | 12 +++--------- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/modules/completion/corfu/autoload.el b/modules/completion/corfu/autoload.el index 195c49c4c..fcac8babe 100644 --- a/modules/completion/corfu/autoload.el +++ b/modules/completion/corfu/autoload.el @@ -49,3 +49,18 @@ ;; Without this corfu quits immediately. (setq this-command #'corfu-insert-separator) (call-interactively #'corfu-insert-separator)))) + +;;;###autoload +(defun +corfu-in-doc-or-comment-p (_sym) + "Return non-nil if point is in a docstring or comment." + (or (nth 4 (syntax-ppss)) + (when-let ((faces '(font-lock-comment-face + font-lock-doc-face + tree-sitter-hl-face:doc + tree-sitter-hl-face:comment)) + (fs (get-text-property (point) 'face))) + (if (listp fs) + (cl-loop for f in fs + if (memq f faces) + return t) + (memq fs faces))))) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index 08b469e6b..a6339e2d4 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -104,11 +104,8 @@ (add-hook! (prog-mode conf-mode) (defun +corfu-add-cape-emoji-h () (add-hook 'completion-at-point-functions - (cape-capf-inside-faces - (cape-capf-prefix-length #'cape-emoji 1) - ;; Only call inside comments and docstrings. - 'tree-sitter-hl-face:doc 'font-lock-doc-face - 'font-lock-comment-face 'tree-sitter-hl-face:comment) + (cape-capf-predicate (cape-capf-prefix-length #'cape-emoji 1) + #'+corfu-in-doc-or-comment-p) 10 t))) (add-hook! text-mode (defun +corfu-add-cape-emoji-text-h () @@ -119,10 +116,7 @@ (add-hook! (prog-mode conf-mode) (defun +corfu-add-cape-dict-h () (add-hook 'completion-at-point-functions - (cape-capf-inside-faces - ;; Only call inside comments and docstrings. - #'cape-dict 'tree-sitter-hl-face:doc 'font-lock-doc-face - 'font-lock-comment-face 'tree-sitter-hl-face:comment) + (cape-capf-predicate #'+corfu-in-doc-or-comment-p #'cape-dict) 40 t))) (add-hook! text-mode (defun +corfu-add-cape-dict-text-h () From 89a30df0c4234b68dc6f1a4ab22fcbccf27be979 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Fri, 23 Feb 2024 17:55:30 -0600 Subject: [PATCH 45/49] fix(corfu): eval lambdas --- modules/config/default/config.el | 30 +++++++++++++++--------------- 1 file changed, 15 insertions(+), 15 deletions(-) diff --git a/modules/config/default/config.el b/modules/config/default/config.el index 0fa77681d..260c9abd3 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -480,22 +480,22 @@ Continues comments if executed from a commented line. Consults "C-S-u" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-down corfu-popupinfo-min-height)) "C-S-d" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-up corfu-popupinfo-min-height))) (:map corfu-map - "C-" '(menu-item "Conclude the minibuffer" exit-minibuffer - :filter (lambda (cmd) (when (minibufferp nil t) cmd))) - "S-" '(menu-item "Insert completion and conclude" - +corfu-complete-and-exit-minibuffer - :filter (lambda (cmd) (when (minibufferp nil t) cmd))))) + "C-" `(menu-item "Conclude the minibuffer" exit-minibuffer + :filter ,(lambda (cmd) (when (minibufferp nil t) cmd))) + "S-" `(menu-item "Insert completion and conclude" + +corfu-complete-and-exit-minibuffer + :filter ,(lambda (cmd) (when (minibufferp nil t) cmd))))) (when-let ((cmds-del (and (modulep! :completion corfu +tng) - '(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" corfu-insert - :filter (lambda (cmd) - (if (eq corfu--index -1) - (corfu-quit) - cmd))))) + `(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" corfu-insert + :filter ,(lambda (cmd) + (if (eq corfu--index -1) + (corfu-quit) + cmd))))) (map! :when (modulep! :completion corfu) :after corfu :map corfu-map From 5ea726cfe4dc94a580dd272485fa137d30e0ee78 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Wed, 28 Feb 2024 16:25:21 -0600 Subject: [PATCH 46/49] feat(config): modify smart-ret in +tng minibuffer If we are using +tng, we can make RET always exit the minibuffer. This has the downside of not being able to insert snippets, but no one writes snippets for the minibuffer anyway. --- modules/config/default/config.el | 25 ++++++++++++++++--------- 1 file changed, 16 insertions(+), 9 deletions(-) diff --git a/modules/config/default/config.el b/modules/config/default/config.el index 260c9abd3..fa98a80a8 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -479,12 +479,13 @@ Continues comments if executed from a commented line. Consults "C-S-n" #'corfu-popupinfo-scroll-up "C-S-u" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-down corfu-popupinfo-min-height)) "C-S-d" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-up corfu-popupinfo-min-height))) - (:map corfu-map - "C-" `(menu-item "Conclude the minibuffer" exit-minibuffer - :filter ,(lambda (cmd) (when (minibufferp nil t) cmd))) - "S-" `(menu-item "Insert completion and conclude" - +corfu-complete-and-exit-minibuffer - :filter ,(lambda (cmd) (when (minibufferp nil t) cmd))))) + (:when (not (modulep! :completion corfu +tng)) + (:map corfu-map + "C-" `(menu-item "Conclude the minibuffer" exit-minibuffer + :filter ,(lambda (cmd) (when (minibufferp nil t) cmd))) + "S-" `(menu-item "Insert completion and conclude" + +corfu-complete-and-exit-minibuffer + :filter ,(lambda (cmd) (when (minibufferp nil t) cmd)))))) (when-let ((cmds-del (and (modulep! :completion corfu +tng) `(menu-item "Reset completion" corfu-reset :filter ,(lambda (cmd) @@ -493,9 +494,15 @@ Continues comments if executed from a commented line. Consults cmd))))) (cmds-ret `(menu-item "Insert completion" corfu-insert :filter ,(lambda (cmd) - (if (eq corfu--index -1) - (corfu-quit) - cmd))))) + (cond ((eq corfu--index -1) + (corfu-quit)) + ((and (modulep! :completion corfu +tng) + (eq corfu-preview-current 'insert) + (minibufferp nil t)) + (corfu-insert) + nil) + (t + cmd)))))) (map! :when (modulep! :completion corfu) :after corfu :map corfu-map From 3aa1ea74d9db1bb42b2e2b0e640f2aef54ef15d9 Mon Sep 17 00:00:00 2001 From: StrawberryTea Date: Wed, 28 Feb 2024 17:42:47 -0600 Subject: [PATCH 47/49] feat(corfu): make minibuffer completion optional --- modules/completion/corfu/config.el | 21 +++++++++++++++++++-- 1 file changed, 19 insertions(+), 2 deletions(-) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index a6339e2d4..7c860e47c 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -6,6 +6,11 @@ (defvar +corfu-want-C-x-bindings t "Whether `C-x' is a completion prefix in Evil insert state.") +(defvar +corfu-want-minibuffer-completion t + "Whether to enable Corfu in the minibuffer. +Setting this to `aggressive' will enable Corfu in more commands which +use the minibuffer such as `query-replace'.") + ;; ;;; Packages (use-package! corfu @@ -13,8 +18,20 @@ :init (add-hook! 'minibuffer-setup-hook (defun +corfu-enable-in-minibuffer () - "Enable Corfu in the minibuffer if `completion-at-point' is bound." - (when (where-is-internal #'completion-at-point (list (current-local-map))) + "Enable Corfu in the minibuffer." + (when (pcase +corfu-want-minibuffer-completion + ('aggressive + (not (or (bound-and-true-p mct--active) + (bound-and-true-p vertico--input) + (eq (current-local-map) read-passwd-map) + (and (featurep 'helm-core) (helm--alive-p)) + (and (featurep 'ido) (ido-active)) + (where-is-internal 'minibuffer-complete + (list (current-local-map))) + (memq #'ivy--queue-exhibit post-command-hook)))) + ('nil nil) + (_ (where-is-internal #'completion-at-point + (list (current-local-map))))) (setq-local corfu-echo-delay nil) (corfu-mode +1)))) (when (modulep! +orderless) From 9e7967c9091f9865bbfb6fac3c03b38f2b90d0bd Mon Sep 17 00:00:00 2001 From: Luigi Sartor Piucco Date: Sat, 2 Mar 2024 13:10:00 -0300 Subject: [PATCH 48/49] refactor(corfu): settings and keybinding overhaul Previously, a distinction was made only between "regular" style (assumed to be for people who prefer to cycle directionally and commit with RET) and +tng (assumed to be for people who prefer TAB and auto-commit). This made composing further variations harder on the user, as they would have to work around our bindings. Now we have many features as documentation, and the user can compose to their liking. The global CAPF list was pruned, suggesting to use individual keys for those functions if required. --- modules/completion/corfu/README.org | 228 +++++++++++----------- modules/completion/corfu/autoload.el | 25 --- modules/completion/corfu/config.el | 44 ++--- modules/config/default/+emacs-bindings.el | 7 - modules/config/default/+evil-bindings.el | 44 ++--- modules/config/default/config.el | 69 +++---- templates/init.example.el | 1 + 7 files changed, 177 insertions(+), 241 deletions(-) diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org index 4842da058..f0f782875 100644 --- a/modules/completion/corfu/README.org +++ b/modules/completion/corfu/README.org @@ -6,11 +6,15 @@ * Description :unfold: This module provides code completion, powered by [[doom-package:corfu]]. -It is recommended to enable either this or [[doom-module::completion company]], in +It is recommended to enable either this or [[doom-module::completion company]] in case you desire pre-configured auto-completion. Corfu is much lighter weight and -focused, plus it's built on native Emacs functionality, whereas company is heavy +focused, plus it's built on native Emacs functionality, whereas Company is heavy and highly non-native, but has some extra features and more maturity. +If you choose Corfu, we also highly recomend reading [[https://github.com/minad/corfu][its README]] and [[https://github.com/minad/cape][cape's +README]], as the backend is very configurable and provides many power-user +utilities for fine-tuning. Only some of common behaviors are documented here. + ** Maintainers - [[doom-user:][@LuigiPiucco]] @@ -19,21 +23,12 @@ and highly non-native, but has some extra features and more maturity. ** Module flags - +icons :: Display icons beside completion suggestions. -- +tng :: - Known as Tab'n'Go to Company users, changes behavior to invoke completion on - [[kbd:][TAB]]. When Corfu is active, [[kbd:][TAB]] and [[kbd:][S-TAB]] will navigate the completion - candidates. Arrow keys and evil-style movement are still supported. - +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. -- +dict :: - Enable and configure dictionary completion for text modes and related regions - in programming modes. -- +emoji :: - Enable and configure emoji completion via the emoji input method. ** Packages - [[doom-package:corfu]] @@ -66,67 +61,90 @@ words. Snippets may also appear in the candidate list if available. 🔨 /This module's usage documentation is incomplete./ [[doom-contrib-module:][Complete it?]] #+end_quote -** Code completion By default, completion gets triggered after typing 2 non-space consecutive -characters, or by means of the [[kbd:][C-SPC]] keybinding at any moment. While the popup -is visible, the following relevant keys are available: +characters, by means of [[kbd:][C-SPC]] at any moment or [[kbd:][TAB]] on a line with proper +indentation. Many styles of completion are documented below, which can be +composed to suit the user. The following keybindings are generally available: -| Keybind | Description | -|----------+-----------------------------------------------------------| -| [[kbd:][]] | Go to next candidate | -| [[kbd:][]] | Go to previous candidate | -| [[kbd:][C-n]] | Go to next candidate | -| [[kbd:][C-p]] | Go to previous candidate | -| [[kbd:][C-j]] | (evil) Go to next candidate | -| [[kbd:][C-k]] | (evil) Go to previous candidate | -| [[kbd:][C-]] | Go to next doc line | -| [[kbd:][C-]] | Go to previous doc line | -| [[kbd:][C-S-n]] | Go to next doc line | -| [[kbd:][C-S-p]] | Go to previous doc line | -| [[kbd:][C-S-j]] | (evil) Go to next doc line | -| [[kbd:][C-S-k]] | (evil) Go to previous doc line | -| [[kbd:][C-h]] | Toggle documentation (if available) | -| [[kbd:][C-S-s]] | Export to minibuffer (if [[doom-module::completion vertico]]) | -| [[kbd:][RET]] | Insert candidate | -| [[kbd:][SPC]] | Quit autocompletion or pass-through after a wildcard | -| [[kbd:][C-SPC]] | Complete (unless [[doom-module::completion corfu +tng]]) | -| [[kbd:][C-SPC]] | (when completing) Insert separator DWIM (see below) | +| Keybind | Description | +|---------+--------------------------------------------| +| [[kbd:][C-n]] | Go to next candidate | +| [[kbd:][C-p]] | Go to previous candidate | +| [[kbd:][C-S-n]] | Go to next doc line | +| [[kbd:][C-S-p]] | Go to previous doc line | +| [[kbd:][C-S-s]] | Export to minibuffer | +| [[kbd:][DEL]] | Reset completion DWIM | +| [[kbd:][TAB]] | (when not completing) Indent or complete | +| [[kbd:][C-SPC]] | (when not completing) Complete | +| [[kbd:][C-u]] | (evil) Go to next candidate page | +| [[kbd:][C-d]] | (evil) Go to previous candidate page | +| [[kbd:][C-h]] | (evil) Toggle documentation (if available) | +| [[kbd:][M-t]] | (emacs) (when not completing) Complete | -If you prefer a [[kbd:][TAB]]-centric completion style, enable the [[doom-module::completion -corfu +tng]] flag so that, instead, you trigger completion with [[kbd:][TAB]], getting the -following additional binds: +Bindings in the following sections are additive, and get enabled by including +the corresponding ~config.el~ snippets or via flags. Additionally, for users of +evil, [[kdb:][C-SPC]] is smart regarding your state. In normal-like states, enter insert +then start corfu; in visual-like states, perform [[help:evil-change][evil-change]] (which leaves you +in insert state) then start corfu; in insert-like states, start corfu +immediatelly. -| Keybind | Description | -|---------+-----------------------------------------------| -| [[kbd:][TAB]] | Complete | -| [[kbd:][TAB]] | (when completing) Go to next candidate | -| [[kbd:][S-TAB]] | (when completing) Go to previous candidate | -| [[kbd:][DEL]] | (when completing) Reset completion DWIM-style | +** Commit preview on type +When the completion popup is visible, by default the current candidate is +previewed into the buffer, and further input commits that candidate as previewed +(note it does not perform candidate exit actions, such as expanding snippets). +If neither ~+on-ret~ or ~+on-ret-pt~ are enabled, this becomes the only default +way to commit a candidate ([[kbd:][RET]] is unbound in that case). -*** Completion in the minibuffer -In the minibuffer, sometimes autocompletion can interfere with your goal; -Imagine you're composing a search pattern incrementally, and you find what you -want early, with only half the word. You then press [[kbd:RET]]. If completion -kicked in as you typed, you may lose the match, since it will complete the -first candidate. On the other hand, if you were paying attention to the -suggestions and selecting one appropriate, that's desired behavior, and you may -even desire to modify the prompt further (if you were composing a command -instead, you may want to extend it after the candidate). To allow better -control, there are 3 confirm bindings when Corfu appears in the minibuffer: +The feature is in line with other common editors, but if you prefer the preview +to be only visual or for there to be no preview, configure +[[var:corfu-preview-current]]. -| Keybind | Description | -|-----------+--------------------------------------------------------------------| -| [[kbd:RET]] | Accept the candidate only | -| [[kbd:C-RET]] | Confirm the current prompt only | -| [[kbd:S-RET]] | Accept the candidate then immediately confirm the completed prompt | +#+begin_src emacs-lisp +;; Non-inserting preview +(setq corfu-preview-current t) +;; No preview +(setq corfu-preview-current nil) +#+end_src -- Use [[kbd:RET]] when you want to continue composing after completing; -- Use [[kbd:C-RET]] when you already have the desired string, and completing would - break it; -- Use [[kbd:S-RET]] when you know the composition will be finished after completion - (thus avoiding the need to type [[kbd:RET]] twice); +** Commit on [[kbd:][RET]] with pass-through +A lot of people like to use [[kbd:][RET]] to commit, so here we bind it to Corfu's +insertion function. Note that Corfu allows "no candidate" to be selected, and in +that case, we have a custom binding to quit completion and pass-through. To make +it less obtrusive by default, the popup starts in this unselected state. See +[[var:corfu-preselect]] to alter the initial behavior; it can start with the first +one selected, for instance. Then, you have to move one candidate backwards to +pass-through The exact action of [[kbd:][RET]] can be changed via +[[var:+corfu-want-ret-to-confirm]]. -** Searching with multiple keywords +| Keybind | Description | +|---------+-----------------------| +| [[kbd:][RET]] | Insert candidate DWIM | + +** Cycle directionally +If you'd rather think in directions rather than next/previous, arrow keys and vi +movements to control the selection and documentation view are bound by default. +You may unbind them by setting to nil, see ~map!~'s documentation. + +| Keybind | Description | +|----------+---------------------------------| +| [[kbd:][]] | Go to next candidate | +| [[kbd:][]] | Go to previous candidate | +| [[kbd:][C-j]] | (evil) Go to next candidate | +| [[kbd:][C-k]] | (evil) Go to previous candidate | +| [[kbd:][C-]] | Go to next doc line | +| [[kbd:][C-]] | Go to previous doc line | +| [[kbd:][C-S-j]] | (evil) Go to next doc line | +| [[kbd:][C-S-k]] | (evil) Go to previous doc line | + +** Cycle with [[kbd:][TAB]] +[[kbd:][TAB]]-based cycling alternatives are also bound according to the table below: + +| Keybind | Description | +|---------+--------------------------| +| [[kbd:][TAB]] | Go to next candidate | +| [[kbd:][S-TAB]] | Go to previous candidate | + +** Searching with multiple keywords (~+orderless~) If the [[doom-module::completion corfu +orderless]] flag is enabled, users can perform code completion with multiple search keywords by use of space as the separator. More information can be found [[https://github.com/oantolin/orderless#company][here]]. Pressing [[kdb:][C-SPC]] again while @@ -139,38 +157,18 @@ backslash, including the space in the search term, and pressing it with an already escaped separator before point deletes it. Thus, you can cycle back if you accidentaly press more than needed. -Additionally, for users of evil and regular corfu style, [[kdb:][C-SPC]] is smart -regarding your state. In normal-like states, enter insert then start corfu; in -visual-like states, perform [[help:evil-change][evil-change]] (which leaves you in insert state) then -start corfu; in insert-like states, start corfu immediatelly. +| Keybind | Description | +|---------+-------------------------------------------------| +| [[kbd:][C-SPC]] | (evil) (when completing) Insert separator DWIM | +| [[kbd:][M-SPC]] | (emacs) (when completing) Insert separator DWIM | +| [[kbd:][SPC]] | (when completing) Quit autocompletion | +| [[kbd:][SPC]] | (when completing with separators) Self-insert | ** Exporting to the minibuffer -The entries shown in the completion popup can be exported to a ~completing-read~ -minibuffer, giving access to all the manipulations that suite allows. Using -Vertico for instance, one could use this to export with [[doom-package:embark]] via -[[kbd:][C-c C-l]] and get a buffer with all candidates. - -** Manually call generic CAPFs -Completion at point functions have the property that, when called interactively -via their symbol, they work as a call to ~completion-at-point~ where -[[var:completion-at-point-functions]] is bound to that CAPF alone. This allows to -assign generic functions to a binding and call as needed, leaving the default -value used for most completion tasks much leaner (thus, faster and easier to -look through). This module provides some such bindings for Evil users (see the -table below), and you're free map your own of course. Emacs users have to map it -themselves for now, due to the author's lack of knowledge on ergonomic -equivalents to the Evil ones. If you have suggestions, though, we'd be happy to -know! - -| Keybind | Description | -|---------+---------------------------------| -| [[kbd:][C-x]] [[kbd:][C-l]] | (insert-state) ~cape-line~ | -| [[kbd:][C-x]] [[kbd:][C-k]] | (insert-state) ~cape-keyword~ | -| [[kbd:][C-x]] [[kbd:][C-f]] | (insert-state) ~cape-file~ | -| [[kbd:][C-x]] [[kbd:][s]] | (insert-state) ~cape-dict~ | -| [[kbd:][C-x]] [[kbd:][C-s]] | (insert-state) ~yasnippet-capf~ | -| [[kbd:][C-x]] [[kbd:][C-n]] | (insert-state) ~cape-dabbrev~ | -| [[kbd:][C-x]] [[kbd:][C-p]] | (insert-state) ~cape-history~ | +The entries shown in the completion popup can be exported to another +~completion-in-region~ minibuffer, giving access to all the manipulations those +suites allow. Using Vertico for instance, one could use this to export with +[[doom-package:embark]] via [[kbd:][C-c C-l]] and get a buffer with all candidates. * Configuration A few variables may be set to change behavior of this module: @@ -191,15 +189,22 @@ A few variables may be set to change behavior of this module: - [[var:corfu-auto-prefix]] :: Number of characters till auto-completion starts to happen. Defaults to 2. - [[var:corfu-on-exact-match]] :: - Configures behavior for exact matches. Its default is nil, and it's - recommended to leave it at that. Otherwise, single matches on snippet keys - expand immediately. + Configures behavior for exact matches. +- [[var:corfu-preselect]] :: + Configures startup selection, choosing between the first candidate or the + prompt. +- [[var:corfu-preview-current]] :: + Configures current candidate preview. - [[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. -- [[var:+corfu-want-C-x-bindings]] :: - Enables autocompletion backends to be bound under the ~C-x~ prefix. This - overrides some built-in Emacs keybindings. +- [[var:+corfu-want-minibuffer-completion]] :: + Enables Corfu in the minibuffer, where it may be obtrusive. May also be set + to ~aggresive~ to enable even in some places without ~completion-at-point~. +- [[var:+corfu-want-ret-to-confirm]] :: + 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. ** Adding CAPFs to a mode To add other CAPFs on a mode-per-mode basis, put either of the following in your @@ -211,24 +216,25 @@ To add other CAPFs on a mode-per-mode basis, put either of the following in your (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 of omitted. Also +~DEPTH~ above is an integer between -100, 100, and defaults to 0 if nil. Also see ~add-hook!~'s documentation for additional ways to call it. ~add-hook~ only accepts the quoted arguments form above. ** Adding CAPFs to a key -To add other CAPFs to keys, adapt the snippet below into your ~config.el~: +You may want to add other CAPFs to keys, so as to not pollute auto completion +and use only when demanded. To do so, adapt the snippet below into your +~config.el~: + #+begin_src emacs-lisp -;; For binding inside `corfu-mode-map'. Line 1 ensures the binding only exists -;; after some-mode-hook runs. Line 2 is needed only if the binding can't leak -;; into other Corfu buffers. When neither of the above make sense, the `map!' -;; call is enough. -(add-hook! some-mode ; Only needed if the binding is mode-specific - (make-local-variable 'corfu-mode-map) - (map! :map corfu-mode-map - :prefix "C-x" ; C-x is usually used as prefix, but it's not required - "e" #'cape-emoji)) ; Evil users probably want :i to avoid this in other states +(map! :map some-mode-map + "C-x e" #'cape-emoji) #+end_src +It's okay to add to the mode directly because ~completion-at-point~ works +regardless of Corfu (the latter is an enhanced UI for the former). Just note not +all CAPFs are interactive to be called this way, in which case you can use +[[doom-package:cape]]'s adapter to enable this. + * Troubleshooting [[doom-report:][Report an issue?]] diff --git a/modules/completion/corfu/autoload.el b/modules/completion/corfu/autoload.el index fcac8babe..60c274c4d 100644 --- a/modules/completion/corfu/autoload.el +++ b/modules/completion/corfu/autoload.el @@ -1,13 +1,5 @@ ;;; completion/corfu/autoload.el -*- lexical-binding: t; -*- -;;;###autoload -(defun +corfu-complete-and-exit-minibuffer () - (interactive) - (if (>= corfu--index 0) - (corfu-complete) - (corfu-insert)) - (exit-minibuffer)) - ;;;###autoload (defun +corfu-move-to-minibuffer () "Move the current list of candidates to your choice of minibuffer completion UI." @@ -46,21 +38,4 @@ (save-excursion (backward-char 1) (insert-char ?\\))) (t - ;; Without this corfu quits immediately. - (setq this-command #'corfu-insert-separator) (call-interactively #'corfu-insert-separator)))) - -;;;###autoload -(defun +corfu-in-doc-or-comment-p (_sym) - "Return non-nil if point is in a docstring or comment." - (or (nth 4 (syntax-ppss)) - (when-let ((faces '(font-lock-comment-face - font-lock-doc-face - tree-sitter-hl-face:doc - tree-sitter-hl-face:comment)) - (fs (get-text-property (point) 'face))) - (if (listp fs) - (cl-loop for f in fs - if (memq f faces) - return t) - (memq fs faces))))) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index 7c860e47c..96651c6b1 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -3,14 +3,19 @@ (defvar +corfu-buffer-scanning-size-limit (* 1 1024 1024) ; 1 MB "Size limit for a buffer to be scanned by `cape-dabbrev'.") -(defvar +corfu-want-C-x-bindings t - "Whether `C-x' is a completion prefix in Evil insert state.") - (defvar +corfu-want-minibuffer-completion t "Whether to enable Corfu in the minibuffer. Setting this to `aggressive' will enable Corfu in more commands which use the minibuffer such as `query-replace'.") +(defvar +corfu-want-ret-to-confirm t + "Configure how the user expects RET to behave. +Possible values are: +- t (default): Insert candidate if one is selected, pass-through otherwise; +- `minibuffer': Insert candidate if one is selected, pass-through otherwise, + and immediatelly exit if in the minibuffer; +- nil: Pass-through without inserting.") + ;; ;;; Packages (use-package! corfu @@ -50,22 +55,18 @@ use the minibuffer such as `query-replace'.") t) corfu-cycle t corfu-separator (when (modulep! +orderless) ?\s) - corfu-preselect (if (modulep! +tng) 'prompt 'valid) + corfu-preselect 'prompt corfu-count 16 corfu-max-width 120 corfu-preview-current 'insert corfu-on-exact-match nil corfu-quit-at-boundary (if (modulep! +orderless) 'separator t) corfu-quit-no-match (if (modulep! +orderless) 'separator t) - ;; In the case of +tng, TAB should be smart regarding completion; - ;; However, it should otherwise behave like normal, whatever normal was. - tab-always-indent (if (modulep! +tng) 'complete tab-always-indent)) + tab-always-indent 'complete) (add-to-list 'completion-category-overrides `(lsp-capf (styles ,@completion-styles))) (add-to-list 'corfu-auto-commands #'lispy-colon) - (add-to-list 'corfu-continue-commands #'+corfu-move-to-minibuffer) - - + (add-to-list 'corfu-continue-commands #'+corfu-smart-sep-toggle-escape) (add-hook 'evil-insert-state-exit-hook #'corfu-quit) (when (modulep! +icons) @@ -116,28 +117,6 @@ use the minibuffer such as `query-replace'.") "\\(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))) - ;; Complete emojis :). - (when (and (modulep! +emoji) (> emacs-major-version 28)) - (add-hook! (prog-mode conf-mode) - (defun +corfu-add-cape-emoji-h () - (add-hook 'completion-at-point-functions - (cape-capf-predicate (cape-capf-prefix-length #'cape-emoji 1) - #'+corfu-in-doc-or-comment-p) - 10 t))) - (add-hook! text-mode - (defun +corfu-add-cape-emoji-text-h () - (add-hook 'completion-at-point-functions - (cape-capf-prefix-length #'cape-emoji 1) 10 t)))) - ;; Enable dictionary-based autocompletion. - (when (modulep! +dict) - (add-hook! (prog-mode conf-mode) - (defun +corfu-add-cape-dict-h () - (add-hook 'completion-at-point-functions - (cape-capf-predicate #'+corfu-in-doc-or-comment-p #'cape-dict) - 40 t))) - (add-hook! text-mode - (defun +corfu-add-cape-dict-text-h () - (add-hook 'completion-at-point-functions #'cape-dict 40 t)))) ;; Make these capfs composable. (advice-add #'comint-completion-at-point :around #'cape-wrap-nonexclusive) @@ -171,7 +150,6 @@ use the minibuffer such as `query-replace'.") :config (after! savehist (add-to-list 'savehist-additional-variables 'corfu-history))) - (use-package! corfu-popupinfo :hook ((corfu-mode . corfu-popupinfo-mode)) :config diff --git a/modules/config/default/+emacs-bindings.el b/modules/config/default/+emacs-bindings.el index 2402e7885..7c63e68e2 100644 --- a/modules/config/default/+emacs-bindings.el +++ b/modules/config/default/+emacs-bindings.el @@ -537,13 +537,6 @@ "C-p" #'company-search-repeat-backward "C-s" (cmd! (company-search-abort) (company-filter-candidates)))) - (:when (modulep! :completion corfu) - :after corfu - (:map corfu-mode-map - "C-M-i" #'completion-at-point) - (:map corfu-popupinfo-map - "C-S-h" #'corfu-popupinfo-toggle)) - ;;; ein notebooks (:after ein:notebook-multilang :map ein:notebook-multilang-mode-map diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index 7b868f1c6..27dc6df54 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -162,34 +162,32 @@ (:when (modulep! :completion corfu) (:after corfu (:map corfu-mode-map - :e "C-M-i" #'completion-at-point - (:when +corfu-want-C-x-bindings - (:prefix "C-x" - :i "C-l" #'cape-line - :i "C-k" #'cape-keyword - :i "C-f" #'cape-file - :i "s" #'cape-dict - :i "C-s" #'yasnippet-capf - :i "C-n" #'cape-dabbrev - :i "C-p" #'cape-history)) - (:unless (modulep! :completion corfu +tng) - :i "C-SPC" #'completion-at-point - :n "C-SPC" (cmd! (call-interactively #'evil-insert-state) - (call-interactively #'completion-at-point)) - :v "C-SPC" (cmd! (call-interactively #'evil-change) - (call-interactively #'completion-at-point)))) + :i "C-SPC" #'completion-at-point + :n "C-SPC" (cmd! (call-interactively #'evil-insert-state) + (call-interactively #'completion-at-point)) + :v "C-SPC" (cmd! (call-interactively #'evil-change) + (call-interactively #'completion-at-point))) (:map corfu-map - "C-u" (cmd! (let (corfu-cycle) - (funcall-interactively #'corfu-next (- corfu-count)))) - "C-d" (cmd! (let (corfu-cycle) - (funcall-interactively #'corfu-next corfu-count))))) + :i "C-SPC" #'corfu-insert-separator + "C-k" #'corfu-previous + "C-j" #'corfu-next + "C-u" (cmd! (let (corfu-cycle) + (funcall-interactively #'corfu-next (- corfu-count)))) + "C-d" (cmd! (let (corfu-cycle) + (funcall-interactively #'corfu-next corfu-count))))) (:after corfu-popupinfo :map corfu-popupinfo-map + "C-h" #'corfu-popupinfo-toggle ;; Reversed because popupinfo assumes opposite of what feels intuitive ;; with evil. - "C-S-k" #'corfu-popupinfo-scroll-down - "C-S-j" #'corfu-popupinfo-scroll-up - "C-h" #'corfu-popupinfo-toggle))) + "C-S-k" #'corfu-popupinfo-scroll-down + "C-S-j" #'corfu-popupinfo-scroll-up + "C-" #'corfu-popupinfo-scroll-down + "C-" #'corfu-popupinfo-scroll-up + "C-S-p" #'corfu-popupinfo-scroll-down + "C-S-n" #'corfu-popupinfo-scroll-up + "C-S-u" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-down corfu-popupinfo-min-height)) + "C-S-d" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-up corfu-popupinfo-min-height))))) ;;; :completion (separate) (map! (:when (modulep! :completion ivy) diff --git a/modules/config/default/config.el b/modules/config/default/config.el index fa98a80a8..f489ca222 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -459,57 +459,42 @@ Continues comments if executed from a commented line. Consults "C-s" command)) (map! :when (modulep! :completion corfu) - :after corfu (:map corfu-map "C-S-s" #'+corfu-move-to-minibuffer "C-p" #'corfu-previous "C-n" #'corfu-next + "S-TAB" #'corfu-previous + [backtab] #'corfu-previous + "TAB" #'corfu-next + [tab] #'corfu-next (:when (modulep! :completion corfu +orderless) - [remap completion-at-point] #'+corfu-smart-sep-toggle-escape) - (:when (modulep! :completion corfu +tng) - :gi [tab] #'corfu-next - :gi "TAB" #'corfu-next - :gi [backtab] #'corfu-previous - :gi "S-TAB" #'corfu-previous)) - (:after corfu-popupinfo - :map corfu-popupinfo-map - "C-" #'corfu-popupinfo-scroll-down - "C-" #'corfu-popupinfo-scroll-up - "C-S-p" #'corfu-popupinfo-scroll-down - "C-S-n" #'corfu-popupinfo-scroll-up - "C-S-u" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-down corfu-popupinfo-min-height)) - "C-S-d" (cmd! (funcall-interactively #'corfu-popupinfo-scroll-up corfu-popupinfo-min-height))) - (:when (not (modulep! :completion corfu +tng)) - (:map corfu-map - "C-" `(menu-item "Conclude the minibuffer" exit-minibuffer - :filter ,(lambda (cmd) (when (minibufferp nil t) cmd))) - "S-" `(menu-item "Insert completion and conclude" - +corfu-complete-and-exit-minibuffer - :filter ,(lambda (cmd) (when (minibufferp nil t) cmd)))))) - (when-let ((cmds-del (and (modulep! :completion corfu +tng) - `(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" corfu-insert - :filter ,(lambda (cmd) - (cond ((eq corfu--index -1) - (corfu-quit)) - ((and (modulep! :completion corfu +tng) - (eq corfu-preview-current 'insert) - (minibufferp nil t)) - (corfu-insert) - nil) - (t - cmd)))))) + [remap corfu-insert-separator] #'+corfu-smart-sep-toggle-escape))) + (let ((cmds-del + `(menu-item "Reset completion" corfu-reset + :filter ,(lambda (cmd) + (interactive) + (when (and (>= corfu--index 0) + (eq corfu-preview-current 'insert)) + cmd)))) + (cmds-ret + `(menu-item "Insert completion DWIM" corfu-insert + :filter ,(lambda (cmd) + (interactive) + (cond ((null +corfu-want-ret-to-confirm) + (corfu-quit)) + ((or (not (minibufferp nil t)) + (eq +corfu-want-ret-to-confirm t)) + (when (>= corfu--index 0) cmd)) + ((eq +corfu-want-ret-to-confirm 'minibuffer) + (funcall-interactively cmd) + nil) + (t cmd)))))) (map! :when (modulep! :completion corfu) - :after corfu :map corfu-map [backspace] cmds-del "DEL" cmds-del - :ig [return] cmds-ret - :ig "RET" cmds-ret)) + :gi [return] cmds-ret + :gi "RET" cmds-ret)) ;; Smarter C-a/C-e for both Emacs and Evil. C-a will jump to indentation. ;; Pressing it again will send you to the true bol. Same goes for C-e, except diff --git a/templates/init.example.el b/templates/init.example.el index 7a5e4e6c7..cef45ecb3 100644 --- a/templates/init.example.el +++ b/templates/init.example.el @@ -22,6 +22,7 @@ :completion company ; the ultimate code completion backend + ;;(corfu +orderless) ; complete with cap(f), cape and a flying feather! ;;helm ; the *other* search engine for love and life ;;ido ; the other *other* search engine... ;;ivy ; a search engine for love and life From 600ebf8b0111df84d473e795a99f501e149b555b Mon Sep 17 00:00:00 2001 From: Luigi Sartor Piucco Date: Mon, 4 Mar 2024 14:17:56 -0300 Subject: [PATCH 49/49] docs(corfu): add @LemonBreezes as co-maintainer Co-authored-by: StrawberryTea --- modules/completion/corfu/README.org | 1 + 1 file changed, 1 insertion(+) diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org index f0f782875..ca8d49053 100644 --- a/modules/completion/corfu/README.org +++ b/modules/completion/corfu/README.org @@ -17,6 +17,7 @@ utilities for fine-tuning. Only some of common behaviors are documented here. ** Maintainers - [[doom-user:][@LuigiPiucco]] +- [[doom-user:][@LemonBreezes]] [[doom-contrib-maintainer:][Become a maintainer?]]