(pages-copy-header-and-position): Call end-of-line, not forward-line.
[bpt/emacs.git] / lisp / simple.el
index 59211c9..8555773 100644 (file)
@@ -1,6 +1,6 @@
 ;;; simple.el --- basic editing commands for Emacs
 
-;; Copyright (C) 1985, 1986, 1987, 1992 Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1987, 1993 Free Software Foundation, Inc.
 
 ;; This file is part of GNU Emacs.
 
 ;; along with GNU Emacs; see the file COPYING.  If not, write to
 ;; the Free Software Foundation, 675 Mass Ave, Cambridge, MA 02139, USA.
 
+;;; Commentary:
+
+;; A grab-bag of basic Emacs commands not specifically related to some
+;; major mode or to file-handling.
+
 ;;; 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))))
 
@@ -46,16 +63,29 @@ With arg, inserts that many newlines."
 
 (defun quoted-insert (arg)
   "Read next input character and insert it.
-Useful for inserting control characters.
-You may also type up to 3 octal digits, to insert a character with that code"
+This is useful for inserting control characters.
+You may also type up to 3 octal digits, to insert a character with that code.
+
+In overwrite mode, this function inserts the character anyway, and
+does not handle octal digits specially.  This means that if you use
+overwrite as your normal editing mode, you can use this function to
+insert characters when necessary.
+
+In binary overwrite mode, this function does overwrite, and octal
+digits are interpreted as a character code.  This is supposed to make
+this function useful in editing binary files."
   (interactive "*p")
-  (let ((char (read-quoted-char)))
-    (while (> arg 0)
-      (insert char)
-      (setq arg (1- arg)))))
+  (let ((char (if (or (not overwrite-mode)
+                     (eq overwrite-mode 'overwrite-mode-binary))
+                 (read-quoted-char)
+               (read-char))))
+    (if (eq overwrite-mode 'overwrite-mode-binary)
+       (delete-char arg))
+    (insert-char char arg)))
 
 (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)
@@ -63,6 +93,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 ()
@@ -140,10 +178,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)
@@ -152,10 +190,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)))
@@ -210,7 +248,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)
@@ -226,7 +265,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)
@@ -257,11 +297,11 @@ it is usually a mistake for a Lisp function to use any subroutine
 that uses or sets the mark."
   (interactive)
   (push-mark (point))
-  (push-mark (point-max))
+  (push-mark (point-max) nil t)
   (goto-char (point-min)))
 
 (defun count-lines-region (start end)
-  "Print number of lines and charcters in the region."
+  "Print number of lines and characters in the region."
   (interactive "r")
   (message "Region has %d lines, %d characters"
           (count-lines start end) (- end start)))
@@ -279,20 +319,25 @@ 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
-      (narrow-to-region start end)
-      (goto-char (point-min))
-      (if (eq selective-display t)
-         (let ((done 0))
-           (while (re-search-forward "[\n\C-m]" nil t 40)
-             (setq done (+ 40 done)))
-           (while (re-search-forward "[\n\C-m]" nil t 1)
-             (setq done (+ 1 done)))
-           done)
-       (- (buffer-size) (forward-line (buffer-size)))))))
+  (save-match-data
+    (save-excursion
+      (save-restriction
+       (narrow-to-region start end)
+       (goto-char (point-min))
+       (if (eq selective-display t)
+           (let ((done 0))
+             (while (re-search-forward "[\n\C-m]" nil t 40)
+               (setq done (+ 40 done)))
+             (while (re-search-forward "[\n\C-m]" nil t 1)
+               (setq done (+ 1 done)))
+             (goto-char (point-max))
+             (if (and (/= start end)
+                      (not (bolp)))
+                 (1+ done)
+               done))
+         (- (buffer-size) (forward-line (buffer-size))))))))
 
 (defun what-cursor-position ()
   "Print info on cursor position (on screen and within buffer)."
@@ -328,14 +373,23 @@ Other major modes are defined by comparison with this one."
   (interactive)
   (kill-all-local-variables))
 
