summary refs log tree commit diff
path: root/config/init-completion.el
blob: 50e05626644cf23bb3fe6974a384a6d32ab14034 (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
;;; init-completion.el --- Configure completion -*- lexical-binding: t -*-
;; Author: Franck Cuny <franck@fcuny.net>

;;; Commentary:

;; Configure completions

;;; Code:

(use-package consult
  :ensure t
  :commands (consult-ripgrep consult-buffer consult-imenu)
  :bind (("C-c m"   . consult-mode-command)
	 ("M-g o"   . consult-org-heading)
	 ("C-x b"   . consult-buffer)
	 ("C-x r b" . consult-bookmark)
	 ("C-x p b" . consult-project-buffer)
	 ("C-c i"   . consult-imenu)
	 ("M-g e"   . consult-compile-error)
	 ("M-g g"   . consult-goto-line)
	 ("M-g M-g" . consult-goto-line)
	 ("M-g m"   . consult-mark)
	 ("M-g k"   . consult-global-mark)))

(use-package corfu
  :ensure t
  :demand t
  :bind (("M-/" . completion-at-point)
	 :map corfu-map
	 ("C-n"      . corfu-next)
	 ("C-p"      . corfu-previous)
	 ("<return>" . corfu-insert)
	 ("M-d"      . corfu-info-documentation)
	 ("M-l"      . corfu-info-location)
	 ("M-."      . corfu-move-to-minibuffer))
  :custom
  ;; Works with `indent-for-tab-command'. Make sure tab doesn't indent when you
  ;; want to perform completion
  (tab-always-indent 'complete)
  (completion-cycle-threshold t)      ; Always show candidates in menu

  (corfu-auto t)
  (corfu-auto-prefix 2)
  (corfu-auto-delay 0.25)

  (corfu-min-width 80)
  (corfu-max-width corfu-min-width)     ; Always have the same width
  (corfu-cycle t)

  ;; `nil' means to ignore `corfu-separator' behavior, that is, use the older
  ;; `corfu-quit-at-boundary' = nil behavior. Set this to separator if using
  ;; `corfu-auto' = `t' workflow (in that case, make sure you also set up
  ;; `corfu-separator' and a keybind for `corfu-insert-separator', which my
  ;; configuration already has pre-prepared). Necessary for manual corfu usage with
  ;; orderless, otherwise first component is ignored, unless `corfu-separator'
  ;; is inserted.
  (corfu-quit-at-boundary nil)
  (corfu-separator ?\s)            ; Use space
  (corfu-quit-no-match 'separator) ; Don't quit if there is `corfu-separator' inserted
  (corfu-preview-current 'insert)  ; Preview first candidate. Insert on input if only one
  (corfu-preselect-first t)        ; Preselect first candidate?

  ;; Other
  (corfu-echo-documentation nil)        ; Already use corfu-popupinfo

  :init
  ;; see https://github.com/minad/corfu#completing-in-the-eshell-or-shell
  (add-hook 'eshell-mode-hook
            (lambda ()
              (setq-local corfu-auto nil)
              (corfu-mode)))
  :config
  (global-corfu-mode))

(use-package corfu-popupinfo
  :after corfu
  :hook (corfu-mode . corfu-popupinfo-mode)
  :bind (:map corfu-map
              ("M-n" . corfu-popupinfo-scroll-up)
              ("M-p" . corfu-popupinfo-scroll-down)
              ([remap corfu-show-documentation] . corfu-popupinfo-toggle))
  :custom
  (corfu-popupinfo-delay 0.5)
  (corfu-popupinfo-max-width 70)
  (corfu-popupinfo-max-height 20)
  ;; Also here to be extra-safe that this is set when `corfu-popupinfo' is
  ;; loaded. I do not want documentation shown in both the echo area and in
  ;; the `corfu-popupinfo' popup.
  (corfu-echo-documentation nil))

(use-package cape
  :demand t
  :ensure t
  :bind (("C-c . p" . completion-at-point)
	 ("C-c . h" . cape-history)
	 ("C-c . f" . cape-file)
	 ("C-c . a" . cape-abbrev)
	 ("C-c . l" . cape-line)
	 ("C-c . w" . cape-dict)
	 ("C-c . r" . cape-rfc1345))
  :init
  ;; Add `completion-at-point-functions', used by `completion-at-point'.
  (add-to-list 'completion-at-point-functions #'cape-file)
  (add-to-list 'completion-at-point-functions #'cape-abbrev))

(use-package marginalia
  :ensure t
  ;; Either bind `marginalia-cycle' globally or only in the minibuffer
  :bind (:map minibuffer-local-map
              ("M-A" . marginalia-cycle))
  :init
  ;; Must be in the :init section of use-package such that the mode gets
  ;; enabled right away. Note that this forces loading the package.
  (marginalia-mode))

(use-package orderless
  :demand t
  :ensure t
  :custom
  (completion-styles '(orderless basic))
  (completion-category-defaults nil))

(use-package vertico
  :ensure t
  :init
  (vertico-mode))

(provide 'init-completion)

;;; init-completion.el ends here