aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorStefan Monnier2020-12-05 10:41:03 -0500
committerStefan Monnier2020-12-05 10:41:20 -0500
commitfc54c835181eb88a748d2fd49b7a4c78b9fe82ee (patch)
treedd1ee63450c8b7747cccaadfc4ef90b535c516fc
parentdc39c66d3bb6b1db6af0519659ff154bf6d8a5d1 (diff)
downloademacs-fc54c835181eb88a748d2fd49b7a4c78b9fe82ee.tar.gz
emacs-fc54c835181eb88a748d2fd49b7a4c78b9fe82ee.zip
* lisp/progmodes/perl-mode.el: Fix handling of s'foo'bar'
(perl-syntax-propertize-function): Don't put a syntax-property on regexp-op delimiters if they're already handled correctly by the normal syntax tables. (perl-syntax-propertize-special-constructs): Mark the middle quote of s'foo'bar' as punctuation. * test/manual/indent/perl.perl: Add new test cases.
-rw-r--r--lisp/progmodes/perl-mode.el39
-rwxr-xr-xtest/manual/indent/perl.perl14
2 files changed, 41 insertions, 12 deletions
diff --git a/lisp/progmodes/perl-mode.el b/lisp/progmodes/perl-mode.el
index bb19436cdad..fd8a51b5a54 100644
--- a/lisp/progmodes/perl-mode.el
+++ b/lisp/progmodes/perl-mode.el
@@ -299,12 +299,21 @@
299 ;; $a = "foo y \"toto\" bar" where we'd end up changing the 299 ;; $a = "foo y \"toto\" bar" where we'd end up changing the
300 ;; syntax of the backslash and hence de-escaping the embedded 300 ;; syntax of the backslash and hence de-escaping the embedded
301 ;; double quote. 301 ;; double quote.
302 (put-text-property (match-beginning 3) (match-end 3) 302 (let* ((b3 (match-beginning 3))
303 'syntax-table 303 (c (char-after b3)))
304 (if (assoc (char-after (match-beginning 3)) 304 (put-text-property
305 perl-quote-like-pairs) 305 b3 (match-end 3) 'syntax-table
306 (string-to-syntax "|") 306 (cond
307 (string-to-syntax "\""))) 307 ((assoc c perl-quote-like-pairs)
308 (string-to-syntax "|"))
309 ;; If the separator is a normal quote and the operation
310 ;; only takes a single arg, then there's nothing
311 ;; special to do.
312 ((and (memq c '(?\" ?\'))
313 (memq (char-after (match-beginning 2)) '(?m ?q)))
314 nil)
315 (t
316 (string-to-syntax "\"")))))
308 (perl-syntax-propertize-special-constructs end)))))) 317 (perl-syntax-propertize-special-constructs end))))))
309 ;; Here documents. 318 ;; Here documents.
310 ((concat 319 ((concat
@@ -379,7 +388,8 @@
379 (put-text-property (1- (point)) (point) 'syntax-table 388 (put-text-property (1- (point)) (point) 'syntax-table
380 (string-to-syntax "> c")))))) 389 (string-to-syntax "> c"))))))
381 ((or (null (setq char (nth 3 state))) 390 ((or (null (setq char (nth 3 state)))
382 (and (characterp char) (eq (char-syntax (nth 3 state)) ?\"))) 391 (and (characterp char)
392 (null (get-text-property (nth 8 state) 'syntax-table))))
383 ;; Normal text, or comment, or docstring, or normal string. 393 ;; Normal text, or comment, or docstring, or normal string.
384 nil) 394 nil)
385 ((eq (nth 3 state) ?\n) 395 ((eq (nth 3 state) ?\n)
@@ -400,6 +410,7 @@
400 (point))) 410 (point)))
401 '("tr" "s" "y")))) 411 '("tr" "s" "y"))))
402 (close (cdr (assq char perl-quote-like-pairs))) 412 (close (cdr (assq char perl-quote-like-pairs)))
413 (middle nil)
403 (st (perl-quote-syntax-table char))) 414 (st (perl-quote-syntax-table char)))
404 (when (with-syntax-table st 415 (when (with-syntax-table st
405 (if close 416 (if close
@@ -430,6 +441,7 @@
430 ;; In the case of s{...}{...}, we only handle the 441 ;; In the case of s{...}{...}, we only handle the
431 ;; first part here and the next below. 442 ;; first part here and the next below.
432 (when (and twoargs (not close)) 443 (when (and twoargs (not close))
444 (setq middle (point))
433 (nth 8 (parse-partial-sexp 445 (nth 8 (parse-partial-sexp
434 (point) limit 446 (point) limit
435 nil nil state 'syntax-table))))))) 447 nil nil state 'syntax-table)))))))
@@ -437,11 +449,14 @@
437 (when (eq (char-before (1- (point))) ?$) 449 (when (eq (char-before (1- (point))) ?$)
438 (put-text-property (- (point) 2) (1- (point)) 450 (put-text-property (- (point) 2) (1- (point))
439 'syntax-table '(1))) 451 'syntax-table '(1)))
440 (put-text-property (1- (point)) (point) 452 (if (and middle (memq char '(?\" ?\')))
441 'syntax-table 453 (put-text-property (1- middle) middle
442 (if close 454 'syntax-table '(1))
443 (string-to-syntax "|") 455 (put-text-property (1- (point)) (point)
444 (string-to-syntax "\""))) 456 'syntax-table
457 (if close
458 (string-to-syntax "|")
459 (string-to-syntax "\""))))
445 ;; If we have two args with a non-self-paired starter (e.g. 460 ;; If we have two args with a non-self-paired starter (e.g.
446 ;; s{...}{...}) we're right after the first arg, so we still have to 461 ;; s{...}{...}) we're right after the first arg, so we still have to
447 ;; handle the second part. 462 ;; handle the second part.
diff --git a/test/manual/indent/perl.perl b/test/manual/indent/perl.perl
index 853aec49245..6ec04303b4f 100755
--- a/test/manual/indent/perl.perl
+++ b/test/manual/indent/perl.perl
@@ -81,3 +81,17 @@ return 'W' if #/^Not Available on Mobile/m; #W=Web only
81# A "y|abc|def|" shouldn't interfere when inside a string! 81# A "y|abc|def|" shouldn't interfere when inside a string!
82$toto = " x \" string\""; 82$toto = " x \" string\"";
83$toto = " y \" string\""; # This is not the `y' operator! 83$toto = " y \" string\""; # This is not the `y' operator!
84
85
86# Tricky cases from Harald Jörg <haj@posteo.de>
87$_ = "abcabc\n";
88s:abc:def:g; # FIXME: the initial s is fontified like a label, and indented
89
90s'def'ghi'g; # The middle ' should not end the quoting.
91s"ghi"ijk"g; # The middle ' should not end the quoting.
92
93s#ijk#lmn#g; # This is a regular expression sustitution.
94
95s #lmn#opq#g; # FIXME: this should be a comment starting with "#lmn"
96 /lmn/rst/g; # and this is the actual regular expression
97print; # prints "rstrst\n"