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 e8805ce2b..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,10 +18,25 @@ :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) + (after! orderless + (setq orderless-component-separator #'orderless-escapable-split-on-space))) :config (setq corfu-auto t corfu-auto-delay 0.1 @@ -41,6 +61,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) @@ -50,10 +71,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 () @@ -104,11 +121,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 +133,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 () diff --git a/modules/config/default/config.el b/modules/config/default/config.el index f3eb854c1..e4b5e4cda 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 @@ -481,19 +479,37 @@ 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 - :enable (minibufferp nil t)) - "S-" '(menu-item "Insert completion and conclude" +corfu-complete-and-exit-minibuffer - :enable (minibufferp nil t)))) + (: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 - :enable (and (> corfu--index -1) - (eq corfu-preview-current 'insert)))))) - (map! :after corfu + `(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)))))) + (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