My Minor Mode Config
My personal Emacs Config, 2021-07-05T11:00:00+02:00Table of Contents
Minor modes
(menu-bar-mode -1)
(toggle-scroll-bar -1)
(tool-bar-mode -1)
Abbrev-mode
See also: DynamicAbbreviations
Emacs has a nice feature to expand abbreviations. If for example, you wanted an abbreviation for ‘Your Name’ to be ‘yn’, just type ‘yn’ and with your point after the ‘n’ do C-x a i g (mnemonic add inverse global) and enter the expansion, in this case ‘Your Name’. In the future, whenever you type ‘yn’ your name will be inserted. The abbrevs are automatically saved between sessions in a file ~/.abbrev_defs .
I find this most useful for fixing typos. Whenever you have a typo (I type ‘becasue’ almost every time) if you are religious (see alt.religion.emacs) and never correct it but instead do C-x a i g and enter the correct spelling, emacs will fix all your typos, and you can type like a reckless madman and emacs will clean up the mess behind you. See AutoCorrection.
If you don’t like an abbrev that you have set up, then do M-x edit-abbrevs. You can have different abbrevs for each mode (cperl, c++, Message); the g in C-x a i g is for global, meaning every mode.
See the Abbrevs node in the emacs info for more.
(add-hook 'text-mode-hook #'abbrev-mode)
Afterglow
(require 'afterglow)
(afterglow-mode 1)
;; Optional
(setq afterglow-default-duration 0.5)
(setq afterglow-default-face 'hl-line)
;; Example 1:
(afterglow-add-triggers
'((evil-previous-visual-line :thing line :width 5 :duration 0.2)
(evil-next-visual-line :thing line :width 5 :duration 0.2)
(previous-line :thing line :duration 0.2)
(next-line :thing line :duration 0.2)
(eval-buffer :thing window :duration 0.2)
(eval-defun :thing defun :duration 0.2)
(eval-expression :thing sexp :duration 1)
(eval-last-sexp :thing sexp :duration 1)
(my-function :thing my-region-function :duration 0.5
:face 'highlight)))
Consult
Corral
Corral is a lightweight package that lets you quickly wrap parentheses and other delimiters around text, intuitively surrounding what you want it to using just two commands.
(require 'corral)
Call a command once to wrap delimiters around the sexp at point. Repeated calls of the same command, backward or forward, will shift the delimiters in the respective direction, corralling more text.
Keep point position instead of following delimiters
This is controlled by the variable corral-preserve-point, which can be set manually or through customize.
(setq corral-preserve-point t)
dame
(load (concat user-emacs-directory "lisp/dame.el"))
(load (concat user-emacs-directory "lisp/dame-org-rifle.el"))
(load (concat user-emacs-directory "lisp/dame-org-ql.el"))
edna
Extensible Dependencies ’N’ Actions (EDNA) for Org Mode tasks
Edna provides an extensible means of specifying conditions which must be fulfilled before a task can be completed and actions to take once it is.
Org Edna runs when either the BLOCKER or TRIGGER properties are set on a heading, and when it is changing from a TODO state to a DONE state.
For brevity, we use TODO state to indicate any state in org-not-done-keywords, and DONE state to indicate any state in org-done-keywords.
(require 'org-edna)
(setq orgstuck-keywords '("project" ("NEXT") nil ""))
(setq Org-todo-repeat-to-state "NEXT")
(org-edna-mode)
Embark (Emacs Mini-Buffer Actions Rooted in Keymaps)
This package provides a sort of right-click contextual menu for Emacs, accessed through the embark-act command (which you should bind to a convenient key), offering you relevant actions to use on a target determined by the context:
Flymake
(setq flymake-error-bitmap '(flymake-double-exclamation-mark modus-themes-fringe-red))
(setq flymake-note-bitmap '(exclamation-mark modus-themes-fringe-cyan))
(setq flymake-warning-bitmap '(exclamation-mark modus-themes-fringe-yellow))
Golden Ratio
When working with many windows at the same time, each window has a size that is not convenient for editing.
golden-ratio helps on this issue by resizing automatically the windows you are working on to the size specified in the "Golden Ratio". The window that has the main focus will have the perfect size for editing, while the ones that are not being actively edited will be re-sized to a smaller size that doesn't get in the way, but at the same time will be readable enough to know it's content.
(require 'golden-ratio)
(golden-ratio-mode 0)
Jinx
Jinx is a fast just-in-time spell-checker for Emacs. Jinx highlights misspelled words in the text of the visible portion of the buffer. For efficiency, Jinx highlights misspellings lazily, recognizes window boundaries and text folding, if any. For example, when unfolding or scrolling, only the newly visible part of the text is checked if it has not been checked before. Each misspelling can be corrected from a list of dictionary words presented as a completion menu.
Jinx has two modes: the command, global-jinx-mode activates globally; and the command, jinx-mode, for activating for specific modes.
(require 'jinx)
;; Alternative 1: Enable Jinx globally
(add-hook 'emacs-startup-hook #'global-jinx-mode)
;; Alternative 2: Enable Jinx per mode
;;(dolist (hook '(text-mode-hook prog-mode-hook conf-mode-hook))
;; (add-hook hook #'jinx-mode))
Line-Wrapping
Visual Line Mode und Visual Fill Column sind beide Emacs-Funktionen, die den Umgang mit langen Zeilen verbessern, aber sie arbeiten auf unterschiedliche Weise und haben unterschiedliche Anwendungsfälle.
Visual Line Mode
- Zweck: Bricht lange Zeilen optisch um, ohne den eigentlichen Text zu ändern.
- Verhalten:
- Zeilen werden am Fensterrand umgebrochen, aber die Datei bleibt unverändert.
- Nützlich für das Lesen von Texten mit langen Zeilen (z. B. Prosa, Markdown, Org-Mode).
- Keine Änderungen an der Datei selbst.
- Aktivierung:
(add-hook 'text-mode-hook #'visual-line-mode)
(add-hook 'markdown-mode-hook #'visual-line-mode)
(add-hook 'org-mode-hook #'visual-line-mode)
Visual Fill Column Mode
Wird benötigt für den Writeroom-Mode.
- Zweck: Bricht lange Zeilen tatsächlich an einer bestimmten Spaltenbreite um und fügt Zeilenumbrüche in den Text ein.
- Verhalten:
- Fügt tatsächliche Zeilenumbrüche in den Text ein, um die Zeilenlänge zu begrenzen.
- Nützlich für das Bearbeiten von Texten, bei denen die Zeilenlänge begrenzt werden soll (z. B. Quellcode-Kommentare, E-Mails, LaTeX).
- Ändert die Datei dauerhaft.
- Aktivierung:
;; Vorausgesetzt, visual-fill-column ist installiert
(require 'visual-fill-column)
;; Gemeinsame Setup-Funktion
(setq-default fill-column 100)
;; gewünschte Textbreite
;; Aktivieren in relevanten Modi
;;(add-hook 'visual-line-mode-hook #'visual-fill-column-mode)
Marginalia
This package provides marginalia-mode which adds marginalia to the minibuffer completions. Marginalia are marks or annotations placed at the margin of the page of a book or in this case helpful colorful annotations placed at the margin of the minibuffer for your completion candidates. Marginalia can only add annotations to be displayed with the completion candidates. It cannot modify the appearance of the candidates themselves, which are shown as supplied by the original commands.
The annotations are added based on the completion category. For example find-file reports the file category and M-x reports the command category. You can cycle between more or less detailed annotators or even disable the annotator with command marginalia-cycle
(require 'marginalia)
(marginalia-mode)
Consult provides practical commands based on the Emacs completion function completing-read. Completion allows you to quickly select an item from a list of candidates. Consult offers in particular an advanced buffer switching command consult-buffer to switch between buffers and recently opened files. Furthermore Consult provides multiple search commands, an asynchronous consult-grep and consult-ripgrep, and the line-based search command consult-line. Some of the Consult commands are enhanced versions of built-in Emacs commands. For example the command consult-imenu presents a flat list of the Imenu with live preview, grouping and narrowing. Please take a look at the full list of commands.
Consult is fully compatible with completion systems centered around the standard Emacs completing-read API, notably the default completion system, Vertico, Mct, and Icomplete.
This package keeps the completion system specifics to a minimum. The ability of the Consult commands to work well with arbitrary completion systems is one of the main advantages of the package. Consult fits well into existing setups and it helps you to create a full completion environment out of small and independent components.
(require 'consult)
Orderless
This package provides an orderless 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.
(require 'orderless)
(setq completion-styles '(substring orderless)
completion-category-defaults nil
completion-category-overrides '((file (styles partial-completion))))
(setq Linum-format "%7i ")
(setq after-save-hook '(org-babel-tangle))
;;(setq ansi-color-faces-vector [default bold shadow italic underline success warning error])
;;(setq ansi-color-map '((ansi-color-make-color-map) t))
;;(setq ansi-color-names-vector ["#454545" "#d65946" "#6aaf50" "#baba36" "#598bc1" "#ab75c3" "#68a5e9" "#AAB0AB"])
(setq auto-revert-avoid-polling t)
(setq awesome-tray-mode-line-active-color "#2fafff")
(setq awesome-tray-mode-line-inactive-color "#323232")
(setq backup-directory-alist '(("." . "~/.backup")))
(setq beacon-color "#ed0547ad8099")
(setq blink-cursor-mode nil)
;;(setq bmkp-last-as-first-bookmark-file concat)
(setq browse-url-firefox-new-window-is-tab t)
(setq browse-url-firefox-program "/home/andy/.local/bin/firefox")
(setq cal-tex-which-days '(1 2 3 4 5 6 0))
(setq calendar-mark-diary-entries-flag t)
(setq calendar-month-name-array
["Januar" "Februar" "März" "April" "Mai" "Juni" "Juli" "August" "September" "Oktober" "November" "Dezember"])
(setq calendar-view-diary-initially-flag t)
(setq column-number-mode t)
(setq compilation-message-face 'default)
(setq completion-styles '(substring orderless))
(setq confirm-kill-processes nil)
(setq consult-preview-key '(:debounce 0.5 any))
(setq create-lockfiles nil)
(setq cua-auto-tabify-rectangles nil)
(setq cua-mode t)
(setq cua-normal-cursor-color "black")
(setq custom-buffer-style 'link)
(setq custom-enabled-themes '(DrOps))
(setq custom-file "~/.config/emacs/custom.el")
(setq custom-safe-themes
'("263e3a9286c7ab0c4f57f5d537033c8a5943e69d142e747723181ab9b12a5855" "fe497072cd9ff25d187db65196b2910d78c938ed71bd3991163f3da6fda62757" "f3c9e341d20be3c006cc8bccb309ef439083d47fed664b4a23133e67b1f8cab8" "92f458ebdf4a4a84f7ff089d58d8c097f09dbf5a4870151a02d257a8574e8671" "043eacb4b2b51cdce979f24b38407e2c6a8f199bafd134e4b9002106ea96c6ad" default))
(setq default-input-method "german-postfix")
(setq diary-date-forms
'((month "-" day "[^-0-9]")
(year "[-/]" month "[-/]" day "[^0-9]")
(dayname "\\W")))
(setq diary-file "~/org/diary")
(setq diary-number-of-entries 7)
(setq dictcc-destination-lang "en")
(setq dictcc-languages-alist
'(("English" . "en")
("German" . "de")
("Swedish" . "sv")
("Icelandic" . "is")
("Russian" . "u")
("Romanian" . "ro")
("Italian" . "it")
("French" . "fr")
("Portuguese" . "pt")
("Hungarian" . "hu")
("Dutch" . "nl")
("Slovak" . "sk")
("Latin" . "la")
("Finnish" . "fi")
("Spanish" . "es")
("Bulgarian" . "bg")
("Croation" . "hr")
("Norwegian" . "no")
("Czech" . "cs")
("Danish" . "da")
("Turkish" . "tr")
("Polish" . "pl")
("Serbian" . "sr")
("Greek" . "el")
("Esperanto" . "eo")
("Bosnian" . "bs")
("Albanian" . "sq")))
(setq dictcc-source-lang "de")
(setq diff-hl-show-hunk-posframe-internal-border-color "#357535753575")
(setq dired-auto-revert-buffer t)
(setq dired-do-revert-buffer '(lambda (dir) (not (file-remote-p dir))))
(setq dired-kill-when-opening-new-dired-buffer t)
(setq display-time-use-mail-icon t)
(setq dnd-open-file-other-window t)
(setq ediff-merge-split-window-function 'split-window-horizontally)
(setq ediff-split-window-function 'split-window-horizontally)
(setq ediff-use-last-dir t)
(setq ediff-window-setup-function 'ediff-setup-windows-default)
(setq electric-pair-mode t)
(setq elfeed-goodies/entry-pane-size 0.5)
(setq elfeed-goodies/log-window-position 'right)
(setq emacsshot-with-timestamp t)
(setq eww-search-prefix
"https://duckduckgo.com/?kae=b&kl=de-de&kad=de_DE&kp=-1&kw=w&kak=-1&kah=de-de&kn=-1&kaj=m&kam=osm&kv=-1&kao=-1&kd=-1&kc=-1&kac=-1&k1=-1&kk=-1&kz=-1&q=")
(setq exwm-floating-border-color "#646464")
(setq fci-rule-character-color "#202020")
(setq fci-rule-color "#222222")
(setq folding-mode-string " fold")
(setq font-lock-global-modes '(not speedbar-mode))
(setq frame-background-mode 'dark)
(setq fringe-mode 4 )
(setq global-auto-revert-mode t)
(global-visual-line-mode 1)
(setq gnus-group-update-tool-bar t)
(setq go-translate-local-language "de")
(setq highlight-changes-colors '("#ff8eff" "#ab7eff"))
(setq highlight-indent-guides-auto-enabled nil)
(setq highlight-symbol-colors
'("#FFEE58" "#C5E1A5" "#80DEEA" "#64B5F6" "#E1BEE7" "#FFCC80"))
(setq highlight-symbol-foreground-color "#E0E0E0")
(setq highlight-tail-colors
'(("#323342" . 0)
("#63de5d" . 20)
("#4BBEAE" . 30)
("#1DB4D0" . 50)
("#9A8F21" . 60)
("#A75B00" . 70)
("#F309DF" . 85)
("#323342" . 100)))
(setq hl-todo-keyword-faces
'(("HOLD" . "#c0c530")
("TODO" . "#feacd0")
("NEXT" . "#b6a0ff")
("THEM" . "#f78fe7")
("PROG" . "#00d3d0")
("OKAY" . "#4ae2f0")
("DONT" . "#70b900")
("FAIL" . "#ff8059")
("BUG" . "#ff8059")
("DONE" . "#44bc44")
("NOTE" . "#d3b55f")
("KLUDGE" . "#d0bc00")
("HACK" . "#d0bc00")
("TEMP" . "#ffcccc")
("FIXME" . "#ff9077")
("XXX+" . "#ef8b50")
("REVIEW" . "#6ae4b9")
("DEPRECATED" . "#bfd9ff")))
(setq hydra-hint-display-type 'posframe)
(setq ibuffer-deletion-face 'diredp-deletion-file-name)
(setq ibuffer-filter-group-name-face 'modus-themes-pseudo-header)
(setq ibuffer-marked-face 'diredp-flag-mark)
(setq ibuffer-title-face 'default)
(setq inhibit-startup-screen t)
(setq keypression-mode t)
(setq keypression-use-child-frame t)
(setq ledger-default-date-format "%Y-%m-%d")
(setq ledger-reconcile-default-commodity " ")
(setq lsp-ui-imenu-colors '("#7FC1CA" "#A8CE93"))
(setq lunar-phase-names
'("Neumond" "zunehmender Mond" "Vollmand" "abnehmender Mond"))
(setq magit-auto-revert-mode t)
(setq magit-diff-use-overlays nil)
(setq mail-user-agent 'mu4e-user-agent)
(setq main-line-color1 "#1E1E1E")
(setq main-line-color2 "#111111")
(setq main-line-separator-style 'chamfer)
(setq menu-bar-mode nil)
(setq mlscroll-in-color "#56bc56bc56bc")
(setq mlscroll-out-color "#424242")
(setq mm-inline-large-images 'resize)
(setq mml-secure-passphrase-cache-expiry 16)
(setq mode-icons-mode t)
(setq nov-text-width 80)
(setq nrepl-message-colors
'("#CC9393" "#DFAF8F" "#F0DFAF" "#7F9F7F" "#BFEBBF" "#93E0E3" "#94BFF3" "#DC8CC3"))
(setq omnisharp-auto-complete-popup-help-delay 2000)
(setq openwith-associations
'(("\\.\\(?:m\\(?:aff\\|ht\\(?:ml\\)?\\)\\)$" "qutebrowser"
(file))
("\\.\\(?:flac\\|m\\(?:4a\\|p3\\)\\|wav\\|webm\\)$" "vlc"
(file))
("\\.\\(?:avi\\|flv\\|m\\(?:ov\\|p\\(?:eg\\|[4g]\\)\\)\\|ogg\\|wmv\\)$" "vlc"
(file))
("\\.\\(?:docx?\\|odt\\)$" "libreoffice"
("--writer" file))
("\\.\\(?:ods\\|xlsx?\\)$" "libreoffice"
("--calc" file))
("\\.\\(?:odp\\|pp\\(?:tx\\|[st]\\)\\)$" "libreoffice"
("--impress" file))
))
(setq openwith-mode t)
(setq pass-username-fallback-on-filename t)
(setq password-cache-expiry nil)
(setq password-store-password-length 16)
(setq pdf-view-midnight-colors '("#ffffff" . "#100f10"))
(setq plantuml-jar-path "/usr/share/plantuml/plantuml.jar")
(setq pos-tip-background-color "#E6DB74")
(setq pos-tip-foreground-color "#242728")
(setq powerline-color1 "#1E1E1E")
(setq powerline-color2 "#111111")
(setq recentf-exclude '("agenda" "history" "tmp" "wiki"))
(setq recentf-max-menu-items 40)
(setq recentf-max-saved-items 40)
(setq recentf-menu-filter 'recentf-arrange-by-mode)
(setq recentf-mode t)
(setq require-final-newline t)
(setq revert-without-query nil)
(setq rmail-movemail-program "/usr/bin/movemail")
(setq rmh-elfeed-org-files '("~/org/feeds.org"))
(setq rmh-elfeed-org-tree-id "feeds")
(setq safe-local-variable-values
'((org-roam-mode . t)
(org-roam-directory . "~/org/odo/")
(initial-major-mode . dokuwiki-mode)))
(setq same-window-buffer-names '("shell"))
(setq save-abbrevs 'silently)
(setq scroll-bar-mode nil)
(setq send-mail-function 'smtpmail-send-it)
(setq size-indication-mode t)
(setq small-temporary-file-directory "/tmp/")
(setq split-height-threshold 20)
(setq split-width-threshold 70)
(setq split-window-preferred-function 'split-window-really-sensibly)
(setq tab-always-indent 'complete)
(setq tab-width 4)
(setq tabbar-background-color "#357535753575")
(setq tool-bar-mode nil)
(setq tooltip-mode t)
(setq tree-widget-themes-directory "tree-widget")
(setq user-mail-address "dr.ops@mailbox.org")
(setq vc-annotate-background "#3C4C55")
(setq vc-annotate-background-mode nil)
(setq vc-annotate-color-map
`((20 \, "#DF8C8C")
(40 \, "#e3af97978d26")
(60 \, "#e780a2a28dc0")
(80 \, "#eb50adac8e5a")
(100 \, "#ef21b8b88ef4")
(120 \, "#F2C38F")
(140 \, "#ee20c861905c")
(160 \, "#e94eccff912a")
(180 \, "#e47dd19d91f7")
(200 \, "#dfabd63b92c5")
(220 \, "#DADA93")
(240 \, "#d0d0d8719393")
(260 \, "#c6c6d6089393")
(280 \, "#bcbcd39f9393")
(300 \, "#b2b2d1369393")
(320 \, "#A8CE93")
(340 \, "#a13ac894a409")
(360 \, "#99ccc25bb480")
(380 \, "#925ebc21c4f7")
(400 \, "#8af0b5e8d56e")
(420 \, "#83AFE5")
(440 \, "#8821aa0fe517")
(460 \, "#8cbfa470e449")
(480 \, "#915d9ed1e37c")
(500 \, "#95fb9932e2ae")
(520 \, "#9A93E1")))
(setq vc-annotate-very-old-color "#7bae760fb4b4")
(setq vc-follow-symlinks nil)
(setq vdirel-repository "~/.vdir/contacts/contacts")
(setq vertico-mode t)
(setq vertico-multiform-mode t)
(setq vertico-posframe-font "FreeMono")
(setq vertico-posframe-mode t)
(setq vertico-sort-function 'vertico-sort-history-length-alpha)
;; (setq weechat-color-list (unspecified "#242728" "#323342" "#F70057" "#ff0066" "#86C30D" "#63de5d" "#BEB244" "#E6DB74" "#40CAE4" "#06d8ff" "#FF61FF" "#ff8eff" "#00b2ac" "#53f2dc" "#f8fbfc" "#ffffff"))
(setq winner-mode t)
(setq wl-message-ignored-field-list
'(".*Received:" ".*Path:" ".*Id:" "^References:" "^Replied:" "^Errors-To:" "^Lines:" "^Sender:" ".*Host:" "^Xref:" "^Content-Type:" "^Precedence:" "^Status:" "^X-*:"))
(setq writeroom-fullscreen-effect 'maximized)
(setq writeroom-global-effects
'(writeroom-set-alpha writeroom-set-menu-bar-lines writeroom-set-tool-bar-lines writeroom-set-vertical-scroll-bars writeroom-set-bottom-divider-width))
(setq writeroom-major-modes '(elfeed-show-mode elfeed-search-mode))
(setq writeroom-width 100)
Projectile
Projectile is a project interaction library for Emacs. Its goal is to provide a nice set of features operating on a project level without introducing external dependencies. For instance - finding project files is done in pure Emacs Lisp without the use of GNU find.
Projectile also tries to be practical - if some external tools could speed up some task substantially and the tools are available, Projectile will leverage them.
This library provides easy project management and navigation. The concept of a project is pretty basic - just a folder containing special file. Currently git, mercurial and bazaar repos are considered projects by default. If you want to mark a folder manually as a project just create an empty .projectile file in it. Some of projectile’s features:
- jump to a file in project
- jump to a project buffer
- kill all project buffers
- replace in project
- multi-occur in project buffers
- grep in project
- regenerate project etags
- visit project in dired
- run make in a project with a single key chord
More information and installation instructions are available on GitHub.
(require 'projectile)
(define-key projectile-mode-map (kbd "s-p") 'projectile-command-map)
(define-key projectile-mode-map (kbd "C-c p") 'projectile-command-map)
(projectile-mode +1)
(setq projectile-project-search-path '("~/prj/"))
(projectile-register-project-type 'nikola '("conf.py")
:compile "nikola build"
:test "nikola auto"
:run "nikola deploy"
:test-suffix ".spec")
Completion
YaSnippet
YASnippet is a template system for Emacs. It allows you to type an abbreviation and automatically expand it into function templates.
See what it looks like: http://www.youtube.com/watch?v=ZCGmZK4V7Sg.
The MELPA package comes with snippets from https://github.com/AndreaCrotti/yasnippet-snippets, language templates include: C, C++, C#, Perl, Python, Ruby, SQL, LaTeX, HTML, CSS and more. The snippet syntax is inspired from TextMate's syntax, you can even import most TextMate templates to YASnippet.
Hosted at https://github.com/joaotavora/yasnippet, manual at http://joaotavora.github.io/yasnippet/. Stable versions also available from GNU ELPA: https://elpa.gnu.org/packages/yasnippet.html
(require 'yasnippet)
(require 'yasnippet-capf)
;; ---------------------------
;; Enable YASnippet globally
;; ---------------------------
(yas-global-mode 1)
;; Optional: add custom snippet directories
(add-to-list 'yas-snippet-dirs "~/./config/emacs/snippets")
Cape
Cape provides Completion At Point Extensions which can be used in combination with Corfu, Company or the default completion UI. The completion backends used by completion-at-point are so called completion-at-point-functions (Capfs).
(require 'cape)
;; ---------------------------
;; CAPE: Completion At Point Extensions
;; ---------------------------
;; Add multiple CAPFs in order of priority
(setq completion-at-point-functions
(list (cape-capf-super
#'yasnippet-capf ; snippets
#'cape-keyword ; language keywords
#'cape-dabbrev ; words in buffer
#'cape-file))) ; file paths
Corfu
Corfu is an Emacs completion frontend — a minimal, fast, and modern way to show inline completion candidates at point. It is frontend-only, meaning it doesn’t generate completions itself but relies on Emacs’ completion-at-point functions (CAPFs) or other sources like CAPE .
- What Corfu does
- Provides a popup menu of completions directly at the cursor (inline, not in the minibuffer).
- Works with any backend that implements CAPF , e.g., LSP servers, keywords, buffer words, snippets.
- Supports cycling through candidates , automatic popups, and minimal distraction.
;;; --------------------------- ;;; Modern Corfu setup for TypeScript (or any LSP-backed language) ;;; --------------------------- ;; --------------------------- ;; Packages: make sure these are installed ;; --------------------------- ;; corfu, cape, yasnippet, lsp-mode, typescript-mode (or other language modes) (require 'corfu) ;; --------------------------- ;; Corfu setup ;; --------------------------- (global-corfu-mode 1) (setq corfu-auto t) ; automatic popup (setq corfu-cycle t) ; cycle through candidates (setq corfu-separator ?\s) ; separator in popup ;; Optional: enable Corfu in minibuffer for commands (defun corfu-enable-in-minibuffer () (when (eq this-command 'eval-expression) (corfu-mode 1))) (add-hook 'minibuffer-setup-hook #'corfu-enable-in-minibuffer) (require 'lsp-mode) (require 'typescript-mode) ;; --------------------------- ;; LSP setup ;; --------------------------- (add-hook 'typescript-mode-hook #'lsp) ; start LSP automatically (setq lsp-enable-snippet t) ; LSP completions can include snippets ;; --------------------------- ;; Keybindings ;; --------------------------- ;; TAB triggers completion or snippet expansion (global-set-key (kbd "TAB") #'completion-at-point) ;; Optional: better TAB behavior in programming buffers (add-hook 'prog-mode-hook (lambda () (local-set-key (kbd "TAB") #'completion-at-point))) ;; --------------------------- ;; Done (message "Corfu + CAPE + YASnippet + LSP configured!")
Vertico
Vertico provides a performant and minimalistic vertical completion UI based on the default completion system. The main focus of Vertico is to provide a UI which behaves correctly under all circumstances. By reusing the built-in facilities system, Vertico achieves full compatibility with built-in Emacs completion commands and completion tables. Vertico only provides the completion UI but aims to be highly flexible, extensible and modular. Additional enhancements are available as extensions or complementary packages. The code base is small and maintainable. The main vertico.el package is only about 600 lines of code without white space and comments.
- Vertical display with arrow key navigation. See the extensions for additional display modes.
- Prompt shows the current candidate index and the total number of candidates.
- The current candidate is inserted with TAB and selected with RET.
- Non-existing candidates can be submitted with M-RET or by moving the point to the prompt.
- Configurable sorting by history position, length and alphabetically.
- Long candidates with newlines are formatted to take up less space.
- Deferred completion style highlighting for performance.
- Annotations are displayed next to the candidates (annotation- and affixation-function).
- Support for candidate grouping and group cycling commands (group-function).
(require 'vertico)
(vertico-mode)
(vertico-buffer-mode)
;; Enable vertico-multiform
(vertico-multiform-mode)
;; Configure the display per command.
;; Use a buffer with indices for imenu
;; and a flat (Ido-like) menu for M-x.
(setq vertico-multiform-commands
'((consult-imenu buffer indexed)
(execute-extended-command grid)
(org-refile buffer)
))
;; Configure the display per completion category.
;; Use the grid display for files and a buffer
;; for the consult-grep commands.
(setq vertico-multiform-categories
'((file grid)
(consult-grep buffer)))
(add-to-list 'vertico-multiform-categories
'(jinx grid (vertico-grid-annotate . 20) (vertico-count . 4)))
;; Add prompt indicator to `completing-read-multiple'.
;; Alternatively try `consult-completing-read-multiple'.
(defun crm-indicator (args)
(cons (concat "[CRM] " (car args)) (cdr args)))
(advice-add #'completing-read-multiple :filter-args #'crm-indicator)
;; Do not allow the cursor in the minibuffer prompt
(setq minibuffer-prompt-properties
'(read-only t cursor-intangible t face minibuffer-prompt))
(add-hook 'minibuffer-setup-hook #'cursor-intangible-mode)
;; Emacs 28: Hide commands in M-x which do not work in the current mode.
;; Vertico commands are hidden in normal buffers.
;; (setq read-extended-command-predicate
;; #'command-completion-default-include-p)
;; Enable recursive minibuffers
(setq enable-recursive-minibuffers t)
(setq vertico-buffer-mode t)
(setq vertico-posframe-font "FreeMono")
(setq vertico-posframe-mode nil)
(vertico-multiform-mode)