diff options
| author | Stefan Monnier | 2020-12-05 10:41:03 -0500 |
|---|---|---|
| committer | Stefan Monnier | 2020-12-05 10:41:20 -0500 |
| commit | fc54c835181eb88a748d2fd49b7a4c78b9fe82ee (patch) | |
| tree | dd1ee63450c8b7747cccaadfc4ef90b535c516fc | |
| parent | dc39c66d3bb6b1db6af0519659ff154bf6d8a5d1 (diff) | |
| download | emacs-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.el | 39 | ||||
| -rwxr-xr-x | test/manual/indent/perl.perl | 14 |
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"; | ||
| 88 | s:abc:def:g; # FIXME: the initial s is fontified like a label, and indented | ||
| 89 | |||
| 90 | s'def'ghi'g; # The middle ' should not end the quoting. | ||
| 91 | s"ghi"ijk"g; # The middle ' should not end the quoting. | ||
| 92 | |||
| 93 | s#ijk#lmn#g; # This is a regular expression sustitution. | ||
| 94 | |||
| 95 | s #lmn#opq#g; # FIXME: this should be a comment starting with "#lmn" | ||
| 96 | /lmn/rst/g; # and this is the actual regular expression | ||
| 97 | print; # prints "rstrst\n" | ||