Emacs: Interactive Abbrev 🚀

By Xah Lee. Date: . Last updated: .

If you have hundreds of abbrevs , one problem is that you forgot what's the abbrev.

Solution is to have a prompt listing all abbreves. A Interactive abbrev.

emacs interactive abbrev 2022-06-02
xah-interactive-abbrev

Here's the code:

(defvar xah-interactive-abbrev-alist nil
  "A asso list for `xah-interactive-abbrev'.
Key is abbrev string.
Value is the text to be inserted.")

(setq
 xah-interactive-abbrev-alist
 '(("optimize png" . "oxipng -o 4 --strip safe *png")
   ("delete metadata" . "exiftool -all= -overwrite_original *png *jpg")
   ("gif to mp4" . "ffmpeg -f gif -i x.gif x.mp4")
   ("gif to webm" . "ffmpeg -f gif -i x.gif x.webm")
   ("gitdiff" . "git --no-pager diff --color --no-index f1 f2")

   ("git archive" . "git archive -o ../xxgit.zip HEAD")

   ("image convert" . "magick xx yy")
   ("image scale" . "magick xx -scale 50% yy")

   ("mov to mp4" . "ffmpeg -f mov -i x.mov x.mp4")

   ("unix chmod file" . "find . -type f -exec chmod 644 {} ';'")
   ("unix chmod2" . "find . -type d -exec chmod 755 {} ';'")
   ("unix delete emacs backup~" . "find . -name \"*~\" -delete")
   ("unix delete empty dir" . "find . -depth -empty -type d -delete")
   ("unix delete empty file" . "find . -type f -empty")
   ("unix delete mac DS_Store" . "find . -name \".DS_Store\" -delete;")
   ("unix delete mac __MACOSX" . "find . -depth -name \"__MACOSX\" -type d -exec rm -rf {} ';'")
   ("unix grep" . "grep -r -F \"hhhh\" --include='*html' ~/web")
   ("unix image -bmp2png" . "find . -name \"*bmp\" | xargs -l -i basename \"{}\" \".bmp\" | xargs -l -i magick \"{}.bmp\" \"{}.png\"")
   ("unix image Batch" . "find . -name \"*png\" | xargs -l -i basename \"{}\" \".png\" | xargs -l -i magick \"{}.png\" \"{}.jpg\"")
   ("unix list empty dir" . "find . -depth -empty -type d")

   ("ytd" . "youtube-dl -f 'bestvideo,bestaudio' -o 'f%(format_id)s.%(ext)s' url")

   ("powershell subdir size" . "dir -Directory | ForEach-Object { Write-Host $_.name \" \" -NoNewLine; \"{0:N0}\" -f ((dir $_ -File -Recurse | measure -Property Length -sum).sum / 1mb); }")
   ("powershell diff" . "diff (cat f1) (cat f2) ")
   ("powershell emacs backup~" . "dir -Recurse -File -Filter *~ | ForEach-Object {$_.fullname}")
   ("powershell .DS_Store" . "dir -Recurse -File -Filter .DS_Store | ForEach-Object {$_.fullname}")

   ("powershell htaccess" . "dir -Recurse -File -Filter .htaccess")
   ("powershell dir" . "dir -Recurse -File -Filter xx* | ForEach-Object {$_.fullname}")))

(defun xah-interactive-abbrev ()
  "Prompt to insert string from `xah-interactive-abbrev-alist'.

URL `http://xahlee.info/emacs/emacs/emacs_interactive_abbrev.html'
Created: 2017-08-13
Version: 2025-01-02"
  (interactive)
  (let ((xinput (completing-read "abbrevs:" xah-interactive-abbrev-alist nil t)))
    (insert (cdr (assoc-string xinput xah-interactive-abbrev-alist t)))))

You should have a easy key for this command, such as F9. 〔see Emacs Keys: Define Key〕

also, you should use fido-vertical-mode or similar for vertical list.

Emacs, using abbrev mode