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`
This commit is contained in:
Luigi Sartor Piucco 2023-10-29 14:31:13 -03:00
parent 3d41c07370
commit fc15f169da
No known key found for this signature in database
GPG key ID: 6FF1A01853A47A66
2 changed files with 27 additions and 66 deletions

View file

@ -6,13 +6,6 @@
As an exception, `cape-line' will also scan buffers with the same As an exception, `cape-line' will also scan buffers with the same
major mode regardless of size.") major mode regardless of size.")
(defvar +orderless-wildcard-character ?,
"A character used as a wildcard in Corfu for fuzzy autocompletion. If you
want to match the wildcard literally in completion, you can
escape it with forward slash. Do NOT set this to SPC.
This variable needs to be set at the top-level before any `after!' blocks.")
;; ;;
;;; Packages ;;; Packages
(use-package! corfu (use-package! corfu
@ -24,6 +17,7 @@ This variable needs to be set at the top-level before any `after!' blocks.")
(setq corfu-auto t (setq corfu-auto t
corfu-auto-delay 0.1 corfu-auto-delay 0.1
corfu-auto-prefix 2 corfu-auto-prefix 2
corfu-separator ?\s
corfu-excluded-modes '(erc-mode corfu-excluded-modes '(erc-mode
circe-mode circe-mode
help-mode help-mode
@ -39,7 +33,7 @@ This variable needs to be set at the top-level before any `after!' blocks.")
corfu-max-width 120 corfu-max-width 120
corfu-preview-current 'insert corfu-preview-current 'insert
corfu-on-exact-match nil corfu-on-exact-match nil
corfu-quit-at-boundary (if (modulep! +orderless) 'separator t) corfu-quit-at-boundary t
corfu-quit-no-match (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; ;; In the case of +tng, TAB should be smart regarding completion;
;; However, it should otherwise behave like normal, whatever normal was. ;; However, it should otherwise behave like normal, whatever normal was.
@ -56,7 +50,7 @@ This variable needs to be set at the top-level before any `after!' blocks.")
(unless (corfu-disable-in-minibuffer-p) (unless (corfu-disable-in-minibuffer-p)
(setq-local corfu-echo-delay nil ;; Disable automatic echo and popup (setq-local corfu-echo-delay nil ;; Disable automatic echo and popup
corfu-popupinfo-delay nil) corfu-popupinfo-delay nil)
(corfu-mode 1))) (corfu-mode +1)))
(add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer) (add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer)
@ -86,54 +80,9 @@ This variable needs to be set at the top-level before any `after!' blocks.")
;; Allow completion after `:' in Lispy. ;; Allow completion after `:' in Lispy.
(add-to-list 'corfu-auto-commands #'lispy-colon) (add-to-list 'corfu-auto-commands #'lispy-colon)
(when (and (modulep! +orderless) (when (modulep! +orderless)
+orderless-wildcard-character)
(defmacro +orderless-escapable-split-fn (char)
(let ((char-string (string (if (symbolp char) (symbol-value char) char))))
`(defun +orderless-escapable-split-on-space-or-char (s)
(mapcar
(lambda (piece)
(replace-regexp-in-string
(string 1) ,char-string
(replace-regexp-in-string
(concat (string 0) "\\|" (string 1))
(lambda (x)
(pcase x
("\0" " ")
("\1" ,char-string)
(_ x)))
piece
;; These are arguments to `replace-regexp-in-string'.
'fixedcase 'literal)
'fixedcase 'literal))
(split-string (replace-regexp-in-string
(concat "\\\\\\\\\\|\\\\ \\|\\\\"
,char-string)
(lambda (x)
(pcase x
("\\ " "\0")
(,(concat "\\" char-string)
"\1")
(_ x)))
s 'fixedcase 'literal)
,(concat "[ " char-string "]+")
t)))))
(after! orderless (after! orderless
;; Orderless splits the string into components and then determines the (setq orderless-component-separator #'orderless-escapable-split-on-space)))
;; matching style for each component. This is all regexp stuff.
(setq orderless-component-separator
(+orderless-escapable-split-fn +orderless-wildcard-character))
(setq corfu-separator +orderless-wildcard-character)
(defun +corfu--maybe-quit-spc-filter (cmd)
(when (and (> (point) (point-min))
(eq (char-before) +orderless-wildcard-character))
cmd))
(let ((wildstr (char-to-string +orderless-wildcard-character))
(mi-spc '(menu-item "corfu-maybe-quit" corfu-reset :filter +corfu--maybe-quit-spc-filter)))
(map! :map corfu-map
wildstr #'+corfu-insert-wildcard-separator
;; Quit completion after typing the wildcard followed by a space.
"SPC" mi-spc))))
(add-hook! 'evil-insert-state-exit-hook (add-hook! 'evil-insert-state-exit-hook
(defun +corfu-quit-on-evil-insert-state-exit-h () (defun +corfu-quit-on-evil-insert-state-exit-h ()
@ -146,22 +95,34 @@ This variable needs to be set at the top-level before any `after!' blocks.")
(when (modulep! +icons) (when (modulep! +icons)
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter)) (add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
(defun +corfu--maybe-reset-backspace-filter (cmd) (defun +corfu--reset-or-passthrough (cmd)
(when (and (modulep! +tng) (when (and (modulep! +tng)
(> corfu--index -1) (> corfu--index -1)
(eq corfu-preview-current 'insert)) (eq corfu-preview-current 'insert))
cmd)) cmd))
(defun +corfu--maybe-quit-return-filter (cmd) (defun +corfu--backward-toggle-escape-sep (cmd)
(let ((corfu--index (if (> corfu--index -1) corfu--index 0))) (save-excursion
(corfu-insert)) (backward-char 1)
cmd) (if (looking-back "\\\\" -1)
(let ((mi-del '(menu-item "corfu-maybe-reset-backspace-filter" corfu-reset #'corfu-reset
:filter +corfu--maybe-reset-backspace-filter))) (lambda ()
(interactive)
(save-excursion
(backward-char 1)
(insert-char ?\\))))))
(defun +corfu--insert-separator-or-toggle-escape (cmd)
(if (char-equal (char-before) corfu-separator)
(+corfu--backward-toggle-escape-sep cmd)
cmd))
(let ((mi-del '(menu-item "corfu-reset-or-passthrough" corfu-reset
:filter +corfu--maybe-reset-backspace-filter))
(mi-c-spc '(menu-item "corfu-insert-separator-or-toggle-escape" corfu-insert-separator
:filter +corfu--insert-separator-or-toggle-escape)))
(map! :map corfu-map (map! :map corfu-map
[return] #'corfu-insert [return] #'corfu-insert
"RET" #'corfu-insert "RET" #'corfu-insert
(:when (modulep! +orderless) (:when (modulep! +orderless)
:gi "C-SPC" #'corfu-insert-separator) :gi "C-SPC" mi-c-spc)
(:when (modulep! +tng) (:when (modulep! +tng)
[tab] #'corfu-next [tab] #'corfu-next
[backtab] #'corfu-previous [backtab] #'corfu-previous
@ -176,7 +137,6 @@ This variable needs to be set at the top-level before any `after!' blocks.")
(:when (modulep! :editor evil) "M-J" #'corfu-move-to-minibuffer)))) (:when (modulep! :editor evil) "M-J" #'corfu-move-to-minibuffer))))
(use-package! cape (use-package! cape
:defer t
:commands :commands
cape-abbrev cape-abbrev
cape-dabbrev cape-dabbrev

View file

@ -98,6 +98,7 @@ orderless."
;; Flex matching ;; Flex matching
((string-prefix-p "~" pattern) `(orderless-flex . ,(substring pattern 1))) ((string-prefix-p "~" pattern) `(orderless-flex . ,(substring pattern 1)))
((string-suffix-p "~" pattern) `(orderless-flex . ,(substring pattern 0 -1))))) ((string-suffix-p "~" pattern) `(orderless-flex . ,(substring pattern 0 -1)))))
;; TODO: Find a way to deduplicate this code from the corfu module.
(add-to-list (add-to-list
'completion-styles-alist 'completion-styles-alist
'(+vertico-basic-remote '(+vertico-basic-remote
@ -110,7 +111,7 @@ orderless."
;; find-file etc. ;; find-file etc.
completion-category-overrides '((file (styles +vertico-basic-remote orderless partial-completion))) completion-category-overrides '((file (styles +vertico-basic-remote orderless partial-completion)))
orderless-style-dispatchers '(+vertico-orderless-dispatch) 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 ;; ...otherwise find-file gets different highlighting than other commands
(set-face-attribute 'completions-first-difference nil :inherit nil)) (set-face-attribute 'completions-first-difference nil :inherit nil))