As part of the ongoing overhaul of my Emacs setupI’ve been trying to make the most of the built-in functionality that recent Emacsreleases keep quietly shipping. My in-buffer completion setup isbased on corfu and capethese days, but it turns out I had overlooked a nice Emacs 30 additionin the same area - completion-preview-mode.It gives you inline completion suggestions - the “ghost text” UI that GitHubCopilot and friends made famous1 - except here it’s powered by plain oldEmacs completions.What It DoesAs you type, completion-preview-mode shows a grayed-out preview of the topcompletion candidate right after point - inline, in the buffer itself. No popup,no minibuffer, no fuss. If the suggestion is what you want, press TAB to acceptit. If not, just keep typing and the preview updates (or goes away).The part I like best - the candidates come from completion-at-point-functions,which means the preview is fed by the exact same backends as corfu andcompany. If you’ve already set up cape-dabbrev, cape-file or eglot,all of them power the ghost text automatically. Batteries very much included.Enabling ItYou can try it out in the current buffer with M-x completion-preview-mode.If you like what you see, you can enable it everywhere:(global-completion-preview-mode 1)Here’s the relevant bit of my config:(use-package completion-preview :ensure nil ; built-in :config ;; cycle through the other candidates with M-n/M-p (those two ;; commands have no default bindings) (define-key completion-preview-active-mode-map (kbd "M-n") #'completion-preview-next-candidate) (define-key completion-preview-active-mode-map (kbd "M-p") #'completion-preview-prev-candidate) (global-completion-preview-mode +1))Essential KeybindingsWhile a preview is visible you can make use of the following keybindings: TAB (completion-preview-insert) - accept the suggested completion M-i (completion-preview-complete) - insert only the longest common prefixof all the candidates (the preview underlines it, so you know in advance whatyou’ll get) and let you keep typing from there M-n / M-p (completion-preview-next-candidate / completion-preview-prev-candidate) -cycle through the other candidates; those are not bound by default, but thedocs themselves suggest M-n and M-p (see my config above)Here’s M-i in action. I had typed my-pro, and pressing M-i filled inject-find-, stopping exactly where the two candidates (my-project-find-fileand my-project-find-dir) diverge:And when you cycle with M-n, Emacs even tells you where you are in thecandidate list in the echo area:There’s basic mouse support as well - clicking the ghost text with mouse-1inserts it, and scrolling the mouse wheel over it cycles through the candidates.(I doubt I’ll ever use that, but it’s kind of cute)Fine-tuningA few user options to adjust the behavior:2;; show the preview only after typing at least 3 characters (the default)(setopt completion-preview-minimum-symbol-length 3);; wait a bit before showing the preview (by default it shows up instantly)(setopt completion-preview-idle-delay 0.2);; show a preview only when there's exactly one candidate(setopt completion-preview-exact-match-only t)There’s also completion-preview-commands - the list of commands after whichthe preview appears (things like self-insert-command). You’ll rarely need totouch it, but it’s good to know it’s there if some command you use doesn’ttrigger the preview.Do You Still Need Corfu?When I first read about completion-preview-mode I assumed it was competingwith corfu and company, but I’ve come to think that’s the wrong way to lookat it. They draw candidates from the same source and simply present themdifferently - corfu gives you the full candidate list with annotations anddocumentation, while the preview gives you the single most likely candidatewith zero visual ceremony. These days I run both: the ghost text handles the“obviously I meant that symbol” cases with a single TAB, and corfu’s popupkicks in when I actually need to browse.Admittedly, two completion UIs at once won’t be everyone’s cup of tea. If youfind it too busy, a nice middle ground is to enable completion-preview-modeonly where a popup feels out of place - e.g. in eshell-mode or comint-modebuffers.Closing ThoughtsEmacs 30 keeps chipping away at my list of third-party packages - which-keyand EditorConfig support are now built-in, and completion-preview-modecovers a niche I didn’t even know I wanted covered. Not bad for a “boring”stable release!Have you tried completion-preview-mode already? Are you a ghost text personor a popup person? (or both, like me) I’d love to hear your thoughts in thecomments!That’s all I have for you today. Keep completing! Unlike the AI assistants, the suggestions here come straight from yourbuffers and your completion-at-point-functions. No subscription neededand no hallucinations included. ↩ If you’re wondering what’s this setopt thing - check outthis article. ↩