1992-05-30 23:54:21 +00:00
|
|
|
|
;;; abbrev.el --- abbrev mode commands for Emacs
|
1991-08-27 03:29:52 +00:00
|
|
|
|
|
1992-07-16 21:47:34 +00:00
|
|
|
|
;; Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
|
1991-08-27 03:29:52 +00:00
|
|
|
|
|
2001-08-06 10:12:17 +00:00
|
|
|
|
;; Maintainer: FSF
|
1998-05-26 09:23:23 +00:00
|
|
|
|
;; Keywords: abbrev convenience
|
1993-03-18 21:29:42 +00:00
|
|
|
|
|
1991-08-27 03:29:52 +00:00
|
|
|
|
;; This file is part of GNU Emacs.
|
|
|
|
|
|
|
|
|
|
;; GNU Emacs is free software; you can redistribute it and/or modify
|
|
|
|
|
;; it under the terms of the GNU General Public License as published by
|
1992-07-16 21:47:34 +00:00
|
|
|
|
;; the Free Software Foundation; either version 2, or (at your option)
|
1991-08-27 03:29:52 +00:00
|
|
|
|
;; any later version.
|
|
|
|
|
|
|
|
|
|
;; GNU Emacs is distributed in the hope that it will be useful,
|
|
|
|
|
;; but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
|
|
;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
|
|
;; GNU General Public License for more details.
|
|
|
|
|
|
|
|
|
|
;; You should have received a copy of the GNU General Public License
|
1996-01-14 07:34:30 +00:00
|
|
|
|
;; along with GNU Emacs; see the file COPYING. If not, write to the
|
|
|
|
|
;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
|
|
|
|
|
;; Boston, MA 02111-1307, USA.
|
1991-08-27 03:29:52 +00:00
|
|
|
|
|
1993-03-22 03:27:18 +00:00
|
|
|
|
;;; Commentary:
|
|
|
|
|
|
|
|
|
|
;; This facility is documented in the Emacs Manual.
|
|
|
|
|
|
1992-07-16 21:47:34 +00:00
|
|
|
|
;;; Code:
|
1991-08-27 03:29:52 +00:00
|
|
|
|
|
1997-08-11 23:54:58 +00:00
|
|
|
|
(defcustom only-global-abbrevs nil
|
|
|
|
|
"*t means user plans to use global abbrevs only.
|
|
|
|
|
This makes the commands that normally define mode-specific abbrevs
|
|
|
|
|
define global abbrevs instead."
|
|
|
|
|
:type 'boolean
|
1998-05-26 09:23:23 +00:00
|
|
|
|
:group 'abbrev-mode
|
|
|
|
|
:group 'convenience)
|
1991-08-27 03:29:52 +00:00
|
|
|
|
|
2000-05-05 13:21:04 +00:00
|
|
|
|
(defun abbrev-mode (&optional arg)
|
1991-08-27 03:29:52 +00:00
|
|
|
|
"Toggle abbrev mode.
|
1992-10-03 17:56:40 +00:00
|
|
|
|
With argument ARG, turn abbrev mode on iff ARG is positive.
|
1991-08-27 03:29:52 +00:00
|
|
|
|
In abbrev mode, inserting an abbreviation causes it to expand
|
|
|
|
|
and be replaced by its expansion."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(setq abbrev-mode
|
|
|
|
|
(if (null arg) (not abbrev-mode)
|
|
|
|
|
(> (prefix-numeric-value arg) 0)))
|
1995-04-25 22:17:14 +00:00
|
|
|
|
(force-mode-line-update))
|
1997-08-11 23:54:58 +00:00
|
|
|
|
|
|
|
|
|
(defcustom abbrev-mode nil
|
|
|
|
|
"Toggle abbrev mode.
|
1999-04-08 16:26:38 +00:00
|
|
|
|
Non-nil means automatically expand abbrevs as they are inserted.
|
|
|
|
|
|
|
|
|
|
Changing it with \\[customize] sets the default value.
|
|
|
|
|
Use the command `abbrev-mode' to enable or disable Abbrev mode in the current
|
|
|
|
|
buffer."
|
1997-08-11 23:54:58 +00:00
|
|
|
|
:type 'boolean
|
|
|
|
|
:group 'abbrev-mode)
|
|
|
|
|
|
1991-08-27 03:29:52 +00:00
|
|
|
|
|
|
|
|
|
(defvar edit-abbrevs-map nil
|
|
|
|
|
"Keymap used in edit-abbrevs.")
|
|
|
|
|
(if edit-abbrevs-map
|
|
|
|
|
nil
|
|
|
|
|
(setq edit-abbrevs-map (make-sparse-keymap))
|
|
|
|
|
(define-key edit-abbrevs-map "\C-x\C-s" 'edit-abbrevs-redefine)
|
|
|
|
|
(define-key edit-abbrevs-map "\C-c\C-c" 'edit-abbrevs-redefine))
|
|
|
|
|
|
|
|
|
|
(defun kill-all-abbrevs ()
|
|
|
|
|
"Undefine all defined abbrevs."
|
|
|
|
|
(interactive)
|
|
|
|
|
(let ((tables abbrev-table-name-list))
|
|
|
|
|
(while tables
|
|
|
|
|
(clear-abbrev-table (symbol-value (car tables)))
|
|
|
|
|
(setq tables (cdr tables)))))
|
|
|
|
|
|
|
|
|
|
(defun insert-abbrevs ()
|
|
|
|
|
"Insert after point a description of all defined abbrevs.
|
|
|
|
|
Mark is set after the inserted text."
|
|
|
|
|
(interactive)
|
|
|
|
|
(push-mark
|
|
|
|
|
(save-excursion
|
|
|
|
|
(let ((tables abbrev-table-name-list))
|
|
|
|
|
(while tables
|
|
|
|
|
(insert-abbrev-table-description (car tables) t)
|
|
|
|
|
(setq tables (cdr tables))))
|
|
|
|
|
(point))))
|
|
|
|
|
|
2000-08-28 16:07:10 +00:00
|
|
|
|
(defun list-abbrevs (&optional local)
|
|
|
|
|
"Display a list of defined abbrevs.
|
|
|
|
|
If LOCAL is non-nil, interactively when invoked with a
|
|
|
|
|
prefix arg, display only local, i.e. mode-specific, abbrevs.
|
|
|
|
|
Otherwise display all abbrevs."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(display-buffer (prepare-abbrev-list-buffer local)))
|
|
|
|
|
|
|
|
|
|
(defun abbrev-table-name (table)
|
|
|
|
|
"Value is the name of abbrev table TABLE."
|
|
|
|
|
(let ((tables abbrev-table-name-list)
|
|
|
|
|
found)
|
|
|
|
|
(while (and (not found) tables)
|
|
|
|
|
(when (eq (symbol-value (car tables)) table)
|
|
|
|
|
(setq found (car tables)))
|
|
|
|
|
(setq tables (cdr tables)))
|
|
|
|
|
found))
|
|
|
|
|
|
|
|
|
|
(defun prepare-abbrev-list-buffer (&optional local)
|
1991-08-27 03:29:52 +00:00
|
|
|
|
(save-excursion
|
2000-11-28 13:57:29 +00:00
|
|
|
|
(let ((table local-abbrev-table))
|
|
|
|
|
(set-buffer (get-buffer-create "*Abbrevs*"))
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(if local
|
|
|
|
|
(insert-abbrev-table-description (abbrev-table-name table) t)
|
|
|
|
|
(dolist (table abbrev-table-name-list)
|
|
|
|
|
(insert-abbrev-table-description table t)))
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(set-buffer-modified-p nil)
|
|
|
|
|
(edit-abbrevs-mode)
|
|
|
|
|
(current-buffer))))
|
1991-08-27 03:29:52 +00:00
|
|
|
|
|
|
|
|
|
(defun edit-abbrevs-mode ()
|
|
|
|
|
"Major mode for editing the list of abbrev definitions.
|
|
|
|
|
\\{edit-abbrevs-map}"
|
|
|
|
|
(interactive)
|
|
|
|
|
(setq major-mode 'edit-abbrevs-mode)
|
|
|
|
|
(setq mode-name "Edit-Abbrevs")
|
|
|
|
|
(use-local-map edit-abbrevs-map))
|
|
|
|
|
|
|
|
|
|
(defun edit-abbrevs ()
|
|
|
|
|
"Alter abbrev definitions by editing a list of them.
|
|
|
|
|
Selects a buffer containing a list of abbrev definitions.
|
|
|
|
|
You can edit them and type \\<edit-abbrevs-map>\\[edit-abbrevs-redefine] to redefine abbrevs
|
|
|
|
|
according to your editing.
|
|
|
|
|
Buffer contains a header line for each abbrev table,
|
|
|
|
|
which is the abbrev table name in parentheses.
|
|
|
|
|
This is followed by one line per abbrev in that table:
|
|
|
|
|
NAME USECOUNT EXPANSION HOOK
|
|
|
|
|
where NAME and EXPANSION are strings with quotes,
|
|
|
|
|
USECOUNT is an integer, and HOOK is any valid function
|
|
|
|
|
or may be omitted (it is usually omitted)."
|
|
|
|
|
(interactive)
|
|
|
|
|
(switch-to-buffer (prepare-abbrev-list-buffer)))
|
|
|
|
|
|
|
|
|
|
(defun edit-abbrevs-redefine ()
|
|
|
|
|
"Redefine abbrevs according to current buffer contents."
|
|
|
|
|
(interactive)
|
|
|
|
|
(define-abbrevs t)
|
|
|
|
|
(set-buffer-modified-p nil))
|
|
|
|
|
|
|
|
|
|
(defun define-abbrevs (&optional arg)
|
|
|
|
|
"Define abbrevs according to current visible buffer contents.
|
|
|
|
|
See documentation of `edit-abbrevs' for info on the format of the
|
|
|
|
|
text you must have in the buffer.
|
|
|
|
|
With argument, eliminate all abbrev definitions except
|
|
|
|
|
the ones defined from the buffer now."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(if arg (kill-all-abbrevs))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char (point-min))
|
|
|
|
|
(while (and (not (eobp)) (re-search-forward "^(" nil t))
|
|
|
|
|
(let* ((buf (current-buffer))
|
|
|
|
|
(table (read buf))
|
1992-07-24 06:09:27 +00:00
|
|
|
|
abbrevs name hook exp count)
|
1991-08-27 03:29:52 +00:00
|
|
|
|
(forward-line 1)
|
|
|
|
|
(while (progn (forward-line 1)
|
|
|
|
|
(not (eolp)))
|
|
|
|
|
(setq name (read buf) count (read buf) exp (read buf))
|
|
|
|
|
(skip-chars-backward " \t\n\f")
|
|
|
|
|
(setq hook (if (not (eolp)) (read buf)))
|
|
|
|
|
(skip-chars-backward " \t\n\f")
|
|
|
|
|
(setq abbrevs (cons (list name exp hook count) abbrevs)))
|
|
|
|
|
(define-abbrev-table table abbrevs)))))
|
|
|
|
|
|
|
|
|
|
(defun read-abbrev-file (&optional file quietly)
|
|
|
|
|
"Read abbrev definitions from file written with `write-abbrev-file'.
|
|
|
|
|
Optional argument FILE is the name of the file to read;
|
|
|
|
|
it defaults to the value of `abbrev-file-name'.
|
2001-11-11 01:49:05 +00:00
|
|
|
|
Optional second argument QUIETLY non-nil means don't display a message."
|
1991-08-27 03:29:52 +00:00
|
|
|
|
(interactive "fRead abbrev file: ")
|
|
|
|
|
(load (if (and file (> (length file) 0)) file abbrev-file-name)
|
|
|
|
|
nil quietly)
|
2001-11-11 01:49:05 +00:00
|
|
|
|
(setq abbrevs-changed nil))
|
1991-08-27 03:29:52 +00:00
|
|
|
|
|
|
|
|
|
(defun quietly-read-abbrev-file (&optional file)
|
|
|
|
|
"Read abbrev definitions from file written with write-abbrev-file.
|
|
|
|
|
Optional argument FILE is the name of the file to read;
|
|
|
|
|
it defaults to the value of `abbrev-file-name'.
|
2001-11-11 01:49:05 +00:00
|
|
|
|
Does not display any message."
|
1991-08-27 03:29:52 +00:00
|
|
|
|
;(interactive "fRead abbrev file: ")
|
|
|
|
|
(read-abbrev-file file t))
|
|
|
|
|
|
|
|
|
|
(defun write-abbrev-file (file)
|
1992-07-16 21:47:34 +00:00
|
|
|
|
"Write all abbrev definitions to a file of Lisp code.
|
1991-08-27 03:29:52 +00:00
|
|
|
|
The file written can be loaded in another session to define the same abbrevs.
|
|
|
|
|
The argument FILE is the file name to write."
|
|
|
|
|
(interactive
|
|
|
|
|
(list
|
|
|
|
|
(read-file-name "Write abbrev file: "
|
|
|
|
|
(file-name-directory (expand-file-name abbrev-file-name))
|
|
|
|
|
abbrev-file-name)))
|
|
|
|
|
(or (and file (> (length file) 0))
|
|
|
|
|
(setq file abbrev-file-name))
|
|
|
|
|
(save-excursion
|
|
|
|
|
(set-buffer (get-buffer-create " write-abbrev-file"))
|
|
|
|
|
(erase-buffer)
|
|
|
|
|
(let ((tables abbrev-table-name-list))
|
|
|
|
|
(while tables
|
|
|
|
|
(insert-abbrev-table-description (car tables) nil)
|
|
|
|
|
(setq tables (cdr tables))))
|
|
|
|
|
(write-region 1 (point-max) file)
|
|
|
|
|
(erase-buffer)))
|
|
|
|
|
|
|
|
|
|
(defun add-mode-abbrev (arg)
|
|
|
|
|
"Define mode-specific abbrev for last word(s) before point.
|
|
|
|
|
Argument is how many words before point form the expansion;
|
|
|
|
|
or zero means the region is the expansion.
|
|
|
|
|
A negative argument means to undefine the specified abbrev.
|
|
|
|
|
Reads the abbreviation in the minibuffer.
|
|
|
|
|
|
|
|
|
|
Don't use this function in a Lisp program; use `define-abbrev' instead."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(add-abbrev
|
|
|
|
|
(if only-global-abbrevs
|
|
|
|
|
global-abbrev-table
|
|
|
|
|
(or local-abbrev-table
|
|
|
|
|
(error "No per-mode abbrev table")))
|
|
|
|
|
"Mode" arg))
|
|
|
|
|
|
|
|
|
|
(defun add-global-abbrev (arg)
|
|
|
|
|
"Define global (all modes) abbrev for last word(s) before point.
|
|
|
|
|
The prefix argument specifies the number of words before point that form the
|
|
|
|
|
expansion; or zero means the region is the expansion.
|
|
|
|
|
A negative argument means to undefine the specified abbrev.
|
|
|
|
|
This command uses the minibuffer to read the abbreviation.
|
|
|
|
|
|
|
|
|
|
Don't use this function in a Lisp program; use `define-abbrev' instead."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(add-abbrev global-abbrev-table "Global" arg))
|
|
|
|
|
|
|
|
|
|
(defun add-abbrev (table type arg)
|
|
|
|
|
(let ((exp (and (>= arg 0)
|
1999-10-18 21:28:04 +00:00
|
|
|
|
(buffer-substring-no-properties
|
1991-08-27 03:29:52 +00:00
|
|
|
|
(point)
|
|
|
|
|
(if (= arg 0) (mark)
|
|
|
|
|
(save-excursion (forward-word (- arg)) (point))))))
|
|
|
|
|
name)
|
|
|
|
|
(setq name
|
|
|
|
|
(read-string (format (if exp "%s abbrev for \"%s\": "
|
|
|
|
|
"Undefine %s abbrev: ")
|
|
|
|
|
type exp)))
|
1994-09-29 19:07:45 +00:00
|
|
|
|
(set-text-properties 0 (length name) nil name)
|
1991-08-27 03:29:52 +00:00
|
|
|
|
(if (or (null exp)
|
|
|
|
|
(not (abbrev-expansion name table))
|
|
|
|
|
(y-or-n-p (format "%s expands to \"%s\"; redefine? "
|
|
|
|
|
name (abbrev-expansion name table))))
|
|
|
|
|
(define-abbrev table (downcase name) exp))))
|
|
|
|
|
|
|
|
|
|
(defun inverse-add-mode-abbrev (arg)
|
|
|
|
|
"Define last word before point as a mode-specific abbrev.
|
|
|
|
|
With prefix argument N, defines the Nth word before point.
|
|
|
|
|
This command uses the minibuffer to read the expansion.
|
|
|
|
|
Expands the abbreviation after defining it."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(inverse-add-abbrev
|
|
|
|
|
(if only-global-abbrevs
|
|
|
|
|
global-abbrev-table
|
|
|
|
|
(or local-abbrev-table
|
|
|
|
|
(error "No per-mode abbrev table")))
|
|
|
|
|
"Mode" arg))
|
|
|
|
|
|
|
|
|
|
(defun inverse-add-global-abbrev (arg)
|
|
|
|
|
"Define last word before point as a global (mode-independent) abbrev.
|
|
|
|
|
With prefix argument N, defines the Nth word before point.
|
|
|
|
|
This command uses the minibuffer to read the expansion.
|
|
|
|
|
Expands the abbreviation after defining it."
|
|
|
|
|
(interactive "p")
|
|
|
|
|
(inverse-add-abbrev global-abbrev-table "Global" arg))
|
|
|
|
|
|
|
|
|
|
(defun inverse-add-abbrev (table type arg)
|
2000-03-17 22:32:39 +00:00
|
|
|
|
(let (name exp start end)
|
1991-08-27 03:29:52 +00:00
|
|
|
|
(save-excursion
|
2000-03-17 22:32:39 +00:00
|
|
|
|
(forward-word (1+ (- arg)))
|
|
|
|
|
(setq end (point))
|
|
|
|
|
(backward-word 1)
|
|
|
|
|
(setq start (point)
|
|
|
|
|
name (buffer-substring-no-properties start end)))
|
|
|
|
|
|
|
|
|
|
(setq exp (read-string (format "%s expansion for \"%s\": " type name)
|
|
|
|
|
nil nil nil t))
|
|
|
|
|
(when (or (not (abbrev-expansion name table))
|
|
|
|
|
(y-or-n-p (format "%s expands to \"%s\"; redefine? "
|
|
|
|
|
name (abbrev-expansion name table))))
|
|
|
|
|
(define-abbrev table (downcase name) exp)
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char end)
|
|
|
|
|
(expand-abbrev)))))
|
1991-08-27 03:29:52 +00:00
|
|
|
|
|
|
|
|
|
(defun abbrev-prefix-mark (&optional arg)
|
|
|
|
|
"Mark current point as the beginning of an abbrev.
|
|
|
|
|
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."
|
|
|
|
|
(interactive "P")
|
|
|
|
|
(or arg (expand-abbrev))
|
|
|
|
|
(setq abbrev-start-location (point-marker)
|
|
|
|
|
abbrev-start-location-buffer (current-buffer))
|
|
|
|
|
(insert "-"))
|
|
|
|
|
|
|
|
|
|
(defun expand-region-abbrevs (start end &optional noquery)
|
|
|
|
|
"For abbrev occurrence in the region, offer to expand it.
|
|
|
|
|
The user is asked to type y or n for each occurrence.
|
|
|
|
|
A prefix argument means don't query; expand all abbrevs.
|
|
|
|
|
If called from a Lisp program, arguments are START END &optional NOQUERY."
|
|
|
|
|
(interactive "r\nP")
|
|
|
|
|
(save-excursion
|
|
|
|
|
(goto-char start)
|
|
|
|
|
(let ((lim (- (point-max) end))
|
|
|
|
|
pnt string)
|
|
|
|
|
(while (and (not (eobp))
|
|
|
|
|
(progn (forward-word 1)
|
|
|
|
|
(<= (setq pnt (point)) (- (point-max) lim))))
|
|
|
|
|
(if (abbrev-expansion
|
|
|
|
|
(setq string
|
1999-10-18 21:28:04 +00:00
|
|
|
|
(buffer-substring-no-properties
|
1991-08-27 03:29:52 +00:00
|
|
|
|
(save-excursion (forward-word -1) (point))
|
|
|
|
|
pnt)))
|
|
|
|
|
(if (or noquery (y-or-n-p (format "Expand `%s'? " string)))
|
|
|
|
|
(expand-abbrev)))))))
|
1992-05-30 23:54:21 +00:00
|
|
|
|
|
|
|
|
|
;;; abbrev.el ends here
|