Minor idlwave change.
[bpt/emacs.git] / lisp / simple.el
index 48e1148..4d6d42f 100644 (file)
@@ -1,11 +1,12 @@
 ;;; 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, 2006, 2007, 2008, 2009, 2010
-;;   Free Software Foundation, Inc.
+;; Copyright (C) 1985, 1986, 1987, 1993, 1994, 1995, 1996, 1997, 1998,
+;;   1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007, 2008, 2009,
+;;   2010  Free Software Foundation, Inc.
 
 ;; Maintainer: FSF
 ;; Keywords: internal
+;; Package: emacs
 
 ;; This file is part of GNU Emacs.
 
@@ -424,6 +425,19 @@ Other major modes are defined by comparison with this one."
 
 ;; Major mode meant to be the parent of programming modes.
 
+(defvar prog-mode-map
+  (let ((map (make-sparse-keymap)))
+    (define-key map [?\C-\M-q] 'prog-indent-sexp)
+    map)
+  "Keymap used for programming modes.")
+
+(defun prog-indent-sexp ()
+  "Indent the expression after point."
+  (interactive)
+  (let ((start (point))
+        (end (save-excursion (forward-sexp 1) (point))))
+    (indent-region start end nil)))
+
 (define-derived-mode prog-mode fundamental-mode "Prog"
   "Major mode for editing programming language source code."
   (set (make-local-variable 'require-final-newline) mode-require-final-newline)
@@ -443,72 +457,43 @@ Call `auto-fill-function' if the current column number is greater
 than the value of `fill-column' and ARG is nil."
   (interactive "*P")
   (barf-if-buffer-read-only)
-  ;; Inserting a newline at the end of a line produces better redisplay in
-  ;; try_window_id than inserting at the beginning of a line, and the textual
-  ;; result is the same.  So, if we're at beginning of line, pretend to be at
-  ;; the end of the previous line.
-  (let ((flag (and (not (bobp))
-                  (bolp)
-                  ;; Make sure no functions want to be told about
-                  ;; the range of the changes.
-                  (not after-change-functions)
-                  (not before-change-functions)
-                  ;; Make sure there are no markers here.
-                  (not (buffer-has-markers-at (1- (point))))
-                  (not (buffer-has-markers-at (point)))
-                  ;; Make sure no text properties want to know
-                  ;; where the change was.
-                  (not (get-char-property (1- (point)) 'modification-hooks))
-                  (not (get-char-property (1- (point)) 'insert-behind-hooks))
-                  (or (eobp)
-                      (not (get-char-property (point) 'insert-in-front-hooks)))
-                  ;; Make sure the newline before point isn't intangible.
-                  (not (get-char-property (1- (point)) 'intangible))
-                  ;; Make sure the newline before point isn't read-only.
-                  (not (get-char-property (1- (point)) 'read-only))
-                  ;; Make sure the newline before point isn't invisible.
-                  (not (get-char-property (1- (point)) 'invisible))
-                  ;; Make sure the newline before point has the same
-                  ;; properties as the char before it (if any).
-                  (< (or (previous-property-change (point)) -2)
-                     (- (point) 2))))
-       (was-page-start (and (bolp)
-                            (looking-at page-delimiter)))
-       (beforepos (point)))
-    (if flag (backward-char 1))
-    ;; Call self-insert so that auto-fill, abbrev expansion etc. happens.
-    ;; Set last-command-event to tell self-insert what to insert.
-    (let ((last-command-event ?\n)
-         ;; Don't auto-fill if we have a numeric argument.
-         ;; Also not if flag is true (it would fill wrong line);
-         ;; there is no need to since we're at BOL.
-         (auto-fill-function (if (or arg flag) nil auto-fill-function)))
-      (unwind-protect
-         (self-insert-command (prefix-numeric-value arg))
-       ;; If we get an error in self-insert-command, put point at right place.
-       (if flag (forward-char 1))))
-    ;; Even if we did *not* get an error, keep that forward-char;
-    ;; all further processing should apply to the newline that the user
-    ;; thinks he inserted.
-
-    ;; Mark the newline(s) `hard'.
-    (if use-hard-newlines
-       (set-hard-newline-properties
-        (- (point) (prefix-numeric-value arg)) (point)))
-    ;; If the newline leaves the previous line blank,
-    ;; and we have a left margin, delete that from the blank line.
-    (or flag
-       (save-excursion
-         (goto-char beforepos)
-         (beginning-of-line)
-         (and (looking-at "[ \t]$")
-              (> (current-left-margin) 0)
-              (delete-region (point) (progn (end-of-line) (point))))))
-    ;; Indent the line after the newline, except in one case:
-    ;; when we added the newline at the beginning of a line
-    ;; which starts a page.
-    (or was-page-start
-       (move-to-left-margin nil t)))
+  ;; Call self-insert so that auto-fill, abbrev expansion etc. happens.
+  ;; Set last-command-event to tell self-insert what to insert.
+  (let* ((was-page-start (and (bolp) (looking-at page-delimiter)))
+         (beforepos (point))
+         (last-command-event ?\n)
+         ;; Don't auto-fill if we have a numeric argument.
+         (auto-fill-function (if arg nil auto-fill-function))
+         (postproc
+          ;; Do the rest in post-self-insert-hook, because we want to do it
+          ;; *before* other functions on that hook.
+          (lambda ()
+            ;; Mark the newline(s) `hard'.
+            (if use-hard-newlines
+                (set-hard-newline-properties
+                 (- (point) (prefix-numeric-value arg)) (point)))
+            ;; If the newline leaves the previous line blank, and we
+            ;; have a left margin, delete that from the blank line.
+            (save-excursion
+              (goto-char beforepos)
+              (beginning-of-line)
+              (and (looking-at "[ \t]$")
+                   (> (current-left-margin) 0)
+                   (delete-region (point)
+                                  (line-end-position))))
+            ;; Indent the line after the newline, except in one case:
+            ;; when we added the newline at the beginning of a line which
+            ;; starts a page.
+            (or was-page-start
+                (move-to-left-margin nil t)))))
+    (unwind-protect
+        (progn
+          (add-hook 'post-self-insert-hook postproc)
+          (self-insert-command (prefix-numeric-value arg)))
+      ;; We first used let-binding to protect the hook, but that was naive
+      ;; since add-hook affects the symbol-default value of the variable,
+      ;; whereas the let-binding might only protect the buffer-local value.
+      (remove-hook 'post-self-insert-hook postproc)))
   nil)
 
 (defun set-hard-newline-properties (from to)
@@ -790,15 +775,16 @@ If BACKWARD-ONLY is non-nil, only delete them before point."
        (constrain-to-field nil orig-pos t)))))
 \f
 (defun beginning-of-buffer (&optional arg)
-  "Move point to the beginning of the buffer; leave mark at previous position.
-With \\[universal-argument] prefix, do not set mark at previous position.
+  "Move point to the beginning of the buffer.
 With numeric arg N, put point N/10 of the way from the beginning.
+If the buffer is narrowed, this command uses the beginning of the
+accessible part of the buffer.
 
-If the buffer is narrowed, this command uses the beginning and size
-of the accessible part of the buffer.
+If Transient Mark mode is disabled, leave mark at previous
+position, unless a \\[universal-argument] prefix is supplied.
 
 Don't use this command in Lisp programs!
-\(goto-char (point-min)) is faster and avoids clobbering the mark."
+\(goto-char (point-min)) is faster."
   (interactive "^P")
   (or (consp arg)
       (region-active-p)
@@ -815,15 +801,16 @@ Don't use this command in Lisp programs!
   (if (and arg (not (consp arg))) (forward-line 1)))
 
 (defun end-of-buffer (&optional arg)
-  "Move point to the end of the buffer; leave mark at previous position.
-With \\[universal-argument] prefix, do not set mark at previous position.
+  "Move point to the end of the buffer.
 With numeric arg N, put point N/10 of the way from the end.
+If the buffer is narrowed, this command uses the end of the
+accessible part of the buffer.
 
-If the buffer is narrowed, this command uses the beginning and size
-of the accessible part of the buffer.
+If Transient Mark mode is disabled, leave mark at previous
+position, unless a \\[universal-argument] prefix is supplied.
 
 Don't use this command in Lisp programs!
-\(goto-char (point-max)) is faster and avoids clobbering the mark."
+\(goto-char (point-max)) is faster."
   (interactive "^P")
   (or (consp arg) (region-active-p) (push-mark))
   (let ((size (- (point-max) (point-min))))
@@ -844,6 +831,78 @@ Don't use this command in Lisp programs!
         (overlay-recenter (point))
         (recenter -3))))
 
+(defcustom delete-active-region t
+  "Whether single-char deletion commands delete an active region.
+This has an effect only if Transient Mark mode is enabled, and
+affects `delete-forward-char' and `delete-backward-char', though
+not `delete-char'.
+
+If the value is the symbol `kill', the active region is killed
+instead of deleted."
+  :type '(choice (const :tag "Delete active region" t)
+                 (const :tag "Kill active region" kill)
+                 (const :tag "Do ordinary deletion" nil))
+  :group 'editing
+  :version "24.1")
+
+(defun delete-backward-char (n &optional killflag)
+  "Delete the previous N characters (following if N is negative).
+If Transient Mark mode is enabled, the mark is active, and N is 1,
+delete the text in the region and deactivate the mark instead.
+To disable this, set `delete-active-region' to nil.
+
+Optional second arg KILLFLAG, if non-nil, means to kill (save in
+kill ring) instead of delete.  Interactively, N is the prefix
+arg, and KILLFLAG is set if N is explicitly specified.
+
+In Overwrite mode, single character backward deletion may replace
+tabs with spaces so as to back over columns, unless point is at
+the end of the line."
+  (interactive "p\nP")
+  (unless (integerp n)
+    (signal 'wrong-type-argument (list 'integerp n)))
+  (cond ((and (use-region-p)
+             delete-active-region
+             (= n 1))
+        ;; If a region is active, kill or delete it.
+        (if (eq delete-active-region 'kill)
+            (kill-region (region-beginning) (region-end))
+          (delete-region (region-beginning) (region-end))))
+       ;; In Overwrite mode, maybe untabify while deleting
+       ((null (or (null overwrite-mode)
+                  (<= n 0)
+                  (memq (char-before) '(?\t ?\n))
+                  (eobp)
+                  (eq (char-after) ?\n)))
+        (let* ((ocol (current-column))
+               (val (delete-char (- n) killflag)))
+          (save-excursion
+            (insert-char ?\s (- ocol (current-column)) nil))))
+       ;; Otherwise, do simple deletion.
+       (t (delete-char (- n) killflag))))
+
+(defun delete-forward-char (n &optional killflag)
+  "Delete the following N characters (previous if N is negative).
+If Transient Mark mode is enabled, the mark is active, and N is 1,
+delete the text in the region and deactivate the mark instead.
+To disable this, set `delete-active-region' to nil.
+
+Optional second arg KILLFLAG non-nil means to kill (save in kill
+ring) instead of delete.  Interactively, N is the prefix arg, and
+KILLFLAG is set if N was explicitly specified."
+  (interactive "p\nP")
+  (unless (integerp n)
+    (signal 'wrong-type-argument (list 'integerp n)))
+  (cond ((and (use-region-p)
+             delete-active-region
+             (= n 1))
+        ;; If a region is active, kill or delete it.
+        (if (eq delete-active-region 'kill)
+            (kill-region (region-beginning) (region-end))
+          (delete-region (region-beginning) (region-end))))
+       ;; Otherwise, do simple deletion.
+       (t (delete-char n killflag))))
+
 (defun mark-whole-buffer ()
   "Put point at beginning and mark at end of buffer.
 You probably should not use this function in Lisp programs;
@@ -1216,6 +1275,40 @@ to get different commands to edit and resubmit."
       (if command-history
          (error "Argument %d is beyond length of command history" arg)
        (error "There are no previous complex commands to repeat")))))
+
+(defun read-extended-command ()
+  "Read command name to invoke in `execute-extended-command'."
+  (minibuffer-with-setup-hook
+      (lambda ()
+       (set (make-local-variable 'minibuffer-default-add-function)
+            (lambda ()
+              ;; Get a command name at point in the original buffer
+              ;; to propose it after M-n.
+              (with-current-buffer (window-buffer (minibuffer-selected-window))
+                (and (commandp (function-called-at-point))
+                     (format "%S" (function-called-at-point)))))))
+    ;; Read a string, completing from and restricting to the set of
+    ;; all defined commands.  Don't provide any initial input.
+    ;; Save the command read on the extended-command history list.
+    (completing-read
+     (concat (cond
+             ((eq current-prefix-arg '-) "- ")
+             ((and (consp current-prefix-arg)
+                   (eq (car current-prefix-arg) 4)) "C-u ")
+             ((and (consp current-prefix-arg)
+                   (integerp (car current-prefix-arg)))
+              (format "%d " (car current-prefix-arg)))
+             ((integerp current-prefix-arg)
+              (format "%d " current-prefix-arg)))
+            ;; This isn't strictly correct if `execute-extended-command'
+            ;; is bound to anything else (e.g. [menu]).
+            ;; It could use (key-description (this-single-command-keys)),
+            ;; but actually a prompt other than "M-x" would be confusing,
+            ;; because "M-x" is a well-known prompt to read a command
+            ;; and it serves as a shorthand for "Extended command: ".
+            "M-x ")
+     obarray 'commandp t nil 'extended-command-history)))
+
 \f
 (defvar minibuffer-history nil
   "Default minibuffer history list.
@@ -2807,11 +2900,8 @@ 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 or two arguments.
-The first argument, TEXT, is a string containing
-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.")
+The function takes one argument, TEXT, which is a string containing
+the text which should be made available.")
 
 (defvar interprogram-paste-function nil
   "Function to call to get text cut from other programs.
@@ -2905,27 +2995,30 @@ argument should still be a \"useful\" string for such uses."
     (if yank-handler
        (signal 'args-out-of-range
                (list string "yank-handler specified for empty string"))))
-  (when (and kill-do-not-save-duplicates
-             (equal string (car kill-ring)))
-    (setq replace t))
-  (if (fboundp 'menu-bar-update-yank-menu)
-      (menu-bar-update-yank-menu string (and replace (car kill-ring))))
+  (unless (and kill-do-not-save-duplicates
+              (equal string (car kill-ring)))
+    (if (fboundp 'menu-bar-update-yank-menu)
+       (menu-bar-update-yank-menu string (and replace (car kill-ring)))))
   (when save-interprogram-paste-before-kill
     (let ((interprogram-paste (and interprogram-paste-function
                                    (funcall interprogram-paste-function))))
       (when interprogram-paste
-        (if (listp interprogram-paste)
-            (dolist (s (nreverse interprogram-paste))
-              (push s kill-ring))
-            (push interprogram-paste kill-ring)))))
-  (if (and replace kill-ring)
-      (setcar kill-ring string)
-    (push string kill-ring)
-    (if (> (length kill-ring) kill-ring-max)
-       (setcdr (nthcdr (1- kill-ring-max) kill-ring) nil)))
+        (dolist (s (if (listp interprogram-paste)
+                      (nreverse interprogram-paste)
+                    (list interprogram-paste)))
+         (unless (and kill-do-not-save-duplicates
+                      (equal s (car kill-ring)))
+           (push s kill-ring))))))
+  (unless (and kill-do-not-save-duplicates
+              (equal string (car kill-ring)))
+    (if (and replace kill-ring)
+       (setcar kill-ring string)
+      (push string kill-ring)
+      (if (> (length kill-ring) kill-ring-max)
+         (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 (not replace))))
+      (funcall interprogram-cut-function string)))
 
 (defun kill-append (string before-p &optional yank-handler)
   "Append STRING to the end of the latest kill in the kill ring.
@@ -3015,7 +3108,8 @@ 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).
+Lisp programs should use this function for killing text.
+ (To delete text, use `delete-region'.)
 Supply two arguments, character positions indicating the stretch of text
  to be killed.
 Any command that calls this function is a \"kill command\".
@@ -3591,29 +3685,28 @@ a mistake; see the documentation of `set-mark'."
       (marker-position (mark-marker))
     (signal 'mark-inactive nil)))
 
-(defcustom select-active-regions nil
-  "If non-nil, an active region automatically becomes the window selection."
-  :type 'boolean
-  :group 'killing
-  :version "23.1")
-
-(declare-function x-selection-owner-p "xselect.c" (&optional selection))
-
-;; Many places set mark-active directly, and several of them failed to also
-;; run deactivate-mark-hook.  This shorthand should simplify.
 (defsubst deactivate-mark (&optional force)
   "Deactivate the mark by setting `mark-active' to nil.
 Unless FORCE is non-nil, this function does nothing if Transient
 Mark mode is disabled.
 This function also runs `deactivate-mark-hook'."
   (when (or transient-mark-mode force)
-    ;; Copy the latest region into the primary selection, if desired.
-    (and select-active-regions
-        mark-active
-        (display-selections-p)
-        (x-selection-owner-p 'PRIMARY)
-        (x-set-selection 'PRIMARY (buffer-substring-no-properties
-                                   (region-beginning) (region-end))))
+    (when (and (if (eq select-active-regions 'only)
+                  (eq (car-safe transient-mark-mode) 'only)
+                select-active-regions)
+              (region-active-p)
+              (display-selections-p))
+      ;; The var `saved-region-selection', if non-nil, is the text in
+      ;; the region prior to the last command modifying the buffer.
+      ;; Set the selection to that, or to the current region.
+      (cond (saved-region-selection
+            (x-set-selection 'PRIMARY saved-region-selection)
+            (setq saved-region-selection nil))
+           ((/= (region-beginning) (region-end))
+            (x-set-selection 'PRIMARY
+                             (buffer-substring-no-properties
+                              (region-beginning)
+                              (region-end))))))
     (if (and (null force)
             (or (eq transient-mark-mode 'lambda)
                 (and (eq (car-safe transient-mark-mode) 'only)
@@ -3631,10 +3724,7 @@ This function also runs `deactivate-mark-hook'."
   (when (mark t)
     (setq mark-active t)
     (unless transient-mark-mode
-      (setq transient-mark-mode 'lambda))
-    (when (and select-active-regions
-              (display-selections-p))
-      (x-set-selection 'PRIMARY (current-buffer)))))
+      (setq transient-mark-mode 'lambda))))
 
 (defun set-mark (pos)
   "Set this buffer's mark to POS.  Don't use this function!
@@ -3657,9 +3747,6 @@ store it in a Lisp variable.  Example:
       (progn
        (setq mark-active t)
        (run-hooks 'activate-mark-hook)
-       (when (and select-active-regions
-                  (display-selections-p))
-         (x-set-selection 'PRIMARY (current-buffer)))
        (set-marker (mark-marker) pos (current-buffer)))
     ;; Normally we never clear mark-active except in Transient Mark mode.
     ;; But when we actually clear out the mark value too, we must
@@ -3685,10 +3772,9 @@ point otherwise."
 This is used by commands that act specially on the region under
 Transient Mark mode.
 
-The return value is t provided Transient Mark mode is enabled and
-the mark is active; and, when `use-empty-active-region' is
-non-nil, provided the region is empty.  Otherwise, the return
-value is nil.
+The return value is t if Transient Mark mode is enabled and the
+mark is active; furthermore, if `use-empty-active-region' is nil,
+the region must not be empty.  Otherwise, the return value is nil.
 
 For some commands, it may be appropriate to ignore the value of
 `use-empty-active-region'; in that case, use `region-active-p'."
@@ -3874,7 +3960,8 @@ Does not set point.  Does nothing if mark ring is empty."
     (setq mark-ring (cdr mark-ring)))
   (deactivate-mark))
 
-(defalias 'exchange-dot-and-mark 'exchange-point-and-mark)
+(define-obsolete-function-alias
+  'exchange-dot-and-mark 'exchange-point-and-mark "23.3")
 (defun exchange-point-and-mark (&optional arg)
   "Put the mark where point is now, and point where the mark is now.
 This command works even when the mark is not active,
@@ -3932,8 +4019,8 @@ deactivate it, and restore the variable `transient-mark-mode' to
 its earlier value."
   (cond ((and shift-select-mode this-command-keys-shift-translated)
          (unless (and mark-active
-                      (eq (car-safe transient-mark-mode) 'only))
-           (setq transient-mark-mode
+                     (eq (car-safe transient-mark-mode) 'only))
+          (setq transient-mark-mode
                  (cons 'only
                        (unless (eq transient-mark-mode 'lambda)
                          transient-mark-mode)))
@@ -3964,29 +4051,8 @@ Invoke \\[apropos-documentation] and type \"transient\" or
 \"mark.*active\" at the prompt, to see the documentation of
 commands which are sensitive to the Transient Mark mode."
   :global t
-  :init-value (not noninteractive)
-  :initialize 'custom-initialize-delay
-  :group 'editing-basics)
-
-;; The variable transient-mark-mode is ugly: it can take on special
-;; values.  Document these here.
-(defvar transient-mark-mode t
-  "*Non-nil if Transient Mark mode is enabled.
-See the command `transient-mark-mode' for a description of this minor mode.
-
-Non-nil also enables highlighting of the region whenever the mark is active.
-The variable `highlight-nonselected-windows' controls whether to highlight
-all windows or just the selected window.
-
-If the value is `lambda', that enables Transient Mark mode temporarily.
-After any subsequent action that would normally deactivate the mark
-\(such as buffer modification), Transient Mark mode is turned off.
-
-If the value is (only . OLDVAL), that enables Transient Mark mode
-temporarily.  After any subsequent point motion command that is not
-shift-translated, or any other action that would normally deactivate
-the mark (such as buffer modification), the value of
-`transient-mark-mode' is set to OLDVAL.")
+  ;; It's defined in C/cus-start, this stops the d-m-m macro defining it again.
+  :variable transient-mark-mode)
 
 (defvar widen-automatically t
   "Non-nil means it is ok for commands to call `widen' when they want to.
@@ -4254,7 +4320,7 @@ into account variable-width characters and line continuation."
     (or (and (= (vertical-motion
                 (cons (or goal-column
                           (if (consp temporary-goal-column)
-                              (truncate (car temporary-goal-column))
+                              (car temporary-goal-column)
                             temporary-goal-column))
                       arg))
                arg)
@@ -4321,7 +4387,7 @@ into account variable-width characters and line continuation."
                  (goto-char (next-char-property-change (point))))
                ;; Move a line.
                ;; We don't use `end-of-line', since we want to escape
-               ;; from field boundaries ocurring exactly at point.
+               ;; from field boundaries occurring exactly at point.
                (goto-char (constrain-to-field
                            (let ((inhibit-field-text-motion t))
                              (line-end-position))
@@ -4539,6 +4605,9 @@ rests."
               (let ((goal-column 0)
                     (line-move-visual nil))
                 (and (line-move arg t)
+                     ;; With bidi reordering, we may not be at bol,
+                     ;; so make sure we are.
+                     (skip-chars-backward "^\n")
                      (not (bobp))
                      (progn
                        (while (and (not (bobp)) (invisible-p (1- (point))))
@@ -5382,21 +5451,40 @@ it skips the contents of comments that end before point."
   :type 'boolean
   :group 'paren-blinking)
 
+(defun blink-matching-check-mismatch (start end)
+  "Return whether or not START...END are matching parens.
+END is the current point and START is the blink position.
+START might be nil if no matching starter was found.
+Returns non-nil if we find there is a mismatch."
+  (let* ((end-syntax (syntax-after (1- end)))
+         (matching-paren (and (consp end-syntax)
+                              (eq (syntax-class end-syntax) 5)
+                              (cdr end-syntax))))
+    ;; For self-matched chars like " and $, we can't know when they're
+    ;; mismatched or unmatched, so we can only do it for parens.
+    (when matching-paren
+      (not (and start
+                (or
+                 (eq (char-after start) matching-paren)
+                 ;; The cdr might hold a new paren-class info rather than
+                 ;; a matching-char info, in which case the two CDRs
+                 ;; should match.
+                 (eq matching-paren (cdr-safe (syntax-after start)))))))))
+
+(defvar blink-matching-check-function #'blink-matching-check-mismatch
+  "Function to check parentheses mismatches.
+The function takes two arguments (START and END) where START is the
+position just before the opening token and END is the position right after.
+START can be nil, if it was not found.
+The function should return non-nil if the two tokens do not match.")
+
 (defun blink-matching-open ()
   "Move cursor momentarily to the beginning of the sexp before point."
   (interactive)
-  (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))))))
+  (when (and (not (bobp))
+            blink-matching-paren)
     (let* ((oldpos (point))
-          (message-log-max nil)  ; Don't log messages about paren matching.
-          (atdollar (eq (syntax-class (syntax-after (1- oldpos))) 8))
-          (isdollar)
+          (message-log-max nil) ; Don't log messages about paren matching.
           (blinkpos
             (save-excursion
               (save-restriction
@@ -5409,38 +5497,29 @@ it skips the contents of comments that end before point."
                        (and parse-sexp-ignore-comments
                             (not blink-matching-paren-dont-ignore-comments))))
                   (condition-case ()
-                      (scan-sexps oldpos -1)
+                      (progn
+                        (forward-sexp -1)
+                        ;; backward-sexp skips backward over prefix chars,
+                        ;; so move back to the matching paren.
+                        (while (and (< (point) (1- oldpos))
+                                    (let ((code (syntax-after (point))))
+                                      (or (eq (syntax-class code) 6)
+                                          (eq (logand 1048576 (car code))
+                                              1048576))))
+                          (forward-char 1))
+                        (point))
                     (error nil))))))
-          (matching-paren
-            (and blinkpos
-                 ;; Not syntax '$'.
-                 (not (setq isdollar
-                            (eq (syntax-class (syntax-after blinkpos)) 8)))
-                 (let ((syntax (syntax-after blinkpos)))
-                   (and (consp syntax)
-                        (eq (syntax-class syntax) 4)
-                        (cdr syntax))))))
+           (mismatch (funcall blink-matching-check-function blinkpos oldpos)))
       (cond
-       ;; isdollar is for:
-       ;; http://lists.gnu.org/archive/html/emacs-devel/2007-10/msg00871.html
-       ((not (or (and isdollar blinkpos)
-                 (and atdollar (not blinkpos)) ; see below
-                 (eq matching-paren (char-before oldpos))
-                 ;; The cdr might hold a new paren-class info rather than
-                 ;; a matching-char info, in which case the two CDRs
-                 ;; should match.
-                 (eq matching-paren (cdr (syntax-after (1- oldpos))))))
-       (if (minibufferp)
-           (minibuffer-message " [Mismatched parentheses]")
-         (message "Mismatched parentheses")))
-       ((not blinkpos)
-        (or blink-matching-paren-distance
-            ;; Don't complain when `$' with no blinkpos, because it
-            ;; could just be the first one typed in the buffer.
-            atdollar
+       (mismatch
+        (if blinkpos
             (if (minibufferp)
-               (minibuffer-message " [Unmatched parenthesis]")
-             (message "Unmatched parenthesis"))))
+                (minibuffer-message " [Mismatched parentheses]")
+              (message "Mismatched parentheses"))
+          (if (minibufferp)
+              (minibuffer-message " [Unmatched parenthesis]")
+            (message "Unmatched parenthesis"))))
+       ((not blinkpos) nil)
        ((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.
@@ -5483,7 +5562,29 @@ it skips the contents of comments that end before point."
             (message "Matches %s"
                      (substring-no-properties open-paren-line-string)))))))))
 
-(setq blink-paren-function 'blink-matching-open)
+(defvar blink-paren-function 'blink-matching-open
+  "Function called, if non-nil, whenever a close parenthesis is inserted.
+More precisely, a char with closeparen syntax is self-inserted.")
+
+(defun blink-paren-post-self-insert-function ()
+  (when (and (eq (char-before) last-command-event) ; Sanity check.
+             (memq (char-syntax last-command-event) '(?\) ?\$))
+             blink-paren-function
+             (not executing-kbd-macro)
+             (not noninteractive)
+            ;; Verify an even number of quoting characters precede the close.
+            (= 1 (logand 1 (- (point)
+                              (save-excursion
+                                (forward-char -1)
+                                (skip-syntax-backward "/\\")
+                                (point))))))
+    (funcall blink-paren-function)))
+
+(add-hook 'post-self-insert-hook #'blink-paren-post-self-insert-function
+          ;; Most likely, this hook is nil, so this arg doesn't matter,
+          ;; but I use it as a reminder that this function usually
+          ;; likes to be run after others since it does `sit-for'.
+          'append)
 \f
 ;; This executes C-g typed while Emacs is waiting for a command.
 ;; Quitting out of a program does not go through here;
@@ -5493,7 +5594,10 @@ it skips the contents of comments that end before point."
 During execution of Lisp code, this character causes a quit directly.
 At top-level, as an editor command, this simply beeps."
   (interactive)
-  (deactivate-mark)
+  ;; Avoid adding the region to the window selection.
+  (setq saved-region-selection nil)
+  (let (select-active-regions)
+    (deactivate-mark))
   (if (fboundp 'kmacro-keyboard-quit)
       (kmacro-keyboard-quit))
   (setq defining-kbd-macro nil)
@@ -5692,7 +5796,7 @@ Each action has the form (FUNCTION . ARGS)."
 The default mail mode is now Message mode.
 You have the following Mail mode variable%s customized:
 \n  %s\n\nTo use Mail mode, set `mail-user-agent' to sendmail-user-agent.
-To disable this warning, set `compose-mail-check-user-agent' to nil."
+To disable this warning, set `compose-mail-user-agent-warnings' to nil."
                                    (if (> (length warn-vars) 1) "s" "")
                                    (mapconcat 'symbol-name
                                               warn-vars " "))))))
@@ -6444,6 +6548,7 @@ call `normal-erase-is-backspace-mode' (which see) instead."
        (if (if (eq normal-erase-is-backspace 'maybe)
                (and (not noninteractive)
                     (or (memq system-type '(ms-dos windows-nt))
+                       (memq window-system '(ns))
                         (and (memq window-system '(x))
                              (fboundp 'x-backspace-delete-keys-p)
                              (x-backspace-delete-keys-p))
@@ -6500,7 +6605,7 @@ See also `normal-erase-is-backspace'."
 
             (if enabled
                 (progn
-                  (define-key local-function-key-map [delete] [?\C-d])
+                  (define-key local-function-key-map [delete] [deletechar])
                   (define-key local-function-key-map [kp-delete] [?\C-d])
                   (define-key local-function-key-map [backspace] [?\C-?])
                    (dolist (b bindings)
@@ -6636,5 +6741,4 @@ warning using STRING as the message.")
 
 (provide 'simple)
 
-;; arch-tag: 24af67c0-2a49-44f6-b3b1-312d8b570dfd
 ;;; simple.el ends here