aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-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 @@
12014-04-07 João Távora <joaotavora@gmail.com> 12014-04-07 João Távora <joaotavora@gmail.com>
2 2
3 * elec-pair.el:
4 (electric-pair--syntax-ppss): When inside comments parse from
5 comment beginning.
6 (electric-pair--balance-info): Fix typo in comment.
7 (electric-pair--in-unterminated-string-p): Delete.
8 (electric-pair--unbalanced-strings-p): New function.
9 (electric-pair-string-bound-function): New var.
10 (electric-pair-inhibit-if-helps-balance): Decide quote pairing
11 according to `electric-pair--in-unterminated-string-p'
12
132014-04-07 João Távora <joaotavora@gmail.com>
14
3 * elec-pair.el (electric-pair-inhibit-if-helps-balance): Inhibit 15 * elec-pair.el (electric-pair-inhibit-if-helps-balance): Inhibit
4 quote pairing if point-max is inside an unterminated string. 16 quote pairing if point-max is inside an unterminated string.
5 (electric-pair--looking-at-unterminated-string-p): 17 (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'."
227 (let* ((pos (or pos (point))) 227 (let* ((pos (or pos (point)))
228 (where (or where '(string comment))) 228 (where (or where '(string comment)))
229 (quick-ppss (syntax-ppss)) 229 (quick-ppss (syntax-ppss))
230 (quick-ppss-at-pos (syntax-ppss pos))) 230 (quick-ppss-at-pos (syntax-ppss pos))
231 (if (or (and (nth 3 quick-ppss) (memq 'string where)) 231 (in-string (and (nth 3 quick-ppss-at-pos) (memq 'string where)))
232 (and (nth 4 quick-ppss) (memq 'comment where))) 232 (in-comment (and (nth 4 quick-ppss-at-pos) (memq 'comment where)))
233 (s-or-c-start (cond (in-string
234 (1+ (nth 8 quick-ppss)))
235 (in-comment
236 (goto-char (nth 8 quick-ppss))
237 (forward-comment (- (point-max)))
238 (skip-syntax-forward " >!")
239 (point)))))
240 (if s-or-c-start
233 (with-syntax-table electric-pair-text-syntax-table 241 (with-syntax-table electric-pair-text-syntax-table
234 (parse-partial-sexp (1+ (nth 8 quick-ppss)) pos)) 242 (parse-partial-sexp s-or-c-start pos))
235 ;; HACK! cc-mode apparently has some `syntax-ppss' bugs 243 ;; HACK! cc-mode apparently has some `syntax-ppss' bugs
236 (if (memq major-mode '(c-mode c++ mode)) 244 (if (memq major-mode '(c-mode c++ mode))
237 (parse-partial-sexp (point-min) pos) 245 (parse-partial-sexp (point-min) pos)
@@ -321,7 +329,7 @@ If point is not enclosed by any lists, return ((t) . (t))."
321 (scan-error 329 (scan-error
322 (cond ((or 330 (cond ((or
323 ;; some error happened and it is not of the "ended 331 ;; some error happened and it is not of the "ended
324 ;; prematurely" kind"... 332 ;; prematurely" kind...
325 (not (string-match "ends prematurely" (nth 1 err))) 333 (not (string-match "ends prematurely" (nth 1 err)))
326 ;; ... or we were in a comment and just came out of 334 ;; ... or we were in a comment and just came out of
327 ;; it. 335 ;; it.
@@ -334,18 +342,29 @@ If point is not enclosed by any lists, return ((t) . (t))."
334 (funcall ended-prematurely-fn))))))) 342 (funcall ended-prematurely-fn)))))))
335 (cons innermost outermost))) 343 (cons innermost outermost)))
336 344
337(defun electric-pair--in-unterminated-string-p (char) 345(defvar electric-pair-string-bound-function 'point-max
338 "Return non-nil if inside unterminated string started by CHAR" 346 "Next buffer position where strings are syntatically unexpected.
339 (let* ((ppss (syntax-ppss)) 347Value is a function called with no arguments and returning a
340 (relevant-ppss (if (nth 4 ppss) ; in comment 348buffer position. Major modes should set this variable
341 (electric-pair--syntax-ppss) 349buffer-locally if they experience slowness with
342 ppss)) 350`electric-pair-mode' when pairing quotes.")
351
352(defun electric-pair--unbalanced-strings-p (char)
353 "Return non-nil if there are unbalanced strings started by CHAR."
354 (let* ((selector-ppss (syntax-ppss))
355 (relevant-ppss (save-excursion
356 (if (nth 4 selector-ppss) ; comment
357 (electric-pair--syntax-ppss
358 (progn
359 (goto-char (nth 8 selector-ppss))
360 (forward-comment (point-max))
361 (skip-syntax-backward " >!")
362 (point)))
363 (syntax-ppss
364 (funcall electric-pair-string-bound-function)))))
343 (string-delim (nth 3 relevant-ppss))) 365 (string-delim (nth 3 relevant-ppss)))
344 (and (or (eq t string-delim) 366 (or (eq t string-delim)
345 (eq char string-delim)) 367 (eq char string-delim))))
346 (condition-case nil (progn (scan-sexps (nth 8 relevant-ppss) 1)
347 nil)
348 (scan-error t)))))
349 368
350(defun electric-pair--inside-string-p (char) 369(defun electric-pair--inside-string-p (char)
351 "Return non-nil if point is inside a string started by CHAR. 370 "Return non-nil if point is inside a string started by CHAR.
@@ -378,9 +397,7 @@ happened."
378 (t 397 (t
379 (eq (cdr outermost) pair))))) 398 (eq (cdr outermost) pair)))))
380 ((eq syntax ?\") 399 ((eq syntax ?\")
381 (save-excursion 400 (electric-pair--unbalanced-strings-p char))))
382 (goto-char (point-max))
383 (electric-pair--in-unterminated-string-p char)))))
384 (insert-char char))))) 401 (insert-char char)))))
385 402
386(defun electric-pair-skip-if-helps-balance (char) 403(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 @@
12014-04-07 João Távora <joaotavora@gmail.com> 12014-04-07 João Távora <joaotavora@gmail.com>
2 2
3 * automated/electric-tests.el (define-electric-pair-test): Don't
4 overtest..
5 (inhibit-in-mismatched-string-inside-ruby-comments): New test.
6 (inhibit-in-mismatched-string-inside-c-comments): New test.
7
82014-04-07 João Távora <joaotavora@gmail.com>
9
3 * automated/electric-tests.el (inhibit-if-strings-mismatched): 10 * automated/electric-tests.el (inhibit-if-strings-mismatched):
4 New test, change from `inhibit-only-of-next-is-mismatched'. 11 New test, change from `inhibit-only-of-next-is-mismatched'.
5 12
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"
141 expected-string 141 expected-string
142 expected-point 142 expected-point
143 bindings 143 bindings
144 (modes '(quote (emacs-lisp-mode ruby-mode c++-mode))) 144 (modes '(quote (ruby-mode c++-mode)))
145 (test-in-comments t) 145 (test-in-comments t)
146 (test-in-strings t) 146 (test-in-strings t)
147 (test-in-code t) 147 (test-in-code t)
@@ -303,6 +303,48 @@ Should %s |%s| and point at %d"
303 :bindings `((electric-pair-text-syntax-table 303 :bindings `((electric-pair-text-syntax-table
304 . ,prog-mode-syntax-table))) 304 . ,prog-mode-syntax-table)))
305 305
306(define-electric-pair-test inhibit-in-mismatched-string-inside-ruby-comments
307 "foo\"\"
308#
309# \"bar\"
310# \" \"
311# \"
312#
313baz\"\""
314 "\""
315 :modes '(ruby-mode)
316 :test-in-strings nil
317 :test-in-comments nil
318 :expected-point 19
319 :expected-string
320 "foo\"\"
321#
322# \"bar\"\"
323# \" \"
324# \"
325#
326baz\"\""
327 :fixture-fn #'(lambda () (goto-char (point-min)) (search-forward "bar")))
328
329(define-electric-pair-test inhibit-in-mismatched-string-inside-c-comments
330 "foo\"\"/*
331 \"bar\"
332 \" \"
333 \"
334*/baz\"\""
335 "\""
336 :modes '(c-mode)
337 :test-in-strings nil
338 :test-in-comments nil
339 :expected-point 18
340 :expected-string
341 "foo\"\"/*
342 \"bar\"\"
343 \" \"
344 \"
345*/baz\"\""
346 :fixture-fn #'(lambda () (goto-char (point-min)) (search-forward "bar")))
347
306 348
307;;; More quotes, but now don't bind `electric-pair-text-syntax-table' 349;;; More quotes, but now don't bind `electric-pair-text-syntax-table'
308;;; to `prog-mode-syntax-table'. Use the defaults for 350;;; to `prog-mode-syntax-table'. Use the defaults for