emacs-diffs
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Emacs-diffs] /srv/bzr/emacs/trunk r110616: * lisp/delsel.el (delete-sel


From: Stefan Monnier
Subject: [Emacs-diffs] /srv/bzr/emacs/trunk r110616: * lisp/delsel.el (delete-selection-helper): New function, extracted from
Date: Sun, 21 Oct 2012 23:15:44 -0400
User-agent: Bazaar (2.5.0)

------------------------------------------------------------
revno: 110616
fixes bug: http://debbugs.gnu.org/cgi/bugreport.cgi?bug=11520
author: Simon Law <address@hidden>
committer: Stefan Monnier <address@hidden>
branch nick: trunk
timestamp: Sun 2012-10-21 23:15:44 -0400
message:
  * lisp/delsel.el (delete-selection-helper): New function, extracted from
  delete-selection-pre-hook.
  (delete-selection-pre-hook): Use it.
  (delete-selection-self-insert-function): New function.
  (delete-selection-self-insert-hooks): New hook.
  (self-insert-command, self-insert-iso): Use it.
  * lisp/electric.el (electric-pair-syntax): New function, extracted from
  electric-pair-post-self-insert-function.
  (electric-pair-post-self-insert-function): Use it.
  (electric-pair-delete-selection-self-insert-function): New function.
  (electric-pair-mode): Require delsel and setup
  delete-selection-self-insert-hooks.
modified:
  lisp/ChangeLog
  lisp/delsel.el
  lisp/electric.el
=== modified file 'lisp/ChangeLog'
--- a/lisp/ChangeLog    2012-10-20 12:04:45 +0000
+++ b/lisp/ChangeLog    2012-10-22 03:15:44 +0000
@@ -1,3 +1,18 @@
+2012-10-22  Simon Law  <address@hidden>  (tiny change)
+
+       * delsel.el (delete-selection-helper): New function, extracted from
+       delete-selection-pre-hook.
+       (delete-selection-pre-hook): Use it.
+       (delete-selection-self-insert-function): New function.
+       (delete-selection-self-insert-hooks): New hook.
+       (self-insert-command, self-insert-iso): Use it.
+       * electric.el (electric-pair-syntax): New function, extracted from
+       electric-pair-post-self-insert-function.
+       (electric-pair-post-self-insert-function): Use it.
+       (electric-pair-delete-selection-self-insert-function): New function.
+       (electric-pair-mode): Require delsel and setup
+       delete-selection-self-insert-hooks (bug#11520).
+
 2012-10-20  Chong Yidong  <address@hidden>
 
        * vc/vc.el (vc-diff-internal): Set up Diff mode even if there are
@@ -8,8 +23,8 @@
 
 2012-10-20  Arne Jørgensen  <address@hidden>
 
-       * progmodes/flymake.el (flymake-create-temp-inplace): Use
-       file-truename.
+       * progmodes/flymake.el (flymake-create-temp-inplace):
+       Use file-truename.
 
 2012-10-20  Eli Zaretskii  <address@hidden>
 

=== modified file 'lisp/delsel.el'
--- a/lisp/delsel.el    2012-08-09 02:18:50 +0000
+++ b/lisp/delsel.el    2012-10-22 03:15:44 +0000
@@ -47,6 +47,9 @@
 ;;  non-nil
 ;;      The normal case: delete the active region prior to executing
 ;;      the command which will insert replacement text.
+;;  hooks
+;;      For commands which need to dynamically determine this behaviour.
+;;      Each hook should return one of the above values or nil.
 
 ;;; Code:
 
@@ -71,66 +74,106 @@
     (transient-mark-mode t)))
 
 (defun delete-active-region (&optional killp)
+  "Delete the active region.
+If KILLP in not-nil, the active region is killed instead of deleted."
   (if killp
       (kill-region (point) (mark))
     (delete-region (point) (mark)))
   t)
 
