;;; abbrev.el --- abbrev mode commands for Emacs -*- lexical-binding: t -*-
-;; Copyright (C) 1985-1987, 1992, 2001-2013 Free Software Foundation,
+;; Copyright (C) 1985-1987, 1992, 2001-2016 Free Software Foundation,
;; Inc.
-;; Maintainer: FSF
+;; Maintainer: emacs-devel@gnu.org
;; Keywords: abbrev convenience
;; Package: emacs
;;; Code:
(eval-when-compile (require 'cl-lib))
+(require 'obarray)
(defgroup abbrev-mode nil
"Word abbreviations mode."
(put 'abbrev-mode 'safe-local-variable 'booleanp)
\f
-(defvar edit-abbrevs-map
+(defvar edit-abbrevs-mode-map
(let ((map (make-sparse-keymap)))
(define-key map "\C-x\C-s" 'abbrev-edit-save-buffer)
(define-key map "\C-x\C-w" 'abbrev-edit-save-to-file)
(define-key map "\C-c\C-c" 'edit-abbrevs-redefine)
map)
"Keymap used in `edit-abbrevs'.")
+(define-obsolete-variable-alias 'edit-abbrevs-map
+ 'edit-abbrevs-mode-map "24.4")
(defun kill-all-abbrevs ()
"Undefine all defined abbrevs."
"Make a new abbrev-table with the same abbrevs as TABLE.
Does not copy property lists."
(let ((new-table (make-abbrev-table)))
- (mapatoms
+ (obarray-map
(lambda (symbol)
(define-abbrev new-table
(symbol-name symbol)
(set-buffer-modified-p nil)
(current-buffer))))
-(defun edit-abbrevs-mode ()
- "Major mode for editing the list of abbrev definitions.
-\\{edit-abbrevs-map}"
- (interactive)
- (kill-all-local-variables)
- (setq major-mode 'edit-abbrevs-mode)
- (setq mode-name "Edit-Abbrevs")
- (use-local-map edit-abbrevs-map)
- (run-mode-hooks 'edit-abbrevs-mode-hook))
-
(defun edit-abbrevs ()
"Alter abbrev definitions by editing a list of them.
Selects a buffer containing a list of abbrev definitions with
(buffer-substring-no-properties
(save-excursion (forward-word -1) (point))
pnt)))
- (if (or noquery (y-or-n-p (format "Expand `%s'? " string)))
+ (if (or noquery (y-or-n-p (format-message "Expand `%s'? " string)))
(expand-abbrev)))))))
;;; Abbrev properties.
(defun abbrev-table-get (table prop)
"Get the PROP property of abbrev table TABLE."
- (let ((sym (intern-soft "" table)))
+ (let ((sym (obarray-get table "")))
(if sym (get sym prop))))
(defun abbrev-table-put (table prop val)
"Set the PROP property of abbrev table TABLE to VAL."
- (let ((sym (intern "" table)))
+ (let ((sym (obarray-put table "")))
(set sym nil) ; Make sure it won't be confused for an abbrev.
(put sym prop val)))
\(fn ABBREV PROP)")
(defalias 'abbrev-put 'put
- "Set the property PROP of abbrev ABREV to value VAL.
+ "Set the property PROP of abbrev ABBREV to value VAL.
See `define-abbrev' for the effect of some special properties.
\(fn ABBREV PROP VAL)")
(defun make-abbrev-table (&optional props)
"Create a new, empty abbrev table object.
PROPS is a list of properties."
- ;; The value 59 is an arbitrary prime number.
- (let ((table (make-vector 59 0)))
+ (let ((table (obarray-make)))
;; Each abbrev-table has a `modiff' counter which can be used to detect
;; when an abbreviation was added. An example of use would be to
;; construct :regexp dynamically as the union of all abbrev names, so
(defun abbrev-table-p (object)
"Return non-nil if OBJECT is an abbrev table."
- (and (vectorp object)
+ (and (obarrayp object)
(numberp (abbrev-table-get object :abbrev-table-modiff))))
(defun abbrev-table-empty-p (object &optional ignore-system)
(unless (abbrev-table-p object)
(error "Non abbrev table object"))
(not (catch 'some
- (mapatoms (lambda (abbrev)
- (unless (or (zerop (length (symbol-name abbrev)))
- (and ignore-system
- (abbrev-get abbrev :system)))
- (throw 'some t)))
- object))))
+ (obarray-map (lambda (abbrev)
+ (unless (or (zerop (length (symbol-name abbrev)))
+ (and ignore-system
+ (abbrev-get abbrev :system)))
+ (throw 'some t)))
+ object))))
(defvar global-abbrev-table (make-abbrev-table)
"The abbrev table whose abbrevs affect all buffers.
(defun clear-abbrev-table (table)
"Undefine all abbrevs in abbrev table TABLE, leaving it empty."
(setq abbrevs-changed t)
- (let* ((sym (intern-soft "" table)))
+ (let* ((sym (obarray-get table "")))
(dotimes (i (length table))
(aset table i 0))
;; Preserve the table's properties.
(cl-assert sym)
- (let ((newsym (intern "" table)))
+ (let ((newsym (obarray-put table "")))
(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
,@(if (cadr props) (list :system (cadr props))))))
(unless (plist-get props :count)
(setq props (plist-put props :count 0)))
+ (setq props (plist-put props :abbrev-table-modiff
+ (abbrev-table-get table :abbrev-table-modiff)))
(let ((system-flag (plist-get props :system))
- (sym (intern name table)))
+ (sym (obarray-put table name)))
;; Don't override a prior user-defined abbrev with a system abbrev,
;; unless system-flag is `force'.
(unless (and (not (memq system-flag '(nil force)))
(boundp sym) (symbol-value sym)
(not (abbrev-get sym :system)))
(unless (or system-flag
- (and (boundp sym) (fboundp sym)
+ (and (boundp sym)
;; load-file-name
(equal (symbol-value sym) expansion)
(equal (symbol-function sym) hook)))
"Check if the characters in ABBREV have word syntax in either the
current (if global is nil) or standard syntax table."
(with-syntax-table
- (cond ((null global) (standard-syntax-table))
+ (cond ((null global) (syntax-table))
;; ((syntax-table-p global) global)
- (t (syntax-table)))
+ (t (standard-syntax-table)))
(when (string-match "\\W" abbrev)
(let ((badchars ())
(pos 0))
;; abbrevs do, we have to be careful.
(sym
;; First try without case-folding.
- (or (intern-soft abbrev table)
+ (or (obarray-get table abbrev)
(when case-fold
;; We didn't find any abbrev, try case-folding.
- (let ((sym (intern-soft (downcase abbrev) table)))
+ (let ((sym (obarray-get table (downcase abbrev))))
;; Only use it if it doesn't require :case-fixed.
(and sym (not (abbrev-get sym :case-fixed))
sym))))))
value))
(defvar abbrev-expand-functions nil
- "Wrapper hook around `expand-abbrev'.")
+ "Wrapper hook around `abbrev--default-expand'.")
(make-obsolete-variable 'abbrev-expand-functions 'abbrev-expand-function "24.4")
(defvar abbrev-expand-function #'abbrev--default-expand
- "Function to perform abbrev expansion.
+ "Function that `expand-abbrev' uses to perform abbrev expansion.
Takes no argument and should return the abbrev symbol if expansion took place.")
(defun expand-abbrev ()
"Expand the abbrev before point, if there is an abbrev there.
Effective when explicitly called even when `abbrev-mode' is nil.
-Returns the abbrev symbol, if expansion took place. (The actual
-return value is that of `abbrev-insert'.)"
+Before doing anything else, runs `pre-abbrev-expand-hook'.
+Calls `abbrev-expand-function' with no argument to do the work,
+and returns whatever it does. (This should be the abbrev symbol
+if expansion occurred, else nil.)"
(interactive)
(run-hooks 'pre-abbrev-expand-hook)
(funcall abbrev-expand-function))
(defun abbrev--default-expand ()
- (with-wrapper-hook abbrev-expand-functions ()
+ "Default function to use for `abbrev-expand-function'.
+This respects the wrapper hook `abbrev-expand-functions'.
+Calls `abbrev-insert' to insert any expansion, and returns what it does."
+ (subr--with-wrapper-hook-no-warnings abbrev-expand-functions ()
(pcase-let ((`(,sym ,name ,wordstart ,wordend) (abbrev--before-point)))
(when sym
(let ((startpos (copy-marker (point) t))
(insert " ))\n\n")))
nil)))
-(put 'define-abbrev-table 'doc-string-elt 3)
(defun define-abbrev-table (tablename definitions
&optional docstring &rest props)
"Define TABLENAME (a symbol) as an abbrev table name.
- `:enable-function' can be set to a function of no argument which returns
non-nil if and only if the abbrevs in this table should be used for this
instance of `expand-abbrev'."
+ (declare (doc-string 3))
;; We used to manually add the docstring, but we also want to record this
;; location as the definition of the variable (in load-history), so we may
;; as well just use `defvar'.
- (eval `(defvar ,tablename nil ,@(if (stringp docstring) (list docstring))))
+ (if (and docstring props (symbolp docstring))
+ ;; There is really no docstring, instead the docstring arg
+ ;; is a property name.
+ (push docstring props) (setq docstring nil))
+ (eval `(defvar ,tablename nil ,@(if docstring (list docstring))))
(let ((table (if (boundp tablename) (symbol-value tablename))))
(unless table
(setq table (make-abbrev-table))
;; if the table was pre-existing as is the case if it was created by
;; loading the user's abbrev file.
(while (consp props)
+ (unless (cdr props) (error "Missing value for property %S" (car props)))
(abbrev-table-put table (pop props) (pop props)))
(dolist (elt definitions)
(apply 'define-abbrev table elt))))
SORTFUN is passed to `sort' to change the default ordering."
(unless sortfun (setq sortfun 'string-lessp))
(let ((entries ()))
- (mapatoms (lambda (abbrev)
- (when (symbol-value abbrev)
- (let ((name (symbol-name abbrev)))
- (push `(,(intern name) menu-item ,name
- (lambda () (interactive)
- (abbrev-insert ',abbrev)))
- entries))))
- table)
+ (obarray-map (lambda (abbrev)
+ (when (symbol-value abbrev)
+ (let ((name (symbol-name abbrev)))
+ (push `(,(intern name) menu-item ,name
+ (lambda () (interactive)
+ (abbrev-insert ',abbrev)))
+ entries))))
+ table)
(nconc (make-sparse-keymap prompt)
(sort entries (lambda (x y)
- (funcall sortfun (nth 2 x) (nth 2 y)))))))
+ (funcall sortfun (nth 2 x) (nth 2 y)))))))
+
+;; Keep it after define-abbrev-table, since define-derived-mode uses
+;; define-abbrev-table.
+(define-derived-mode edit-abbrevs-mode fundamental-mode "Edit-Abbrevs"
+ "Major mode for editing the list of abbrev definitions.")
(provide 'abbrev)