Reputation: 1389
I would like to define an abbrev in Emacs local to a document, that is:
So far what I have is this:
%%% eval: (define-abbrev-table 'latex-mode-abbrev-table '(("tc" "triangular clique" nil 0)))
but this does not satisfy my requirements...,
Upvotes: 2
Views: 533
Reputation: 4534
The accepted answer works. However, abbrevs are not visible through list-abbrevs
.
(defun my-define-local-abbrev-table (definitions)
"Define abbrev table with DEFINITIONS local to the current buffer.
Abbrev DEFINITIONS is a list of elements of the form (ABBREVNAME
EXPANSION ...) that are passed to `define-abbrev'.
The local abbrev table has name of the current buffer appended
with \"-abbrev-table\".
Use `my-clear-local-abbrev-table' to remove local abbrev
definitions."
(let* ((table-symbol (intern (concat (buffer-name) "-abbrev-table")))) ; inserts in obarray
(define-abbrev-table table-symbol definitions)
(setq-local local-abbrev-table (symbol-value table-symbol))
(message "Created local abbrev table '%s'" table-symbol)))
(defun my-clear-local-abbrev-table ()
"Clear buffer-local abbrevs.
See `my-define-local-abbrev-table'."
(let* ((buffer-table-string (concat (buffer-name) "-abbrev-table"))
(buffer-table-symbol (intern-soft buffer-table-string)) ; nil if not in obarray
(buffer-table (if buffer-table-symbol
(symbol-value buffer-table-symbol))))
(cond ((abbrev-table-p buffer-table)
(clear-abbrev-table buffer-table)
(if (intern-soft buffer-table-string)
(unintern buffer-table-string))
(message "Cleared local abbrev table '%s'" buffer-table-string)))))
(my-define-local-abbrev-table
'(("TC" "triangular clique" nil :case-fixed t)
("banana" "rama")
))
;; Type TC<SPC> in the desired buffer and see that it expands into
;; 'triangular clique'
;; Type TC<SPC> in a different buffer and see that it doesn't expand
;; Notice that tc doesn't expand in the desired buffer
;; Notice that both banana and BaNaNA expand in the desired buffer
;; Notice that abbrevs are visible through M-x list-abbrevs
(my-clear-local-abbrev-table)
Upvotes: 2
Reputation: 281
How about this:
(defun set-local-abbrevs (abbrevs)
"Add ABBREVS to `local-abbrev-table' and make it buffer local.
ABBREVS should be a list of abbrevs as passed to `define-abbrev-table'.
The `local-abbrev-table' will be replaced by a copy with the new
abbrevs added, so that it is not the same as the abbrev table used
in other buffers with the same `major-mode'."
(let* ((bufname (buffer-name))
(prefix (substring (md5 bufname) 0 (length bufname)))
(tblsym (intern (concat prefix "-abbrev-table"))))
(set tblsym (copy-abbrev-table local-abbrev-table))
(dolist (abbrev abbrevs)
(define-abbrev (eval tblsym)
(car abbrev)
(cadr abbrev)
(caddr abbrev)))
(setq-local local-abbrev-table (eval tblsym))))
and then:
(set-local-abbrevs '(("tc" "triangular clique" nil)))
Upvotes: 1