I want to have feedback on a small addition I have made to Emacs abbrev
functionality. First some background...
Some days back I was typing away in Emacs and after typing some hard to
spell word I realized that I probably had an abbrev defined for that
word. I checked by abbrev definitions and, yes, it was there. It turns
out I had many defined abbrevs that I had forgotten about, so I was
typing more than I needed. This got me thinking that it would be nice if
Emacs could tell me when I have typed a word that exists as an abbrev
expansion. After some research in abbrev.el I finally got something to
work, and you can find it below.
I would like to have people's comments on the idea, and know if this
might allredy exist (I tried to find something similar but couldn't), and
also if there are any performance problems or other in my code. The
internals of abbrevs are dark and mysterious to me, so I might miss some
crucial things. But, the code seems to do what I want it to.
Also, if people like this idea, perhaps it could be added to Emacs
proper. Surely it can live on its life as a separate library on Melpa,
Elpa or other place, but the code is quite short and this feels like
something that could be a simple option/toggle in Emacs standard abbrev
functionality. I have papers in place if this is something people would
Without further ado, here is the current code I have:
;;; absug.el --- Suggest an abbrev based on the word before point
;; Copyright stuff to be added later...
;; This library helps the user remember defined abbrevs by suggesting
;; them after having typed an abbrev expansion manually.
;; For example, if the user has defined the abbrev `doc' with the
;; expansion `document', if the user manually types `document' with
;; `abbrev-mode' active, a message will be presented suggesting to use
;; the defined abbrev `doc' instead.
;; To install, load or require this file/library and also add the
;; following code to your .emacs or init.el file:
;; (It is also a command you can call interactively)
;; You can interactively turn off abbrev suggestion by calling the
;; command `absug-disable'.
(defun absug-word-before-point ()
"Return the word before point."
(let ((lim (point))
(setq start (point))
(setq end (min (point) lim))
(buffer-substring-no-properties start end)))
(defun absug-get-active-tables-including-parents ()
"Return a list of all active abbrev tables, including parent tables."
(let* ((tables (abbrev--active-tables))
(dolist (table tables)
(setq all (append (abbrev-table-get table :parents) all)))
(defun absug-get-active-abbrev-expansions ()
"Return a list of all the active abbrev expansions.
Includes expansions from parent abbrev tables."
(dolist (table (absug-get-active-tables-including-parents))
(mapatoms (lambda (e)
(let ((value (symbol-value (abbrev--symbol e table))))
(cons (cons value (symbol-name e))
(defun absug-maybe-suggest ()
"Suggest an abbrev to the user based on the word before point."
(let* ((word (absug-word-before-point))
(abbrev (assoc word expansions)))
(message "Abbrev suggestion: The word `%s' has the abbrev
`%s' defined" (car abbrev) (cdr abbrev)))))
(defun absug-default-expand ()
"My version to use for `abbrev-expand-function'.
If no abbrev expansion is found by `abbrev--default-expand', see
if there is an abbrev defined for the word before point, and
suggest it to the user."
(defun absug-disable ()
"Disable abbrev suggestions"
(setq abbrev-expand-function #'abbrev--default-expand))
(defun absug-enable ()
"Enable abbrev suggestions"
(setq abbrev-expand-function #'absug-default-expand))
;;; absug.el ends here