]> code.delx.au - gnu-emacs/blobdiff - lisp/simple.el
Merged from miles@gnu.org--gnu-2005 (patch 142-148, 615-628)
[gnu-emacs] / lisp / simple.el
index 204b2fb21bb450fd28de538417f70f0e1456d81f..2602c35c094e0c5e17819c149a8482d10ab43a64 100644 (file)
@@ -1,8 +1,7 @@
 ;;; simple.el --- basic editing commands for Emacs
 
 ;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998, 1999,
-;;               2000, 2001, 2002, 2003, 2004, 2005
-;;        Free Software Foundation, Inc.
+;;   2000, 2001, 2002, 2003, 2004, 2005 Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: internal
@@ -21,8 +20,8 @@
 
 ;; You should have received a copy of the GNU General Public License
 ;; along with GNU Emacs; see the file COPYING.  If not, write to the
-;; Free Software Foundation, Inc., 59 Temple Place - Suite 330,
-;; Boston, MA 02111-1307, USA.
+;; Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
+;; Boston, MA 02110-1301, USA.
 
 ;;; Commentary:
 
@@ -35,6 +34,8 @@
   (autoload 'widget-convert "wid-edit")
   (autoload 'shell-mode "shell"))
 
+(defvar compilation-current-error)
+
 (defcustom idle-update-delay 0.5
   "*Idle time delay before updating various things on the screen.
 Various Emacs features that update auxiliary information when point moves
@@ -74,7 +75,7 @@ wait this many seconds after Emacs becomes idle before doing an update."
 ;;; next-error support framework
 
 (defgroup next-error nil
-  "next-error support framework."
+  "`next-error' support framework."
   :group 'compilation
   :version "22.1")
 
@@ -86,8 +87,8 @@ wait this many seconds after Emacs becomes idle before doing an update."
 
 (defcustom next-error-highlight 0.1
   "*Highlighting of locations in selected source buffers.
-If number, highlight the locus in next-error face for given time in seconds.
-If t, use persistent overlays fontified in next-error face.
+If number, highlight the locus in `next-error' face for given time in seconds.
+If t, use persistent overlays fontified in `next-error' face.
 If nil, don't highlight the locus in the source buffer.
 If `fringe-arrow', indicate the locus by the fringe arrow."
   :type '(choice (number :tag "Delay")
@@ -99,8 +100,8 @@ If `fringe-arrow', indicate the locus by the fringe arrow."
 
 (defcustom next-error-highlight-no-select 0.1
   "*Highlighting of locations in non-selected source buffers.
-If number, highlight the locus in next-error face for given time in seconds.
-If t, use persistent overlays fontified in next-error face.
+If number, highlight the locus in `next-error' face for given time in seconds.
+If t, use persistent overlays fontified in `next-error' face.
 If nil, don't highlight the locus in the source buffer.
 If `fringe-arrow', indicate the locus by the fringe arrow."
   :type '(choice (number :tag "Delay")
@@ -110,16 +111,19 @@ If `fringe-arrow', indicate the locus by the fringe arrow."
   :group 'next-error
   :version "22.1")
 
+(defcustom next-error-hook nil
+  "*List of hook functions run by `next-error' after visiting source file."
+  :type 'hook
+  :group 'next-error)
+
 (defvar next-error-highlight-timer nil)
 
 (defvar next-error-overlay-arrow-position nil)
-;; This is nil so as not to really display anything on text
-;; terminals.  On text terminals, it would hide part of the file name.
-(put 'next-error-overlay-arrow-position 'overlay-arrow-string "")
+(put 'next-error-overlay-arrow-position 'overlay-arrow-string "=>")
 (add-to-list 'overlay-arrow-variable-list 'next-error-overlay-arrow-position)
 
 (defvar next-error-last-buffer nil
-  "The most recent next-error buffer.
+  "The most recent `next-error' buffer.
 A buffer becomes most recent when its compilation, grep, or
 similar mode is started, or when it is used with \\[next-error]
 or \\[compile-goto-error].")
@@ -140,7 +144,7 @@ to navigate in it.")
                               &optional avoid-current
                               extra-test-inclusive
                               extra-test-exclusive)
-  "Test if BUFFER is a next-error capable buffer.
+  "Test if BUFFER is a `next-error' capable buffer.
 
 If AVOID-CURRENT is non-nil, treat the current buffer
 as an absolute last resort only.
@@ -150,7 +154,7 @@ that normally would not qualify.  If it returns t, the buffer
 in question is treated as usable.
 
 The function EXTRA-TEST-EXCLUSIVE, if non-nil is called in each buffer
-that would normally be considered usable.  if it returns nil,
+that would normally be considered usable.  If it returns nil,
 that buffer is rejected."
   (and (buffer-name buffer)            ;First make sure it's live.
        (not (and avoid-current (eq buffer (current-buffer))))
@@ -167,11 +171,11 @@ that buffer is rejected."
 (defun next-error-find-buffer (&optional avoid-current
                                         extra-test-inclusive
                                         extra-test-exclusive)
-  "Return a next-error capable buffer.
+  "Return a `next-error' capable buffer.
 If AVOID-CURRENT is non-nil, treat the current buffer
 as an absolute last resort only.
 
-The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffers
+The function EXTRA-TEST-INCLUSIVE, if non-nil, is called in each buffer
 that normally would not qualify.  If it returns t, the buffer
 in question is treated as usable.
 
@@ -220,7 +224,7 @@ that buffer is rejected."
    (error "No next-error capable buffer found")))
 
 (defun next-error (&optional arg reset)
-  "Visit next next-error message and corresponding source code.
+  "Visit next `next-error' message and corresponding source code.
 
 If all the error messages parsed so far have been processed already,
 the message buffer is checked for new ones.
@@ -242,9 +246,10 @@ To specify use of a particular buffer for error messages, type
 \\[next-error] in that buffer when it is the only one displayed
 in the current frame.
 
-Once \\[next-error] has chosen the buffer for error messages,
-it stays with that buffer until you use it in some other buffer which
-uses Compilation mode or Compilation Minor mode.
+Once \\[next-error] has chosen the buffer for error messages, it
+runs `next-error-hook' with `run-hooks', and stays with that buffer
+until you use it in some other buffer which uses Compilation mode
+or Compilation Minor mode.
 
 See variables `compilation-parse-errors-function' and
 \`compilation-error-regexp-alist' for customization ideas."
@@ -253,13 +258,22 @@ See variables `compilation-parse-errors-function' and
   (when (setq next-error-last-buffer (next-error-find-buffer))
     ;; we know here that next-error-function is a valid symbol we can funcall
     (with-current-buffer next-error-last-buffer
-      (funcall next-error-function (prefix-numeric-value arg) reset))))
+      (funcall next-error-function (prefix-numeric-value arg) reset)
+      (run-hooks 'next-error-hook))))
+
+(defun next-error-internal ()
+  "Visit the source code corresponding to the `next-error' message at point."
+  (setq next-error-last-buffer (current-buffer))
+  ;; we know here that next-error-function is a valid symbol we can funcall
+  (with-current-buffer next-error-last-buffer
+    (funcall next-error-function 0 nil)
+    (run-hooks 'next-error-hook)))
 
 (defalias 'goto-next-locus 'next-error)
 (defalias 'next-match 'next-error)
 
 (defun previous-error (&optional n)
-  "Visit previous next-error message and corresponding source code.
+  "Visit previous `next-error' message and corresponding source code.
 
 Prefix arg N says how many error messages to move backwards (or
 forwards, if negative).
@@ -277,7 +291,7 @@ This operates on the output from the \\[compile] command, for instance."
   (next-error n t))
 
 (defun next-error-no-select (&optional n)
-  "Move point to the next error in the next-error buffer and highlight match.
+  "Move point to the next error in the `next-error' buffer and highlight match.
 Prefix arg N says how many error messages to move forwards (or
 backwards, if negative).
 Finds and highlights the source line like \\[next-error], but does not
@@ -288,7 +302,7 @@ select the source buffer."
   (pop-to-buffer next-error-last-buffer))
 
 (defun previous-error-no-select (&optional n)
-  "Move point to the previous error in the next-error buffer and highlight match.
+  "Move point to the previous error in the `next-error' buffer and highlight match.
 Prefix arg N says how many error messages to move backwards (or
 forwards, if negative).
 Finds and highlights the source line like \\[previous-error], but does not
@@ -304,11 +318,11 @@ select the source buffer."
 When turned on, cursor motion in the compilation, grep, occur or diff
 buffer causes automatic display of the corresponding source code
 location."
-  :group 'next-error :init-value " Fol"
+  :group 'next-error :init-value nil :lighter " Fol"
   (if (not next-error-follow-minor-mode)
       (remove-hook 'post-command-hook 'next-error-follow-mode-post-command-hook t)
     (add-hook 'post-command-hook 'next-error-follow-mode-post-command-hook nil t)
-    (make-variable-buffer-local 'next-error-follow-last-line)))
+    (make-local-variable 'next-error-follow-last-line)))
 
 ;;; Used as a `post-command-hook' by `next-error-follow-mode'
 ;;; for the *Compilation* *grep* and *Occur* buffers.
@@ -329,7 +343,8 @@ location."
 Other major modes are defined by comparison with this one."
   (interactive)
   (kill-all-local-variables)
-  (run-hooks 'after-change-major-mode-hook))
+  (unless delay-mode-hooks
+    (run-hooks 'after-change-major-mode-hook)))
 
 ;; Making and deleting lines.
 
@@ -420,8 +435,8 @@ than the value of `fill-column' and ARG is nil."
 
 (defun open-line (n)
   "Insert a newline and leave point before it.
-If there is a fill prefix and/or a left-margin, insert them on the new line
-if the line would have been blank.
+If there is a fill prefix and/or a `left-margin', insert them
+on the new line if the line would have been blank.
 With arg N, insert N newlines."
   (interactive "*p")
   (let* ((do-fill-prefix (and fill-prefix (bolp)))
@@ -443,7 +458,7 @@ With arg N, insert N newlines."
 (defun split-line (&optional arg)
   "Split current line, moving portion beyond point vertically down.
 If the current line starts with `fill-prefix', insert it on the new
-line as well.  With prefix ARG, don't insert fill-prefix on new line.
+line as well.  With prefix ARG, don't insert `fill-prefix' on new line.
 
 When called from Lisp code, ARG may be a prefix string to copy."
   (interactive "*P")
@@ -641,7 +656,7 @@ Leave one space or none, according to the context."
            (save-excursion (forward-char -1)
                            (looking-at "$\\|\\s(\\|\\s'")))
        nil
-      (insert ?\ ))))
+      (insert ?\s))))
 
 (defun delete-horizontal-space (&optional backward-only)
   "Delete all spaces and tabs around point.
@@ -665,9 +680,9 @@ If BACKWARD-ONLY is non-nil, only delete spaces before point."
     (skip-chars-backward " \t")
     (constrain-to-field nil orig-pos)
     (dotimes (i (or n 1))
-      (if (= (following-char) ?\ )
+      (if (= (following-char) ?\s)
          (forward-char 1)
-       (insert ?\ )))
+       (insert ?\s)))
     (delete-region
      (point)
      (progn
@@ -881,22 +896,42 @@ in *Help* buffer.  See also the command `describe-char'."
          (message "point=%d of %d (%d%%) column %d %s"
                   pos total percent col hscroll))
       (let ((coding buffer-file-coding-system)
-           encoded encoding-msg)
+           encoded encoding-msg display-prop under-display)
        (if (or (not coding)
                (eq (coding-system-type coding) t))
            (setq coding default-buffer-file-coding-system))
        (if (not (char-valid-p char))
            (setq encoding-msg
                  (format "(0%o, %d, 0x%x, invalid)" char char char))
-         (setq encoded (and (>= char 128) (encode-coding-char char coding)))
+         ;; Check if the character is displayed with some `display'
+         ;; text property.  In that case, set under-display to the
+         ;; buffer substring covered by that property.
+         (setq display-prop (get-text-property pos 'display))
+         (if display-prop
+             (let ((to (or (next-single-property-change pos 'display)
+                           (point-max))))
+               (if (< to (+ pos 4))
+                   (setq under-display "")
+                 (setq under-display "..."
+                       to (+ pos 4)))
+               (setq under-display
+                     (concat (buffer-substring-no-properties pos to)
+                             under-display)))
+           (setq encoded (and (>= char 128) (encode-coding-char char coding))))
          (setq encoding-msg
-               (if encoded
-                   (format "(0%o, %d, 0x%x, file %s)"
-                           char char char
-                           (if (> (length encoded) 1)
-                               "..."
-                             (encoded-string-description encoded coding)))
-                 (format "(0%o, %d, 0x%x)" char char char))))
+               (if display-prop
+                   (if (not (stringp display-prop))
+                       (format "(0%o, %d, 0x%x, part of display \"%s\")"
+                               char char char under-display)
+                     (format "(0%o, %d, 0x%x, part of display \"%s\"->\"%s\")"
+                             char char char under-display display-prop))
+                 (if encoded
+                     (format "(0%o, %d, 0x%x, file %s)"
+                             char char char
+                             (if (> (length encoded) 1)
+                                 "..."
+                               (encoded-string-description encoded coding)))
+                   (format "(0%o, %d, 0x%x)" char char char)))))
        (if detail
            ;; We show the detailed information about CHAR.
            (describe-char (point)))
@@ -907,9 +942,11 @@ in *Help* buffer.  See also the command `describe-char'."
                       (buffer-substring-no-properties (point) (1+ (point))))
                     encoding-msg pos total percent beg end col hscroll)
          (message "Char: %s %s point=%d of %d (%d%%) column %d %s"
-                  (if (< char 256)
-                      (single-key-description char)
-                    (buffer-substring-no-properties (point) (1+ (point))))
+                  (if enable-multibyte-characters
+                      (if (< char 128)
+                          (single-key-description char)
+                        (buffer-substring-no-properties (point) (1+ (point))))
+                    (single-key-description char))
                   encoding-msg pos total percent col hscroll))))))
 \f
 (defvar read-expression-map
@@ -922,21 +959,21 @@ in *Help* buffer.  See also the command `describe-char'."
 (defvar read-expression-history nil)
 
 (defcustom eval-expression-print-level 4
-  "*Value to use for `print-level' when printing value in `eval-expression'.
+  "Value for `print-level' while printing value in `eval-expression'.
 A value of nil means no limit."
   :group 'lisp
   :type '(choice (const :tag "No Limit" nil) integer)
   :version "21.1")
 
 (defcustom eval-expression-print-length 12
-  "*Value to use for `print-length' when printing value in `eval-expression'.
+  "Value for `print-length' while printing value in `eval-expression'.
 A value of nil means no limit."
   :group 'lisp
   :type '(choice (const :tag "No Limit" nil) integer)
   :version "21.1")
 
 (defcustom eval-expression-debug-on-error t
-  "*Non-nil means set `debug-on-error' when evaluating in `eval-expression'.
+  "If non-nil set `debug-on-error' to t in `eval-expression'.
 If nil, don't change the value of `debug-on-error'."
   :group 'lisp
   :type 'boolean
@@ -1268,7 +1305,7 @@ by the new completion."
 ;; For compatibility with the old subr of the same name.
 (defun minibuffer-prompt-width ()
   "Return the display width of the minibuffer prompt.
-Return 0 if current buffer is not a mini-buffer."
+Return 0 if current buffer is not a minibuffer."
   ;; Return the width of everything before the field at the end of
   ;; the buffer; this should be 0 for normal buffers.
   (1- (minibuffer-prompt-end)))
@@ -1289,7 +1326,7 @@ A redo record for ordinary undo maps to the following (earlier) undo.")
 
 (defvar pending-undo-list nil
   "Within a run of consecutive undo commands, list remaining to be undone.
-t if we undid all the way to the end of it.")
+If t, we undid all the way to the end of it.")
 
 (defun undo (&optional arg)
   "Undo some previous changes.
@@ -1401,16 +1438,16 @@ Contrary to `undo', this will not redo a previous undo."
   "Non-nil while performing an undo.
 Some change-hooks test this variable to do something different.")
 
-(defun undo-more (count)
+(defun undo-more (n)
   "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."
   (or (listp pending-undo-list)
-      (error (format "No further undo information%s"
-                    (if (and transient-mark-mode mark-active)
-                        " for region" ""))))
+      (error (concat "No further undo information"
+                     (and transient-mark-mode mark-active
+                          " for region"))))
   (let ((undo-in-progress t))
-    (setq pending-undo-list (primitive-undo count pending-undo-list))
+    (setq pending-undo-list (primitive-undo n pending-undo-list))
     (if (null pending-undo-list)
        (setq pending-undo-list t))))
 
@@ -2249,7 +2286,7 @@ is nil, the buffer substring is returned unaltered.
 If DELETE is non-nil, the text between BEG and END is deleted
 from the buffer.
 
-Point is temporarily set to BEG before caling
+Point is temporarily set to BEG before calling
 `buffer-substring-filters', in case the functions need to know
 where the text came from.
 
@@ -2282,6 +2319,8 @@ the text which should be made available.
 The second, optional, argument PUSH, has the same meaning as the
 similar argument to `x-set-cut-buffer', which see.")
 
+(make-variable-frame-local 'interprogram-cut-function)
+
 (defvar interprogram-paste-function nil
   "Function to call to get text cut from other programs.
 
@@ -2302,6 +2341,8 @@ most recent string, the function should return nil.  If it is
 difficult to tell whether Emacs or some other program provided the
 current string, it is probably good enough to return nil if the string
 is equal (according to `string=') to the last text Emacs provided.")
+
+(make-variable-frame-local 'interprogram-paste-function)
 \f
 
 
@@ -2339,7 +2380,7 @@ handler, if non-nil, is stored as a `yank-handler' text property on STRING).
 
 When the yank handler has a non-nil PARAM element, the original STRING
 argument is not used by `insert-for-yank'.  However, since Lisp code
-may access and use elements from the kill-ring directly, the STRING
+may access and use elements from the kill ring directly, the STRING
 argument should still be a \"useful\" string for such uses."
   (if (> (length string) 0)
       (if yank-handler
@@ -2570,7 +2611,11 @@ 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."
+comes the newest one.
+
+When this command inserts killed text into the buffer, it honors
+`yank-excluded-properties' and `yank-handler' as described in the
+doc string for `insert-for-yank-1', which see."
   (interactive "*p")
   (if (not (eq last-command 'yank))
       (error "Previous command was not a yank"))
@@ -2602,6 +2647,11 @@ killed OR yanked.  Put point at end, and set mark at beginning.
 With just \\[universal-argument] 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.
+
+When this command inserts killed text into the buffer, it honors
+`yank-excluded-properties' and `yank-handler' as described in the
+doc string for `insert-for-yank-1', which see.
+
 See also the command \\[yank-pop]."
   (interactive "*P")
   (setq yank-window-start (window-start))
@@ -2669,7 +2719,7 @@ and KILLP is t if a prefix arg was specified."
              (let ((col (current-column)))
                (forward-char -1)
                (setq col (- col (current-column)))
-               (insert-char ?\  col)
+               (insert-char ?\s col)
                (delete-char 1)))
          (forward-char -1)
          (setq count (1- count))))))
@@ -2756,7 +2806,7 @@ even beep.)"
   "Kill current line.
 With prefix arg, kill that many lines starting from the current line.
 If arg is negative, kill backward.  Also kill the preceding newline.
-\(This is meant to make C-x z work well with negative arguments.\)
+\(This is meant to make \\[repeat] work well with negative arguments.\)
 If arg is zero, kill current line but exclude the trailing newline."
   (interactive "p")
   (if (and (> arg 0) (eobp) (save-excursion (forward-visible-line 0) (eobp)))
@@ -3226,8 +3276,8 @@ as a fallback, and won't change the buffer bounds.")
     (or (and (>= position (point-min))
             (<= position (point-max)))
        (if widen-automatically
-           (error "Global mark position is outside accessible part of buffer")
-         (widen)))
+           (widen)
+         (error "Global mark position is outside accessible part of buffer")))
     (goto-char position)
     (switch-to-buffer buffer)))
 \f
@@ -3335,34 +3385,43 @@ Outline mode sets this."
       (or (memq prop buffer-invisibility-spec)
          (assq prop buffer-invisibility-spec)))))
 
-;; Perform vertical scrolling of tall images if necessary.
-;; Don't vscroll in a keyboard macro.
+;; This is like line-move-1 except that it also performs
+;; vertical scrolling of tall images if appropriate.
+;; That is not really a clean thing to do, since it mixes
+;; scrolling with cursor motion.  But so far we don't have
+;; a cleaner solution to the problem of making C-n do something
+;; useful given a tall image.
 (defun line-move (arg &optional noerror to-end try-vscroll)
   (if (and auto-window-vscroll try-vscroll
+          ;; But don't vscroll in a keyboard macro.
           (not defining-kbd-macro)
           (not executing-kbd-macro))
       (let ((forward (> arg 0))
            (part (nth 2 (pos-visible-in-window-p (point) nil t))))
        (if (and (consp part)
-                (> (setq part (if forward (cdr part) (car part))) 0))
+                (> (if forward (cdr part) (car part)) 0))
            (set-window-vscroll nil
                                (if forward
                                    (+ (window-vscroll nil t)
-                                      (min part
+                                      (min (cdr part)
                                            (* (frame-char-height) arg)))
                                  (max 0
                                       (- (window-vscroll nil t)
-                                         (min part
+                                         (min (car part)
                                               (* (frame-char-height) (- arg))))))
                                t)
          (set-window-vscroll nil 0)
          (when (line-move-1 arg noerror to-end)
-           (sit-for 0)
-           (if (and (not forward)
-                    (setq part (nth 2 (pos-visible-in-window-p
-                                       (line-beginning-position) nil t)))
-                    (> (cdr part) 0))
-               (set-window-vscroll nil (cdr part) t))
+           (when (not forward)
+             ;; Update display before calling pos-visible-in-window-p,
+             ;; because it depends on window-start being up-to-date.
+             (sit-for 0)
+             ;; If the current line is partly hidden at the bottom,
+             ;; scroll it partially up so as to unhide the bottom.
+             (if (and (setq part (nth 2 (pos-visible-in-window-p
+                                         (line-beginning-position) nil t)))
+                      (> (cdr part) 0))
+                 (set-window-vscroll nil (cdr part) t)))
            t)))
     (line-move-1 arg noerror to-end)))
 
@@ -3416,39 +3475,41 @@ Outline mode sets this."
                ;; Now move a line.
                (end-of-line)
                ;; If there's no invisibility here, move over the newline.
-               (if (and (not (integerp selective-display))
-                        (not (line-move-invisible-p (point))))
-                   ;; We avoid vertical-motion when possible
-                   ;; because that has to fontify.
-                   (if (eobp)
-                       (if (not noerror)
-                           (signal 'end-of-buffer nil)
-                         (setq done t))
-                     (forward-line 1))
-                 ;; Otherwise move a more sophisticated way.
-                 ;; (What's the logic behind this code?)
-                 (and (zerop (vertical-motion 1))
-                      (if (not noerror)
-                          (signal 'end-of-buffer nil)
-                        (setq done t))))
+               (cond
+                ((eobp)
+                 (if (not noerror)
+                     (signal 'end-of-buffer nil)
+                   (setq done t)))
+                ((and (> arg 1)  ;; Use vertical-motion for last move
+                      (not (integerp selective-display))
+                      (not (line-move-invisible-p (point))))
+                 ;; We avoid vertical-motion when possible
+                 ;; because that has to fontify.
+                 (forward-line 1))
+                ;; Otherwise move a more sophisticated way.
+                ((zerop (vertical-motion 1))
+                 (if (not noerror)
+                     (signal 'end-of-buffer nil)
+                   (setq done t))))
                (unless done
                  (setq arg (1- arg))))
              ;; The logic of this is the same as the loop above,
              ;; it just goes in the other direction.
              (while (and (< arg 0) (not done))
                (beginning-of-line)
-               (if (or (bobp)
-                       (and (not (integerp selective-display))
-                            (not (line-move-invisible-p (1- (point))))))
-                   (if (bobp)
-                       (if (not noerror)
-                           (signal 'beginning-of-buffer nil)
-                         (setq done t))
-                     (forward-line -1))
-                 (if (zerop (vertical-motion -1))
-                     (if (not noerror)
-                         (signal 'beginning-of-buffer nil)
-                       (setq done t))))
+               (cond
+                ((bobp)
+                 (if (not noerror)
+                     (signal 'beginning-of-buffer nil)
+                   (setq done t)))
+                ((and (< arg -1) ;; Use vertical-motion for last move
+                      (not (integerp selective-display))
+                      (not (line-move-invisible-p (1- (point)))))
+                 (forward-line -1))
+                ((zerop (vertical-motion -1))
+                 (if (not noerror)
+                     (signal 'beginning-of-buffer nil)
+                   (setq done t))))
                (unless done
                  (setq arg (1+ arg))
                  (while (and ;; Don't move over previous invis lines
@@ -3465,8 +3526,8 @@ Outline mode sets this."
             ;; at least go to end of line.
             (end-of-line))
            ((< arg 0)
-            ;; If we did not move down as far as desired,
-            ;; at least go to end of line.
+            ;; If we did not move up as far as desired,
+            ;; at least go to beginning of line.
             (beginning-of-line))
            (t
             (line-move-finish (or goal-column temporary-goal-column)
@@ -3484,10 +3545,11 @@ Outline mode sets this."
             ;; Compute the end of the line
             ;; ignoring effectively invisible newlines.
             (save-excursion
-              (end-of-line)
+              ;; Like end-of-line but ignores fields.
+              (skip-chars-forward "^\n")
               (while (and (not (eobp)) (line-move-invisible-p (point)))
                 (goto-char (next-char-property-change (point)))
-                (end-of-line))
+                (skip-chars-forward "^\n"))
               (point))))
 
        ;; Move to the desired column.
@@ -3641,9 +3703,18 @@ The goal column is stored in the variable `goal-column'."
         (setq goal-column nil)
         (message "No goal column"))
     (setq goal-column (current-column))
-    (message (substitute-command-keys
-             "Goal column %d (use \\[set-goal-column] with an arg to unset it)")
-            goal-column))
+    ;; The older method below can be erroneous if `set-goal-column' is bound
+    ;; to a sequence containing %
+    ;;(message (substitute-command-keys
+    ;;"Goal column %d (use \\[set-goal-column] with an arg to unset it)")
+    ;;goal-column)
+    (message "%s"
+            (concat 
+             (format "Goal column %d " goal-column)
+             (substitute-command-keys
+              "(use \\[set-goal-column] with an arg to unset it)")))
+    
+    )
   nil)
 \f
 
@@ -3908,9 +3979,7 @@ If optional arg REALLY-WORD is non-nil, it finds just a word."
 
 This function is only called during auto-filling of a comment section.
 The function should take a single optional argument, which is a flag
-indicating whether it should use soft newlines.
-
-Setting this variable automatically makes it local to the current buffer.")
+indicating whether it should use soft newlines.")
 
 ;; This function is used as the auto-fill-function of a buffer
 ;; when Auto-Fill mode is enabled.
@@ -4051,7 +4120,7 @@ Just \\[universal-argument] as argument means to use the current column."
       (setq arg (current-column)))
   (if (not (integerp arg))
       ;; Disallow missing argument; it's probably a typo for C-x C-f.
-      (error "Set-fill-column requires an explicit argument")
+      (error "set-fill-column requires an explicit argument")
     (message "Fill column set to %d (was %d)" arg fill-column)
     (setq fill-column arg)))
 \f
@@ -4131,7 +4200,7 @@ with the character typed.
 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
+specialization of overwrite mode, entered by setting the
 `overwrite-mode' variable to `overwrite-mode-binary'."
   (interactive "P")
   (setq overwrite-mode
@@ -4184,8 +4253,9 @@ when it is off screen)."
   :group 'paren-blinking)
 
 (defcustom blink-matching-paren-distance (* 25 1024)
-  "*If non-nil, is maximum distance to search for matching open-paren."
-  :type 'integer
+  "*If non-nil, maximum distance to search backwards for matching open-paren.
+If nil, search stops at the beginning of the accessible portion of the buffer."
+  :type '(choice (const nil) integer)
   :group 'paren-blinking)
 
 (defcustom blink-matching-delay 1
@@ -4201,88 +4271,90 @@ when it is off screen)."
 (defun blink-matching-open ()
   "Move cursor momentarily to the beginning of the sexp before point."
   (interactive)
-  (and (> (point) (1+ (point-min)))
-       blink-matching-paren
-       ;; Verify an even number of quoting characters precede the close.
-       (= 1 (logand 1 (- (point)
-                        (save-excursion
-                          (forward-char -1)
-                          (skip-syntax-backward "/\\")
-                          (point)))))
-       (let* ((oldpos (point))
-             (blinkpos)
-             (mismatch)
-             matching-paren)
-        (save-excursion
-          (save-restriction
-            (if blink-matching-paren-distance
-                (narrow-to-region (max (point-min)
-                                       (- (point) blink-matching-paren-distance))
-                                  oldpos))
-            (condition-case ()
-                (let ((parse-sexp-ignore-comments
-                       (and parse-sexp-ignore-comments
-                            (not blink-matching-paren-dont-ignore-comments))))
-                  (setq blinkpos (scan-sexps oldpos -1)))
-              (error nil)))
-          (and blinkpos
-                ;; Not syntax '$'.
-               (not (eq (syntax-class (syntax-after blinkpos)) 8))
-               (setq matching-paren
-                     (let ((syntax (syntax-after blinkpos)))
-                       (and (consp syntax)
-                            (eq (syntax-class syntax) 4)
-                            (cdr syntax)))
-                     mismatch
-                     (or (null matching-paren)
-                         (/= (char-after (1- oldpos))
-                             matching-paren))))
-          (if mismatch (setq blinkpos nil))
-          (if blinkpos
-              ;; Don't log messages about paren matching.
-              (let (message-log-max)
-               (goto-char blinkpos)
-               (if (pos-visible-in-window-p)
-                   (and blink-matching-paren-on-screen
-                        (sit-for blink-matching-delay))
-                 (goto-char blinkpos)
-                 (message
-                  "Matches %s"
-                  ;; Show what precedes the open in its line, if anything.
-                  (if (save-excursion
-                        (skip-chars-backward " \t")
-                        (not (bolp)))
-                      (buffer-substring (progn (beginning-of-line) (point))
-                                        (1+ blinkpos))
-                    ;; Show what follows the open in its line, if anything.
-                    (if (save-excursion
-                          (forward-char 1)
-                          (skip-chars-forward " \t")
-                          (not (eolp)))
-                        (buffer-substring blinkpos
-                                          (progn (end-of-line) (point)))
-                      ;; Otherwise show the previous nonblank line,
-                      ;; if there is one.
-                      (if (save-excursion
-                            (skip-chars-backward "\n \t")
-                            (not (bobp)))
-                          (concat
-                           (buffer-substring (progn
+  (when (and (> (point) (point-min))
+            blink-matching-paren
+            ;; Verify an even number of quoting characters precede the close.
+            (= 1 (logand 1 (- (point)
+                              (save-excursion
+                                (forward-char -1)
+                                (skip-syntax-backward "/\\")
+                                (point))))))
+    (let* ((oldpos (point))
+          blinkpos
+          message-log-max  ; Don't log messages about paren matching.
+          matching-paren
+          open-paren-line-string)
+      (save-excursion
+       (save-restriction
+         (if blink-matching-paren-distance
+             (narrow-to-region (max (point-min)
+                                    (- (point) blink-matching-paren-distance))
+                               oldpos))
+         (condition-case ()
+             (let ((parse-sexp-ignore-comments
+                    (and parse-sexp-ignore-comments
+                         (not blink-matching-paren-dont-ignore-comments))))
+               (setq blinkpos (scan-sexps oldpos -1)))
+           (error nil)))
+       (and blinkpos
+            ;; Not syntax '$'.
+            (not (eq (syntax-class (syntax-after blinkpos)) 8))
+            (setq matching-paren
+                  (let ((syntax (syntax-after blinkpos)))
+                    (and (consp syntax)
+                         (eq (syntax-class syntax) 4)
+                         (cdr syntax)))))
+       (cond
+        ((or (null matching-paren)
+             (/= (char-before oldpos)
+                 matching-paren))
+         (message "Mismatched parentheses"))
+        ((not blinkpos)
+         (if (not blink-matching-paren-distance)
+             (message "Unmatched parenthesis")))
+        ((pos-visible-in-window-p blinkpos)
+         ;; Matching open within window, temporarily move to blinkpos but only
+         ;; if `blink-matching-paren-on-screen' is non-nil.
+         (when blink-matching-paren-on-screen
+           (save-excursion
+             (goto-char blinkpos)
+             (sit-for blink-matching-delay))))
+        (t
+         (save-excursion
+           (goto-char blinkpos)
+           (setq open-paren-line-string
+                 ;; Show what precedes the open in its line, if anything.
+                 (if (save-excursion
+                       (skip-chars-backward " \t")
+                       (not (bolp)))
+                     (buffer-substring (line-beginning-position)
+                                       (1+ blinkpos))
+                   ;; Show what follows the open in its line, if anything.
+                   (if (save-excursion
+                         (forward-char 1)
+                         (skip-chars-forward " \t")
+                         (not (eolp)))
+                       (buffer-substring blinkpos
+                                         (line-end-position))
+                     ;; Otherwise show the previous nonblank line,
+                     ;; if there is one.
+                     (if (save-excursion
+                           (skip-chars-backward "\n \t")
+                           (not (bobp)))
+                         (concat
+                          (buffer-substring (progn
                                               (skip-chars-backward "\n \t")
-                                              (beginning-of-line)
-                                              (point))
-                                             (progn (end-of-line)
-                                                    (skip-chars-backward " \t")
-                                                    (point)))
-                           ;; Replace the newline and other whitespace with `...'.
-                           "..."
-                           (buffer-substring blinkpos (1+ blinkpos)))
-                        ;; There is nothing to show except the char itself.
-                        (buffer-substring blinkpos (1+ blinkpos))))))))
-            (cond (mismatch
-                   (message "Mismatched parentheses"))
-                  ((not blink-matching-paren-distance)
-                   (message "Unmatched parenthesis"))))))))
+                                              (line-beginning-position))
+                                            (progn (end-of-line)
+                                                   (skip-chars-backward " \t")
+                                                   (point)))
+                          ;; Replace the newline and other whitespace with `...'.
+                          "..."
+                          (buffer-substring blinkpos (1+ blinkpos)))
+                       ;; There is nothing to show except the char itself.
+                       (buffer-substring blinkpos (1+ blinkpos)))))))
+         (message "Matches %s"
+                  (substring-no-properties open-paren-line-string))))))))
 
 ;Turned off because it makes dbx bomb out.
 (setq blink-paren-function 'blink-matching-open)
@@ -4489,10 +4561,11 @@ Each action has the form (FUNCTION . ARGS)."
 (defvar set-variable-value-history nil
   "History of values entered with `set-variable'.")
 
-(defun set-variable (var val &optional make-local)
+(defun set-variable (variable value &optional make-local)
   "Set VARIABLE to VALUE.  VALUE is a Lisp object.
-When using this interactively, enter a Lisp object for VALUE.
-If you want VALUE to be a string, you must surround it with doublequotes.
+VARIABLE should be a user option variable name, a Lisp variable
+meant to be customized by users.  You should enter VALUE in Lisp syntax,
+so if you want VALUE to be a string, you must surround it with doublequotes.
 VALUE is used literally, not evaluated.
 
 If VARIABLE has a `variable-interactive' property, that is used as if
@@ -4504,46 +4577,54 @@ in the definition is used to check that VALUE is valid.
 With a prefix argument, set VARIABLE to VALUE buffer-locally."
   (interactive
    (let* ((default-var (variable-at-point))
-          (var (if (symbolp default-var)
-                   (read-variable (format "Set variable (default %s): " default-var)
-                                  default-var)
-                 (read-variable "Set variable: ")))
+          (var (if (user-variable-p default-var)
+                  (read-variable (format "Set variable (default %s): " default-var)
+                                 default-var)
+                (read-variable "Set variable: ")))
          (minibuffer-help-form '(describe-variable var))
          (prop (get var 'variable-interactive))
-         (prompt (format "Set %s%s to value: " var
+          (obsolete (car (get var 'byte-obsolete-variable)))
+         (prompt (format "Set %s %s to value: " var
                          (cond ((local-variable-p var)
-                                " (buffer-local)")
+                                "(buffer-local)")
                                ((or current-prefix-arg
                                     (local-variable-if-set-p var))
-                                " buffer-locally")
-                               (t " globally"))))
-         (val (if prop
-                  ;; Use VAR's `variable-interactive' property
-                  ;; as an interactive spec for prompting.
-                  (call-interactively `(lambda (arg)
-                                         (interactive ,prop)
-                                         arg))
-                (read
-                 (read-string prompt nil
-                              'set-variable-value-history)))))
+                                "buffer-locally")
+                               (t "globally"))))
+         (val (progn
+                 (when obsolete
+                   (message (concat "`%S' is obsolete; "
+                                    (if (symbolp obsolete) "use `%S' instead" "%s"))
+                            var obsolete)
+                   (sit-for 3))
+                 (if prop
+                     ;; Use VAR's `variable-interactive' property
+                     ;; as an interactive spec for prompting.
+                     (call-interactively `(lambda (arg)
+                                            (interactive ,prop)
+                                            arg))
+                   (read
+                    (read-string prompt nil
+                                 'set-variable-value-history
+                                (format "%S" (symbol-value var))))))))
      (list var val current-prefix-arg)))
 
-  (and (custom-variable-p var)
-       (not (get var 'custom-type))
-       (custom-load-symbol var))
-  (let ((type (get var 'custom-type)))
+  (and (custom-variable-p variable)
+       (not (get variable 'custom-type))
+       (custom-load-symbol variable))
+  (let ((type (get variable 'custom-type)))
     (when type
       ;; Match with custom type.
       (require 'cus-edit)
       (setq type (widget-convert type))
-      (unless (widget-apply type :match val)
+      (unless (widget-apply type :match value)
        (error "Value `%S' does not match type %S of %S"
-              val (car type) var))))
+              value (car type) variable))))
 
   (if make-local
-      (make-local-variable var))
+      (make-local-variable variable))
 
-  (set var val)
+  (set variable value)
 
   ;; Force a thorough redisplay for the case that the variable
   ;; has an effect on the display, like `tab-width' has.
@@ -4755,7 +4836,7 @@ Use \\<completion-list-mode-map>\\[mouse-choose-completion] to select one\
   (setq major-mode 'completion-list-mode)
   (make-local-variable 'completion-base-size)
   (setq completion-base-size nil)
-  (run-hooks 'completion-list-mode-hook))
+  (run-mode-hooks 'completion-list-mode-hook))
 
 (defun completion-list-mode-finish ()
   "Finish setup of the completions buffer.
@@ -4769,10 +4850,13 @@ Called from `temp-buffer-show-hook'."
   "Normal hook run at the end of setting up a completion list buffer.
 When this hook is run, the current buffer is the one in which the
 command to display the completion list buffer was run.
-The completion list buffer is available as the value of `standard-output'.")
+The completion list buffer is available as the value of `standard-output'.
+The common prefix substring for completion may be available as the 
+value of `completion-common-substring'. See also `display-completion-list'.")
+
+
+;; Variables and faces used in `completion-setup-function'.
 
-;; This function goes in completion-setup-hook, so that it is called
-;; after the text of the completion list buffer is written.
 (defface completions-first-difference
   '((t (:inherit bold)))
   "Face put on the first uncommon character in completions in *Completions* buffer."
@@ -4792,6 +4876,17 @@ of the differing parts is, by contrast, slightly highlighted."
 (defvar completion-root-regexp "^/"
   "Regexp to use in `completion-setup-function' to find the root directory.")
 
+(defvar completion-common-substring nil
+  "Common prefix substring to use in `completion-setup-function' to put faces.
+The value is set by `display-completion-list' during running `completion-setup-hook'.
+
+To put faces, `completions-first-difference' and `completions-common-part' 
+into \"*Completions*\* buffer, the common prefix substring in completions is
+needed as a hint. (Minibuffer is a special case. The content of minibuffer itself 
+is the substring.)")
+
+;; This function goes in completion-setup-hook, so that it is called
+;; after the text of the completion list buffer is written.
 (defun completion-setup-function ()
   (let ((mainbuf (current-buffer))
        (mbuf-contents (minibuffer-contents)))
@@ -4824,11 +4919,17 @@ of the differing parts is, by contrast, slightly highlighted."
                    (- (point) (minibuffer-prompt-end)))))
        ;; Otherwise, in minibuffer, the whole input is being completed.
        (if (minibufferp mainbuf)
-           (setq completion-base-size 0)))
+           (if (and (symbolp minibuffer-completion-table)
+                    (get minibuffer-completion-table 'completion-base-size-function))
+               (setq completion-base-size
+                     (funcall (get minibuffer-completion-table 'completion-base-size-function)))
+             (setq completion-base-size 0))))
       ;; Put faces on first uncommon characters and common parts.
-      (when completion-base-size
+      (when (or completion-common-substring completion-base-size)
        (let* ((common-string-length
-               (- (length mbuf-contents) completion-base-size))
+               (if completion-common-substring
+                   (length completion-common-substring)
+                 (- (length mbuf-contents) completion-base-size)))
               (element-start (next-single-property-change
                               (point-min)
                               'mouse-face))
@@ -4963,7 +5064,7 @@ PREFIX is the string that represents this modifier in an event type symbol."
      (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-space ?\s)
    (kp-tab ?\t)
    (kp-enter ?\r)
    (kp-multiply ?*)
@@ -5095,7 +5196,7 @@ after it has been set up properly in other respects."
 (defun clone-indirect-buffer (newname display-flag &optional norecord)
   "Create an indirect buffer that is a twin copy of the current buffer.
 
-Give the indirect buffer name NEWNAME.  Interactively, read NEW-NAME
+Give the indirect buffer name NEWNAME.  Interactively, read NEWNAME
 from the minibuffer when invoked with a prefix arg.  If NEWNAME is nil
 or if not called with a prefix arg, NEWNAME defaults to the current
 buffer's name.  The name is modified by adding a `<N>' suffix to it
@@ -5104,7 +5205,7 @@ or by incrementing the N in an existing suffix.
 DISPLAY-FLAG non-nil means show the new buffer with `pop-to-buffer'.
 This is always done when called interactively.
 
-Optional last arg NORECORD non-nil means do not put this buffer at the
+Optional third arg NORECORD non-nil means do not put this buffer at the
 front of the list of recently selected ones."
   (interactive
    (progn
@@ -5138,36 +5239,33 @@ the front of the list of recently selected ones."
 \f
 ;;; Handling of Backspace and Delete keys.
 
-(defcustom normal-erase-is-backspace
-  (and (not noninteractive)
-       (or (memq system-type '(ms-dos windows-nt))
-          (eq window-system 'mac)
-          (and (memq window-system '(x))
-               (fboundp 'x-backspace-delete-keys-p)
-               (x-backspace-delete-keys-p))
-          ;; If the terminal Emacs is running on has erase char
-          ;; set to ^H, use the Backspace key for deleting
-          ;; backward and, and the Delete key for deleting forward.
-          (and (null window-system)
-               (eq tty-erase-char ?\^H))))
-  "If non-nil, Delete key deletes forward and Backspace key deletes backward.
-
-On window systems, the default value of this option is chosen
-according to the keyboard used.  If the keyboard has both a Backspace
-key and a Delete key, and both are mapped to their usual meanings, the
-option's default value is set to t, so that Backspace can be used to
-delete backward, and Delete can be used to delete forward.
-
-If not running under a window system, customizing this option accomplishes
-a similar effect by mapping C-h, which is usually generated by the
-Backspace key, to DEL, and by mapping DEL to C-d via
-`keyboard-translate'.  The former functionality of C-h is available on
-the F1 key.  You should probably not use this setting if you don't
-have both Backspace, Delete and F1 keys.
+(defcustom normal-erase-is-backspace 'maybe
+  "Set the default behaviour of the Delete and Backspace keys.
+
+If set to t, Delete key deletes forward and Backspace key deletes
+backward.
+
+If set to nil, both Delete and Backspace keys delete backward.
+
+If set to 'maybe (which is the default), Emacs automatically
+selects a behaviour.  On window systems, the behaviour depends on
+the keyboard used.  If the keyboard has both a Backspace key and
+a Delete key, and both are mapped to their usual meanings, the
+option's default value is set to t, so that Backspace can be used
+to delete backward, and Delete can be used to delete forward.
+
+If not running under a window system, customizing this option
+accomplishes a similar effect by mapping C-h, which is usually
+generated by the Backspace key, to DEL, and by mapping DEL to C-d
+via `keyboard-translate'.  The former functionality of C-h is
+available on the F1 key.  You should probably not use this
+setting if you don't have both Backspace, Delete and F1 keys.
 
 Setting this variable with setq doesn't take effect.  Programmatically,
 call `normal-erase-is-backspace-mode' (which see) instead."
-  :type 'boolean
+  :type '(choice (const :tag "Off" nil)
+                (const :tag "Maybe" maybe)
+                (other :tag "On" t))
   :group 'editing-basics
   :version "21.1"
   :set (lambda (symbol value)
@@ -5177,17 +5275,40 @@ call `normal-erase-is-backspace-mode' (which see) instead."
             (normal-erase-is-backspace-mode (or value 0))
           (set-default symbol value))))
 
+(defun normal-erase-is-backspace-setup-frame (&optional frame)
+  "Set up `normal-erase-is-backspace-mode' on FRAME, if necessary."
+  (unless frame (setq frame (selected-frame)))
+  (with-selected-frame frame
+    (unless (terminal-parameter-p nil 'normal-erase-is-backspace)
+      (if (cond ((terminal-parameter-p nil 'normal-erase-is-backspace)
+                (terminal-parameter nil 'normal-erase-is-backspace))
+               ((eq normal-erase-is-backspace 'maybe)
+                (and (not noninteractive)
+                     (or (memq system-type '(ms-dos windows-nt))
+                         (eq window-system 'mac)
+                         (and (memq window-system '(x))
+                              (fboundp 'x-backspace-delete-keys-p)
+                              (x-backspace-delete-keys-p))
+                         ;; If the terminal Emacs is running on has erase char
+                         ;; set to ^H, use the Backspace key for deleting
+                         ;; backward and, and the Delete key for deleting forward.
+                         (and (null window-system)
+                              (eq tty-erase-char ?\^H)))))
+               (t
+                normal-erase-is-backspace))
+         (normal-erase-is-backspace-mode 1)
+       (normal-erase-is-backspace-mode 0)))))
 
 (defun normal-erase-is-backspace-mode (&optional arg)
   "Toggle the Erase and Delete mode of the Backspace and Delete keys.
 
 With numeric arg, turn the mode on if and only if ARG is positive.
 
-On window systems, when this mode is on, Delete is mapped to C-d and
-Backspace is mapped to DEL; when this mode is off, both Delete and
-Backspace are mapped to DEL.  (The remapping goes via
-`function-key-map', so binding Delete or Backspace in the global or
-local keymap will override that.)
+On window systems, when this mode is on, Delete is mapped to C-d
+and Backspace is mapped to DEL; when this mode is off, both
+Delete and Backspace are mapped to DEL.  (The remapping goes via
+`local-function-key-map', so binding Delete or Backspace in the
+global or local keymap will override that.)
 
 In addition, on window systems, the bindings of C-Delete, M-Delete,
 C-M-Delete, C-Backspace, M-Backspace, and C-M-Backspace are changed in
@@ -5209,32 +5330,33 @@ have both Backspace, Delete and F1 keys.
 
 See also `normal-erase-is-backspace'."
   (interactive "P")
-  (setq normal-erase-is-backspace
-       (if arg
-           (> (prefix-numeric-value arg) 0)
-         (not normal-erase-is-backspace)))
+  (set-terminal-parameter
+   nil 'normal-erase-is-backspace
+   (if arg
+       (> (prefix-numeric-value arg) 0)
+     (not (terminal-parameter nil 'normal-erase-is-backspace))))
 
   (cond ((or (memq window-system '(x w32 mac pc))
             (memq system-type '(ms-dos windows-nt)))
-        (let ((bindings
-               `(([C-delete] [C-backspace])
-                 ([M-delete] [M-backspace])
-                 ([C-M-delete] [C-M-backspace])
-                 (,esc-map
-                  [C-delete] [C-backspace])))
-              (old-state (lookup-key function-key-map [delete])))
-
-          (if normal-erase-is-backspace
+        (let* ((bindings
+                `(([C-delete] [C-backspace])
+                  ([M-delete] [M-backspace])
+                  ([C-M-delete] [C-M-backspace])
+                  (,esc-map
+                   [C-delete] [C-backspace])))
+               (old-state (lookup-key local-function-key-map [delete])))
+
+          (if (terminal-parameter nil 'normal-erase-is-backspace)
               (progn
-                (define-key function-key-map [delete] [?\C-d])
-                (define-key function-key-map [kp-delete] [?\C-d])
-                (define-key function-key-map [backspace] [?\C-?]))
-            (define-key function-key-map [delete] [?\C-?])
-            (define-key function-key-map [kp-delete] [?\C-?])
-            (define-key function-key-map [backspace] [?\C-?]))
+                (define-key local-function-key-map [delete] [?\C-d])
+                (define-key local-function-key-map [kp-delete] [?\C-d])
+                (define-key local-function-key-map [backspace] [?\C-?]))
+            (define-key local-function-key-map [delete] [?\C-?])
+            (define-key local-function-key-map [kp-delete] [?\C-?])
+            (define-key local-function-key-map [backspace] [?\C-?]))
 
           ;; Maybe swap bindings of C-delete and C-backspace, etc.
-          (unless (equal old-state (lookup-key function-key-map [delete]))
+          (unless (equal old-state (lookup-key local-function-key-map [delete]))
             (dolist (binding bindings)
               (let ((map global-map))
                 (when (keymapp (car binding))
@@ -5246,7 +5368,7 @@ See also `normal-erase-is-backspace'."
                   (define-key map key1 binding2)
                   (define-key map key2 binding1)))))))
         (t
-         (if normal-erase-is-backspace
+         (if (terminal-parameter nil 'normal-erase-is-backspace)
              (progn
                (keyboard-translate ?\C-h ?\C-?)
                (keyboard-translate ?\C-? ?\C-d))