rvf0068
rvf0068

Reputation: 1389

Abbrev local to document in Emacs

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

Answers (2)

Lorem Ipsum
Lorem Ipsum

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

Ben
Ben

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

Related Questions