;;; syd-completion.el -*- lexical-binding: t; -*- (require 'syd-general) (use-package emacs :custom ;; Allow the opening of new minibuffers from inside existing minibuffers. ((enable-recursive-minibuffers t) ;; Hide commands in M-x which do not work in the current mode. (read-extended-command-predicate #'command-completion-default-include-p)) :config ;; Disable blinking cursor. Aesthetically, I personally don't fancy it; ;; technically, it doesn't play well with `evil-terminal-cursor-changer'. (blink-cursor-mode -1)) ;; Consult adds various search and navigation tools using Emacs' completing-read ;; function; i.e., in our case, Vertico. (use-package consult :defer t) (use-package embark-consult :after (embark consult)) ;; Vertico is a simple completion engine that replaces Emacs' built-in ;; completion engine, achieving Just Works™ compatibility. This is in contrast ;; to e.g. Helm and Ivy, which spawn ecosystems orthogonal to Emacs, and ;; diametrically-opposed to each other. (use-package vertico :hook (on-first-input . vertico-mode) :general (:keymaps 'vertico-map "DEL" #'vertico-directory-delete-char "C-SPC" #'+vertico/embark-preview "C-j" #'vertico-next "C-k" #'vertico-previous "C-M-j" #'vertico-next-group "C-M-k" #'vertico-previous-group) :custom ((vertico-resize nil) (vertico-count 17) (vertico-cycle t)) :config (setq-default completion-in-region-function #'consult-completion-in-region) ;; Cleans up path when moving directories with shadowed paths syntax, e.g. ;; cleans ~/foo/bar/// to /, and ~/foo/bar/~/ to ~/. (add-hook 'rfn-eshadow-update-overlay-hook #'vertico-directory-tidy)) (defun +vertico-orderless-dispatch (pattern _index _total) "Like `orderless-affix-dispatch', but allows affixes to be escaped. Shamelessly stolen from Doom. }:3" (let ((len (length pattern)) (alist orderless-affix-dispatch-alist)) (when (> len 0) (cond ;; Ignore single dispatcher character ((and (= len 1) (alist-get (aref pattern 0) alist)) #'ignore) ;; Prefix ((when-let ((style (alist-get (aref pattern 0) alist)) ((not (char-equal (aref pattern (max (1- len) 1)) ?\\)))) (cons style (substring pattern 1)))) ;; Suffix ((when-let ((style (alist-get (aref pattern (1- len)) alist)) ((not (char-equal (aref pattern (max 0 (- len 2))) ?\\)))) (cons style (substring pattern 0 -1)))))))) ;; Orderless provides a completion style that divides the pattern into ;; space-separated components, and matches candidates that match all of the ;; components in any order. Each component can match in any one of several ;; ways: literally, as a regexp, as an initialism, in the flex style, or as ;; multiple word prefixes. By default, regexp and literal matches are enabled. (use-package orderless :after vertico :custom ((completion-styles '(orderless basic)) (completion-category-overrides '((file (styles ;basic-remote orderless partial-completion)))) (orderless-style-dispatchers '(+vertico-orderless-dispatch)) ;; TODO: See Doom's `+vertico-orderless-dispatch'. (orderless-affix-dispatch-alist '((?! . orderless-without-literal) (?& . orderless-annotation) ;; %1 -> {1, ₁, ꘡, ⒈, ...} (?% . char-fold-to-regexp) ;; ,wcb -> {with-current-buffer, widget-convert-button, ...} (?, . orderless-initialism) (?= . orderless-literal) (?^ . orderless-literal-prefix) (?~ . orderless-flex))))) ;;;###autoload (defun embark-which-key-indicator () "An embark indicator that displays keymaps using which-key. The which-key help message will show the type and value of the current target followed by an ellipsis if there are further targets." (lambda (&optional keymap targets prefix) (if (null keymap) (which-key--hide-popup-ignore-command) (which-key--show-keymap (if (eq (plist-get (car targets) :type) 'embark-become) "Become" (format "Act on %s '%s'%s" (plist-get (car targets) :type) (embark--truncate-target (plist-get (car targets) :target)) (if (cdr targets) "…" ""))) (if prefix (pcase (lookup-key keymap prefix 'accept-default) ((and (pred keymapp) km) km) (_ (key-binding prefix 'accept-default))) keymap) nil nil t (lambda (binding) (not (string-suffix-p "-argument" (cdr binding)))))))) ;; TODO: Mark the Embark export buffer as a popup. (use-package embark :after vertico :defer t :custom ((which-key-use-C-h-commands nil) (prefix-help-command #'embark-prefix-help-command) ;; Embark uses their own custom interface that is essentially ;; equivalent to which-key; just use which-key. }:) (embark-indicators '(embark-which-key-indicator))) :general (:keymaps 'minibuffer-local-map "C-;" `("Actions" . ,#'embark-act)) (:keymaps 'syd-leader-map "a" `("Actions" . ,#'embark-act))) (provide 'syd-completion)