;;; abbrev.el --- abbrev mode commands for Emacs
;; Copyright (C) 1985, 1986, 1987, 1992, 2001, 2002, 2003, 2004,
-;; 2005, 2006, 2007, 2008 Free Software Foundation, Inc.
+;; 2005, 2006, 2007, 2008, 2009, 2010 Free Software Foundation, Inc.
;; Maintainer: FSF
;; Keywords: abbrev convenience
;; Todo:
-;; - Make abbrev-file-name obey user-emacs-directory.
;; - Cleanup name space.
;;; Code:
:link '(custom-manual "(emacs)Abbrevs")
:group 'abbrev)
+(defcustom abbrev-file-name
+ (locate-user-emacs-file "abbrev_defs" ".abbrev_defs")
+ "Default name of file from which to read abbrevs."
+ :initialize 'custom-initialize-delay
+ :type 'file)
+
(defcustom only-global-abbrevs nil
"Non-nil means user plans to use global abbrevs only.
This makes the commands that normally define mode-specific abbrevs
Abbrev to be expanded starts here rather than at beginning of word.
This way, you can expand an abbrev with a prefix: insert the prefix,
use this command, then insert the abbrev. This command inserts a
-temporary hyphen after the prefix \(until the intended abbrev
+temporary hyphen after the prefix (until the intended abbrev
expansion occurs).
If the prefix is itself an abbrev, this command expands it, unless
ARG is non-nil. Interactively, ARG is the prefix argument."
\(fn ABBREV PROP VAL)")
-(defmacro abbrev-with-wrapper-hook (var &rest body)
- "Run BODY wrapped with the VAR hook.
-VAR is a special hook: its functions are called with one argument which
-is the \"original\" code (the BODY), so the hook function can wrap the
-original function, can call it several times, or even not call it at all.
-VAR is normally a symbol (a variable) in which case it is treated like a hook,
-with a buffer-local and a global part. But it can also be an arbitrary expression.
-This is similar to an `around' advice."
- (declare (indent 1) (debug t))
- ;; We need those two gensyms because CL's lexical scoping is not available
- ;; for function arguments :-(
- (let ((funs (make-symbol "funs"))
- (global (make-symbol "global")))
- ;; Since the hook is a wrapper, the loop has to be done via
- ;; recursion: a given hook function will call its parameter in order to
- ;; continue looping.
- `(labels ((runrestofhook (,funs ,global)
- ;; `funs' holds the functions left on the hook and `global'
- ;; holds the functions left on the global part of the hook
- ;; (in case the hook is local).
- (lexical-let ((funs ,funs)
- (global ,global))
- (if (consp funs)
- (if (eq t (car funs))
- (runrestofhook (append global (cdr funs)) nil)
- (funcall (car funs)
- (lambda () (runrestofhook (cdr funs) global))))
- ;; Once there are no more functions on the hook, run
- ;; the original body.
- ,@body))))
- (runrestofhook ,var
- ;; The global part of the hook, if any.
- ,(if (symbolp var)
- `(if (local-variable-p ',var)
- (default-value ',var)))))))
-
-
;;; Code that used to be implemented in src/abbrev.c
(defvar abbrev-table-name-list '(fundamental-mode-abbrev-table
(defvar last-abbrev-text nil
"The exact text of the last abbrev expanded.
-nil if the abbrev has already been unexpanded.")
+It is nil if the abbrev has already been unexpanded.")
(defvar last-abbrev-location 0
"The location of the start of the last abbrev expanded.")
(set newsym nil) ; Make sure it won't be confused for an abbrev.
(setplist newsym (symbol-plist sym)))
(abbrev-table-put table :abbrev-table-modiff
- (1+ (abbrev-table-get table :abbrev-table-modiff)))))
+ (1+ (abbrev-table-get table :abbrev-table-modiff))))
+ ;; For backward compatibility, always return nil.
+ nil)
(defun define-abbrev (table name expansion &optional hook &rest props)
"Define an abbrev in TABLE named NAME, to expand to EXPANSION and call HOOK.
To undefine an abbrev, define it with EXPANSION = nil.
If HOOK is non-nil, it should be a function of no arguments;
it is called after EXPANSION is inserted.
-If EXPANSION is not a string, the abbrev is a special one,
- which does not expand in the usual way but only runs HOOK.
+If EXPANSION is not a string (and not nil), the abbrev is a
+ special one, which does not expand in the usual way but only
+ runs HOOK.
PROPS is a property list. The following properties are special:
- `:count': the value for the abbrev's usage-count, which is incremented each
(setq tables (append (abbrev-table-get table :parents) tables))
(setq res
(and (or (not enable-fun) (funcall enable-fun))
- (looking-back (or (abbrev-table-get table :regexp)
- "\\<\\(\\w+\\)\\W*")
- (line-beginning-position))
- (setq start (match-beginning 1))
- (setq end (match-end 1))
+ (let ((re (abbrev-table-get table :regexp)))
+ (if (null re)
+ ;; We used to default `re' to "\\<\\(\\w+\\)\\W*"
+ ;; but when words-include-escapes is set, that
+ ;; is not right and fixing it is boring.
+ (let ((lim (point)))
+ (backward-word 1)
+ (setq start (point))
+ (forward-word 1)
+ (setq end (min (point) lim)))
+ (when (looking-back re (line-beginning-position))
+ (setq start (match-beginning 1))
+ (setq end (match-end 1)))))
(setq name (buffer-substring start end))
(let ((abbrev (abbrev-symbol name table)))
(when abbrev
"Insert abbrev ABBREV at point.
If non-nil, NAME is the name by which this abbrev was found.
If non-nil, WORDSTART is the place where to insert the abbrev.
-If non-nil, WORDEND the abbrev replaces the previous text between
+If WORDEND is non-nil, the abbrev replaces the previous text between
WORDSTART and WORDEND.
Return ABBREV if the expansion should be considered as having taken place."
(unless name (setq name (symbol-name abbrev)))
Returns the abbrev symbol, if expansion took place."
(interactive)
(run-hooks 'pre-abbrev-expand-hook)
- (abbrev-with-wrapper-hook abbrev-expand-functions
+ (with-wrapper-hook abbrev-expand-functions ()
(destructuring-bind (&optional sym name wordstart wordend)
(abbrev--before-point)
(when sym
;; to do the expansion.
(let ((val (symbol-value last-abbrev)))
(unless (stringp val)
- (error "value of abbrev-symbol must be a string"))
- (delete-region (point) (+ (point) (length val)))
+ (error "Value of abbrev-symbol must be a string"))
;; Don't inherit properties here; just copy from old contents.
(insert last-abbrev-text)
+ ;; Delete after inserting, to better preserve markers.
+ (delete-region (point) (+ (point) (length val)))
(setq last-abbrev-text nil))))))
(defun abbrev--write (sym)
(insert "\n\n"))
(insert "(define-abbrev-table '")
(prin1 name)
- (insert " '(")
- (mapc 'abbrev--write symbols)
- (insert " ))\n\n"))
+ (if (null symbols)
+ (insert " '())\n\n")
+ (insert "\n '(\n")
+ (mapc 'abbrev--write symbols)
+ (insert " ))\n\n")))
nil)))
(put 'define-abbrev-table 'doc-string-elt 3)