dotfiles/.emacs.d/lisp/init-completion.el

188 lines
6.9 KiB
EmacsLisp
Raw Normal View History

2021-08-18 20:10:25 +00:00
;;; init-completion.el --- Completion Configuration File -*- lexical-binding: t -*-
2021-08-17 11:49:19 +00:00
;;; Commentary:
2021-08-28 13:41:35 +00:00
;; Config for completion-at-point (corfu), as well as orderless (see also init-minibuffer.el)
;; Most of it is taken from the READMEs and wikis of those packages
2021-08-17 11:49:19 +00:00
;;; Code:
2022-10-14 11:26:19 +00:00
(use-feature dabbrev
2021-09-06 19:21:22 +00:00
:diminish
2022-07-19 15:03:49 +00:00
:custom
2022-10-14 11:26:19 +00:00
(dabbrev-case-distinction nil)
(dabbrev-case-fold-search t)
(dabbrev-case-replace nil))
2021-08-17 11:49:19 +00:00
2022-10-10 15:28:16 +00:00
(use-feature hippie-expand
2022-10-14 11:29:07 +00:00
:config
2021-08-17 11:49:19 +00:00
(setq hippie-expand-try-functions-list
2023-01-17 13:21:19 +00:00
'(;yas-hippie-try-expand
try-expand-dabbrev
try-expand-all-abbrevs
try-expand-dabbrev-all-buffers
try-expand-dabbrev-from-kill
try-complete-file-name-partially
try-complete-file-name
try-expand-list
try-expand-line
try-complete-lisp-symbol-partially
try-complete-lisp-symbol))
;; https://www.emacswiki.org/emacs/HippieExpand#h5o-9
(defadvice he-substitute-string (after he-paredit-fix)
"Remove extra paren when expanding line in paredit."
2022-11-01 16:27:42 +00:00
(if (and (or smartparens-mode paredit-mode) (equal (substring str -1) ")"))
(progn (backward-delete-char 1) (forward-char))))
2021-08-17 11:49:19 +00:00
:bind
2021-09-06 19:21:22 +00:00
("C-M-/" . hippie-expand))
2021-08-17 11:49:19 +00:00
2021-08-28 13:41:35 +00:00
(use-package fancy-dabbrev
:diminish
:config
2022-07-19 15:03:49 +00:00
(global-fancy-dabbrev-mode)
(defun fancy-dabbrev-popup-advice (_next)
(local-set-key (kbd "C-M-/") #'fancy-dabbrev-backward))
(defun fancy-dabbrev-popup-exit-advice ()
(local-unset-key (kbd "C-M-/")))
(advice-add #'fancy-dabbrev--expand-again :before #'fancy-dabbrev-popup-advice)
(advice-add #'fancy-dabbrev--on-exit :after #'fancy-dabbrev-popup-exit-advice)
2022-07-19 15:03:49 +00:00
:bind ("M-/" . fancy-dabbrev-expand))
2021-08-28 13:41:35 +00:00
2023-05-19 11:09:57 +00:00
(use-feature emacs
2021-08-17 11:49:19 +00:00
:init
(setq completion-cycle-threshold 3)
2021-08-28 13:41:35 +00:00
(setq tab-always-indent 'complete))
2021-08-17 11:49:19 +00:00
(use-package orderless
2022-10-14 11:29:07 +00:00
:defer 2
2022-09-16 11:24:31 +00:00
:bind (:map minibuffer-local-map
2021-08-17 11:49:19 +00:00
("C-l" . my/orderless-match-components-literally))
2022-10-14 11:29:07 +00:00
:custom
(orderless-component-separator 'orderless-escapable-split-on-space)
(completion-styles '(orderless partial-completion basic))
(completion-category-defaults nil)
(completion-category-overrides '((file (styles . (partial-completion orderless)))))
(orderless-matching-styles '(orderless-literal orderless-regexp orderless-strict-initialism))
2022-10-14 11:29:07 +00:00
(orderless-style-dispatchers '(+orderless-dispatch))
:config
2021-08-17 11:49:19 +00:00
(defun my/orderless-match-components-literally ()
"Components match literally for the rest of the session."
(interactive)
(setq-local orderless-matching-styles '(orderless-literal)
orderless-style-dispatchers nil))
2022-10-14 11:29:07 +00:00
2022-09-16 11:35:05 +00:00
(defun orderless-strict-initialism (component &optional leading)
"Match a component as a strict leading initialism.
This means the characters in COMPONENT must occur in the
candidate, in that order, at the beginning of words, with
2022-09-16 11:35:05 +00:00
no words in between. If LEADING is non-nil, anchor to the
first word."
(orderless--separated-by '(seq (zero-or-more word) (zero-or-more punct))
(cl-loop for char across component collect `(seq word-start ,char))
2022-09-16 11:35:05 +00:00
(when leading '(seq buffer-start))))
(defun orderless-strict-leading-initialism (component)
"Match a component as a strict leading initialism.
This means the characters in COMPONENT must occur in the
candidate, in that order, at the beginning of words, with
no words in between, beginning with the first word."
(orderless-strict-initialism component t))
;; based on https://github.com/minad/consult/wiki#minads-orderless-configuration
(defvar +orderless-dispatch-alist
'((?% . char-fold-to-regexp)
(?! . orderless-without-literal)
(?` . orderless-strict-leading-initialism)
(?= . orderless-literal)
(?_ . orderless-prefix)
(?~ . orderless-flex)))
(defun +orderless--suffix-regexp ()
(if (and (boundp 'consult--tofu-char) (boundp 'consult--tofu-range))
(format "[%c-%c]*$"
consult--tofu-char
(+ consult--tofu-char consult--tofu-range -1))
"$"))
2021-08-17 11:49:19 +00:00
;; Recognizes the following patterns:
;; * ~flex flex~
;; * =literal literal=
;; * _prefix prefix_
2021-08-17 11:49:19 +00:00
;; * %char-fold char-fold%
;; * `strict-leading-initialism strict-leading-initialism`
2021-08-17 11:49:19 +00:00
;; * !without-literal without-literal!
;; * .ext (file extension)
;; * regexp$ (regexp matching at end)
(defun +orderless-dispatch (word _index _total)
2021-08-17 11:49:19 +00:00
(cond
;; Ensure that $ works with Consult commands, which add disambiguation suffixes
((string-suffix-p "$" word)
`(orderless-regexp . ,(concat (substring word 0 -1) (+orderless--suffix-regexp))))
2021-08-17 11:49:19 +00:00
;; File extensions
((and (or minibuffer-completing-file-name
(derived-mode-p 'eshell-mode))
(string-match-p "\\`\\.." word))
`(orderless-regexp . ,(concat "\\." (substring word 1) (+orderless--suffix-regexp))))
2021-08-17 11:49:19 +00:00
;; Ignore single !
((equal "!" word) `(orderless-literal . ""))
;; Prefix and suffix
((if-let (x (assq (aref word 0) +orderless-dispatch-alist))
(cons (cdr x) (substring word 1))
(when-let (x (assq (aref word (1- (length word))) +orderless-dispatch-alist))
2022-10-14 11:29:07 +00:00
(cons (cdr x) (substring word 0 -1))))))))
2021-08-17 11:49:19 +00:00
;; code completion - corfu
(use-package corfu
2023-05-19 11:09:57 +00:00
:elpaca (corfu :files (:defaults "extensions/*")
:includes (corfu-indexed corfu-quick corfu-history corfu-info corfu-popupinfo))
2021-08-17 11:49:19 +00:00
:custom
2022-10-17 15:05:08 +00:00
(corfu-cycle t)
2021-08-17 11:49:19 +00:00
:bind (:map corfu-map
2022-10-17 15:05:08 +00:00
("TAB" . corfu-next)
([tab] . corfu-next)
("S-TAB" . corfu-previous)
([backtab] . corfu-previous))
2023-05-19 11:09:57 +00:00
:hook (elpaca-after-init . global-corfu-mode))
2021-08-17 11:49:19 +00:00
2022-10-17 15:05:08 +00:00
(use-extension corfu corfu-indexed
:config (corfu-indexed-mode 1))
(use-extension corfu corfu-quick
:bind (:map corfu-map
2022-10-22 14:58:00 +00:00
("M-;" . corfu-quick-insert)
("M-'" . corfu-quick-exit)))
2022-10-17 15:05:08 +00:00
(use-extension corfu corfu-history
2023-05-19 11:09:57 +00:00
:after savehist
2022-10-17 15:05:08 +00:00
:config
(corfu-history-mode 1)
(add-to-list 'savehist-additional-variables 'corfu-history))
2022-11-29 16:14:26 +00:00
(use-extension corfu corfu-popupinfo
:hook (global-corfu-mode . corfu-popupinfo-mode))
2022-03-22 08:43:55 +00:00
2022-06-23 07:10:17 +00:00
(use-package cape
:bind (("C-c p p" . completion-at-point) ;; capf
("C-c p t" . complete-tag) ;; etags
("C-c p d" . cape-dabbrev) ;; or dabbrev-completion
("C-c p h" . cape-history)
("C-c p f" . cape-file)
("C-c p k" . cape-keyword)
("C-c p s" . cape-symbol)
("C-c p a" . cape-abbrev)
("C-c p i" . cape-ispell)
("C-c p l" . cape-line)
("C-c p w" . cape-dict)
("C-c p \\" . cape-tex)
("C-c p _" . cape-tex)
("C-c p ^" . cape-tex)
("C-c p &" . cape-sgml)
("C-c p r" . cape-rfc1345))
:custom
(cape-dict-file "/usr/share/dict/words")
:init
(add-to-list 'completion-at-point-functions #'cape-file t)
(add-to-list 'completion-at-point-functions #'cape-dabbrev t)
(add-to-list 'completion-at-point-functions #'cape-dict t)
(add-to-list 'completion-at-point-functions #'cape-ispell t))
2021-08-17 11:49:19 +00:00
(provide 'init-completion)
;;; init-completion.el ends here