5

Q: can I mix abbrev expansions such that some expand automatically, and some only with an explicit call?

When abbrev-mode is enabled, an abbrev expands whenever typing a self-inserting whitespace or punctuation character. However, expand-abbrev will expand the abbrev at point even when abbrev-mode is disabled.

Is it possible to enable abbrev-mode and have some expansions happen automatically (ie, after whitespace and punctuation), but others expand only when I explicitly call expand-abbrev?

Rationale:

  • I'd like to use abbrevs automatically to correct common mistyped words (eg, teh => the)...
  • ... but would like to have explicit control of others that I use for shorthand (eg, sometimes I want to leave dem as dem, and other times I'd like it to expand to democracy).
    • (I know I could type dem C-q <space>, but it's awkward to do so and I usually want to use the shorthand rather than the expansion.)

To forestall well-intentioned "why not use yasnippet?" inquiries:

  • I'm experimenting with a combination of abbrev-mode and yasnippet, and would prefer to use the latter for complicated expansions and the former for simple ones.
Dan
  • 32,584
  • 6
  • 98
  • 168

3 Answers3

3

define-abbrev accepts a predicate, just use it to specify the abbrev should only expand when requested explicitly.

(define-abbrev text-mode-abbrev-table "dem" "democracy" nil
  :enable-function (lambda () (eq this-command 'expand-abbrev)))

The above abbrev will not expand when you hit SPC (or any other self-inserting character), but it will expand when you invoke expand-abbrev directly.

You'll probably want to bind it to a key then:

(global-set-key (kbd "C-M-i") #'expand-abbrev)
Malabarba
  • 22,878
  • 6
  • 78
  • 163
  • Thanks -- I'm trying to define one table with explicit-only expansions (via `define-abbrev-table`) to be included as a parent for the core table (or perhaps it should be the other way around). Not working yet, but I presume that some variant of this answer will work in `define-abbrev-table` as well. – Dan Feb 16 '15 at 23:52
1

It's possible, see abel. Here's the predicate:

(defun abel-p ()
  "Don't expand in strings, comments and function arguments."
  (let ((ppss (syntax-ppss)))
    (unless (or (elt ppss 3) (elt ppss 4))
      (or (memq this-command '(expand-abbrev aya-open-line))
          (save-match-data
            (and (looking-back "([[:alnum:]]*")
                 (save-excursion
                   (goto-char (match-beginning 0))
                   (and (not (looking-back "(lambda *"))
                        (condition-case nil
                            (progn
                              (up-list)
                              (backward-sexp)
                              (not
                               (or
                                (looking-at "(defun *")
                                (looking-back "(let\\*? *"))))
                          (error t))))))))))
abo-abo
  • 13,943
  • 1
  • 29
  • 43
0

Would introduce an own mode for that:

my-special-mode, once called, whould create an

my-special-mode-abbrev-table.

Than create a command which combines toggling resp. switching-on with expand-abbrev.

Andreas Röhler
  • 1,894
  • 10
  • 10