]> code.delx.au - gnu-emacs/blobdiff - lisp/simple.el
* configure: Start with a blank line; this keeps some old CSH's
[gnu-emacs] / lisp / simple.el
index 3989a3685a27942f27a5a63259d4c46cafe3fe20..c0d796b97b7307602d06437a9fa8fb953f6ba6b4 100644 (file)
@@ -6,7 +6,7 @@
 
 ;; 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,
 ;; along with GNU Emacs; see the file COPYING.  If not, write to
 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
+;;; Code:
 
 (defun open-line (arg)
-  "Insert a newline and leave point before it.  If there is a fill
-prefix, inserts the fill prefix after the newline that it inserts.
-With arg, inserts that many newlines."
+  "Insert a newline and leave point before it.
+If there is a fill prefix, insert the fill prefix on the new line
+if the line would have been empty.
+With arg N, insert N newlines."
   (interactive "*p")
-  (let ((flag (and (bolp) (not (bobp)))))
-    (if flag (forward-char -1))
+  (let* ((do-fill-prefix (and fill-prefix (bolp)))
+        (flag (and (null do-fill-prefix) (bolp) (not (bobp)))))
+    ;; If this is a simple case, and we are at the beginning of a line,
+    ;; actually insert the newline *before* the preceding newline
+    ;; instead of after.  That makes better display behavior.
+    (if flag
+       (progn
+         ;; If undo is enabled, don't let this hack be visible:
+         ;; record the real value of point as the place to move back to
+         ;; if we undo this insert.
+         (if (and buffer-undo-list (not (eq buffer-undo-list t)))
+             (setq buffer-undo-list (cons (point) buffer-undo-list)))
+         (forward-char -1)))
     (while (> arg 0)
       (save-excursion
-        (insert ?\n)
-       (if fill-prefix (insert fill-prefix)))
+        (insert ?\n))
+      (if do-fill-prefix (insert fill-prefix))
       (setq arg (1- arg)))
     (if flag (forward-char 1))))
 
