aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorJoão Távora2014-04-05 00:31:02 +0100
committerJoão Távora2014-04-05 00:31:02 +0100
commit5cb0cc903f64607a07b4cb3129f28e2cc072f5d7 (patch)
treefbfc3b0f3be3d9018b10a562adf5a89496b82030
parent6b31e6b1ec3bc8b69c522dcabe0bf1e2eab03710 (diff)
downloademacs-5cb0cc903f64607a07b4cb3129f28e2cc072f5d7.tar.gz
emacs-5cb0cc903f64607a07b4cb3129f28e2cc072f5d7.zip
Improve on previous quote autopairing change
* 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 418a586b220..170fcd2892a 100644
--- a/lisp/ChangeLog
+++ b/lisp/ChangeLog
@@ -1,3 +1,15 @@
12014-04-04 João Távora <joaotavora@gmail.com>
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
12014-04-04 Stefan Monnier <monnier@iro.umontreal.ca> 132014-04-04 Stefan Monnier <monnier@iro.umontreal.ca>
2 14
3 * textmodes/reftex-parse.el (reftex--index-tags): Rename `index-tags'. 15 * textmodes/reftex-parse.el (reftex--index-tags): Rename `index-tags'.
diff --git a/lisp/elec-pair.el b/lisp/elec-pair.el
index 2d7060eb27c..73eabdf51c8 100644
--- a/lisp/elec-pair.el
+++ b/lisp/elec-pair.el
@@ -257,11 +257,19 @@ when to fallback to `parse-partial-sexp'."
257 (let* ((pos (or pos (point))) 257 (let* ((pos (or pos (point)))
258 (where (or where '(string comment))) 258 (where (or where '(string comment)))
259 (quick-ppss (syntax-ppss)) 259 (quick-ppss (syntax-ppss))
260 (quick-ppss-at-pos (syntax-ppss pos))) 260 (quick-ppss-at-pos (syntax-ppss pos))
261 (if (or (and (nth 3 quick-ppss) (memq 'string where)) 261 (in-string (and (nth 3 quick-ppss-at-pos) (memq 'string where)))
262 (and (nth 4 quick-ppss) (memq 'comment where))) 262 (in-comment (and (nth 4 quick-ppss-at-pos) (memq 'comment where)))
263 (s-or-c-start (cond (in-string
264 (1+ (nth 8 quick-ppss)))
265 (in-comment
266 (goto-char (nth 8 quick-ppss))
267 (forward-comment (- (point-max)))
268 (skip-syntax-forward " >!")
269 (point)))))
270 (if s-or-c-start
263 (with-syntax-table electric-pair-text-syntax-table 271 (with-syntax-table electric-pair-text-syntax-table
264 (parse-partial-sexp (1+ (nth 8 quick-ppss)) pos)) 272 (parse-partial-sexp s-or-c-start pos))
265 ;; HACK! cc-mode apparently has some `syntax-ppss' bugs 273 ;; HACK! cc-mode apparently has some `syntax-ppss' bugs
266 (if (memq major-mode '(c-mode c++ mode)) 274 (if (memq major-mode '(c-mode c++ mode))
267 (parse-partial-sexp (point-min) pos) 275 (parse-partial-sexp (point-min) pos)
@@ -351,7 +359,7 @@ If point is not enclosed by any lists, return ((t) . (t))."
351 (scan-error 359 (scan-error
352 (cond ((or 360 (cond ((or
353 ;; some error happened and it is not of the "ended 361 ;; some error happened and it is not of the "ended
354 ;; prematurely" kind"... 362 ;; prematurely" kind...
355 (not (string-match "ends prematurely" (nth 1 err))) 363 (not (string-match "ends prematurely" (nth 1 err)))
356 ;; ... or we were in a comment and just came out of 364 ;; ... or we were in a comment and just came out of
357 ;; it. 365 ;; it.
@@ -364,18 +372,29 @@ If point is not enclosed by any lists, return ((t) . (t))."
364 (funcall ended-prematurely-fn))))))) 372 (funcall ended-prematurely-fn)))))))
365 (cons innermost outermost))) 373 (cons innermost outermost)))
366 374
367(defun electric-pair--in-unterminated-string-p (char) 375(defvar electric-pair-string-bound-function 'point-max
368 "Return non-nil if inside unterminated string started by CHAR" 376 "Next buffer position where strings are syntatically unexpected.
369 (let* ((ppss (syntax-ppss)) 377Value is a function called with no arguments and returning a
370 (relevant-ppss (if (nth 4 ppss) ; in comment 378buffer position. Major modes should set this variable
371 (electric-pair--syntax-ppss) 379buffer-locally if they experience slowness with
372 ppss)) 380`electric-pair-mode' when pairing quotes.")
381
382(defun electric-pair--unbalanced-strings-p (char)
383 "Return non-nil if there are unbalanced strings started by CHAR."
384 (let* ((selector-ppss (syntax-ppss))
385 (relevant-ppss (save-excursion
386 (if (nth 4 selector-ppss) ; comment
387 (electric-pair--syntax-ppss
388 (progn
389 (goto-char (nth 8 selector-ppss))
390 (forward-comment (point-max))
391 (skip-syntax-backward " >!")
392 (point)))
393 (syntax-ppss
394 (funcall electric-pair-string-bound-function)))))
373 (string-delim (nth 3 relevant-ppss))) 395 (string-delim (nth 3 relevant-ppss)))
374 (and (or (eq t string-delim) 396 (or (eq t string-delim)
375 (eq char string-delim)) 397 (eq char string-delim))))
376 (condition-case nil (progn (scan-sexps (nth 8 relevant-ppss) 1)
377 nil)
378 (scan-error t)))))
379 398
380(defun electric-pair--inside-string-p (char) 399(defun electric-pair--inside-string-p (char)
381 "Return non-nil if point is inside a string started by CHAR. 400 "Return non-nil if point is inside a string started by CHAR.
@@ -408,9 +427,7 @@ happened."
408 (t 427 (t
409 (eq (cdr outermost) pair))))) 428 (eq (cdr outermost) pair)))))
410 ((eq syntax ?\") 429 ((eq syntax ?\")
411 (save-excursion 430 (electric-pair--unbalanced-strings-p char))))
412 (goto-char (point-max))
413 (electric-pair--in-unterminated-string-p char)))))
414 (insert-char char))))) 431 (insert-char char)))))
415 432
416(defun electric-pair-skip-if-helps-balance (char) 433(defun electric-pair-skip-if-helps-balance (char)
diff --git a/test/ChangeLog b/test/ChangeLog
index be845db162a..4b1e352051b 100644
--- a/test/ChangeLog
+++ b/test/ChangeLog
@@ -1,3 +1,10 @@
12014-04-04 João Távora <joaotavora@gmail.com>
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
12014-04-02 João Távora <joaotavora@gmail.com> 82014-04-02 João Távora <joaotavora@gmail.com>
2 9
3 * automated/electric-tests.el (inhibit-if-strings-mismatched): 10 * automated/electric-tests.el (inhibit-if-strings-mismatched):
diff --git a/test/automated/electric-tests.el b/test/automated/electric-tests.el
index c43b87f3f81..9f0973e16b3 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