summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJoão Távora <joaotavora@gmail.com>2014-04-07 08:29:50 +0100
committerJoão Távora <joaotavora@gmail.com>2014-04-07 08:29:50 +0100
commit190f899aed4eeb62286874bda47a92236d52ad4c (patch)
tree1fad7c0081bf964b85ab7e34683866ca2285c66c
parent528c33b52868be1d01353f00996d8c63804f74e0 (diff)
downloademacs-190f899aed4eeb62286874bda47a92236d52ad4c.tar.gz
Improve on previous quote autopairing change
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.
-rw-r--r--lisp/ChangeLog12
-rw-r--r--lisp/elec-pair.el55
-rw-r--r--test/ChangeLog7
-rw-r--r--test/automated/electric-tests.el44
4 files changed, 98 insertions, 20 deletions
diff --git a/lisp/ChangeLog b/lisp/ChangeLog
index 9d2fd9854e8..ad6805f7685 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,5 +1,17 @@
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
quote pairing if point-max is inside an unterminated string.
(electric-pair--looking-at-unterminated-string-p):
diff --git a/lisp/elec-pair.el b/lisp/elec-pair.el
index 2a3e4008269..c16c1141800 100644
--- a/lisp/elec-pair.el
+++ b/lisp/elec-pair.el
@@ -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)
diff --git a/test/ChangeLog b/test/ChangeLog
index c94bf21fd36..5aca4a1d063 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,5 +1,12 @@
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):
New test, change from `inhibit-only-of-next-is-mismatched'.
diff --git a/test/automated/electric-tests.el b/test/automated/electric-tests.el
index 301130747f3..bcef9cc2adb 100644
--- a/test/automated/electric-tests.el
+++ b/test/automated/electric-tests.el
@@ -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")))
+
;;; More quotes, but now don't bind `electric-pair-text-syntax-table'
;;; to `prog-mode-syntax-table'. Use the defaults for