12 KiB
Emacs — Packages — Autocompletion
Autocompletion
Code Autocompletion
Company is, in my opinion, the best autocompleting engine for Emacs, and it is one of the most popular if not the most popular.
(use-package company
:straight (:build t)
:defer t
:hook (company-mode . evil-normalize-keymaps)
:init (global-company-mode)
:config
(setq company-minimum-prefix-length 2
company-toolsip-limit 14
company-tooltip-align-annotations t
company-require-match 'never
company-global-modes '(not erc-mode message-mode help-mode gud-mode)
company-frontends
'(company-pseudo-tooltip-frontend ; always show candidates in overlay tooltip
company-echo-metadata-frontend) ; show selected candidate docs in echo area
company-backends '(company-capf)
company-auto-commit nil
company-auto-complete-chars nil
company-dabbrev-other-buffers nil
company-dabbrev-ignore-case nil
company-dabbrev-downcase nil))
This package is a backend for company. It emulates
ac-source-dictionary
by proposing text related to the current
major-mode.
(use-package company-dict
:after company
:straight (:build t)
:config
(setq company-dict-dir (expand-file-name "dicts" user-emacs-directory)))
On the other hand, company-box
is a Company front-end which offers
colours, icons, documentation and so on. Very nice.
Declaring all the icons for the variable
company-box-icons-all-the-icons
is quite verbose in Elisp, so I do it
with an org-table.
Type | Icon | Color |
---|---|---|
Unknown | find_in_page | purple |
Text | text_fields | green |
Method | functions | red |
Function | functions | red |
Constructor | functions | red |
Field | functions | red |
Variable | adjust | blue |
Class | class | red |
Interface | settings_input_component | red |
Module | view_module | red |
Property | settings | red |
Unit | straighten | red |
Value | filter_1 | red |
Enum | plus_one | red |
Keyword | filter_center_focus | red |
Snippet | short_text | red |
Color | color_lens | red |
File | insert_drive_file | red |
Reference | collections_bookmark | red |
Folder | folder | red |
EnumMember | people | red |
Constant | pause_circle_filled | red |
Struct | streetview | red |
Event | event | red |
Operator | control_point | red |
TypeParameter | class | red |
Template | short_text | green |
ElispFunction | functions | red |
ElispVariable | check_circle | blue |
ElispFeature | stars | orange |
ElispFace | format_paint | pink |
(mapconcat (lambda (row)
(format "(%s . ,(all-the-icons-material \"%s\" :face 'all-the-icons-%s))"
(car row)
(cadr row)
(caddr row)))
table
"\n")
(use-package company-box
:straight (:build t)
:after (company all-the-icons)
:config
(setq company-box-show-single-candidate t
company-box-backends-colors nil
company-box-max-candidates 50
company-box-icons-alist 'company-box-icons-all-the-icons
company-box-icons-all-the-icons
(let ((all-the-icons-scale-factor 0.8))
`(
<<gen-company-box-icons()>>))))
Ivy
My main menu package is ivy
which I use as much as possible –I’ve
noticed helm
can be slow, very slow in comparison to ivy
, so I’ll use
the latter as much as possible. Actually, only ivy
is installed for
now. I could have used ido
too, but I find it to be a bit too
restricted in terms of features compared to ivy
.
(use-package ivy
:straight t
:defer t
:diminish
:bind (("C-s" . swiper)
:map ivy-minibuffer-map
("TAB" . ivy-alt-done)
("C-l" . ivy-alt-done)
("C-t" . ivy-next-line)
("C-s" . ivy-previous-line)
("C-u" . ivy-scroll-up-command)
("C-d" . ivy-scroll-down-command)
:map ivy-switch-buffer-map
("C-t" . ivy-next-line)
("C-s" . ivy-previous-line)
("C-l" . ivy-done)
("C-d" . ivy-switch-buffer-kill)
:map ivy-reverse-i-search-map
("C-t" . ivy-next-line)
("C-s" . ivy-previous-line)
("C-d" . ivy-reverse-i-search-kill))
:config
(ivy-mode 1)
(setq ivy-wrap t
ivy-height 17
ivy-sort-max-size 50000
ivy-fixed-height-minibuffer t
ivy-read-action-functions #'ivy-hydra-read-action
ivy-read-action-format-function #'ivy-read-action-format-columns
projectile-completion-system 'ivy
ivy-on-del-error-function #'ignore
ivy-use-selectable-prompt t))
There is also prescient.el
that offers some nice features when
coupled with ivy
, guess what was born out of it? ivy-prescient
, of
course!
(use-package ivy-prescient
:after ivy
:straight (:build t))
I warned you I’d use too much all-the-icons
, I did!
(use-package all-the-icons-ivy
:straight (:build t)
:after (ivy all-the-icons)
:init (all-the-icons-ivy-setup)
:hook (after-init . all-the-icons-ivy-setup))
(all-the-icons-ivy-setup)
A buffer popping at the bottom of the screen is nice and all, but have you considered a floating buffer in the centre of your frame?
(use-package ivy-posframe
:defer t
:after (:any ivy helpful)
:hook (ivy-mode . ivy-posframe-mode)
:straight (:build t)
:init
(ivy-posframe-mode 1)
:config
(setq ivy-fixed-height-minibuffer nil
ivy-posframe-border-width 10
ivy-posframe-parameters
`((min-width . 90)
(min-height . ,ivy-height))))
Something that can be missing sometimes in Ivy is the ability to
select multiple entries at once. For instance, when programming in
Java, LPS can offer you to automatically generate the methods equals
and hashCode
based on selected members, but with vanilla Ivy, you can
only select one. Not really useful. ivy-hydra
is a package that offers
a Hydra interface when in Ivy which allows you to select multiple
choices among other things.
(use-package ivy-hydra
:requires (ivy hydra)
:after ivy
:straight (:build t))
Finally, let’s make ivy
richer:
(use-package ivy-rich
:straight (:build t)
:after ivy
:init
(ivy-rich-mode 1))
Counsel
I could almost merge this chapter with the previous one since counsel
is a package that provides loads of completion functions for ivy. The
ones I find most useful are counsel-M-x
and counsel-find-file
.
(use-package counsel
:straight t
:after recentf
:after ivy
:bind (("M-x" . counsel-M-x)
("C-x b" . counsel-ibuffer)
("C-x C-f" . counsel-find-file)
:map minibuffer-local-map
("C-r" . 'counsel-minibuffer-history)))
Yasnippet
Yasnippet allows you to insert some pre-made code by just typing a few characters. It can even generate some string with Elisp expressions and ask the user for some input in some precise places.
(use-package yasnippet
:defer t
:straight (:build t)
:init
(yas-global-mode)
:hook ((prog-mode . yas-minor-mode)
(text-mode . yas-minor-mode)))
Of course, yasnippet wouldn’t be as awesome as it is without pre-made snippets.
(use-package yasnippet-snippets
:defer t
:after yasnippet
:straight (:build t))
Similarly, yatemplate offers pre-made files rather than just strings. That’s still yasnippet by the way.
(use-package yatemplate
:defer t
:after yasnippet
:straight (:build t))
And finally, with ivy you can choose your snippets from a menu if you’re not sure or if you don’t remember what your snippet is.
(use-package ivy-yasnippet
:defer t
:after (ivy yasnippet)
:straight (:build t)
:general
(phundrak/leader-key
:infix "i"
:packages 'ivy-yasnippet
"y" #'ivy-yasnippet))