(write-abbrev-file): Simplify, and put a coding cookie
[bpt/emacs.git] / lisp / abbrev.el
index 3cbeb19..8d9b762 100644 (file)
@@ -1,12 +1,15 @@
 ;;; abbrev.el --- abbrev mode commands for Emacs
 
-;; Copyright (C) 1985-1991 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
+
+;; Maintainer: FSF
+;; Keywords: abbrev convenience
 
 ;; 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
-;; the Free Software Foundation; either version 1, or (at your option)
+;; the Free Software Foundation; either version 2, or (at your option)
 ;; any later version.
 
 ;; GNU Emacs is distributed in the hope that it will be useful,
 ;; GNU General Public License for more details.
 
 ;; You should have received a copy of the GNU General Public License
-;; along with GNU Emacs; see the file COPYING.  If not, write to
-;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
+;; 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.
+
+;;; Commentary:
+
+;; This facility is documented in the Emacs Manual.
 
+;;; Code:
 
-(defconst only-global-abbrevs nil "\
-*t means user plans to use global abbrevs only.
-Makes the commands to define mode-specific abbrevs define global ones instead.")
+(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
+  :group 'abbrev-mode
+  :group 'convenience)
 
-(defun abbrev-mode (arg)
+(defun abbrev-mode (&optional arg)
   "Toggle abbrev mode.
-With arg, turn abbrev mode on iff arg is positive.
+With argument ARG, turn abbrev mode on iff ARG is positive.
 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)))
-  (set-buffer-modified-p (buffer-modified-p))) ;No-op, but updates mode line.
+  (force-mode-line-update))
+
+(defcustom abbrev-mode nil
+  "Toggle abbrev mode.
+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."
+  :type 'boolean
+  :group 'abbrev-mode)
+
 \f
 (defvar edit-abbrevs-map nil
   "Keymap used in edit-abbrevs.")
@@ -50,6 +74,18 @@ and be replaced by its expansion."
       (clear-abbrev-table (symbol-value (car tables)))
       (setq tables (cdr tables)))))
 
+(defun copy-abbrev-table (table)
+  "Make a new abbrev-table with the same abbrevs as TABLE."
+  (let ((new-table (make-abbrev-table)))
+    (mapatoms
+     (lambda (symbol)
+       (define-abbrev new-table
+        (symbol-name symbol)
+        (symbol-value symbol)
+        (symbol-function symbol)))
+     table)
+    new-table))
+
 (defun insert-abbrevs ()
   "Insert after point a description of all defined abbrevs.
 Mark is set after the inserted text."
@@ -62,23 +98,37 @@ Mark is set after the inserted text."
        (setq tables (cdr tables))))
     (point))))
 
-(defun list-abbrevs ()
-  "Display a list of all defined abbrevs."
-  (interactive)
-  (display-buffer (prepare-abbrev-list-buffer)))
+(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 ()
+(defun prepare-abbrev-list-buffer (&optional local)
   (save-excursion
-    (set-buffer (get-buffer-create "*Abbrevs*"))
-    (erase-buffer)
-    (let ((tables abbrev-table-name-list))
-      (while tables
-       (insert-abbrev-table-description (car tables) t)
-       (setq tables (cdr tables))))
-    (goto-char (point-min))
-    (set-buffer-modified-p nil)
-    (edit-abbrevs-mode))
-  (get-buffer-create "*Abbrevs*"))
+    (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))))
 
 (defun edit-abbrevs-mode ()
   "Major mode for editing the list of abbrev definitions.
@@ -122,7 +172,7 @@ the ones defined from the buffer now."
    (while (and (not (eobp)) (re-search-forward "^(" nil t))
      (let* ((buf (current-buffer))
            (table (read buf))
-           abbrevs)
+           abbrevs name hook exp count)
        (forward-line 1)
        (while (progn (forward-line 1)
                     (not (eolp)))
@@ -137,22 +187,22 @@ the ones defined from the buffer now."
   "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'.
-Optional second argument QUIETLY non-nil means don't print anything."
+Optional second argument QUIETLY non-nil means don't display a message."
   (interactive "fRead abbrev file: ")
   (load (if (and file (> (length file) 0)) file abbrev-file-name)
        nil quietly)
-  (setq save-abbrevs t abbrevs-changed nil))
+  (setq abbrevs-changed nil))
 
 (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'.
-Does not print anything."
+Does not display any message."
   ;(interactive "fRead abbrev file: ")
   (read-abbrev-file file t))
 
 (defun write-abbrev-file (file)
-  "Write all abbrev definitions to file of Lisp code.
+  "Write all abbrev definitions to file of Lisp code.
 The file written can be loaded in another session to define the same abbrevs.
 The argument FILE is the file name to write."
   (interactive
@@ -160,18 +210,13 @@ The argument FILE is the file name to write."
     (read-file-name "Write abbrev file: "
                    (file-name-directory (expand-file-name abbrev-file-name))
                    abbrev-file-name)))
-  (interactive "FWrite abbrev file: ")
   (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)))