+(defvar read-expression-map (cons '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,
+(defvar read-expression-history nil)
+
+;; 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
+                              'read-expression-history)))
   (setq values (cons (eval expression) values))
   (prin1 (car values) t))
 
@@ -343,34 +397,12 @@ 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))))
-    ;; Add edited command to command history, unless redundant.
-    (or (equal command (car command-history))
-       (setq command-history (cons command command-history)))
+  (let ((command (read-from-minibuffer prompt
+                                      (prin1-to-string command)
+                                      read-expression-map t
+                                      '(command-history . 1))))
     (eval command)))
 
-;; (defvar repeat-complex-command nil)
-
-(defvar minibuffer-history nil)
-(defvar minibuffer-history-sexp-flag nil)
-(setq minibuffer-history-variable 'minibuffer-history)
-(setq minibuffer-history-position nil)
-
-(define-key minibuffer-local-map "\en" 'next-history-element)
-(define-key minibuffer-local-ns-map "\en" 'next-history-element)
-(define-key minibuffer-local-ns-map "\en" 'next-history-element)
-(define-key minibuffer-local-completion-map "\en" 'next-history-element)
-(define-key minibuffer-local-completion-map "\en" 'next-history-element)
-(define-key minibuffer-local-must-match-map "\en" 'next-history-element)
-
-(define-key minibuffer-local-map "\ep" 'previous-history-element)
-(define-key minibuffer-local-ns-map "\ep" 'previous-history-element)
-(define-key minibuffer-local-ns-map "\ep" 'previous-history-element)
-(define-key minibuffer-local-completion-map "\ep" 'previous-history-element)
-(define-key minibuffer-local-completion-map "\ep" 'previous-history-element)
-(define-key minibuffer-local-must-match-map "\ep" 'previous-history-element)
-
 (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.
@@ -378,26 +410,139 @@ 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- arg) command-history))
        (minibuffer-history-position arg)
        (minibuffer-history-sexp-flag t)
-       (repeat-complex-command-flag t)
        newcmd)
     (if elt
-       (let ((minibuffer-history-variable ' command-history))
-         (setq newcmd (read-from-minibuffer "Redo: "
-                                            (prin1-to-string elt)
-                                            minibuffer-local-map
-                                            t))
+       (progn
+         (setq newcmd
+               (read-from-minibuffer
+                "Redo: " (prin1-to-string elt) 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))))
+\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
+ (lambda (key-and-command)
+   (mapcar
+    (lambda (keymap-and-completionp)
+      ;; Arg is (KEYMAP-SYMBOL . COMPLETION-MAP-P).
+      ;; If the cdr of KEY-AND-COMMAND (the command) is a cons,
+      ;; its car is used if COMPLETION-MAP-P is nil, its cdr if it is t.
+      (define-key (symbol-value (car keymap-and-completionp))
+       (car key-and-command)
+       (let ((command (cdr key-and-command)))
+         (if (consp command)
+             ;; (and ... nil) => ... turns back on the completion-oriented
+             ;; history commands which rms turned off since they seem to
+             ;; do things he doesn't like.
+             (if (and (cdr keymap-and-completionp) nil) ;XXX turned off
+                 (progn (error "EMACS BUG!") (cdr command))
+               (car command))
+           command))))
+    '((minibuffer-local-map . nil)
+      (minibuffer-local-ns-map . nil)
+      (minibuffer-local-completion-map . t)
+      (minibuffer-local-must-match-map . t)
+      (read-expression-map . nil))))
+ '(("\en" . (next-history-element . next-complete-history-element))
+   ([next] . (next-history-element . next-complete-history-element))
+   ("\ep" . (previous-history-element . previous-complete-history-element))
+   ([prior] . (previous-history-element . previous-complete-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)
+         (regexp (read-from-minibuffer "Previous element matching (regexp): "
+                                       nil
+                                       minibuffer-local-map
+                                       nil
+                                       'minibuffer-history-search-history)))
+     ;; Use the last regexp specified, by default, if input is empty.
+     (list (if (string= regexp "")
+              (setcar minibuffer-history-search-history
+                      (nth 1 minibuffer-history-search-history))
+            regexp)
+          (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)
+         (regexp (read-from-minibuffer "Next element matching (regexp): "
+                                       nil
+                                       minibuffer-local-map
+                                       nil
+                                       'minibuffer-history-search-history)))
+     ;; Use the last regexp specified, by default, if input is empty.
+     (list (if (string= regexp "")
+              (setcar minibuffer-history-search-history
+                      (nth 1 minibuffer-history-search-history))
+            regexp)
+          (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."
@@ -406,8 +551,8 @@ Whilst editing the command, the following commands are available:
                   (length (symbol-value minibuffer-history-variable)))))
     (if (= minibuffer-history-position narg)
        (error (if (= minibuffer-history-position 1)
-                  "No following item in minibuffer history"
-                "No preceding item in minibuffer history"))
+                  "End of history; no next item"
+                "Beginning of history; no preceding item"))
       (erase-buffer)
       (setq minibuffer-history-position narg)
       (let ((elt (nth (1- minibuffer-history-position)
@@ -415,16 +560,31 @@ Whilst editing the command, the following commands are available:
        (insert
         (if minibuffer-history-sexp-flag
             (prin1-to-string elt)
-          elt))))
+          elt)))
       (goto-char (point-min)))))
 
 (defun previous-history-element (n)
-  "Inserts the previous element of `command-history' into the minibuffer."
+  "Inserts the previous element of the minibuffer history into the minibuffer."
   (interactive "p")
-;;  (if repeat-complex-command-flag
   (next-history-element (- n)))
-;;    (repeat-complex-command 1)))
 
+(defun next-complete-history-element (n)
+  "\
+Get previous element of history which is a completion of minibuffer contents."
+  (interactive "p")
+  (let ((point-at-start (point)))
+    (next-matching-history-element
+     (concat "^" (regexp-quote (buffer-substring (point-min) (point)))) n)
+    ;; next-matching-history-element always puts us at (point-min).
+    ;; Move to the position we were at before changing the buffer contents.
+    ;; This is still sensical, because the text before point has not changed.
+    (goto-char point-at-start)))
+
+(defun previous-complete-history-element (n)
+  "Get next element of history which is a completion of minibuffer contents."
+  (interactive "p")
+  (next-complete-history-element (- n)))
+\f
 (defun goto-line (arg)
   "Goto line ARG, counting from line 1 at beginning of buffer."
   (interactive "NGoto line: ")
@@ -436,14 +596,15 @@ Whilst editing the command, the following commands are available:
       (forward-line (1- arg)))))
 
 ;Put this on C-x u, so we can force that rather than C-_ into startup msg
-(fset 'advertised-undo 'undo)
+(define-function 'advertised-undo 'undo)
 
 (defun undo (&optional arg)
   "Undo some previous changes.
 Repeat this command to undo more changes.
 A numeric argument serves as a repeat count."
   (interactive "*p")
-  (let ((modified (buffer-modified-p)))
+  (let ((modified (buffer-modified-p))
+       (recent-save (recent-auto-save-p)))
     (or (eq (selected-window) (minibuffer-window))
        (message "Undo!"))
     (or (eq last-command 'undo)
@@ -452,25 +613,28 @@ A numeric argument serves as a repeat count."
     (setq this-command 'undo)
     (undo-more (or arg 1))
     (and modified (not (buffer-modified-p))
-        (delete-auto-save-file-if-necessary))))
+        (delete-auto-save-file-if-necessary recent-save))))
+
+(defvar pending-undo-list nil
+  "Within a run of consecutive undo commands, list remaining to be undone.")
 
 (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)))
 
-(defvar last-shell-command "")
-(defvar last-shell-command-on-region "")
+(defvar shell-command-history nil
+  "History list for some commands that read shell commands.")
 
 (defun shell-command (command &optional flag)
   "Execute string COMMAND in inferior shell; display output, if any.
@@ -479,7 +643,8 @@ If COMMAND ends in ampersand, execute it asynchronously.
 Optional second arg non-nil (prefix arg, if interactive)
 means insert output in current buffer after point (leave mark after it).
 This cannot be done asynchronously."
-  (interactive (list (read-string "Shell command: " last-shell-command)
+  (interactive (list (read-from-minibuffer "Shell command: "
+                                          nil nil nil 'shell-command-history)
                     current-prefix-arg))
   (if flag
       (progn (barf-if-buffer-read-only)
@@ -491,7 +656,12 @@ This cannot be done asynchronously."
             ;; aliases for shell commands then they can still have them.
             (call-process shell-file-name nil t nil
                           "-c" command)
-            (exchange-point-and-mark))
+            ;; This is like exchange-point-and-mark, but doesn't activate the mark.
+            ;; It is cleaner to avoid activation, even though the command
+            ;; loop would deactivate the mark because we inserted text.
+            (goto-char (prog1 (mark t)
+                         (set-marker (mark-marker) (point)
+                                     (current-buffer)))))
     ;; Preserve the match data in case called from a program.
     (let ((data (match-data)))
       (unwind-protect
@@ -568,9 +738,9 @@ 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))
-                    (read-string "Shell command on region: "
-                                 last-shell-command-on-region)
+  (interactive (list (region-beginning) (region-end)
+                    (read-from-minibuffer "Shell command on region: "
+                                          nil nil nil 'shell-command-history)
                     current-prefix-arg
                     (prefix-numeric-value current-prefix-arg)))
   (if flag
@@ -651,7 +821,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)
@@ -669,13 +840,7 @@ Repeating \\[universal-argument] without digits or minus sign
        (progn
          (describe-arg value sign)
          (setq key (read-key-sequence nil t))))
-    (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))
-      ;; We can't push back a longer string, so we'll emulate the
-      ;; command loop ourselves.
-      (command-execute (key-binding key)))))
+    (setq unread-command-events (listify-key-sequence key))))
 
 (defun describe-arg (value sign)
   (cond ((numberp value)
@@ -710,21 +875,29 @@ Repeating \\[universal-argument] without digits or minus sign
   (forward-line (- arg))
   (skip-chars-forward " \t"))
 
+(defvar kill-whole-line nil
+  "*If non-nil, `kill-line' with no arg at beg of line kills the whole line.")
+
 (defun kill-line (&optional arg)
   "Kill the rest of the current line; if no nonblanks there, kill thru newline.
 With prefix argument, kill that many lines from point.
 Negative arguments kill lines backward.
 
 When calling from a program, nil means \"no arg\",
-a number counts as a prefix arg."
+a number counts as a prefix arg.
+
+If `kill-whole-line' is non-nil, then kill the whole line
+when given no argument at the beginning of a line."
   (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)
                       (signal 'end-of-buffer nil))
-                  (if (looking-at "[ \t]*$")
+                  (if (or (looking-at "[ \t]*$") (and kill-whole-line (bolp)))
                       (forward-line 1)
                     (end-of-line)))
                 (point))))
@@ -735,20 +908,23 @@ a number counts as a prefix arg."
   "Function to call to make a killed region available to other programs.
 
 Most window systems provide some sort of facility for cutting and
-pasting text between the windows of different programs.  On startup,
-this variable is set to a function which emacs will call whenever text
-is put in the kill ring to make the new kill available to other
+pasting text between the windows of different programs.
+This variable holds a function that Emacs calls whenever text
+is put in the kill ring, to make the new kill available to other
 programs.
 
-The function takes one argument, TEXT, which is a string containing
-the text which should be made available.")
+The function takes one or two arguments.
+The first argument, TEXT, is a string containing
+the text which should be made available.
+The second, PUSH, if non-nil means this is a \"new\" kill;
+nil means appending to an \"old\" kill.")
 
 (defvar interprogram-paste-function nil
   "Function to call to get text cut from other programs.
 
 Most window systems provide some sort of facility for cutting and
-pasting text between the windows of different programs.  On startup,
-this variable is set to a function which emacs will call to obtain
+pasting text between the windows of different programs.
+This variable holds a function that Emacs calls to obtain
 text that other programs have provided for pasting.
 
 The function should be called with no arguments.  If the function
@@ -792,12 +968,12 @@ If `interprogram-cut-function' is non-nil, apply it to STRING."
       (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil))
   (setq kill-ring-yank-pointer kill-ring)
   (if interprogram-cut-function
-      (funcall interprogram-cut-function string)))
+      (funcall interprogram-cut-function string t)))
 
 (defun kill-append (string before-p)
   "Append STRING to the end of the latest kill in the kill ring.
 If BEFORE-P is non-nil, prepend STRING to the kill.
-If 'interprogram-cut-function' is set, pass the resulting kill to
+If `interprogram-cut-function' is set, pass the resulting kill to
 it."
   (setcar kill-ring
          (if before-p
@@ -816,10 +992,6 @@ yanking point; just return the Nth kill forward."
   (let ((interprogram-paste (and (= n 0)
                                 interprogram-paste-function
                                 (funcall interprogram-paste-function))))
-;;; RMS: Turn off the interprogram paste feature 
-;;; because currently it is wedged: it is always
-;;; giving a null string.
-    (setq interprogram-paste nil)
     (if interprogram-paste
        (progn
          ;; Disable the interprogram cut function when we add the new
@@ -829,11 +1001,10 @@ yanking point; just return the Nth kill forward."
            (kill-new interprogram-paste))
          interprogram-paste)
       (or kill-ring (error "Kill ring is empty"))
-      (let* ((length (length kill-ring))
-            (ARGth-kill-element
-             (nthcdr (% (+ n (- length (length kill-ring-yank-pointer)))
-                        length)
-                     kill-ring)))
+      (let ((ARGth-kill-element
+            (nthcdr (mod (- n (length kill-ring-yank-pointer))
+                         (length kill-ring))
+                    kill-ring)))
        (or do-not-move
            (setq kill-ring-yank-pointer ARGth-kill-element))
        (car ARGth-kill-element)))))
@@ -847,6 +1018,9 @@ yanking point; just return the Nth kill forward."
 The text is deleted but saved in the kill ring.
 The command \\[yank] can retrieve it from there.
 \(If you want to kill and then yank immediately, use \\[copy-region-as-kill].)
+If the buffer is read-only, Emacs will beep and refrain from deleting
+the text, but put the text in the kill ring anyway.  This means that
+you can use the killing commands to copy text from a read-only buffer.
 
 This is the primitive for programs to kill text (as opposed to deleting it).
 Supply two arguments, character numbers indicating the stretch of text
@@ -857,18 +1031,35 @@ the text killed this time appends to the text killed last time
 to make one entry in the kill ring."
   (interactive "r")
   (cond
+
+   ;; If the buffer is read-only, we should beep, in case the person
+   ;; just isn't aware of this.  However, there's no harm in putting
+   ;; the region's text in the kill ring, anyway.
    (buffer-read-only
-    (copy-region-as-kill beg end))
+    (copy-region-as-kill beg end)
+    ;; This should always barf, and give us the correct error.
+    (barf-if-buffer-read-only))
+
+   ;; In certain cases, we can arrange for the undo list and the kill
+   ;; ring to share the same string object.  This code does that.
    ((not (or (eq buffer-undo-list t)
             (eq last-command 'kill-region)
-            (eq beg end)))
+            (equal beg end)))
     ;; Don't let the undo list be truncated before we can even access it.
-    (let ((undo-strong-limit (+ (- (max beg end) (min beg end)) 100)))
+    (let ((undo-strong-limit (+ (- (max beg end) (min beg end)) 100))
+         (old-list buffer-undo-list)
+         tail)
       (delete-region beg end)
+      ;; Search back in buffer-undo-list for this string,
+      ;; in case a change hook made property changes.
+      (setq tail buffer-undo-list)
+      (while (not (stringp (car (car tail))))
+       (setq tail (cdr tail)))
       ;; Take the same string recorded for undo
       ;; and put it in the kill-ring.
-      (kill-new (car (car buffer-undo-list)))
+      (kill-new (car (car tail)))
       (setq this-command 'kill-region)))
+
    (t
     (copy-region-as-kill beg end)
     (delete-region beg end))))
@@ -885,27 +1076,43 @@ system cut and paste."
   nil)
 
 (defun kill-ring-save (beg end)
-  "Save the region as if killed, but don't kill it."
+  "Save the region as if killed, but don't kill it.
+This command is similar to `copy-region-as-kill', except that it gives
+visual feedback indicating the extent of the region being copied.
+If `interprogram-cut-function' is non-nil, also save the text for a window
+system cut and paste."
   (interactive "r")
   (copy-region-as-kill beg end)
   (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)))))))))
+      (let ((other-end (if (= (point) beg) end beg))
+           (opoint (point))
+           ;; Inhibit quitting so we can make a quit here
+           ;; look like a C-g typed as a command.
+           (inhibit-quit t))
+       (if (pos-visible-in-window-p other-end (selected-window))
+           (progn
+             ;; Swap point and mark.
+             (set-marker (mark-marker) (point) (current-buffer))
+             (goto-char other-end)
+             (sit-for 1)
+             ;; Swap back.
+             (set-marker (mark-marker) other-end (current-buffer))
+             (goto-char opoint)
+             ;; If user quit, deactivate the mark
+             ;; as C-g would as a command.
+             (and quit-flag mark-active
+                  (deactivate-mark)))
+         (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
@@ -914,15 +1121,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."
@@ -930,18 +1137,24 @@ comes the newest one."
   (if (not (eq last-command 'yank))
       (error "Previous command was not a yank"))
   (setq this-command 'yank)
-  (let ((before (< (point) (mark))))
-    (delete-region (point) (mark))
-    (set-mark (point))
+  (let ((before (< (point) (mark t))))
+    (delete-region (point) (mark t))
+    (set-marker (mark-marker) (point) (current-buffer))
     (insert (current-kill arg))
-    (if before (exchange-point-and-mark))))
+    (if before
+       ;; This is like exchange-point-and-mark, but doesn't activate the mark.
+       ;; It is cleaner to avoid activation, even though the command
+       ;; loop would deactivate the mark because we inserted text.
+       (goto-char (prog1 (mark t)
+                    (set-marker (mark-marker) (point) (current-buffer))))))
+  nil)
 
 (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")
@@ -951,7 +1164,12 @@ See also the command \\[yank-pop]."
                         ((eq arg '-) -1)
                         (t (1- arg)))))
   (if (consp arg)
-      (exchange-point-and-mark)))
+      ;; This is like exchange-point-and-mark, but doesn't activate the mark.
+      ;; It is cleaner to avoid activation, even though the command
+      ;; loop would deactivate the mark because we inserted text.
+      (goto-char (prog1 (mark t)
+                  (set-marker (mark-marker) (point) (current-buffer)))))
+  nil)
 
 (defun rotate-yank-pointer (arg)
   "Rotate the yanking point in the kill ring.
@@ -964,7 +1182,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)
@@ -974,7 +1193,8 @@ BUFFER may be a buffer or a buffer name."
        (setq start (point-min) end (point-max)))
       (insert-buffer-substring buffer start end)
       (setq newmark (point)))
-    (push-mark newmark)))
+    (push-mark newmark))
+  nil)
 
 (defun append-to-buffer (buffer start end)
   "Append to specified buffer the text of the region.
@@ -984,7 +1204,8 @@ When calling from a program, give three arguments:
 BUFFER (or buffer name), START and END.
 START and END specify the portion of the current buffer to be copied."
   (interactive
-   (list (read-buffer "Append to buffer: " (other-buffer nil t) t)))
+   (list (read-buffer "Append to buffer: " (other-buffer nil t))
+        (region-beginning) (region-end)))
   (let ((oldbuf (current-buffer)))
     (save-excursion
       (set-buffer (get-buffer-create buffer))
@@ -1019,11 +1240,36 @@ START and END specify the portion of the current buffer to be copied."
       (save-excursion
        (insert-buffer-substring oldbuf start end)))))
 \f
-(defun mark ()
-  "Return this buffer's mark value as integer, or nil if no mark.
+(defvar mark-even-if-inactive nil
+  "*Non-nil means you can use the mark even when inactive.
+This option makes a difference in Transient Mark mode.
+When the option is non-nil, deactivation of the mark
+turns off region highlighting, but commands that use the mark
+behave as if the mark were still active.")
+
+(put 'mark-inactive 'error-conditions '(mark-inactive error))
+(put 'mark-inactive 'error-message "The mark is not active now")
+
+(defun mark (&optional force)
+  "Return this buffer's mark value as integer; error if mark inactive.
+If optional argument FORCE is non-nil, access the mark value
+even if the mark is not currently active, and return nil
+if there is no mark at all.
+
 If you are using this in an editing command, you are most likely making
 a mistake; see the documentation of `set-mark'."
-  (marker-position (mark-marker)))
+  (if (or force mark-active mark-even-if-inactive)
+      (marker-position (mark-marker))
+    (signal 'mark-inactive nil)))
+
+;; Many places set mark-active directly, and several of them failed to also
+;; run deactivate-mark-hook.  This shorthand should simplify.
+(defsubst deactivate-mark ()
+  "Deactivate the mark by setting `mark-active' to nil.
+\(That makes a difference only in Transient Mark mode.)
+Also runs the hook `deactivate-mark-hook'."
+  (setq mark-active nil)
+  (run-hooks 'deactivate-mark-hook))
 
 (defun set-mark (pos)
   "Set this buffer's mark to POS.  Don't use this function!
@@ -1034,7 +1280,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,
@@ -1042,7 +1288,13 @@ store it in a Lisp variable.  Example:
 
    (let ((beg (point))) (forward-line 1) (delete-region beg (point)))."
 
-  (set-marker (mark-marker) pos (current-buffer)))
+  (if pos
+      (progn
+       (setq mark-active t)
+       (run-hooks 'activate-mark-hook)
+       (set-marker (mark-marker) pos (current-buffer)))
+    (deactivate-mark)
+    (set-marker (mark-marker) pos (current-buffer))))
 
 (defvar mark-ring nil
   "The list of saved former marks of the current buffer,
@@ -1054,35 +1306,41 @@ most recent first.")
 
 (defun set-mark-command (arg)
   "Set mark at where point is, or jump to mark.
-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.
+With no prefix argument, set mark, and push old mark position on mark ring.
+With argument, jump to mark, and pop a new position for mark off the 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)
-      (push-mark)
-    (if (null (mark))
+      (progn
+       (push-mark nil nil t))
+    (if (null (mark t))
        (error "No mark set in this buffer")
-      (goto-char (mark))
+      (goto-char (mark t))
       (pop-mark))))
 
-(defun push-mark (&optional location nomsg)
+(defun push-mark (&optional location nomsg activate)
   "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.
+Display `Mark set' unless the optional second arg NOMSG is non-nil.
+In Transient Mark mode, activate mark if optional third arg ACTIVATE non-nil.
 
-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))
+Novice Emacs Lisp programmers often try to use the mark for the wrong
+purposes.  See the documentation of `set-mark' for more information.
+
+In Transient Mark mode, this does not activate the mark."
+  (if (null (mark t))
       nil
     (setq mark-ring (cons (copy-marker (mark-marker)) mark-ring))
     (if (> (length mark-ring) mark-ring-max)
        (progn
          (move-marker (car (nthcdr mark-ring-max mark-ring)) nil)
          (setcdr (nthcdr (1- mark-ring-max) mark-ring) nil))))
-  (set-mark (or location (point)))
+  (set-marker (mark-marker) (or location (point)) (current-buffer))
   (or nomsg executing-macro (> (minibuffer-depth) 0)
       (message "Mark set"))
+  (if (or activate (not transient-mark-mode))
+      (set-mark (mark t)))
   nil)
 
 (defun pop-mark ()
@@ -1091,30 +1349,50 @@ Does not set point.  Does nothing if mark ring is empty."
   (if mark-ring
       (progn
        (setq mark-ring (nconc mark-ring (list (copy-marker (mark-marker)))))
-       (set-mark (+ 0 (car mark-ring)))
+       (set-marker (mark-marker) (+ 0 (car mark-ring)) (current-buffer))
+       (deactivate-mark)
        (move-marker (car mark-ring) nil)
-       (if (null (mark)) (ding))
+       (if (null (mark t)) (ding))
        (setq mark-ring (cdr mark-ring)))))
 
-(fset 'exchange-dot-and-mark 'exchange-point-and-mark)
+(define-function 'exchange-dot-and-mark 'exchange-point-and-mark)
 (defun exchange-point-and-mark ()
-  "Put the mark where point is now, and point where the mark is now."
+  "Put the mark where point is now, and point where the mark is now.
+This command works even when the mark is not active,
+and it reactivates the mark."
   (interactive nil)
-  (let ((omark (mark)))
+  (let ((omark (mark t)))
     (if (null omark)
        (error "No mark set in this buffer"))
     (set-mark (point))
     (goto-char omark)
     nil))
+
+(defun transient-mark-mode (arg)
+  "Toggle Transient Mark mode.
+With arg, turn Transient Mark mode on if arg is positive, off otherwise.
+
+In Transient Mark mode, changing the buffer \"deactivates\" the mark.
+While the mark is active, the region is highlighted."
+  (interactive "P")
+  (setq transient-mark-mode
+       (if (null arg)
+           (not transient-mark-mode)
+         (> (prefix-numeric-value arg) 0))))
 \f
+(defvar next-line-add-newlines t
+  "*If non-nil, `next-line' inserts newline to avoid `end of buffer' error.")
+
 (defun next-line (arg)
   "Move cursor vertically down ARG lines.
 If there is no character in the target line exactly under the current column,
 the cursor is positioned after the character in that line which spans this
 column, or at the end of the line if it is not long enough.
-If there is no line in the buffer after this one,
-a newline character is inserted to create a line
-and the cursor moves to that line.
+If there is no line in the buffer after this one, behavior depends on the
+value of next-line-add-newlines.  If non-nil, a newline character is inserted
+to create a line and the cursor moves to that line, otherwise the cursor is
+moved to the end of the buffer (if already at the end of the buffer, an error
+is signaled).
 
 The command \\[set-goal-column] can be used to create
 a semipermanent goal column to which this command always moves.
@@ -1125,15 +1403,20 @@ If you are thinking of using this in a Lisp program, consider
 using `forward-line' instead.  It is usually easier to use
 and more reliable (no dependence on goal column, etc.)."
   (interactive "p")
-  (if (= arg 1)
-      (let ((opoint (point)))
-       (forward-line 1)
-       (if (or (= opoint (point))
-               (not (eq (preceding-char) ?\n)))
-           (insert ?\n)
-         (goto-char opoint)
-         (line-move arg)))
-    (line-move arg))
+  (let ((opoint (point)))
+    (if next-line-add-newlines
+       (if (/= arg 1)
+           (line-move arg)
+         (forward-line 1)
+         (if (or (= opoint (point)) (not (eq (preceding-char) ?\n)))
+             (insert ?\n)
+           (goto-char opoint)
+           (line-move arg)))
+      (if (eobp)
+         (signal 'end-of-buffer nil))
+      (line-move arg)
+      (if (= opoint (point))
+         (end-of-line))))
   nil)
 
 (defun previous-line (arg)
@@ -1147,7 +1430,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))
@@ -1158,9 +1441,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.
@@ -1193,13 +1476,17 @@ When the `track-eol' feature is doing its job, the value is 9999.")
   (move-to-column (or goal-column temporary-goal-column))
   nil)
 
+;;; Many people have said they rarely use this feature, and often type
+;;; it by accident.  Maybe it shouldn't even be on a key.
+(put 'set-goal-column 'disabled t)
 
 (defun set-goal-column (arg)
   "Set the current horizontal position as a goal for \\[next-line] and \\[previous-line].
 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
@@ -1211,6 +1498,66 @@ so that \\[next-line] and \\[previous-line] resume vertical motion."
             goal-column))
   nil)
 \f
+;;; Partial support for horizontal autoscrolling.  Someday, this feature
+;;; will be built into the C level and all the (hscroll-point-visible) calls
+;;; will go away.
+
+(defvar hscroll-step 0
+   "*The number of columns to try scrolling a window by when point moves out.
+If that fails to bring point back on frame, point is centered instead.
+If this is zero, point is always centered after it moves off frame.")
+
+(defun hscroll-point-visible ()
+  "Scrolls the window horizontally to make point visible."
+  (let* ((here (current-column))
+        (left (window-hscroll))
+        (right (- (+ left (window-width)) 3)))
+    (cond
+     ;; Should we recenter?
+     ((or (< here (- left  hscroll-step))
+         (> here (+ right hscroll-step)))
+      (set-window-hscroll
+       (selected-window)
+       ;; Recenter, but don't show too much white space off the end of
+       ;; the line.
+       (max 0
+           (min (- (save-excursion (end-of-line) (current-column))
+                   (window-width)
+                   -5)
+                (- here (/ (window-width) 2))))))
+     ;; Should we scroll left?
+     ((> here right)
+      (scroll-left hscroll-step))
+     ;; Or right?
+     ((< here left)
+      (scroll-right hscroll-step)))))
+  
+;; rms: (1) The definitions of arrow keys should not simply restate
+;; what keys they are.  The arrow keys should run the ordinary commands.
+;; (2) The arrow keys are just one of many common ways of moving point
+;; within a line.  Real horizontal autoscrolling would be a good feature,
+;; but supporting it only for arrow keys is too incomplete to be desirable.
+
+;;;;; Make arrow keys do the right thing for improved terminal support
+;;;;; When we implement true horizontal autoscrolling, right-arrow and
+;;;;; left-arrow can lose the (if truncate-lines ...) clause and become
+;;;;; aliases.  These functions are bound to the corresponding keyboard
+;;;;; events in loaddefs.el.
+
+;;(defun right-arrow (arg)
+;;  "Move right one character on the screen (with prefix ARG, that many chars).
+;;Scroll right if needed to keep point horizontally onscreen."
+;;  (interactive "P")
+;;  (forward-char arg)
+;;  (hscroll-point-visible))
+
+;;(defun left-arrow (arg)
+;;  "Move left one character on the screen (with prefix ARG, that many chars).
+;;Scroll left if needed to keep point horizontally onscreen."
+;;  (interactive "P")
+;;  (backward-char arg)
+;;  (hscroll-point-visible))
+\f
 (defun transpose-chars (arg)
   "Interchange characters around point, moving forward one character.
 With prefix arg ARG, effect is to take character before point
@@ -1309,7 +1656,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
@@ -1324,7 +1673,12 @@ at the place matched by the close of the first pair.")
   "*String to insert to end a new comment.
 Should be an empty string if comments are terminated by end-of-line.")
 
-(defconst comment-indent-hook
+(defconst comment-indent-hook nil
+  "Obsolete variable for function to compute desired indentation for a comment.
+This function is called with no args with point at the beginning of
+the comment's starting delimiter.")
+
+(defconst comment-indent-function
   '(lambda () comment-column)
   "Function to compute desired indentation for a comment.
 This function is called with no args with point at the beginning of
@@ -1345,16 +1699,19 @@ the comment's starting delimiter.")
                 ;; position at the end of the first pair.
                 (if (match-end 1)
                     (goto-char (match-end 1))
-                  ;; If comment-start-skip matched a string with internal
-                  ;; whitespace (not final whitespace) then the delimiter
-                  ;; start at the end of that whitespace.
-                  ;; Otherwise, it starts at the beginning of what was matched.
-                  (skip-chars-backward " \t" (match-beginning 0))
-                  (skip-chars-backward "^ \t" (match-beginning 0)))))
+                  ;; If comment-start-skip matched a string with
+                  ;; internal whitespace (not final whitespace) then
+                  ;; the delimiter start at the end of that
+                  ;; whitespace.  Otherwise, it starts at the
+                  ;; beginning of what was matched.
+                  (skip-syntax-backward " " (match-beginning 0))
+                  (skip-syntax-backward "^ " (match-beginning 0)))))
       (setq begpos (point))
       ;; Compute desired indent.
       (if (= (current-column)
-            (setq indent (funcall comment-indent-hook)))
+            (setq indent (if comment-indent-hook
+                             (funcall comment-indent-hook)
+                           (funcall comment-indent-function))))
          (goto-char begpos)
        ;; If that's different from current, change it.
        (skip-chars-backward " \t")
@@ -1461,7 +1818,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) ()
@@ -1472,7 +1830,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)))
 
@@ -1482,19 +1840,48 @@ In programs, it is faster to call forward-word with negative arg."
   (push-mark
     (save-excursion
       (forward-word arg)
-      (point))))
+      (point))
+    nil t))
 
 (defun kill-word (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.
 With argument, do this that many times."
   (interactive "p")
   (kill-word (- arg)))
+
+(defun current-word ()
+  "Return the word point is on as a string, if it's between two
+word-constituent characters. If not, but it immediately follows one,
+move back first.  Otherwise, if point precedes a word constituent,
+move forward first.  Otherwise, move backwards until a word constituent
+is found and get that word; if you reach a newline first, move forward
+instead."
+  (interactive)
+  (save-excursion
+    (let ((oldpoint (point)) (start (point)) (end (point)))
+      (skip-syntax-backward "w_") (setq start (point))
+      (goto-char oldpoint)
+      (skip-syntax-forward "w_") (setq end (point))
+      (if (and (eq start oldpoint) (eq end oldpoint))
+         (progn
+           (skip-syntax-backward "^w_"
+                                 (save-excursion (beginning-of-line) (point)))
+           (if (eq (preceding-char) ?\n)
+               (progn
+                 (skip-syntax-forward "^w_")
+                 (setq start (point))
+                 (skip-syntax-forward "w_")
+                 (setq end (point)))
+             (setq end (point))
+             (skip-syntax-backward "w_")
+             (setq start (point)))))
+      (buffer-substring start end))))
 \f
 (defconst fill-prefix nil
   "*String for filling to insert at front of new line, or nil for none.
@@ -1524,16 +1911,22 @@ Setting this variable automatically makes it local to the current buffer.")
            (if (save-excursion
                  (goto-char fill-point)
                  (not (bolp)))
-               ;; If point is at the fill-point, do not `save-excursion'.
-               ;; Otherwise, if a comment prefix or fill-prefix is inserted,
-               ;; point will end up before it rather than after it.
-               (if (save-excursion
-                     (skip-chars-backward " \t")
-                     (= (point) fill-point))
-                   (indent-new-comment-line)
-                 (save-excursion
-                   (goto-char fill-point)
-                   (indent-new-comment-line)))
+               (let ((prev-column (current-column)))
+                 ;; If point is at the fill-point, do not `save-excursion'.
+                 ;; Otherwise, if a comment prefix or fill-prefix is inserted,
+                 ;; point will end up before it rather than after it.
+                 (if (save-excursion
+                       (skip-chars-backward " \t")
+                       (= (point) fill-point))
+                     (indent-new-comment-line)
+                   (save-excursion
+                     (goto-char fill-point)
+                     (indent-new-comment-line)))
+                 ;; If making the new line didn't reduce the hpos of
+                 ;; the end of the line, then give up now;
+                 ;; trying again will not help.
+                 (if (>= (current-column) prev-column)
+                     (setq give-up t)))
              ;; No place to break => stop trying.
              (setq give-up t)))))))
 