+(defun delete-selection-helper (type)
+  "Deletes selection according to TYPE:
+ 'yank
+     For commands which do a yank; ensures the region about to be
+     deleted isn't yanked.
+ 'supersede
+     Delete the active region and ignore the current command,
+     i.e. the command will just delete the region.
+ 'kill
+     `kill-region' is used on the selection, rather than
+     `delete-region'.  (Text selected with the mouse will typically
+     be yankable anyhow.)
+ non-nil
+     The normal case: delete the active region prior to executing
+     the command which will insert replacement text.
+ hooks
+     For commands which need to dynamically determine this behaviour.
+     Each hook should return one of the above values or nil."
+  (condition-case data
+      (cond ((eq type 'kill)
+            (delete-active-region t))
+           ((eq type 'yank)
+            ;; Before a yank command, make sure we don't yank the
+            ;; head of the kill-ring that really comes from the
+            ;; currently active region we are going to delete.
+            ;; That would make yank a no-op.
+            (when (and (string= (buffer-substring-no-properties
+                                 (point) (mark))
+                                (car kill-ring))
+                       (fboundp 'mouse-region-match)
+                       (mouse-region-match))
+              (current-kill 1))
+            (delete-active-region))
+           ((eq type 'supersede)
+            (let ((empty-region (= (point) (mark))))
+              (delete-active-region)
+              (unless empty-region
+                (setq this-command 'ignore))))
+           ((and (symbolp type) (not (booleanp type)))
+            (delete-selection-helper
+             (run-hook-with-args-until-success type)))
+           (type
+            (delete-active-region)
+            (if (and overwrite-mode
+                     (eq this-command 'self-insert-command))
+                (let ((overwrite-mode nil))
+                  (self-insert-command
+                   (prefix-numeric-value current-prefix-arg))
+                  (setq this-command 'ignore)))))
+    ;; If ask-user-about-supersession-threat signals an error,
+    ;; stop safe_run_hooks from clearing out pre-command-hook.
+    (file-supersession (message "%s" (cadr data)) (ding))
+    (text-read-only
+     ;; This signal may come either from `delete-active-region' or
+     ;; `self-insert-command' (when `overwrite-mode' is non-nil).
+     ;; To avoid clearing out `pre-command-hook' we handle this case
+     ;; by issuing a simple message.  Note, however, that we do not
+     ;; handle all related problems: When read-only text ends before
+     ;; the end of the region, the latter is not deleted but any
+     ;; subsequent insertion will succeed.  We could avoid this case
+     ;; by doing a (setq this-command 'ignore) here.  This would,
+     ;; however, still not handle the case where read-only text ends
+     ;; precisely where the region starts: In that case the deletion
+     ;; would succeed but the subsequent insertion would fail with a
+     ;; text-read-only error.  To handle that case we would have to
+     ;; investigate text properties at both ends of the region and
+     ;; skip the deletion when inserting text is forbidden there.
+     (message "Text is read-only") (ding))))
+
 (defun delete-selection-pre-hook ()
+  "Normal hook run before commands that delete selections are executed.
+Commands which will delete the selection need a 'delete-selection
+property on their symbols; commands which insert text but don't
+have this property won't delete the selection.
+
+See `delete-selection-helper'.
+"
   (when (and delete-selection-mode transient-mark-mode mark-active
             (not buffer-read-only))
     (let ((type (and (symbolp this-command)
                     (get this-command 'delete-selection))))
-      (condition-case data
-         (cond ((eq type 'kill)
-                (delete-active-region t))
-               ((eq type 'yank)
-                ;; Before a yank command, make sure we don't yank the
-                ;; head of the kill-ring that really comes from the
-                ;; currently active region we are going to delete.
-                ;; That would make yank a no-op.
-                (when (and (string= (buffer-substring-no-properties
-                                      (point) (mark))
-                                    (car kill-ring))
-                           (fboundp 'mouse-region-match)
-                           (mouse-region-match))
-                  (current-kill 1))
-                (delete-active-region))
-               ((eq type 'supersede)
-                (let ((empty-region (= (point) (mark))))
-                  (delete-active-region)
-                  (unless empty-region
-                    (setq this-command 'ignore))))
-               (type
-                (delete-active-region)
-                (if (and overwrite-mode
-                          (eq this-command 'self-insert-command))
-                  (let ((overwrite-mode nil))
-                    (self-insert-command
-                      (prefix-numeric-value current-prefix-arg))
-                    (setq this-command 'ignore)))))
-        ;; If ask-user-about-supersession-threat signals an error,
-        ;; stop safe_run_hooks from clearing out pre-command-hook.
-       (file-supersession (message "%s" (cadr data)) (ding))
-       (text-read-only
-        ;; This signal may come either from `delete-active-region' or
-        ;; `self-insert-command' (when `overwrite-mode' is non-nil).
-        ;; To avoid clearing out `pre-command-hook' we handle this case
-        ;; by issuing a simple message.  Note, however, that we do not
-        ;; handle all related problems: When read-only text ends before
-        ;; the end of the region, the latter is not deleted but any
-        ;; subsequent insertion will succeed.  We could avoid this case
-        ;; by doing a (setq this-command 'ignore) here.  This would,
-        ;; however, still not handle the case where read-only text ends
-        ;; precisely where the region starts: In that case the deletion
-        ;; would succeed but the subsequent insertion would fail with a
-        ;; text-read-only error.  To handle that case we would have to
-        ;; investigate text properties at both ends of the region and
-        ;; skip the deletion when inserting text is forbidden there.
-        (message "Text is read-only") (ding))))))
-
-(put 'self-insert-command 'delete-selection t)
-(put 'self-insert-iso 'delete-selection t)
+      (delete-selection-helper type))))
+
+(defun delete-selection-self-insert-function ()
+  t)
+
+(defvar delete-selection-self-insert-hooks
+  '(delete-selection-self-insert-function)
+  "Abnormal hook run before commands that insert characters.
+This hook should return a TYPE that `delete-selection-helper' understands.")
+
+(put 'self-insert-command 'delete-selection 
'delete-selection-self-insert-hooks)
+(put 'self-insert-iso 'delete-selection 'delete-selection-self-insert-hooks)
 
 (put 'yank 'delete-selection 'yank)
 (put 'clipboard-yank 'delete-selection 'yank)

=== modified file 'lisp/electric.el'
--- a/lisp/electric.el  2012-07-14 05:32:23 +0000
+++ b/lisp/electric.el  2012-10-22 03:15:44 +0000
@@ -301,14 +301,17 @@
   :version "24.1"
   :type 'boolean)
 
+(defun electric-pair-syntax (command-event)
+  (and electric-pair-mode
+       (let ((x (assq command-event electric-pair-pairs)))
+        (cond
+         (x (if (eq (car x) (cdr x)) ?\" ?\())
+         ((rassq command-event electric-pair-pairs) ?\))
+         (t (char-syntax command-event))))))
+
 (defun electric-pair-post-self-insert-function ()
   (let* ((syntax (and (eq (char-before) last-command-event) ; Sanity check.
-                      electric-pair-mode
-                      (let ((x (assq last-command-event electric-pair-pairs)))
-                        (cond
-                         (x (if (eq (car x) (cdr x)) ?\" ?\())
-                         ((rassq last-command-event electric-pair-pairs) ?\))
-                         (t (char-syntax last-command-event))))))
+                     (electric-pair-syntax last-command-event)))
          ;; FIXME: when inserting the closer, we should maybe use
          ;; self-insert-command, although it may prove tricky running
          ;; post-self-insert-hook recursively, and we wouldn't want to trigger
@@ -355,6 +358,12 @@
                (eq (char-syntax (following-char)) ?w)))
       (save-excursion (insert closer))))))
 
+(defun electric-pair-delete-selection-self-insert-function ()
+  (let ((syntax (electric-pair-syntax last-command-event)))
+    (if (and (memq syntax '(?\( ?\" ?\$)) (use-region-p))
+       'keep
+      t)))
+
 ;;;###autoload
 (define-minor-mode electric-pair-mode
   "Toggle automatic parens pairing (Electric Pair mode).
@@ -370,10 +379,16 @@
   :global t
   :group 'electricity
   (if electric-pair-mode
-      (add-hook 'post-self-insert-hook
-                #'electric-pair-post-self-insert-function)
+      (progn
+       (require 'delsel)
+       (add-hook 'post-self-insert-hook
+                 #'electric-pair-post-self-insert-function)
+       (add-hook 'delete-selection-self-insert-hooks
+                 #'electric-pair-delete-selection-self-insert-function))
     (remove-hook 'post-self-insert-hook
-                 #'electric-pair-post-self-insert-function)))
+                 #'electric-pair-post-self-insert-function)
+    (remove-hook 'delete-selection-self-insert-hooks
+                 #'electric-pair-delete-selection-self-insert-function)))
 
 ;; Automatically add newlines after/before/around some chars.
 


reply via email to

[Prev in Thread] Current Thread [Next in Thread]