+  (let ((coding-system-for-write 'emacs-mule))
+    (with-temp-file file
+      (insert ";;-*-coding: emacs-mule;-*-\n")
+      (dolist (table abbrev-table-name-list)
+       (insert-abbrev-table-description table nil)))))
 \f
 (defun add-mode-abbrev (arg)
   "Define mode-specific abbrev for last word(s) before point.
@@ -202,7 +247,7 @@ Don't use this function in a Lisp program; use `define-abbrev' instead."
 
 (defun add-abbrev (table type arg)
   (let ((exp (and (>= arg 0)
-                 (buffer-substring
+                 (buffer-substring-no-properties
                   (point)
                   (if (= arg 0) (mark)
                     (save-excursion (forward-word (- arg)) (point))))))
@@ -211,12 +256,13 @@ Don't use this function in a Lisp program; use `define-abbrev' instead."
          (read-string (format (if exp "%s abbrev for \"%s\": "
                                 "Undefine %s abbrev: ")
                               type exp)))
+    (set-text-properties 0 (length name) nil name)
     (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.
@@ -225,7 +271,7 @@ Expands the abbreviation after defining it."
   (interactive "p")
   (inverse-add-abbrev
    (if only-global-abbrevs
-       global-abbrev-table 
+       global-abbrev-table
      (or local-abbrev-table
         (error "No per-mode abbrev table")))
    "Mode" arg))
@@ -239,21 +285,23 @@ Expands the abbreviation after defining it."
   (inverse-add-abbrev global-abbrev-table "Global" arg))
 
 (defun inverse-add-abbrev (table type arg)
-  (let (name nameloc exp)
+  (let (name exp start end)
     (save-excursion
-     (forward-word (- arg))
-     (setq name (buffer-substring (point) (progn (forward-word 1)
-                                              (setq nameloc (point))))))
-    (setq exp (read-string (format "%s expansion for \"%s\": "
-                                  type name)))
-    (if (or (not (abbrev-expansion name table))
-           (y-or-n-p (format "%s expands to \"%s\"; redefine? "
-                             name (abbrev-expansion name table))))
-       (progn
-        (define-abbrev table (downcase name) exp)
-        (save-excursion
-         (goto-char nameloc)
-         (expand-abbrev))))))
+      (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)))))
 
 (defun abbrev-prefix-mark (&optional arg)
   "Mark current point as the beginning of an abbrev.
@@ -281,7 +329,7 @@ If called from a Lisp program, arguments are START END &optional NOQUERY."
                         (<= (setq pnt (point)) (- (point-max) lim))))
        (if (abbrev-expansion
             (setq string
-                  (buffer-substring
+                  (buffer-substring-no-properties
                    (save-excursion (forward-word -1) (point))
                    pnt)))
            (if (or noquery (y-or-n-p (format "Expand `%s'? " string)))