]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve on previous quote autopairing change
authorJoão Távora <joaotavora@gmail.com>
Mon, 7 Apr 2014 07:29:50 +0000 (08:29 +0100)
committerJoão Távora <joaotavora@gmail.com>
Mon, 7 Apr 2014 07:29:50 +0000 (08:29 +0100)
Backported from trunk 2014-04-04T23:31:02Z!joaotavora@gmail.com

* lisp/elec-pair.el:
(electric-pair--syntax-ppss): When inside comments parse from
comment beginning.
(electric-pair--balance-info): Fix typo in comment.
(electric-pair--in-unterminated-string-p): Delete.
(electric-pair--unbalanced-strings-p): New function.
(electric-pair-string-bound-function): New var.
(electric-pair-inhibit-if-helps-balance): Decide quote pairing
according to `electric-pair--in-unterminated-string-p'

* test/automated/electric-tests.el (define-electric-pair-test): Don't
overtest..
(inhibit-in-mismatched-string-inside-ruby-comments): New test.
(inhibit-in-mismatched-string-inside-c-comments): New test.

lisp/ChangeLog
lisp/elec-pair.el
test/ChangeLog
test/automated/electric-tests.el

index 9d2fd9854e84534935a3afbacb7e8926ee43b4a8..ad6805f768598ddc1fb392789d83b7276f4c75ab 100644 (file)
@@ -1,3 +1,15 @@
+2014-04-07  João Távora  <joaotavora@gmail.com>
+
+       * elec-pair.el:
+       (electric-pair--syntax-ppss): When inside comments parse from
+       comment beginning.
+       (electric-pair--balance-info): Fix typo in comment.
+       (electric-pair--in-unterminated-string-p): Delete.
+       (electric-pair--unbalanced-strings-p): New function.
+       (electric-pair-string-bound-function): New var.
+       (electric-pair-inhibit-if-helps-balance): Decide quote pairing
+       according to `electric-pair--in-unterminated-string-p'
+
 2014-04-07  João Távora  <joaotavora@gmail.com>
 
        * elec-pair.el (electric-pair-inhibit-if-helps-balance): Inhibit
index 2a3e4008269e83c34c5c7ca818a9c464add2bbc3..c16c1141800a8c7929c65c8af0490dce123c7b51 100644 (file)
@@ -227,11 +227,19 @@ when to fallback to `parse-partial-sexp'."
   (let* ((pos (or pos (point)))
          (where (or where '(string comment)))
          (quick-ppss (syntax-ppss))
-         (quick-ppss-at-pos (syntax-ppss pos)))
-    (if (or (and (nth 3 quick-ppss) (memq 'string where))
-            (and (nth 4 quick-ppss) (memq 'comment where)))
+         (quick-ppss-at-pos (syntax-ppss pos))
+         (in-string (and (nth 3 quick-ppss-at-pos) (memq 'string where)))
+         (in-comment (and (nth 4 quick-ppss-at-pos) (memq 'comment where)))
+         (s-or-c-start (cond (in-string
+                              (1+ (nth 8 quick-ppss)))
+                             (in-comment
+                              (goto-char (nth 8 quick-ppss))
+                              (forward-comment (- (point-max)))
+                              (skip-syntax-forward " >!")
+                              (point)))))
+    (if s-or-c-start
         (with-syntax-table electric-pair-text-syntax-table
-          (parse-partial-sexp (1+ (nth 8 quick-ppss)) pos))
+          (parse-partial-sexp s-or-c-start pos))
       ;; HACK! cc-mode apparently has some `syntax-ppss' bugs
       (if (memq major-mode '(c-mode c++ mode))
           (parse-partial-sexp (point-min) pos)
@@ -321,7 +329,7 @@ If point is not enclosed by any lists, return ((t) . (t))."
           (scan-error
            (cond ((or
                    ;; some error happened and it is not of the "ended
-                   ;; prematurely" kind"...
+                   ;; prematurely" kind...
                    (not (string-match "ends prematurely" (nth 1 err)))
                    ;; ... or we were in a comment and just came out of
                    ;; it.
@@ -334,18 +342,29 @@ If point is not enclosed by any lists, return ((t) . (t))."
                   (funcall ended-prematurely-fn)))))))
     (cons innermost outermost)))
 
