(pages-copy-header-and-position): Call end-of-line, not forward-line.
[bpt/emacs.git] / lisp / simple.el
index 1662127..8555773 100644 (file)
@@ -201,6 +201,18 @@ column specified by the variable `left-margin'."
   (newline)
   (indent-according-to-mode))
 
+;; Internal subroutine of delete-char
+(defun kill-forward-chars (arg)
+  (if (listp arg) (setq arg (car arg)))
+  (if (eq arg '-) (setq arg -1))
+  (kill-region (point) (+ (point) arg)))
+
+;; Internal subroutine of backward-delete-char
+(defun kill-backward-chars (arg)
+  (if (listp arg) (setq arg (car arg)))
+  (if (eq arg '-) (setq arg -1))
+  (kill-region (point) (- (point) arg)))
+
 (defun backward-delete-char-untabify (arg &optional killp)
   "Delete characters backward, changing tabs into spaces.
 Delete ARG chars, and kill (save in kill ring) if KILLP is non-nil.
@@ -285,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)))
@@ -320,7 +332,11 @@ and the greater of them is not at the start of a line."
                (setq done (+ 40 done)))
              (while (re-search-forward "[\n\C-m]" nil t 1)
                (setq done (+ 1 done)))
-             done)
+             (goto-char (point-max))
+             (if (and (/= start end)
+                      (not (bolp)))
+                 (1+ done)
+               done))
          (- (buffer-size) (forward-line (buffer-size))))))))
 
 (defun what-cursor-position ()
@@ -357,19 +373,23 @@ Other major modes are defined by comparison with this one."
   (interactive)
   (kill-all-local-variables))
 
-(defvar read-expression-map (copy-keymap minibuffer-local-map)
+(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 the variable `values'."
-  (interactive (list (read-from-minibuffer "Eval: "
-                                          nil read-expression-map t)))
+  (interactive
+   (list (read-from-minibuffer "Eval: "
+                              nil read-expression-map t
+                              'read-expression-history)))
   (setq values (cons (eval expression) values))
   (prin1 (car values) t))
 
@@ -379,10 +399,8 @@ COMMAND is a Lisp expression.  Let user edit that expression in
 the minibuffer, then read and evaluate the result."
   (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)))
+                                      read-expression-map t
+                                      '(command-history . 1))))
     (eval command)))
 
 (defun repeat-complex-command (arg)
@@ -401,16 +419,16 @@ to get different commands to edit and resubmit."
        newcmd)
     (if elt
        (progn
-         (setq newcmd (read-from-minibuffer "Redo: "
-                                            (prin1-to-string elt)
-                                            read-expression-map
-                                            t
-                                            (cons 'command-history
-                                                  arg)))
+         (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))
@@ -466,13 +484,18 @@ contains expressions rather than strings.")
 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)
+   (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
@@ -506,13 +529,18 @@ If N is negative, find the next or Nth next match."
 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)
+   (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)))
 
@@ -568,14 +596,15 @@ Get previous element of history which is a completion of minibuffer contents."
       (forward-line (1- arg)))))
 
 ;Put this on C-x u, so we can force that rather than C-_ into startup msg
-(defalias '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)
@@ -584,7 +613,10 @@ 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 ()
   "Set `pending-undo-list' to the front of the undo list.
@@ -601,8 +633,8 @@ then call `undo-more' one or more times to undo them."
       (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.
@@ -611,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)
@@ -623,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
@@ -701,8 +739,8 @@ 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 (region-beginning) (region-end)
-                    (read-string "Shell command on region: "
-                                 last-shell-command-on-region)
+                    (read-from-minibuffer "Shell command on region: "
+                                          nil nil nil 'shell-command-history)
                     current-prefix-arg
                     (prefix-numeric-value current-prefix-arg)))
   (if flag
@@ -838,17 +876,18 @@ Repeating \\[universal-argument] without digits or minus sign
   (skip-chars-forward " \t"))
 
 (defvar kill-whole-line nil
-  "*If non-nil, kill-line kills the whole line (including the newline)
- if point is positioned at the beginning of a line.")
+  "*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 the line is blank, or if point is at
-the beginning of the line and kill-whole-line is non-nil, kill thru newline.
+  "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)
               ;; Don't shift point before doing the delete; that way,
@@ -869,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
@@ -926,7 +968,7 @@ 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.
@@ -959,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)))))
@@ -1003,13 +1044,20 @@ to make one entry in the kill ring."
    ;; 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
@@ -1029,27 +1077,39 @@ system cut and paste."
 
 (defun kill-ring-save (beg end)
   "Save the region as if killed, but don't kill it.
-This command is similar to copy-region-as-kill, except that it gives
+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 it kills, to append to previous kill."
@@ -1077,11 +1137,16 @@ 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)
@@ -1099,7 +1164,11 @@ 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)
@@ -1135,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))
@@ -1170,16 +1240,36 @@ START and END specify the portion of the current buffer to be copied."
       (save-excursion
        (insert-buffer-substring oldbuf start end)))))
 \f
+(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, or nil if no active mark now.
+  "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.
+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'."
-  (if (or force mark-active)
+  (if (or force mark-active mark-even-if-inactive)
       (marker-position (mark-marker))
-    (error "The mark is not currently active")))
+    (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!
@@ -1198,9 +1288,13 @@ store it in a Lisp variable.  Example:
 
    (let ((beg (point))) (forward-line 1) (delete-region beg (point)))."
 
-  (setq mark-active t)
-  (run-hooks 'activate-mark-hook)
-  (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,
@@ -1219,18 +1313,22 @@ 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)
+      (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."
+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))
@@ -1238,9 +1336,11 @@ purposes.  See the documentation of `set-mark' for more information."
        (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 ()
@@ -1249,12 +1349,13 @@ 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)))))
 
-(defalias '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.
 This command works even when the mark is not active,
@@ -1266,11 +1367,21 @@ and it reactivates the mark."
     (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 will insert a newline into the buffer
- when invoked with no newline character between the point and the end
- of the buffer.")
+  "*If non-nil, `next-line' inserts newline to avoid `end of buffer' error.")
 
 (defun next-line (arg)
   "Move cursor vertically down ARG lines.
@@ -1387,23 +1498,65 @@ The goal column is stored in the variable `goal-column'."
             goal-column))
   nil)
 \f
-(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)
-  (if truncate-lines
-      (let ((x (current-column)) (w (- (window-width) 2)))
-       (set-window-hscroll (selected-window) (- x (% x w)) ))))
-
-(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)
-  (if truncate-lines
-      (let ((x (current-column)) (w (- (window-width) 2)))
-       (set-window-hscroll (selected-window) (- x (% x w)) ))))
+;;; 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.
@@ -1687,7 +1840,8 @@ 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.
@@ -1757,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)))))))
 
@@ -1945,15 +2105,14 @@ in the mode line."
 (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)
@@ -2003,13 +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.
 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)
@@ -2048,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