@@ -1625,17 +2018,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"))
@@ -1652,29 +2045,74 @@ selective-display's value is separate for each buffer."
   (prin1 selective-display t)
   (princ "." t))
 
+(defconst overwrite-mode-textual " Ovwrt"
+  "The string displayed in the mode line when in overwrite mode.")
+(defconst overwrite-mode-binary " Bin Ovwrt"
+  "The string displayed in the mode line when in binary overwrite mode.")
+
 (defun overwrite-mode (arg)
   "Toggle overwrite mode.
 With arg, turn overwrite mode on iff arg is positive.
 In overwrite mode, printing characters typed in replace existing text
-on a one-for-one basis, rather than pushing it to the right."
+on a one-for-one basis, rather than pushing it to the right.  At the
+end of a line, such characters extend the line.  Before a tab,
+such characters insert until the tab is filled in.
+\\[quoted-insert] still inserts characters in overwrite mode; this
+is supposed to make it easier to insert characters when necessary."
   (interactive "P")
   (setq overwrite-mode
-       (if (null arg) (not overwrite-mode)
-         (> (prefix-numeric-value arg) 0)))
-  (set-buffer-modified-p (buffer-modified-p))) ;No-op, but updates mode line.
+       (if (if (null arg) (not overwrite-mode)
+             (> (prefix-numeric-value arg) 0))
+           'overwrite-mode-textual))
+  (force-mode-line-update))
+
+(defun binary-overwrite-mode (arg)
+  "Toggle binary overwrite mode.
+With arg, turn binary overwrite mode on iff arg is positive.
+In binary overwrite mode, printing characters typed in replace
+existing text.  Newlines are not treated specially, so typing at the
+end of a line joins the line to the next, with the typed character
+between them.  Typing before a tab character simply replaces the tab
+with the character typed.
+\\[quoted-insert] replaces the text at the cursor, just as ordinary
+typing characters do.
+
+Note that binary overwrite mode is not its own minor mode; it is a
+specialization of overwrite-mode, entered by setting the
+`overwrite-mode' variable to `overwrite-mode-binary'."
+  (interactive "P")
+  (setq overwrite-mode
+       (if (if (null arg)
+               (not (eq overwrite-mode 'overwrite-mode-binary))
+             (> (prefix-numeric-value arg) 0))
+           'overwrite-mode-binary))
+  (force-mode-line-update))
 \f
+(defvar line-number-mode nil
+  "*Non-nil means display line number in mode line.")
+
+(defun line-number-mode (arg)
+  "Toggle Line Number mode.
+With arg, turn Line Number mode on iff arg is positive.
+When Line Number mode is enabled, the line number appears
+in the mode line."
+  (interactive "P")
+  (setq line-number-mode
+       (if (null arg) (not line-number-mode)
+         (> (prefix-numeric-value arg) 0)))
+  (force-mode-line-update))
+
 (defvar blink-matching-paren t
   "*Non-nil means show matching open-paren when close-paren is inserted.")
 
-(defconst blink-matching-paren-distance 4000
-  "*If non-nil, is maximum distance to search for matching open-paren
-when close-paren is inserted.")
+(defconst blink-matching-paren-distance 12000
+  "*If non-nil, is maximum distance to search for matching open-paren.")
 
 (defun blink-matching-open ()
   "Move cursor momentarily to the beginning of the sexp before point."
   (interactive)
   (and (> (point) (1+ (point-min)))
-       (/= (char-syntax (char-after (- (point) 2))) ?\\ )
+       (not (memq (char-syntax (char-after (- (point) 2))) '(?/ ?\\ )))
        blink-matching-paren
        (let* ((oldpos (point))
              (blinkpos)
@@ -1724,11 +2162,15 @@ when close-paren is inserted.")
 ;Turned off because it makes dbx bomb out.
 (setq blink-paren-function 'blink-matching-open)
 
-; this is just something for the luser to see in a keymap -- this is not
-;  how quitting works normally!
+;; This executes C-g typed while Emacs is waiting for a command.
+;; Quitting out of a program does not go through here;
+;; that happens in the QUIT macro at the C code level.
 (defun keyboard-quit ()
-  "Signal a  quit  condition."
+  "Signal a  quit  condition.
+During execution of Lisp code, this character causes a quit directly.
+At top-level, as an editor command, this simply beeps."
   (interactive)
+  (deactivate-mark)
   (signal 'quit nil))
 
 (define-key global-map "\C-g" 'keyboard-quit)
@@ -1767,5 +2209,62 @@ it were the arg to `interactive' (which see) to interactively read the value."
                                           'arg))
               (eval-minibuffer (format "Set %s to value: " var)))))))
   (set var val))
+\f
+;; Define the major mode for lists of completions.
+
+(defvar completion-list-mode-map nil)
+(or completion-list-mode-map
+    (let ((map (make-sparse-keymap)))
+      (define-key map [mouse-2] 'mouse-choose-completion)
+      (setq completion-list-mode-map map)))
+
+;; Completion mode is suitable only for specially formatted data.
+(put 'completion-list-mode 'mode-class 'special)
+
+(defun completion-list-mode ()
+  "Major mode for buffers showing lists of possible completions.
+Type \\<completion-list-mode-map>\\[mouse-choose-completion] to select
+a completion with the mouse."
+  (interactive)
+  (kill-all-local-variables)
+  (use-local-map completion-list-mode-map)
+  (setq mode-name "Completion List")
+  (setq major-mode 'completion-list-mode)
+  (run-hooks 'completion-list-mode-hook))
+
+(defun completion-setup-function ()
+  (save-excursion
+    (completion-list-mode)
+    (goto-char (point-min))
+    (if window-system
+       (insert (substitute-command-keys
+                "Click \\[mouse-choose-completion] on a completion to select it.\n\n")))))
+
+(add-hook 'completion-setup-hook 'completion-setup-function)
+\f
+;;;; Keypad support.
+
+;;; Make the keypad keys act like ordinary typing keys.  If people add
+;;; bindings for the function key symbols, then those bindings will
+;;; override these, so this shouldn't interfere with any existing
+;;; bindings.
+
+(mapcar
+ (lambda (keypad-normal)
+   (let ((keypad (nth 0 keypad-normal))
+        (normal (nth 1 keypad-normal)))
+     (define-key function-key-map (vector keypad) (vector normal))))
+ '((kp-0 ?0) (kp-1 ?1) (kp-2 ?2) (kp-3 ?3) (kp-4 ?4)
+   (kp-5 ?5) (kp-6 ?6) (kp-7 ?7) (kp-8 ?8) (kp-9 ?9)
+   (kp-space ?\ )
+   (kp-tab ?\t)
+   (kp-enter ?\r)
+   (kp-multiply ?*)
+   (kp-add ?+)
+   (kp-separator ?,)
+   (kp-subtract ?-)
+   (kp-decimal ?.)
+   (kp-divide ?/)
+   (kp-equal ?=)))
 
 ;;; simple.el ends here