diff --git a/early-init.el b/early-init.el index bc6032b42..9d6778109 100644 --- a/early-init.el +++ b/early-init.el @@ -109,7 +109,7 @@ ;; 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 _ + (condition-case-unless-debug _ ;; Load the heart of Doom Emacs. (load (expand-file-name "lisp/doom" user-emacs-directory) nil (not init-file-debug) nil 'must-suffix) diff --git a/lisp/doom-ui.el b/lisp/doom-ui.el index 95d5b92ce..64db32afd 100644 --- a/lisp/doom-ui.el +++ b/lisp/doom-ui.el @@ -498,23 +498,6 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original (cons 'custom-theme-directory (delq 'custom-theme-directory custom-theme-load-path))) -(defun doom--make-font-specs (face font frame) - (let* ((base-specs (cadr (assq 'user (get face 'theme-face)))) - (base-specs (or base-specs '((t nil)))) - (attrs '(:family :foundry :slant :weight :height :width)) - (new-specs nil)) - (dolist (spec base-specs) - ;; Each SPEC has the form (DISPLAY ATTRIBUTE-PLIST) - (let ((display (car spec)) - (plist (copy-tree (nth 1 spec)))) - ;; Alter only DISPLAY conditions matching this frame. - (when (or (memq display '(t default)) - (face-spec-set-match-display display frame)) - (dolist (attr attrs) - (setq plist (plist-put plist attr (face-attribute face attr))))) - (push (list display plist) new-specs))) - (nreverse new-specs))) - (defun doom-init-fonts-h (&optional _reload) "Loads `doom-font', `doom-serif-font', and `doom-variable-pitch-font'." (let ((this-frame (selected-frame))) @@ -530,11 +513,24 @@ windows, switch to `doom-fallback-buffer'. Otherwise, delegate to original (set-face-attribute face frame :width 'normal :weight 'normal :slant 'normal :font font))) - (let ((new-specs (doom--make-font-specs face font this-frame))) - ;; Don't save to `customized-face' so it's omitted from `custom-file' - ;;(put face 'customized-face new-specs) - (custom-push-theme 'theme-face face 'user 'set new-specs) - (put face 'face-modified nil))) + (custom-push-theme + 'theme-face face 'user 'set + (let* ((base-specs (cadr (assq 'user (get face 'theme-face)))) + (base-specs (or base-specs '((t nil)))) + (attrs '(:family :foundry :slant :weight :height :width)) + (new-specs nil)) + (dolist (spec base-specs) + ;; Each SPEC has the form (DISPLAY ATTRIBUTE-PLIST) + (let ((display (car spec)) + (plist (copy-tree (nth 1 spec)))) + ;; Alter only DISPLAY conditions matching this frame. + (when (or (memq display '(t default)) + (face-spec-set-match-display display this-frame)) + (dolist (attr attrs) + (setq plist (plist-put plist attr (face-attribute face attr))))) + (push (list display plist) new-specs))) + (nreverse new-specs))) + (put face 'face-modified nil)) ('error (ignore-errors (doom--reset-inhibited-vars-h)) (if (string-prefix-p "Font not available" (error-message-string e)) diff --git a/lisp/doom.el b/lisp/doom.el index 885e31f29..9545c215a 100644 --- a/lisp/doom.el +++ b/lisp/doom.el @@ -433,82 +433,102 @@ users).") (doom-partial #'tty-run-terminal-initialization (selected-frame) nil t)))) - (unless init-file-debug - ;; PERF,UX: Site files tend to use `load-file', which emits "Loading X..." - ;; messages in the echo area. Writing to the echo-area triggers a - ;; redisplay, which can be expensive during startup. This may also cause - ;; an flash of white when creating the first frame. - (define-advice load-file (:override (file) silence) - (load file nil 'nomessage)) - ;; COMPAT: But undo our `load-file' advice later, as to limit the scope of - ;; any edge cases it could induce. - (define-advice startup--load-user-init-file (:before (&rest _) undo-silence) - (advice-remove #'load-file #'load-file@silence)) + ;; PERF,UX: Site files tend to use `load-file', which emits "Loading X..." + ;; messages in the echo area. Writing to the echo-area triggers a + ;; redisplay, which can be expensive during startup. This may also cause + ;; an flash of white when creating the first frame. Needs to be undo + ;; later, though. + (define-advice load-file (:override (file) silence) + (load file nil 'nomessage)) - ;; PERF: `load-suffixes' and `load-file-rep-suffixes' are consulted on - ;; each `require' and `load'. Doom won't load any modules this early, so - ;; omit .so for a tiny startup boost. Is later restored in doom-start. - (put 'load-suffixes 'initial-value (default-toplevel-value 'load-suffixes)) - (put 'load-file-rep-suffixes 'initial-value (default-toplevel-value 'load-file-rep-suffixes)) - (set-default-toplevel-value 'load-suffixes '(".elc" ".el")) - (set-default-toplevel-value 'load-file-rep-suffixes '("")) - ;; COMPAT: Undo any problematic startup optimizations; from this point, I - ;; make no assumptions about what might be loaded in userland. - (add-hook! 'doom-before-init-hook - (defun doom--reset-load-suffixes-h () - (setq load-suffixes (get 'load-suffixes 'initial-value) - load-file-rep-suffixes (get 'load-file-rep-suffixes 'initial-value)))) + ;; PERF: `load-suffixes' and `load-file-rep-suffixes' are consulted on + ;; each `require' and `load'. Doom won't load any modules this early, so + ;; omit .so for a tiny startup boost. Is later restored in doom-start. + (put 'load-suffixes 'initial-value (default-toplevel-value 'load-suffixes)) + (put 'load-file-rep-suffixes 'initial-value (default-toplevel-value 'load-file-rep-suffixes)) + (set-default-toplevel-value 'load-suffixes '(".elc" ".el")) + (set-default-toplevel-value 'load-file-rep-suffixes '("")) + ;; COMPAT: Undo any problematic startup optimizations; from this point, I + ;; make no assumptions about what might be loaded in userland. + (add-hook! 'doom-before-init-hook + (defun doom--reset-load-suffixes-h () + (setq load-suffixes (get 'load-suffixes 'initial-value) + load-file-rep-suffixes (get 'load-file-rep-suffixes 'initial-value)))) - ;; PERF: Doom uses `defcustom' to indicate variables that users are - ;; expected to reconfigure. Trouble is it fires off initializers meant - ;; to accommodate any user attempts to configure them before they were - ;; defined. This is unnecessary before $DOOMDIR/init.el is loaded, so I - ;; disable them until it is. - (setq custom-dont-initialize t) - (add-hook! 'doom-before-init-hook - (defun doom--reset-custom-dont-initialize-h () - (setq custom-dont-initialize nil))) + ;; PERF: Doom uses `defcustom' to indicate variables that users are + ;; expected to reconfigure. Trouble is it fires off initializers meant + ;; to accommodate any user attempts to configure them before they were + ;; defined. This is unnecessary work before $DOOMDIR/init.el is loaded, + ;; so I disable them until it is. + (setq custom-dont-initialize t) + (add-hook! 'doom-before-init-hook + (defun doom--reset-custom-dont-initialize-h () + (setq custom-dont-initialize nil))) - ;; PERF: The mode-line procs a couple dozen times during startup. This is - ;; normally quite fast, but disabling the default mode-line and reducing - ;; the update delay timer seems to stave off ~30-50ms. - (put 'mode-line-format 'initial-value (default-toplevel-value 'mode-line-format)) - (setq-default mode-line-format nil) - (dolist (buf (buffer-list)) - (with-current-buffer buf (setq mode-line-format nil))) - ;; PERF,UX: Premature redisplays can substantially affect startup times and - ;; produce ugly flashes of unstyled Emacs. - (setq-default inhibit-redisplay t - inhibit-message t) - ;; COMPAT: Then reset with advice, because `startup--load-user-init-file' - ;; will never be interrupted by errors. And if these settings are left - ;; set, Emacs could appear frozen or garbled. - (defun doom--reset-inhibited-vars-h () - (setq-default inhibit-redisplay nil - ;; Inhibiting `message' only prevents redraws and - inhibit-message nil) - (redraw-frame)) - (add-hook 'after-init-hook #'doom--reset-inhibited-vars-h) - (define-advice startup--load-user-init-file (:after (&rest _) undo-inhibit-vars) - (when init-file-had-error - (doom--reset-inhibited-vars-h)) - (unless (default-toplevel-value 'mode-line-format) - (setq-default mode-line-format (get 'mode-line-format 'initial-value)))) + ;; PERF: Doom disables the UI elements by default, so that there's less + ;; for the frame to initialize. However, the toolbar is still populated + ;; regardless, so I lazy load it until tool-bar-mode is actually used. + (advice-add #'tool-bar-setup :override #'ignore) - ;; PERF: Doom disables the UI elements by default, so that there's less - ;; for the frame to initialize. However, the toolbar is still populated - ;; regardless, so I lazy load it until tool-bar-mode is actually used. - (advice-add #'tool-bar-setup :override #'ignore) - (define-advice startup--load-user-init-file (:before (&rest _) defer-tool-bar-setup) - (advice-remove #'tool-bar-setup #'ignore) - (add-transient-hook! 'tool-bar-mode (tool-bar-setup))) + ;; PERF: The mode-line procs a couple dozen times during startup. This is + ;; normally quite fast, but disabling the default mode-line and reducing + ;; the update delay timer seems to stave off ~30-50ms. + (put 'mode-line-format 'initial-value (default-toplevel-value 'mode-line-format)) + (setq-default mode-line-format nil) + (dolist (buf (buffer-list)) + (with-current-buffer buf (setq mode-line-format nil))) + ;; PERF,UX: Premature redisplays can substantially affect startup times + ;; and/or produce ugly flashes of unstyled Emacs. + (setq-default inhibit-redisplay t + inhibit-message t) + ;; COMPAT: Then reset with advice, because `startup--load-user-init-file' + ;; will never be interrupted by errors. And if these settings are left + ;; set, Emacs could appear frozen or garbled. + (defun doom--reset-inhibited-vars-h () + (setq-default inhibit-redisplay nil + ;; Inhibiting `message' only prevents redraws and + inhibit-message nil) + (redraw-frame)) + (add-hook 'after-init-hook #'doom--reset-inhibited-vars-h) - ;; PERF: Unset a non-trivial list of command line options that aren't - ;; relevant to this session, but `command-line-1' still processes. - (unless doom--system-macos-p - (setq command-line-ns-option-alist nil)) - (unless (memq initial-window-system '(x pgtk)) - (setq command-line-x-option-alist nil))))) + ;; PERF,UX: An annoying aspect of site-lisp files is that they're often + ;; noisy (they emit load messages or other output to stdout). These + ;; queue unnecessary redraws at startup, cost startup time, and pollute + ;; the logs. I get around it by suppressing it until we can load it + ;; manually, later (in the `startup--load-user-init-file' advice below). + (put 'site-run-file 'initial-value site-run-file) + (setq site-run-file nil) + + (define-advice startup--load-user-init-file (:around (fn &rest args) undo-inhibit-vars) + (let (--init--) + (unwind-protect + (progn + ;; COMPAT: Onces startup is sufficiently complete, undo some + ;; optimizations to reduce the scope of potential edge cases. + (advice-remove #'load-file #'load-file@silence) + (advice-remove #'tool-bar-setup #'ignore) + (add-transient-hook! 'tool-bar-mode (tool-bar-setup)) + (when (setq site-run-file (get 'site-run-file 'initial-value)) + (let ((inhibit-startup-screen inhibit-startup-screen)) + (letf! (defun load (file &optional noerror _nomessage &rest args) + (apply load file noerror t args)) + (load site-run-file t t)))) + ;; Then startup as normal. + (apply fn args) + (setq --init-- t)) + (when (or (not --init--) init-file-had-error) + ;; If we don't undo our inhibit-{message,redisplay} and there's an + ;; error, we'll see nothing but a blank Emacs frame. + (doom--reset-inhibited-vars-h)) + (unless (default-toplevel-value 'mode-line-format) + (setq-default mode-line-format (get 'mode-line-format 'initial-value)))))) + + ;; PERF: Unset a non-trivial list of command line options that aren't + ;; relevant to this session, but `command-line-1' still processes. + (unless doom--system-macos-p + (setq command-line-ns-option-alist nil)) + (unless (memq initial-window-system '(x pgtk)) + (setq command-line-x-option-alist nil)))) ;; diff --git a/modules/completion/corfu/README.org b/modules/completion/corfu/README.org index ca8d49053..e10d1b17d 100644 --- a/modules/completion/corfu/README.org +++ b/modules/completion/corfu/README.org @@ -74,7 +74,6 @@ composed to suit the user. The following keybindings are generally available: | [[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 | @@ -82,19 +81,16 @@ composed to suit the user. The following keybindings are generally available: | [[kbd:][C-h]] | (evil) Toggle documentation (if available) | | [[kbd:][M-t]] | (emacs) (when not completing) Complete | -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. +Bindings in the following sections are additive, and unless otherwise noted, are +enabled by default with configurable behavior. 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. ** 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). 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 @@ -166,10 +162,10 @@ you accidentaly press more than needed. | [[kbd:][SPC]] | (when completing with separators) Self-insert | ** Exporting to the minibuffer -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. +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. * Configuration A few variables may be set to change behavior of this module: @@ -196,16 +192,16 @@ A few variables may be set to change behavior of this module: 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-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. +- [[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-minibuffer-completion]] :: + Whether to enable Corfu in the minibuffer. See its documentation for + additional tweaks. ** Adding CAPFs to a mode To add other CAPFs on a mode-per-mode basis, put either of the following in your @@ -222,9 +218,7 @@ 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 -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~: +To add other CAPFs to keys, adapt the snippet below into your ~config.el~: #+begin_src emacs-lisp (map! :map some-mode-map diff --git a/modules/completion/corfu/autoload.el b/modules/completion/corfu/autoload.el index 60c274c4d..43005c6c1 100644 --- a/modules/completion/corfu/autoload.el +++ b/modules/completion/corfu/autoload.el @@ -14,17 +14,16 @@ ((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. + ;; Important: `completion-in-region-function' is set to corfu at + ;; this moment, so `completion-in-region' (single -) doesn't work + ;; below. + ((modulep! :completion helm) + ;; Helm is special and wants to _wrap_ `completion--in-region' + ;; instead of replacing it in `completion-in-region-function'. + ;; But because the advice is too unreliable we "fake" the wrapping. + (helm--completion-in-region #'completion--in-region beg end table pred)) + ((modulep! :completion ido) (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 @@ -37,5 +36,4 @@ ((char-equal (char-before) corfu-separator) (save-excursion (backward-char 1) (insert-char ?\\))) - (t - (call-interactively #'corfu-insert-separator)))) + (t (call-interactively #'corfu-insert-separator)))) diff --git a/modules/completion/corfu/config.el b/modules/completion/corfu/config.el index 96651c6b1..475894fa5 100644 --- a/modules/completion/corfu/config.el +++ b/modules/completion/corfu/config.el @@ -1,13 +1,5 @@ ;;; 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'.") - -(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: @@ -16,6 +8,14 @@ Possible values are: and immediatelly exit if in the minibuffer; - nil: Pass-through without inserting.") +(defvar +corfu-buffer-scanning-size-limit (* 1 1024 1024) ; 1 MB + "Size limit for a buffer to be scanned by `cape-dabbrev'.") + +(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 @@ -39,9 +39,6 @@ Possible values are: (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 @@ -54,11 +51,9 @@ Possible values are: vterm-mode) t) corfu-cycle t - corfu-separator (when (modulep! +orderless) ?\s) 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) @@ -69,9 +64,6 @@ Possible values are: (add-to-list 'corfu-continue-commands #'+corfu-smart-sep-toggle-escape) (add-hook 'evil-insert-state-exit-hook #'corfu-quit) - (when (modulep! +icons) - (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) - ;; 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 () @@ -89,7 +81,21 @@ Possible values are: (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)))))) + (timer--args evil--ex-search-update-timer))))) + + ;; HACK: If your dictionaries aren't set up in text-mode buffers, ispell will + ;; continuously pester you about errors. This ensures it only happens once + ;; per session. + (defadvice! +corfu--auto-disable-ispell-capf-a (fn &rest args) + "If ispell isn't properly set up, only complain once per session." + :around #'ispell-completion-at-point + (condition-case-unless-debug e + (apply fn args) + ('error + (message "Error: %s" (error-message-string e)) + (message "Auto-disabling `text-mode-ispell-word-completion'") + (setq text-mode-ispell-word-completion nil) + (remove-hook 'completion-at-point-functions #'ispell-completion-at-point t))))) (use-package! cape :defer t @@ -102,6 +108,7 @@ Possible values are: (add-hook 'completion-at-point-functions #'cape-elisp-block 0 t))) ;; Enable Dabbrev completion basically everywhere as a fallback. (when (modulep! +dabbrev) + (setq cape-dabbrev-check-other-buffers t) ;; Set up `cape-dabbrev' options. (defun +dabbrev-friend-buffer-p (other-buffer) (< (buffer-size other-buffer) +corfu-buffer-scanning-size-limit)) @@ -110,8 +117,7 @@ Possible values are: (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 + (setq dabbrev-friend-buffer-function #'+dabbrev-friend-buffer-p dabbrev-ignored-buffer-regexps '("^ " "\\(TAGS\\|tags\\|ETAGS\\|etags\\|GTAGS\\|GRTAGS\\|GPATH\\)\\(<[0-9]+>\\)?") @@ -119,16 +125,16 @@ Possible values are: (add-to-list 'dabbrev-ignored-buffer-modes 'pdf-view-mode))) ;; Make these capfs composable. + (advice-add #'lsp-completion-at-point :around #'cape-wrap-noninterruptible) + (advice-add #'lsp-completion-at-point :around #'cape-wrap-nonexclusive) (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)) + (advice-add 'pcomplete-completions-at-point :around #'cape-wrap-purify))) (use-package! yasnippet-capf :when (modulep! :editor snippets) @@ -139,9 +145,11 @@ Possible values are: (add-hook 'completion-at-point-functions #'yasnippet-capf 30 t)))) (use-package! corfu-terminal + :when (modulep! :os tty) :when (not (display-graphic-p)) :hook ((corfu-mode . corfu-terminal-mode))) + ;; ;;; Extensions @@ -154,3 +162,22 @@ Possible values are: :hook ((corfu-mode . corfu-popupinfo-mode)) :config (setq corfu-popupinfo-delay '(0.5 . 1.0))) + +(use-package! nerd-icons-corfu + :when (modulep! +icons) + :defer t + :init + (after! corfu + (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))) + +;; If vertico is not enabled, orderless will be installed but not configured. +;; That may break smart separator behavior, so we conditionally configure it. +(use-package! orderless + :when (and (not (modulep! :completion vertico)) + (modulep! +orderless)) + :config + (setq completion-styles '(orderless basic) + completion-category-defaults nil + completion-category-overrides '((file (styles orderless partial-completion))) + orderless-component-separator #'orderless-escapable-split-on-space) + (set-face-attribute 'completions-first-difference nil :inherit nil)) diff --git a/modules/completion/corfu/packages.el b/modules/completion/corfu/packages.el index 05f2d9b98..cf45a992f 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 "b48d3017a47706198e04440cc1b3483bdf646771") -(package! cape :pin "bfde79ed440343c0dbf0f64cfe7913c1efbe3f83") +(package! corfu :pin "c1e7b6190b00158e67347b4db0a8f7964e5d2f8b") +(package! cape :pin "a397a0c92de38277b7f835fa999fac400a764908") (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 "db12b55cd08b614cbba134008566e48d7faf660e")) + (package! yasnippet-capf :pin "9043f8275176a8f198ce8e81fadab1870fa165bb")) diff --git a/modules/completion/vertico/config.el b/modules/completion/vertico/config.el index cca3c88ca..d48e0e3a6 100644 --- a/modules/completion/vertico/config.el +++ b/modules/completion/vertico/config.el @@ -252,6 +252,11 @@ orderless." (not (modulep! :checkers syntax +flymake))) :after (consult flycheck)) +(use-package! consult-yasnippet + :when (modulep! :editor snippets) + :defer t + :init (map! [remap yas-insert-snippet] #'consult-yasnippet)) + (use-package! embark :defer t diff --git a/modules/completion/vertico/packages.el b/modules/completion/vertico/packages.el index 348f43ce7..8d1f9c75f 100644 --- a/modules/completion/vertico/packages.el +++ b/modules/completion/vertico/packages.el @@ -1,19 +1,19 @@ ;; -*- no-byte-compile: t; -*- ;;; completion/vertico/packages.el -(package! vertico :pin "4a7da56b02c6aefff8f6b4574a530a7cb54bc21a") +(package! vertico :pin "68cbd47589446e9674921bae0b98ff8fbe28be23") -(package! orderless :pin "b24748093b00b37c3a572c4909f61c08fa27504f") +(package! orderless :pin "dc7a781acf2e58ac7d20d1b522be0cde5213e057") -(package! consult :pin "9463146ba754103db9475ae56e46561366ba4773") +(package! consult :pin "b48ff6bf0527baeb6bfd07c6da9d303ff0b79c3d") (package! consult-dir :pin "3f5f4b71ebe819392cb090cda71bd39a93bd830a") (when (and (modulep! :checkers syntax) (not (modulep! :checkers syntax +flymake))) - (package! consult-flycheck :pin "d83f87581af74f7a2739d8b1b90c37da5ae3d310")) -(package! embark :pin "60139db8794f7e4a08076d9f7597d08f6c8083d1") -(package! embark-consult :pin "60139db8794f7e4a08076d9f7597d08f6c8083d1") + (package! consult-flycheck :pin "754f5497d827f7d58009256a21af614cc44378a3")) +(package! embark :pin "c93abadc8220c0caa6fea805f7a736c346d47e7e") +(package! embark-consult :pin "c93abadc8220c0caa6fea805f7a736c346d47e7e") -(package! marginalia :pin "ea356ebb1ddb8d6da78574b517155475cf52d46f") +(package! marginalia :pin "f6fe86b989a177355ab3ff7e97a384e10a7b0bb1") (package! wgrep :pin "208b9d01cfffa71037527e3a324684b3ce45ddc4") @@ -24,3 +24,6 @@ (package! vertico-posframe :recipe (:host github :repo "tumashu/vertico-posframe") :pin "2e0e09e5bbd6ec576ddbe566ab122575ef051fab")) + +(when (modulep! :editor snippets) + (package! consult-yasnippet :pin "834d39acfe8a7d2c304afbe4d649b9372118c756")) diff --git a/modules/config/default/+evil-bindings.el b/modules/config/default/+evil-bindings.el index 1cab4a3c9..af9f3fec4 100644 --- a/modules/config/default/+evil-bindings.el +++ b/modules/config/default/+evil-bindings.el @@ -45,7 +45,7 @@ (modulep! :completion company +tng)) #'company-indent-or-complete-common (and (bound-and-true-p corfu-mode) - (modulep! :completion corfu +tng)) + (modulep! :completion corfu)) #'completion-at-point) :m [tab] (cmds! (and (modulep! :editor snippets) (evil-visual-state-p) @@ -186,8 +186,8 @@ "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))))) + "C-S-u" (cmd!! #'corfu-popupinfo-scroll-down nil corfu-popupinfo-min-height) + "C-S-d" (cmd!! #'corfu-popupinfo-scroll-up nil corfu-popupinfo-min-height)))) ;;; :completion (separate) (map! (:when (modulep! :completion ivy) @@ -424,7 +424,9 @@ :desc "Incoming call hierarchy" "y" #'lsp-treemacs-call-hierarchy :desc "Outgoing call hierarchy" "Y" (cmd!! #'lsp-treemacs-call-hierarchy t) :desc "References tree" "R" (cmd!! #'lsp-treemacs-references t) - :desc "Symbols" "S" #'lsp-treemacs-symbols)) + :desc "Symbols" "S" #'lsp-treemacs-symbols + :desc "LSP" "l" #'+default/lsp-command-map + :desc "LSP Rename" "r" #'lsp-rename)) (:when (modulep! :tools lsp +eglot) :desc "LSP Execute code action" "a" #'eglot-code-actions :desc "LSP Rename" "r" #'eglot-rename diff --git a/modules/config/default/config.el b/modules/config/default/config.el index 864e14d1e..e52133fe7 100644 --- a/modules/config/default/config.el +++ b/modules/config/default/config.el @@ -459,35 +459,39 @@ Continues comments if executed from a commented line. Consults "C-s" command)) (map! :when (modulep! :completion corfu) + :after corfu (:map corfu-map + [remap corfu-insert-separator] #'+corfu-smart-sep-toggle-escape "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 corfu-insert-separator] #'+corfu-smart-sep-toggle-escape))) + [tab] #'corfu-next)) (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 "Reset completion" corfu-reset + :filter ,(lambda (cmd) + (when (and (>= corfu--index 0) + (eq corfu-preview-current 'insert)) + cmd)))) + (cmds-ret `(menu-item "Insert completion DWIM" corfu-insert :filter ,(lambda (cmd) (interactive) (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)) + (corfu-quit) + nil) ((eq +corfu-want-ret-to-confirm 'minibuffer) (funcall-interactively cmd) nil) + ((and (or (not (minibufferp nil t)) + (eq +corfu-want-ret-to-confirm t)) + (>= corfu--index 0)) + cmd) + ((or (not (minibufferp nil t)) + (eq +corfu-want-ret-to-confirm t)) + nil) (t cmd)))))) (map! :when (modulep! :completion corfu) :map corfu-map diff --git a/modules/editor/fold/autoload/fold.el b/modules/editor/fold/autoload/fold.el index 2b757cc87..1052374bb 100644 --- a/modules/editor/fold/autoload/fold.el +++ b/modules/editor/fold/autoload/fold.el @@ -75,8 +75,8 @@ Targets `vimmish-fold', `hideshow', `ts-fold' and `outline' folds." (cl-letf (((symbol-function #'outline-hide-subtree) (symbol-function #'outline-hide-entry))) (outline-toggle-children))) - ((+fold--ts-fold-p) (ts-fold-toggle)) - ((+fold--hideshow-fold-p) (+fold-from-eol (hs-toggle-hiding)))))) + ((+fold--hideshow-fold-p) (+fold-from-eol (hs-toggle-hiding))) + ((+fold--ts-fold-p) (ts-fold-toggle))))) ;;;###autoload (defun +fold/open () @@ -89,8 +89,8 @@ Targets `vimmish-fold', `hideshow', `ts-fold' and `outline' folds." ((+fold--outline-fold-p) (outline-show-children) (outline-show-entry)) - ((+fold--ts-fold-p) (ts-fold-open)) - ((+fold--hideshow-fold-p) (+fold-from-eol (hs-show-block)))))) + ((+fold--hideshow-fold-p) (+fold-from-eol (hs-show-block))) + ((+fold--ts-fold-p) (ts-fold-open))))) ;;;###autoload (defun +fold/close () @@ -100,9 +100,9 @@ Targets `vimmish-fold', `hideshow', `ts-fold' and `outline' folds." (interactive) (save-excursion (cond ((+fold--vimish-fold-p) (vimish-fold-refold)) - ((+fold--ts-fold-p) (ts-fold-close)) + ((+fold--outline-fold-p) (outline-hide-subtree)) ((+fold--hideshow-fold-p) (+fold-from-eol (hs-hide-block))) - ((+fold--outline-fold-p) (outline-hide-subtree))))) + ((+fold--ts-fold-p) (ts-fold-close))))) ;;;###autoload (defun +fold/open-all (&optional level) diff --git a/modules/lang/java/packages.el b/modules/lang/java/packages.el index 8e84b5088..c51e11afe 100644 --- a/modules/lang/java/packages.el +++ b/modules/lang/java/packages.el @@ -14,4 +14,10 @@ (when (modulep! +lsp) (unless (modulep! :tools lsp +eglot) + ;; HACK: lsp-java depends on lsp-treemacs without declaring it as a + ;; dependency, thereby throwing errors if :ui (treemacs +lsp) isn't + ;; enabled (i.e. lsp-treemacs isn't installed). This needs to be tackled + ;; upstream, but for now: + (unless (alist-get 'lsp-treemacs doom-packages) + (package! lsp-treemacs :pin "e54e74deb8150964e3c3024e1ec14295a34e2a3b")) (package! lsp-java :pin "c962a3b3ac2beabdf1ce83b815396d6c38e3cefa"))) diff --git a/modules/lang/julia/config.el b/modules/lang/julia/config.el index 6f3f33358..657574431 100644 --- a/modules/lang/julia/config.el +++ b/modules/lang/julia/config.el @@ -106,12 +106,10 @@ :when (modulep! :term vterm) :hook (julia-mode . julia-snail-mode) :config - (setq julia-snail-popup-display-eval-results :command) - (setq julia-snail-multimedia-enable t) - (setq julia-snail-popup-display-face '(:background base3 :box `(:line-width -1 :color base5))) - (set-popup-rule! "^\\*julia.*\\*$" :ttl nil :select nil :quit nil) + (setq-default julia-snail-multimedia-enable t) + (after! julia-mode (set-repl-handler! 'julia-mode #'+julia/open-snail-repl :persist t diff --git a/modules/tools/eval/autoload/eval.el b/modules/tools/eval/autoload/eval.el index dbec32bcf..78ded4c82 100644 --- a/modules/tools/eval/autoload/eval.el +++ b/modules/tools/eval/autoload/eval.el @@ -24,34 +24,33 @@ (defun +eval-display-results-in-overlay (output &optional source-buffer) "Display OUTPUT in a floating overlay next to the cursor." (require 'eros) - (let* ((this-command #'+eval/buffer-or-region) - (prefix eros-eval-result-prefix) - (lines (split-string output "\n")) - (prefixlen (length prefix)) - (len (+ (apply #'max (mapcar #'length lines)) - prefixlen)) - (col (- (current-column) (window-hscroll))) - (next-line? (or (cdr lines) - (< (- (window-width) - (save-excursion (goto-char (point-at-eol)) - (- (current-column) - (window-hscroll)))) - len))) - (pad (if next-line? - (+ (window-hscroll) prefixlen) - 0)) - (where (if next-line? - (line-beginning-position 2) - (line-end-position))) - eros-eval-result-prefix - eros-overlays-use-font-lock) - (with-current-buffer (or source-buffer (current-buffer)) + (with-current-buffer (or source-buffer (current-buffer)) + (let* ((this-command #'+eval/buffer-or-region) + (prefix eros-eval-result-prefix) + (lines (split-string output "\n")) + (prefixlen (length prefix)) + (len (+ (apply #'max (mapcar #'length lines)) + prefixlen)) + (col (- (current-column) (window-hscroll))) + (next-line? (or (cdr lines) + (< (- (window-width) + (save-excursion (goto-char (line-end-position)) + (- (current-column) + (window-hscroll)))) + len))) + (pad (if next-line? + (+ (window-hscroll) prefixlen) + 0)) + eros-overlays-use-font-lock) (eros--make-result-overlay (concat (make-string (max 0 (- pad prefixlen)) ?\s) prefix - (string-join lines (concat "\n" (make-string pad ?\s)))) - :where where - :duration eros-eval-result-duration)))) + (string-join lines (concat hard-newline (make-string pad ?\s)))) + :where (if next-line? + (line-beginning-position 2) + (line-end-position)) + :duration eros-eval-result-duration + :format "%s")))) ;;;###autoload (defun +eval-display-results (output &optional source-buffer) diff --git a/modules/tools/magit/packages.el b/modules/tools/magit/packages.el index 6bc86d4e5..7bebc3a57 100644 --- a/modules/tools/magit/packages.el +++ b/modules/tools/magit/packages.el @@ -1,9 +1,9 @@ ;; -*- no-byte-compile: t; -*- ;;; tools/magit/packages.el -(when (package! magit :pin "65ecb9c5fc7586a1c527b60d180a97ea230da99f") +(when (package! magit :pin "0963697f24cfbe80f92312044bd9ab28b914b053") (when (modulep! +forge) - (package! forge :pin "03b48be2a12a282cd47b92287fc1701a81f1cece") + (package! forge :pin "68771ca4d53c3aea5c860eeb888cee8e9cb5ca37") (package! code-review :recipe (:host github :repo "doomelpa/code-review"