-(defun electric-pair--in-unterminated-string-p (char)
-  "Return non-nil if inside unterminated string started by CHAR"
-  (let* ((ppss (syntax-ppss))
-         (relevant-ppss (if (nth 4 ppss) ; in comment
-                            (electric-pair--syntax-ppss)
-                          ppss))
+(defvar electric-pair-string-bound-function 'point-max
+  "Next buffer position where strings are syntatically unexpected.
+Value is a function called with no arguments and returning a
+buffer position. Major modes should set this variable
+buffer-locally if they experience slowness with
+`electric-pair-mode' when pairing quotes.")
+
+(defun electric-pair--unbalanced-strings-p (char)
+  "Return non-nil if there are unbalanced strings started by CHAR."
+  (let* ((selector-ppss (syntax-ppss))
+         (relevant-ppss (save-excursion
+                          (if (nth 4 selector-ppss) ; comment
+                              (electric-pair--syntax-ppss
+                               (progn
+                                 (goto-char (nth 8 selector-ppss))
+                                 (forward-comment (point-max))
+                                 (skip-syntax-backward " >!")
+                                 (point)))
+                            (syntax-ppss
+                             (funcall electric-pair-string-bound-function)))))
          (string-delim (nth 3 relevant-ppss)))
-    (and (or (eq t string-delim)
-             (eq char string-delim))
-         (condition-case nil (progn (scan-sexps (nth 8 relevant-ppss) 1)
-                                    nil)
-           (scan-error t)))))
+    (or (eq t string-delim)
+        (eq char string-delim))))
 
 (defun electric-pair--inside-string-p (char)
   "Return non-nil if point is inside a string started by CHAR.
@@ -378,9 +397,7 @@ happened."
                           (t
                            (eq (cdr outermost) pair)))))
                  ((eq syntax ?\")
-                  (save-excursion
-                    (goto-char (point-max))
-                    (electric-pair--in-unterminated-string-p char)))))
+                  (electric-pair--unbalanced-strings-p char))))
        (insert-char char)))))
 
 (defun electric-pair-skip-if-helps-balance (char)
index c94bf21fd36c396c6c355746f642e399b27c7eff..5aca4a1d06391ea25e9734b8477b2edc984ea334 100644 (file)
@@ -1,3 +1,10 @@
+2014-04-07  João Távora  <joaotavora@gmail.com>
+
+       * automated/electric-tests.el (define-electric-pair-test): Don't
+       overtest..
+       (inhibit-in-mismatched-string-inside-ruby-comments): New test.
+       (inhibit-in-mismatched-string-inside-c-comments): New test.
+
 2014-04-07  João Távora  <joaotavora@gmail.com>
 
        * automated/electric-tests.el (inhibit-if-strings-mismatched):
index 301130747f3ce8317a9ac4a845c671dae353ee15..bcef9cc2adb4c9e44be360dfdc3e830923d86faf 100644 (file)
@@ -141,7 +141,7 @@ Should %s |%s| and point at %d"
           expected-string
           expected-point
           bindings
-          (modes '(quote (emacs-lisp-mode ruby-mode c++-mode)))
+          (modes '(quote (ruby-mode c++-mode)))
           (test-in-comments t)
           (test-in-strings t)
           (test-in-code t)
@@ -303,6 +303,48 @@ Should %s |%s| and point at %d"
   :bindings `((electric-pair-text-syntax-table
                . ,prog-mode-syntax-table)))
 
+(define-electric-pair-test inhibit-in-mismatched-string-inside-ruby-comments
+  "foo\"\"
+#
+#    \"bar\"
+#    \"   \"
+#    \"
+#
+baz\"\""
+  "\""
+  :modes '(ruby-mode)
+  :test-in-strings nil
+  :test-in-comments nil
+  :expected-point 19
+  :expected-string
+  "foo\"\"
+#
+#    \"bar\"\"
+#    \"   \"
+#    \"
+#
+baz\"\""
+  :fixture-fn #'(lambda () (goto-char (point-min)) (search-forward "bar")))
+
+(define-electric-pair-test inhibit-in-mismatched-string-inside-c-comments
+  "foo\"\"/*
+    \"bar\"
+    \"   \"
+    \"
+*/baz\"\""
+  "\""
+  :modes '(c-mode)
+  :test-in-strings nil
+  :test-in-comments nil
+  :expected-point 18
+  :expected-string
+  "foo\"\"/*
+    \"bar\"\"
+    \"   \"
+    \"
+*/baz\"\""
+  :fixture-fn #'(lambda () (goto-char (point-min)) (search-forward "bar")))
+
 \f
 ;;; More quotes, but now don't bind `electric-pair-text-syntax-table'
 ;;; to `prog-mode-syntax-table'. Use the defaults for