Commit 183e254cf0
Unsigned
Layout: unified · split
content/blog/2026-02-02-emacs-carnival-2026-02-completion.org added +160
| @@ -0,0 +1,160 @@ | ||
| 1 | #+date: <2026-02-02 18:40:21> | |
| 2 | #+title: Emacs Carnival: "Completion" | |
| 3 | #+description: My response to the Emacs Carnival post for February 2026. | |
| 4 | #+slug: emacs-carnival-2026-02-completion | |
| 5 | ||
| 6 | I'm having a great time with the Emacs Carnival, as it has inspired me to write | |
| 7 | two posts in such a short time. It's been a much needed inspiration to write | |
| 8 | during my busy season at work. | |
| 9 | ||
| 10 | Anyway, let's get to it. The topic today is [[https://www.emacswiki.org/emacs/CategoryCompletion][Completion]]: the magical thing that | |
| 11 | turns someone like me, who cannot remember long lists of commands to save my | |
| 12 | life, from an illiterate to a literate programmer. | |
| 13 | ||
| 14 | * Defining Custom Abbreviations | |
| 15 | ||
| 16 | While you can define [[https://www.gnu.org/software/emacs/manual/html_node/emacs/Abbrevs.html][abbrevs]] dynamically in the buffer with ~C-x a g~ (which | |
| 17 | generally saves abbrevs to ~/.emacs.d/abbrev_defs~), I prefer to define my | |
| 18 | abbreviations directly within my ~config.el~ file. | |
| 19 | ||
| 20 | This allows for better portability between my machines, as well as clearer | |
| 21 | configuration for myself. | |
| 22 | ||
| 23 | To create a new abbrev, I simply open ~~/.config/doom/config.el~ and add a new one | |
| 24 | to the list below. | |
| 25 | ||
| 26 | #+begin_src elisp | |
| 27 | ;; Abbreviations | |
| 28 | (setq-default abbrev-mode t) | |
| 29 | (define-abbrev-table 'global-abbrev-table | |
| 30 | '( | |
| 31 | ;; ("abbreviation" "expansion") | |
| 32 | ("omw" "on my way") | |
| 33 | ("eml" "hello@cleberg.net") | |
| 34 | ("shrg" "¯\_(ツ)_/¯") | |
| 35 | ("teh" "the") | |
| 36 | ("xtoday" "" (lambda () (insert (format-time-string "%Y-%m-%d %H:%M:%S")))) | |
| 37 | ("xnow" "" (lambda () (insert (format-time-string "%H:%M:%S")))) | |
| 38 | )) | |
| 39 | #+end_src | |
| 40 | ||
| 41 | Now, I can type something like ~xtoday~ in my buffer and get the fully formatted | |
| 42 | time string, like so: ~2026-02-02 21:52:55~. | |
| 43 | ||
| 44 | ~¯\_(ツ)_/¯~ | |
| 45 | ||
| 46 | This comes in handy most at work, where I need to constantly use acronyms and | |
| 47 | take shorthand notes to fill-out phrases that I'm, unfortunately, required to | |
| 48 | re-use constantly. Looking at you, "completeness and accuracy of the data". | |
| 49 | ||
| 50 | * Doom Configuration | |
| 51 | ||
| 52 | I have played around with a few different completion options for my purposes and | |
| 53 | have settled on the following packages. | |
| 54 | ||
| 55 | Here is how I have my ~:completion~, ~:tools~, and ~:lang~ modules toggled in | |
| 56 | ~~/.config/doom/init.el~: | |
| 57 | ||
| 58 | #+begin_src elisp | |
| 59 | (doom! :input | |
| 60 | :completion | |
| 61 | (corfu +orderless) ; complete with cap(f), cape and a flying feather! | |
| 62 | vertico ; the search engine of the future | |
| 63 | ||
| 64 | :checkers | |
| 65 | syntax ; tasing you for every semicolon you forget | |
| 66 | (spell +flyspell) ; tasing you for misspelling mispelling | |
| 67 | grammar ; tasing grammar mistake every you make | |
| 68 | ||
| 69 | :tools | |
| 70 | (lsp +eglot) ; M-x vscode | |
| 71 | ||
| 72 | :lang | |
| 73 | data ; config/data formats | |
| 74 | emacs-lisp ; drown in parentheses | |
| 75 | json ; At least it ain't XML | |
| 76 | javascript ; all(hope(abandon(ye(who(enter(here)))))) | |
| 77 | markdown ; writing docs for people to ignore | |
| 78 | (org +dragndrop ; drag & drop images/files into org | |
| 79 | +hugo ; use this if you plan to use weblorg/hugo for your site | |
| 80 | +journal ; daily logging | |
| 81 | +noter ; for annotating PDFs (great for research) | |
| 82 | +roam2) ; Zettelkasten note-taking | |
| 83 | python ; beautiful is better than ugly | |
| 84 | sh ; she sells {ba,z,fi}sh shells on the C xor | |
| 85 | ||
| 86 | :config | |
| 87 | (default +bindings +smartparens)) | |
| 88 | #+end_src | |
| 89 | ||
| 90 | With his setup, I am able to get a wonderful IDE-level experience within Emacs | |
| 91 | and without the bloat of a traditional IDE. It's the perfect balance of speed | |
| 92 | and power for my work and hobbies. | |
| 93 | ||
| 94 | ** [[https://github.com/minad/vertico][vertico]] + [[https://github.com/minad/marginalia][marginalia]] | |
| 95 | ||
| 96 | Vertico is wonderful for finding files (~SPC .~) or running commands (~SPC :~). It | |
| 97 | provides a clean, vertical interface for the minibuffer. | |
| 98 | ||
| 99 | Marginalia works wonderfully with Vertico, as it provides marginalia to the | |
| 100 | minibuffer commands within the command selection buffer. | |
| 101 | ||
| 102 | #+caption: Vertico: Command | |
| 103 | [[https://img.cleberg.net/blog/20260202-emacs-carnival-2026-02-completion/vertico-commands.webp]] | |
| 104 | ||
| 105 | #+caption: Vertico: Files | |
| 106 | [[https://img.cleberg.net/blog/20260202-emacs-carnival-2026-02-completion/vertico-files.webp]] | |
| 107 | ||
| 108 | ** [[https://github.com/oantolin/orderless][orderless]] | |
| 109 | ||
| 110 | Orderless is a game changer. As I mentioned above, I'm terrible with | |
| 111 | memorization. Therefore, I use this package and am able to search with multiple | |
| 112 | out-of-order terms to find a result in my Vertico searches. | |
| 113 | ||
| 114 | #+caption: Orderless | |
| 115 | [[https://img.cleberg.net/blog/20260202-emacs-carnival-2026-02-completion/orderless.webp]] | |
| 116 | ||
| 117 | ** [[https://github.com/minad/corfu][corfu]] | |
| 118 | ||
| 119 | For code completion, I’ve swapped out the venerable Company mode for Corfu. It’s | |
| 120 | faster, stays out of my way until I need it, and uses a small popup that feels | |
| 121 | right at home in a terminal or a GUI. | |
| 122 | ||
| 123 | #+caption: Corfu | |
| 124 | [[https://img.cleberg.net/blog/20260202-emacs-carnival-2026-02-completion/python.webp]] | |
| 125 | ||
| 126 | ** [[https://github.com/joaotavora/eglot][eglot]] | |
| 127 | ||
| 128 | To actually "know" what my code is doing, I use LSP (Language Server Protocol). | |
| 129 | I've enabled the ~+eglot~ flag in Doom because Eglot is now built into Emacs core | |
| 130 | and tends to be a bit more stable and performant for my Python and JavaScript | |
| 131 | workflows. | |
| 132 | ||
| 133 | ** [[https://github.com/leotaku/flycheck-aspell?tab=readme-ov-file][flyspell]] | |
| 134 | ||
| 135 | Flyspell is the last piece to my puzzle, as it allows for easy help in | |
| 136 | correcting grammar errors within the buffer. I combine ~flypell~ + ~syntax~ + | |
| 137 | ~grammar~ for ultimate writing guidance. Whether or not I choose to follow that | |
| 138 | guidance is another story entirely. | |
| 139 | ||
| 140 | #+caption: Flyspell | |
| 141 | [[https://img.cleberg.net/blog/20260202-emacs-carnival-2026-02-completion/suggestions.webp]] | |
| 142 | ||
| 143 | * Looking Forward | |
| 144 | ||
| 145 | I know this is just the tip of the iceberg, so I've made a list of packages I | |
| 146 | want to dive into deeper in the future: | |
| 147 | ||
| 148 | - ~tempel~ | |
| 149 | - ~yasnippet~ | |
| 150 | - ~consult~ | |
| 151 | - ~embark~ | |
| 152 | - ~cape~ | |
| 153 | - ~kind-icon~ | |
| 154 | - ~prescient.el~ | |
| 155 | ||
| 156 | Completion and expansion utilities are phenomenal and have been one of the | |
| 157 | larger tools in my development and writing. | |
| 158 | ||
| 159 | Want to participate in the Emacs Carnival or read more posts? Visit the main | |
| 160 | [[https://www.emacswiki.org/emacs/Carnival][Carnival]] page on the Emacs Wiki to learn more. | |