]> git.eshelyaron.com Git - emacs.git/commitdiff
Improve on previous quote autopairing change
authorJoão Távora <joaotavora@gmail.com>
Fri, 4 Apr 2014 23:31:02 +0000 (00:31 +0100)
committerJoão Távora <joaotavora@gmail.com>
Fri, 4 Apr 2014 23:31:02 +0000 (00:31 +0100)
* 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 418a586b220dd3adfb3e0ec1898180c6ebb7a647..170fcd2892ae72970a587acdfe128ccb055cc364 100644 (file)
@@ -1,3 +1,15 @@
+2014-04-04  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-04  Stefan Monnier  <monnier@iro.umontreal.ca>
 
        * textmodes/reftex-parse.el (reftex--index-tags): Rename `index-tags'.
index 2d7060eb27c1a88120587900a0c12469f5ddb23e..73eabdf51c86ad8cd2e0f241afb6c9dca46cf039 100644 (file)
@@ -257,11 +257,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)
@@ -351,7 +359,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.
@@ -364,18 +372,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.
@@ -408,9 +427,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 be845db162a2a2ee7a2f1f4f7cecce28b1436666..4b1e352051bf5107d667c119ea4ce9fb8d34b0ba 100644 (file)
@@ -1,3 +1,10 @@
+2014-04-04  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-02  João Távora  <joaotavora@gmail.com>
 
        * automated/electric-tests.el (inhibit-if-strings-mismatched):
index c43b87f3f8135f5f0728740ad025e33335c0eb5b..9f0973e16b3569b6dcea05b92d265a23a2f6ddf1 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