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. | ||