@@ -45,7 +58,7 @@ With arg, inserts that many newlines."
 
 (defun quoted-insert (arg)
   "Read next input character and insert it.
-Useful for inserting control characters.
+This is useful for inserting control characters.
 You may also type up to 3 octal digits, to insert a character with that code"
   (interactive "*p")
   (let ((char (read-quoted-char)))
@@ -55,6 +68,7 @@ You may also type up to 3 octal digits, to insert a character with that code"
 
 (defun delete-indentation (&optional arg)
   "Join this line to previous and fix up whitespace at join.
+If there is a fill prefix, delete it from the beginning of this line.
 With argument, join this line to following line."
   (interactive "*P")
   (beginning-of-line)
@@ -62,6 +76,14 @@ With argument, join this line to following line."
   (if (eq (preceding-char) ?\n)
       (progn
        (delete-region (point) (1- (point)))
+       ;; If the second line started with the fill prefix,
+       ;; delete the prefix.
+       (if (and fill-prefix
+                (<= (+ (point) (length fill-prefix)) (point-max))
+                (string= fill-prefix
+                         (buffer-substring (point)
+                                           (+ (point) (length fill-prefix)))))
+           (delete-region (point) (+ (point) (length fill-prefix))))
        (fixup-whitespace))))
 
 (defun fixup-whitespace ()
@@ -139,10 +161,10 @@ On nonblank line, delete all blank lines that follow it."
 
 (defun newline-and-indent ()
   "Insert a newline, then indent according to major mode.
-Indentation is done using the current indent-line-function.
+Indentation is done using the value of `indent-line-function'.
 In programming language modes, this is the same as TAB.
-In some text modes, where TAB inserts a tab, this indents to the
-specified left-margin column."
+In some text modes, where TAB inserts a tab, this command indents to the
+column specified by the variable `left-margin'."
   (interactive "*")
   (delete-region (point) (progn (skip-chars-backward " \t") (point)))
   (newline)
@@ -151,10 +173,10 @@ specified left-margin column."
 (defun reindent-then-newline-and-indent ()
   "Reindent current line, insert newline, then indent the new line.
 Indentation of both lines is done according to the current major mode,
-which means that the current value of indent-line-function is called.
+which means calling the current value of `indent-line-function'.
 In programming language modes, this is the same as TAB.
 In some text modes, where TAB inserts a tab, this indents to the
-specified left-margin column."
+column specified by the variable `left-margin'."
   (interactive "*")
   (save-excursion
     (delete-region (point) (progn (skip-chars-backward " \t") (point)))
@@ -209,7 +231,8 @@ Goes backward if ARG is negative; error if CHAR not found."
 (defun beginning-of-buffer (&optional arg)
   "Move point to the beginning of the buffer; leave mark at previous position.
 With arg N, put point N/10 of the way from the true beginning.
-Don't use this in Lisp programs!
+
+Don't use this command in Lisp programs!
 \(goto-char (point-min)) is faster and avoids clobbering the mark."
   (interactive "P")
   (push-mark)
@@ -225,7 +248,8 @@ Don't use this in Lisp programs!
 (defun end-of-buffer (&optional arg)
   "Move point to the end of the buffer; leave mark at previous position.
 With arg N, put point N/10 of the way from the true end.
-Don't use this in Lisp programs!
+
+Don't use this command in Lisp programs!
 \(goto-char (point-max)) is faster and avoids clobbering the mark."
   (interactive "P")
   (push-mark)
@@ -237,10 +261,17 @@ Don't use this in Lisp programs!
                           (/ (buffer-size) 10))
                      (/ (* (buffer-size) (prefix-numeric-value arg)) 10)))
               (point-max)))
+  ;; If we went to a place in the middle of the buffer,
+  ;; adjust it to the beginning of a line.
   (if arg (forward-line 1)
-    ;; Scroll to put point near bottom--show nearly maximum amount of text,
-    ;; but leave room to add something.
-    (recenter -3)))
+    ;; If the end of the buffer is not already on the screen,
+    ;; then scroll specially to put it near, but not at, the bottom.
+    (if (let ((old-point (point)))
+         (save-excursion
+                   (goto-char (window-start))
+                   (vertical-motion (window-height))
+                   (< (point) old-point)))
+       (recenter -3))))
 
 (defun mark-whole-buffer ()
   "Put point at beginning and mark at end of buffer.
@@ -271,7 +302,7 @@ that uses or sets the mark."
 (defun count-lines (start end)
   "Return number of lines between START and END.
 This is usually the number of newlines between them,
-but will be one more if START is not equal to END
+but can be one more if START is not equal to END
 and the greater of them is not at the start of a line."
   (save-excursion
     (save-restriction
@@ -320,14 +351,19 @@ Other major modes are defined by comparison with this one."
   (interactive)
   (kill-all-local-variables))
 
+(defvar read-expression-map (copy-keymap minibuffer-local-map)
+  "Minibuffer keymap used for reading Lisp expressions.")
+(define-key read-expression-map "\M-\t" 'lisp-complete-symbol)
+
 (put 'eval-expression 'disabled t)
 
 ;; We define this, rather than making  eval  interactive,
 ;; for the sake of completion of names like eval-region, eval-current-buffer.
 (defun eval-expression (expression)
   "Evaluate EXPRESSION and print value in minibuffer.
-Value is also consed on to front of variable  values  's value."
-  (interactive "xEval: ")
+Value is also consed on to front of the variable `values'."
+  (interactive (list (read-from-minibuffer "Eval: "
+                                          nil read-expression-map t)))
   (setq values (cons (eval expression) values))
   (prin1 (car values) t))
 
@@ -335,66 +371,156 @@ Value is also consed on to front of variable  values  's value."
   "Prompting with PROMPT, let user edit COMMAND and eval result.
 COMMAND is a Lisp expression.  Let user edit that expression in
 the minibuffer, then read and evaluate the result."
-  (let ((command (read-minibuffer prompt
-                                 (prin1-to-string command))))
+  (let ((command (read-from-minibuffer prompt
+                                      (prin1-to-string command)
+                                      read-expression-map t)))
     ;; Add edited command to command history, unless redundant.
     (or (equal command (car command-history))
        (setq command-history (cons command command-history)))
     (eval command)))
 
-;; (defvar repeat-complex-command nil)
-
-(defvar repeat-complex-command-map (copy-keymap minibuffer-local-map))
-(define-key repeat-complex-command-map "\ep" 'previous-complex-command)
-(define-key repeat-complex-command-map "\en" 'next-complex-command)
-(defun repeat-complex-command (repeat-complex-command-arg)
+(defun repeat-complex-command (arg)
   "Edit and re-evaluate last complex command, or ARGth from last.
 A complex command is one which used the minibuffer.
 The command is placed in the minibuffer as a Lisp form for editing.
 The result is executed, repeating the command as changed.
 If the command has been changed or is not the most recent previous command
 it is added to the front of the command history.
-Whilst editing the command, the following commands are available:
-\\{repeat-complex-command-map}"
+You can use the minibuffer history commands \\<minibuffer-local-map>\\[next-history-element] and \\[previous-history-element]
+to get different commands to edit and resubmit."
   (interactive "p")
-  (let ((elt (nth (1- repeat-complex-command-arg) command-history))
-       (repeat-complex-command-flag t)
+  (let ((elt (nth (1- arg) command-history))
+       (minibuffer-history-position arg)
+       (minibuffer-history-sexp-flag t)
        newcmd)
     (if elt
        (progn
          (setq newcmd (read-from-minibuffer "Redo: "
                                             (prin1-to-string elt)
-                                            repeat-complex-command-map
-                                            t))
+                                            read-expression-map
+                                            t
+                                            (cons 'command-history
+                                                  arg)))
+         ;; If command was added to command-history as a string,
+         ;; get rid of that.  We want only evallable expressions there.
+         (if (stringp (car command-history))
+             (setq command-history (cdr command-history)))
          ;; If command to be redone does not match front of history,
          ;; add it to the history.
          (or (equal newcmd (car command-history))
              (setq command-history (cons newcmd command-history)))
          (eval newcmd))
       (ding))))
-
-(defun next-complex-command (n)
-  "Inserts the next element of `command-history' into the minibuffer."
+\f
+(defvar minibuffer-history nil
+  "Default minibuffer history list.
+This is used for all minibuffer input
+except when an alternate history list is specified.")
+(defvar minibuffer-history-sexp-flag nil
+  "Nonzero when doing history operations on `command-history'.
+More generally, indicates that the history list being acted on
+contains expressions rather than strings.")
+(setq minibuffer-history-variable 'minibuffer-history)
+(setq minibuffer-history-position nil)
+(defvar minibuffer-history-search-history nil)
+
+(mapcar
+ (function (lambda (key-and-command)
+            (mapcar
+             (function (lambda (keymap)
+                         (define-key (symbol-value keymap)
+                           (car key-and-command)
+                           (cdr key-and-command))))
+             '(minibuffer-local-map
+               minibuffer-local-ns-map
+               minibuffer-local-completion-map
+               minibuffer-local-must-match-map
+               read-expression-map))))
+ '(("\en" . next-history-element) ([next] . next-history-element)
+   ("\ep" . previous-history-element) ([prior] . previous-history-element)
+   ("\er" . previous-matching-history-element)
+   ("\es" . next-matching-history-element)))
+
+(defun previous-matching-history-element (regexp n)
+  "Find the previous history element that matches REGEXP.
+\(Previous history elements refer to earlier actions.)
+With prefix argument N, search for Nth previous match.
+If N is negative, find the next or Nth next match."
+  (interactive
+   (let ((enable-recursive-minibuffers t)
+        (minibuffer-history-sexp-flag nil))
+     (list (read-from-minibuffer "Previous element matching (regexp): "
+                                nil
+                                minibuffer-local-map
+                                nil
+                                'minibuffer-history-search-history)
+          (prefix-numeric-value current-prefix-arg))))
+  (let ((history (symbol-value minibuffer-history-variable))
+       prevpos
+       (pos minibuffer-history-position))
+    (while (/= n 0)
+      (setq prevpos pos)
+      (setq pos (min (max 1 (+ pos (if (< n 0) -1 1))) (length history)))
+      (if (= pos prevpos)
+         (error (if (= pos 1)
+                    "No later matching history item"
+                  "No earlier matching history item")))
+      (if (string-match regexp
+                       (if minibuffer-history-sexp-flag
+                           (prin1-to-string (nth (1- pos) history))
+                         (nth (1- pos) history)))
+         (setq n (+ n (if (< n 0) 1 -1)))))
+    (setq minibuffer-history-position pos)
+    (erase-buffer)
+    (let ((elt (nth (1- pos) history)))
+      (insert (if minibuffer-history-sexp-flag
+                 (prin1-to-string elt)
+               elt)))
+      (goto-char (point-min)))
+  (if (or (eq (car (car command-history)) 'previous-matching-history-element)
+         (eq (car (car command-history)) 'next-matching-history-element))
+      (setq command-history (cdr command-history))))
+
+(defun next-matching-history-element (regexp n)
+  "Find the next history element that matches REGEXP.
+\(The next history element refers to a more recent action.)
+With prefix argument N, search for Nth next match.
+If N is negative, find the previous or Nth previous match."
+  (interactive
+   (let ((enable-recursive-minibuffers t)
+        (minibuffer-history-sexp-flag nil))
+     (list (read-from-minibuffer "Next element matching (regexp): "
+                                nil
+                                minibuffer-local-map
+                                nil
+                                'minibuffer-history-search-history)
+          (prefix-numeric-value current-prefix-arg))))
+  (previous-matching-history-element regexp (- n)))
+
+(defun next-history-element (n)
+  "Insert the next element of the minibuffer history into the minibuffer."
   (interactive "p")
-  (let ((narg (min (max 1 (- repeat-complex-command-arg n))
-                  (length command-history))))
-    (if (= repeat-complex-command-arg narg)
-       (error (if (= repeat-complex-command-arg 1)
-                  "No following item in command history"
-                "No preceding item in command history"))
+  (let ((narg (min (max 1 (- minibuffer-history-position n))
+                  (length (symbol-value minibuffer-history-variable)))))
+    (if (= minibuffer-history-position narg)
+       (error (if (= minibuffer-history-position 1)
+                  "End of history; no next item"
+                "Beginning of history; no preceding item"))
       (erase-buffer)
-      (setq repeat-complex-command-arg narg)
-      (insert (prin1-to-string (nth (1- repeat-complex-command-arg)
-                                   command-history)))
+      (setq minibuffer-history-position narg)
+      (let ((elt (nth (1- minibuffer-history-position)
+                     (symbol-value minibuffer-history-variable))))
+       (insert
+        (if minibuffer-history-sexp-flag
+            (prin1-to-string elt)
+          elt)))
       (goto-char (point-min)))))
 
-(defun previous-complex-command (n)
-  "Inserts the previous element of `command-history' into the minibuffer."
+(defun previous-history-element (n)
+  "Inserts the previous element of the minibuffer history into the minibuffer."
   (interactive "p")
-  (if repeat-complex-command-flag
-      (next-complex-command (- n))
-    (repeat-complex-command 1)))
-
+  (next-history-element (- n)))
+\f
 (defun goto-line (arg)
   "Goto line ARG, counting from line 1 at beginning of buffer."
   (interactive "NGoto line: ")
@@ -425,16 +551,16 @@ A numeric argument serves as a repeat count."
         (delete-auto-save-file-if-necessary))))
 
 (defun undo-start ()
-  "Move pending-undo-list to front of undo records.
-The next call to undo-more will undo the most recently made change."
+  "Set `pending-undo-list' to the front of the undo list.
+The next call to `undo-more' will undo the most recently made change."
   (if (eq buffer-undo-list t)
       (error "No undo information in this buffer"))
   (setq pending-undo-list buffer-undo-list))
 
 (defun undo-more (count)
   "Undo back N undo-boundaries beyond what was already undone recently.
-Call undo-start to get ready to undo recent changes,
-then call undo-more one or more times to undo them."
+Call `undo-start' to get ready to undo recent changes,
+then call `undo-more' one or more times to undo them."
   (or pending-undo-list
       (error "No further undo information"))
   (setq pending-undo-list (primitive-undo count pending-undo-list)))
@@ -538,7 +664,7 @@ but it is nonetheless available in buffer `*Shell Command Output*'
 even though that buffer is not automatically displayed.  If there is no output
 or output is inserted in the current buffer then `*Shell Command Output*' is
 deleted." 
-  (interactive (list (min (point) (mark)) (max (point) (mark))
+  (interactive (list (region-beginning) (region-end)
                     (read-string "Shell command on region: "
                                  last-shell-command-on-region)
                     current-prefix-arg
@@ -621,7 +747,8 @@ Repeating \\[universal-argument] without digits or minus sign
       (setq sign (- sign) factor nil)
 ;;      (describe-arg value sign)
       (setq key (read-key-sequence nil t)))
-    (while (and (= (length key) 1)
+    (while (and (stringp key)
+               (= (length key) 1)
                (not (string< key "0"))
                (not (string< "9" key)))
       (setq value (+ (* (if (numberp value) value 0) 10)
@@ -642,7 +769,7 @@ Repeating \\[universal-argument] without digits or minus sign
     (if (= (length key) 1)
        ;; Make sure self-insert-command finds the proper character;
        ;; unread the character and let the command loop process it.
-       (setq unread-command-char (string-to-char key))
+       (setq unread-command-event (string-to-char key))
       ;; We can't push back a longer string, so we'll emulate the
       ;; command loop ourselves.
       (command-execute (key-binding key)))))
@@ -689,7 +816,9 @@ When calling from a program, nil means \"no arg\",
 a number counts as a prefix arg."
   (interactive "P")
   (kill-region (point)
-              (progn
+              ;; Don't shift point before doing the delete; that way,
+              ;; undo will record the right position of point.
+              (save-excursion
                 (if arg
                     (forward-line (prefix-numeric-value arg))
                   (if (eobp)
@@ -829,7 +958,7 @@ to make one entry in the kill ring."
             (eq last-command 'kill-region)
             (eq beg end)))
     ;; Don't let the undo list be truncated before we can even access it.
-    (let ((undo-high-threshold (+ (- (max beg end) (min beg end)) 100)))
+    (let ((undo-strong-limit (+ (- (max beg end) (min beg end)) 100)))
       (delete-region beg end)
       ;; Take the same string recorded for undo
       ;; and put it in the kill-ring.
@@ -854,23 +983,24 @@ system cut and paste."
   "Save the region as if killed, but don't kill it."
   (interactive "r")
   (copy-region-as-kill beg end)
-  (save-excursion
-    (let ((other-end (if (= (point) beg) end beg)))
-      (if (pos-visible-in-window-p other-end (selected-window))
-         (progn
-           (goto-char other-end)
-           (sit-for 1))
-       (let* ((killed-text (current-kill 0))
-              (message-len (min (length killed-text) 40)))
-         (message
-          (if (= (point) beg)
-              (format "Killed until \"%s\""
-                      (substring killed-text (- message-len)))
-            (format "Killed from \"%s\""
-                    (substring killed-text 0 message-len)))))))))
+  (if (interactive-p)
+      (save-excursion
+       (let ((other-end (if (= (point) beg) end beg)))
+         (if (pos-visible-in-window-p other-end (selected-window))
+             (progn
+               (goto-char other-end)
+               (sit-for 1))
+           (let* ((killed-text (current-kill 0))
+                  (message-len (min (length killed-text) 40)))
+             (if (= (point) beg)
+                 ;; Don't say "killed"; that is misleading.
+                 (message "Saved text until \"%s\""
+                         (substring killed-text (- message-len)))
+               (message "Saved text from \"%s\""
+                       (substring killed-text 0 message-len)))))))))
 
 (defun append-next-kill ()
-  "Cause following command, if kill, to append to previous kill."
+  "Cause following command, if it kills, to append to previous kill."
   (interactive)
   (if (interactive-p)
       (progn
@@ -879,15 +1009,15 @@ system cut and paste."
     (setq last-command 'kill-region)))
 
 (defun yank-pop (arg)
-  "Replace just-yanked stretch of killed-text with a different stretch.
-This command is allowed only immediately after a  yank  or a  yank-pop.
+  "Replace just-yanked stretch of killed text with a different stretch.
+This command is allowed only immediately after a `yank' or a `yank-pop'.
 At such a time, the region contains a stretch of reinserted
-previously-killed text.  yank-pop  deletes that text and inserts in its
+previously-killed text.  `yank-pop' deletes that text and inserts in its
 place a different stretch of killed text.
 
 With no argument, the previous kill is inserted.
-With argument n, the n'th previous kill is inserted.
-If n is negative, this is a more recent kill.
+With argument N, insert the Nth previous kill.
+If N is negative, this is a more recent kill.
 
 The sequence of kills wraps around, so that after the oldest one
 comes the newest one."
@@ -904,9 +1034,9 @@ comes the newest one."
 (defun yank (&optional arg)
   "Reinsert the last stretch of killed text.
 More precisely, reinsert the stretch of killed text most recently
-killed OR yanked.
-With just C-U as argument, same but put point in front (and mark at end).
-With argument n, reinsert the nth most recently killed stretch of killed
+killed OR yanked.  Put point at end, and set mark at beginning.
+With just C-u as argument, same but put point at beginning (and mark at end).
+With argument N, reinsert the Nth most recently killed stretch of killed
 text.
 See also the command \\[yank-pop]."
   (interactive "*P")
@@ -929,7 +1059,8 @@ With argument, rotate that many kills forward (or backward, if negative)."
   "Insert after point the contents of BUFFER.
 Puts mark after the inserted text.
 BUFFER may be a buffer or a buffer name."
-  (interactive (list (read-buffer "Insert buffer: " (other-buffer) t)))
+  (interactive (list (progn (barf-if-buffer-read-only)
+                           (read-buffer "Insert buffer: " (other-buffer) t))))
   (or (bufferp buffer)
       (setq buffer (get-buffer buffer)))
   (let (start end newmark)
@@ -999,7 +1130,7 @@ mark position to be lost.
 Normally, when a new mark is set, the old one should go on the stack.
 This is why most applications should use push-mark, not set-mark.
 
-Novice emacs-lisp programmers often try to use the mark for the wrong
+Novice Emacs Lisp programmers often try to use the mark for the wrong
 purposes.  The mark saves a location for the user's convenience.
 Most editing commands should not alter the mark.
 To remember a location for internal use in the Lisp program,
@@ -1022,7 +1153,7 @@ most recent first.")
 With no prefix argument, set mark, and push previous mark on mark ring.
 With argument, jump to mark, and pop into mark off the mark ring.
 
-Novice emacs-lisp programmers often try to use the mark for the wrong
+Novice Emacs Lisp programmers often try to use the mark for the wrong
 purposes.  See the documentation of `set-mark' for more information."
   (interactive "P")
   (if (null arg)
@@ -1036,7 +1167,7 @@ purposes.  See the documentation of `set-mark' for more information."
   "Set mark at LOCATION (point, by default) and push old mark on mark ring.
 Displays \"Mark set\" unless the optional second arg NOMSG is non-nil.
 
-Novice emacs-lisp programmers often try to use the mark for the wrong
+Novice Emacs Lisp programmers often try to use the mark for the wrong
 purposes.  See the documentation of `set-mark' for more information."
   (if (null (mark))
       nil
@@ -1112,7 +1243,7 @@ a semipermanent goal column to which this command always moves.
 Then it does not try to move vertically.
 
 If you are thinking of using this in a Lisp program, consider using
-`forward-line' with negative argument instead..  It is usually easier
+`forward-line' with a negative argument instead.  It is usually easier
 to use and more reliable (no dependence on goal column, etc.)."
   (interactive "p")
   (line-move (- arg))
@@ -1123,9 +1254,9 @@ to use and more reliable (no dependence on goal column, etc.)."
 This means moving to the end of each line moved onto.
 The beginning of a blank line does not count as the end of a line.")
 
-(make-variable-buffer-local
- (defvar goal-column nil
-   "*Semipermanent goal column for vertical motion, as set by \\[set-goal-column], or nil."))
+(defvar goal-column nil
+  "*Semipermanent goal column for vertical motion, as set by \\[set-goal-column], or nil.")
+(make-variable-buffer-local 'goal-column)
 
 (defvar temporary-goal-column 0
   "Current goal column for vertical motion.
@@ -1164,7 +1295,8 @@ When the `track-eol' feature is doing its job, the value is 9999.")
 Those commands will move to this position in the line moved to
 rather than trying to keep the same horizontal position.
 With a non-nil argument, clears out the goal column
-so that \\[next-line] and \\[previous-line] resume vertical motion."
+so that \\[next-line] and \\[previous-line] resume vertical motion.
+The goal column is stored in the variable `goal-column'."
   (interactive "P")
   (if arg
       (progn
@@ -1274,7 +1406,9 @@ With argument 0, interchanges line point is in with line mark is in."
 \f
 (defconst comment-column 32
   "*Column to indent right-margin comments to.
-Setting this variable automatically makes it local to the current buffer.")
+Setting this variable automatically makes it local to the current buffer.
+Each mode establishes a different default value for this variable; you
+can the value for a particular mode using that mode's hook.")
 (make-variable-buffer-local 'comment-column)
 
 (defconst comment-start nil
@@ -1426,7 +1560,8 @@ not end the comment.  Blank lines do not get comments."
                     (skip-chars-backward " \t")
                     (backward-char (length ce))
                     (if (looking-at (regexp-quote ce))
-                        (delete-char (length ce))))))
+                        (delete-char (length ce)))))
+               (forward-line 1))
             (if (looking-at "[ \t]*$") ()
               (insert cs)
               (if (string= "" ce) ()
@@ -1437,7 +1572,7 @@ not end the comment.  Blank lines do not get comments."
 (defun backward-word (arg)
   "Move backward until encountering the end of a word.
 With argument, do this that many times.
-In programs, it is faster to call forward-word with negative arg."
+In programs, it is faster to call `forward-word' with negative arg."
   (interactive "p")
   (forward-word (- arg)))
 
@@ -1453,7 +1588,7 @@ In programs, it is faster to call forward-word with negative arg."
   "Kill characters forward until encountering the end of a word.
 With argument, do this that many times."
   (interactive "p")
-  (kill-region (point) (progn (forward-word arg) (point))))
+  (kill-region (point) (save-excursion (forward-word arg) (point))))
 
 (defun backward-kill-word (arg)
   "Kill characters backward until encountering the end of a word.
@@ -1590,17 +1725,17 @@ automatically breaks the line at a previous space."
   (auto-fill-mode 1))
 
 (defun set-fill-column (arg)
-  "Set fill-column to current column, or to argument if given.
-fill-column's value is separate for each buffer."
+  "Set `fill-column' to current column, or to argument if given.
+The variable `fill-column' has a separate value for each buffer."
   (interactive "P")
   (setq fill-column (if (integerp arg) arg (current-column)))
   (message "fill-column set to %d" fill-column))
 \f
 (defun set-selective-display (arg)
-  "Set selective-display to ARG; clear it if no arg.
-When selective-display is a number > 0,
-lines whose indentation is >= selective-display are not displayed.
-selective-display's value is separate for each buffer."
+  "Set `selective-display' to ARG; clear it if no arg.
+When the value of `selective-display' is a number > 0,
+lines whose indentation is >= that value are not displayed.
+The variable `selective-display' has a separate value for each buffer."
   (interactive "P")
   (if (eq selective-display t)
       (error "selective-display already in use for marked lines"))
@@ -1701,7 +1836,10 @@ when close-paren is inserted.")
 (defun set-variable (var val)
   "Set VARIABLE to VALUE.  VALUE is a Lisp object.
 When using this interactively, supply a Lisp expression for VALUE.
-If you want VALUE to be a string, you must surround it with doublequotes."
+If you want VALUE to be a string, you must surround it with doublequotes.
+
+If VARIABLE has a `variable-interactive' property, that is used as if
+it were the arg to `interactive' (which see) to interactively read the value."
   (interactive
    (let* ((var (read-variable "Set variable: "))
          (minibuffer-help-form
@@ -1720,89 +1858,14 @@ If you want VALUE to be a string, you must surround it with doublequotes."
                      (prin1 (symbol-value var))))
                nil)))))
      (list var
-          (eval-minibuffer (format "Set %s to value: " var)))))
+          (let ((prop (get var 'variable-interactive)))
+            (if prop
+                ;; Use VAR's `variable-interactive' property
+                ;; as an interactive spec for prompting.
+                (call-interactively (list 'lambda '(arg)
+                                          (list 'interactive prop)
+                                          'arg))
+              (eval-minibuffer (format "Set %s to value: " var)))))))
   (set var val))
-\f
-;These commands are defined in editfns.c
-;but they are not assigned to keys there.
-(put 'narrow-to-region 'disabled t)
-(define-key ctl-x-map "n" 'narrow-to-region)
-(define-key ctl-x-map "w" 'widen)
-
-(define-key global-map "\C-j" 'newline-and-indent)
-(define-key global-map "\C-m" 'newline)
-(define-key global-map "\C-o" 'open-line)
-(define-key esc-map "\C-o" 'split-line)
-(define-key global-map "\C-q" 'quoted-insert)
-(define-key esc-map "^" 'delete-indentation)
-(define-key esc-map "\\" 'delete-horizontal-space)
-(define-key esc-map "m" 'back-to-indentation)
-(define-key ctl-x-map "\C-o" 'delete-blank-lines)
-(define-key esc-map " " 'just-one-space)
-(define-key esc-map "z" 'zap-to-char)
-(define-key esc-map "=" 'count-lines-region)
-(define-key ctl-x-map "=" 'what-cursor-position)
-(define-key esc-map "\e" 'eval-expression)
-(define-key ctl-x-map "\e" 'repeat-complex-command)
-(define-key ctl-x-map "u" 'advertised-undo)
-(define-key global-map "\C-_" 'undo)
-(define-key esc-map "!" 'shell-command)
-(define-key esc-map "|" 'shell-command-on-region)
-
-(define-key global-map "\C-u" 'universal-argument)
-(let ((i ?0))
-  (while (<= i ?9)
-    (define-key esc-map (char-to-string i) 'digit-argument)
-    (setq i (1+ i))))
-(define-key esc-map "-" 'negative-argument)
-
-(define-key global-map "\C-k" 'kill-line)
-(define-key global-map "\C-w" 'kill-region)
-(define-key esc-map "w" 'kill-ring-save)
-(define-key esc-map "\C-w" 'append-next-kill)
-(define-key global-map "\C-y" 'yank)
-(define-key esc-map "y" 'yank-pop)
-
-(define-key ctl-x-map "a" 'append-to-buffer)
-
-(define-key global-map "\C-@" 'set-mark-command)
-(define-key ctl-x-map "\C-x" 'exchange-point-and-mark)
-
-(define-key global-map "\C-n" 'next-line)
-(define-key global-map "\C-p" 'previous-line)
-(define-key ctl-x-map "\C-n" 'set-goal-column)
-
-(define-key global-map [up] 'previous-line)
-(define-key global-map [down] 'next-line)
-(define-key global-map [left] 'backward-char)
-(define-key global-map [right] 'forward-char)
-
-(define-key global-map "\C-t" 'transpose-chars)
-(define-key esc-map "t" 'transpose-words)
-(define-key esc-map "\C-t" 'transpose-sexps)
-(define-key ctl-x-map "\C-t" 'transpose-lines)
-
-(define-key esc-map ";" 'indent-for-comment)
-(define-key esc-map "j" 'indent-new-comment-line)
-(define-key esc-map "\C-j" 'indent-new-comment-line)
-(define-key ctl-x-map ";" 'set-comment-column)
-(define-key ctl-x-map "f" 'set-fill-column)
-(define-key ctl-x-map "$" 'set-selective-display)
-
-(define-key esc-map "@" 'mark-word)
-(define-key esc-map "f" 'forward-word)
-(define-key esc-map "b" 'backward-word)
-(define-key esc-map "d" 'kill-word)
-(define-key esc-map "\177" 'backward-kill-word)
-
-(define-key esc-map "<" 'beginning-of-buffer)
-(define-key esc-map ">" 'end-of-buffer)
-(define-key ctl-x-map "h" 'mark-whole-buffer)
-(define-key esc-map "\\" 'delete-horizontal-space)
-
-(fset 'mode-specific-command-prefix (make-sparse-keymap))
-(defconst mode-specific-map (symbol-function 'mode-specific-command-prefix)
-  "Keymap for characters following C-c.")
-(define-key global-map "\C-c" 'mode-specific-command-prefix)
 
 ;;; simple.el ends here