Hello crafters community! Nice to meet you! I come here because I require the knowledge of the elisp-fu masters. I had a semi-working Emacs configuration that had somewhat bad autocompletions but overall it kind of worked save for a few details. I now don’t know if these new packages are faster but fragile-er or if there’s anything I can do to fix the mess I have in my Emacs Lisp configurations. I would be extremely grateful if anyone can shed some light onto this skill-issue I have with Emacs Lisp myself.
I used a minimal init.el
file I found on GitHub many years ago, and have jumped from helm to ivy to the newest sensation which is vertico
, marginalia
, corfu
, cape
, orderless
, prescient
& embark
. I however have the following issues and I haven’t found a single repository, explanation or single source of truth on how this package bundle should be configured:
- No autocomplete happens in some programming language modes even when
eglot
is present - For some reason
<Space>
doesn’t stop the autocompletion work, I have to escape first and then continue typing (I’m using evil) nerd-icons
are partially working only insideconsult
andneotree
, howevermarginalia
,vertico
&corfu
are not showing any icons no matter what options are used.
I’m using a “layered” approach and no package manager outside the included (use-package)
as I wanted to keep the package count as low as possible.
I could paste my configuration here but it exceeds well over 1000 lines of elisp so I’ll include the relevant parts only:
The layer responsible for nerd-icons
does work since neotree
and consult
do show icons:
(use-package nerd-icons
:defer t
:custom
(nerd-icons-scale-factor 0.9))
Here’s the ~/.config/emacs/layers/neotree-layer.el
:
(use-package neotree
:ensure t
:init
(global-set-key [f3] 'neotree-toggle)
:config
(setq neo-smart-open t)
(setq neo-show-hidden-files t)
(setq neo-create-file-auto-open t)
(setq neo-window-width 55)
(setq neo-window-fixed-size nil)
(setq inhibit-compacting-font-caches t)
(setq neo-theme (if (display-graphic-p) 'nerd-icons))
(setq projectile-switch-project-action 'neotree-projectile-action))
; Neotree won't load icons inside emacsclient because `display-graphic-p` does not load
;; at server init.
(defun neo-icons-mode-hook ()
"Custom `neo-theme` to always display icons."
(when (display-graphic-p)
(setq neo-theme 'nerd-icons)))
(add-hook 'neotree-mode-hook #'neo-icons-mode-hook)
I have this ~/.config/emacs/layers/completion-layer.el
:
(use-package prescient
:custom
(prescient-filter-method '(literal initialism regexp))
(prescient-sort-length-enable nil)
(prescient-sort-full-matches-first t)
(prescient-history-length 200)
(prescient-frequency-decay 0.997)
(prescient-frequency-threshold 0.05)
:config
(prescient-persist-mode 1))
(use-package corfu
:ensure t
:demand t
:init
(global-corfu-mode)
:custom
(corfu-auto t)
(corfu-auto-delay 0.3)
(corfu-cycle t)
(corfu-preselect 'first)
(corfu-quit-at-boundary nil)
(corfu-separator ?\s)
(corfu-quit-no-match 'separator)
(corfu-preview-current t)
(corfu-on-exact-match nil)
(corfu-count 14)
(corfu-scroll-margin 4))
(use-package nerd-icons-corfu
:ensure t
:after corfu
:requires nerd-icons
:if (display-graphic-p)
:config
(add-to-list 'corfu-margin-formatters #'nerd-icons-corfu-formatter))
(use-package corfu-prescient
:demand t
:after corfu prescient
:custom
(corfu-prescient-enable-sorting t)
(corfu-prescient-override-sorting nil)
(corfu-prescient-enable-filtering nil)
(corfu-prescient-completion-styles '(prescient flex))
(corfu-prescient-completion-category-overrides
'((file (styles partial-completion prescient))
(eglot (styles prescient flex))))
:config
(corfu-prescient-mode 1))
(use-package corfu-popupinfo
:ensure nil
:hook (corfu-mode . corfu-popupinfo-mode)
:bind ( :map corfu-map
([remap corfu-info-documentation] . corfu-popupinfo-toggle)
("M-l" . corfu-popupinfo-location))
:custom
(corfu-popupinfo-delay '(nil . 0.3)) ; Don't display initially
(corfu-popupinfo-direction '(right left vertical))
(corfu-popupinfo-hide t)
(corfu-popupinfo-resize t)
(corfu-popupinfo-max-height 70)
(corfu-popupinfo-max-width 80)
(corfu-popupinfo-min-height 1)
(corfu-popupinfo-min-width 25))
(use-package emacs
:custom
(completion-cycle-threshold 5)
(enable-recursive-minibuffers t)
(read-extended-command-predicate #'command-completion-default-include-p)
(tab-always-indent 'complete)
(read-extended-command-predicate #'command-completion-default-include-p)
:init
(defun crm-indicator (args)
(cons (format "[CRM%s] %s"
(replace-regexp-in-string
"\\`\\[.*?]\\*\\|\\[.*?]\\*\\'" ""
crm-separator)
(car args))
(cdr args)))
(advice-add #'completing-read-multiple :filter-args #'crm-indicator)
(setq minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode))
(use-package orderless
:custom
(orderless-matching-styles
'(orderless-regexp
orderless-prefixes
orderless-initialism))
(orderless-component-separator 'orderless-escapable-split-on-space)
:config
(add-to-list 'completion-category-overrides '(eglot (styles . (orderless flex)))))
(use-package cape
:ensure t
:defer t
:init
(add-hook 'completion-at-point-functions #'cape-dabbrev)
(add-hook 'completion-at-point-functions #'cape-file)
(add-hook 'completion-at-point-function #'cape-history)
(add-hook 'completion-at-point-function #'cape-elisp-symbol)
(add-hook 'completion-at-point-function #'cape-keyword)
(add-hook 'completion-at-point-function #'cape-sgml)
:custom
(cape-dabbrev-min-length 2)
:config
(setq-local completion-at-point-functions
(list (cape-capf-super #'cape-dabbrev #'cape-dict #'cape-keyword))))
(use-package marginalia
:ensure t
:demand t
:custom
(marginalia-max-relative-age 0)
(marginalia-align 'left)
:bind (:map minibuffer-local-map
("M-A" . marginalia-cycle))
:custom
(marginalia-annotators '(marginalia-annotators-heavy marginalia-annotators-light nil))
:init
(marginalia-mode))
(use-package consult
:init
(advice-add #'register-preview :override #'consult-register-window)
(setq register-preview-delay 0.5)
(setq xref-show-xrefs-function #'consult-xref
xref-show-definitions-function #'consult-xref)
:config
(consult-customize
consult-theme :preview-key '(:debounce 0.2 any)
consult-ripgrep consult-git-grep consult-grep
consult-bookmark consult-recent-file consult-xref
consult--source-bookmark consult--source-file-register
consult--source-recent-file consult--source-project-recent-file
:preview-key '(:debounce 0.4 any))
(setq consult-narrow-key "<") ;; "C-+")
(use-package consult-dir
:ensure t
:after (consult))
(use-package embark
:ensure t
:bind
(("C-." . embark-act) ;; pick some comfortable binding
("M-." . embark-dwim) ;; good alternative: M-.
("C-h B" . embark-bindings)) ;; alternative for `describe-bindings'
:init
(setq prefix-help-command #'embark-prefix-help-command)
:config
(add-to-list 'display-buffer-alist
'("\\`\\*Embark Collect \\(Live\\|Completions\\)\\*"
nil
(window-parameters (mode-line-format . none)))))
;; Consult users will also want the embark-consult package.
(use-package embark-consult
:ensure t ; only need to install it, embark loads it after consult if found
:defer t
:after (consult embark)
:hook
(embark-collect-mode . consult-preview-at-point-mode))
(use-package flymake :ensure nil
:hook
(prog-mode . flymake-mode)
:config ; (Optional) For fix bad icon display (Only for left margin)
(advice-add #'flymake--indicator-overlay-spec
:filter-return
(lambda (indicator)
(concat indicator
(propertize " "
'face 'default
'display `((margin left-margin)
(space :width 5))))))
:custom
(flymake-indicator-type 'margins)
(flymake-margin-indicators-string
`((error ,(nerd-icons-faicon "nf-fa-remove_sign") compilation-error)
(warning ,(nerd-icons-faicon "nf-fa-warning") compilation-warning)
(note ,(nerd-icons-faicon "nf-fa-circle_info") compilation-info))))
(use-package nerd-icons-completion
:ensure t
:hook (marginalia-mode . nerd-icons-completion-marginalia-setup)
:config
(nerd-icons-completion-mode 1))
Finally I have my ~/.config/emacs/layers/vertico-layer.el
:
(use-package vertico
:ensure t
:demand t
:defer t
:bind (:map vertico-map
("C-j" . vertico-next)
("C-k" . vertico-previous)
("C-f" . vertico-exit)
:map minibuffer-local-map
("M-h" . backward-kill-word))
:hook
(minibuffer-setup-hook . vertico-repeat-save)
:custom
(vertico-scroll-margin 0)
(vertico-count 20)
(vertico-resize t)
(vertico-cycle t)
:init
(vertico-mode)
(vertico-mouse-mode))
(use-package vertico-directory
:ensure nil
:requires vertico
:after vertico
:hook
(rfn-eshadow-update-overlay-hook . vertico-directory-tidy))
(use-package vertico-flat
:ensure nil
:requires vertico
:after vertico
:custom
(vertico-flat-annotate t)
(vertico-flat-format
`( :multiple #("\n{%s}" 0 2 (face minibuffer-prompt) 4 5 (face minibuffer-prompt))
:single #("\n[%s]" 0 2 (face minibuffer-prompt) 2 4 (face success) 4 5 (face minibuffer-prompt))
:prompt #("(%s)" 0 1 (face minibuffer-prompt) 3 4 (face minibuffer-prompt))
:separator #(" | " 0 5 (face minibuffer-prompt))
:ellipsis ,(propertize "…" 'face 'minibuffer-prompt)
:no-match ,(propertize "\n[No match]" 'face 'shadow)
:spacer #(" " 0 1 (cursor t)))))
(use-package vertico-multiform
:ensure nil
:requires vertico
:after vertico
:defer t
:hook
(vertico-mode-hook . vertico-multiform-mode)
:custom
(vertico-multiform-categories
'((buffer flat (vertico-sort-function . nil))
(file grid (:keymap . vertico-directory-map))
(project-file grid) ; For `project-find-file'
(command flat (vertico-flat-annotate . nil))
(symbol-help flat)
(kill-ring (vertico-sort-function . nil))
(color (vertico-sort-function . vertico-sort-history-length-alpha))
(jinx grid
(vertico-grid-annotate . 20)
(vertico-grid-max-columns . 12)
(vertico-grid-separator
. #(" | " 4 5 (display (space :width (1)) face (:inherit shadow :inverse-video t)))))))
(vertico-multiform-commands
`((pdf-view-goto-label
(vertico-sort-function . nil))
(".+-history" (vertico-sort-function . nil))
(,(rx bol (or (seq "recentf" (* (any alnum))) "consult-recent-file"))
(vertico-sort-function . nil))
(,(rx bol (literal "customize-"))
flat)
(,(rx bol (or (seq (zero-or-one (literal "krisb-")) (literal "find-library"))
(literal "load-library")))
flat)
(,(rx bol (literal "consult-history"))
(vertico-sort-function . nil))
(,(rx (or "find-function"
"find-library"
"find-variable"))
flat))))
(use-package vertico-buffer
:requires vertico
:ensure nil
:custom
(vertico-buffer-hide-prompt nil)
(vertico-buffer-display-action '(display-buffer-reuse-window)))
(use-package vertico-prescient
:requires vertico
:after prescient
:custom
;; Sorting
(vertico-prescient-enable-sorting t)
(vertico-prescient-override-sorting nil)
(vertico-prescient-enable-filtering nil)
(vertico-prescient-completion-styles '(prescient flex))
(vertico-prescient-completion-category-overrides
'((file (styles partial-completion prescient))
(eglot (styles prescient flex))))
:config
(vertico-prescient-mode 1))
I know for a fact I must be doing something wrong here, I just don’t know where am I having conflicting settings or if my configuration is outated I’ve googled for many Emacs configurations but I haven’t found any answers. I thank you in advance for taking the time to read this long post and for any light you can bring into this not-so-skilled lisper.