diff options
| author | Laurence Warne | 2022-08-09 08:33:18 +0100 |
|---|---|---|
| committer | Lars Ingebrigtsen | 2022-08-09 19:21:36 +0200 |
| commit | b92e88875802724af9e08201ea65a96dd5f20ff1 (patch) | |
| tree | 9a0136781ddab7618c4752d60c1c84830a07d95a /lisp/progmodes/python.el | |
| parent | 3ef18c7a213f4f3c03eec033fcb8219fb17cd53d (diff) | |
| download | emacs-b92e88875802724af9e08201ea65a96dd5f20ff1.tar.gz emacs-b92e88875802724af9e08201ea65a96dd5f20ff1.zip | |
Fix python escape code fontification for multi-line literals
* lisp/progmodes/python.el (python--string-bytes-literal-matcher): Go
backward one char after a match so that consecutive escape codes are
highlighted
(python--not-raw-string-literal-start-regexp): Make regular expression
more comprehensive, so multi-line bytes literals are not caught
(python-rx): Accept one to three octal digits in octal escape codes
instead of always three
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 22 |
1 files changed, 15 insertions, 7 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 5edd6e7df56..96f9d14832d 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -432,7 +432,7 @@ This variant of `rx' supports common Python named REGEXPS." | |||
| 432 | (seq (not "\\") | 432 | (seq (not "\\") |
| 433 | (group (or "\\\\" "\\'" "\\a" "\\b" "\\f" | 433 | (group (or "\\\\" "\\'" "\\a" "\\b" "\\f" |
| 434 | "\\n" "\\r" "\\t" "\\v" | 434 | "\\n" "\\r" "\\t" "\\v" |
| 435 | (seq "\\" (= 3 (in "0-7"))) | 435 | (seq "\\" (** 1 3 (in "0-7"))) |
| 436 | (seq "\\x" hex hex))))) | 436 | (seq "\\x" hex hex))))) |
| 437 | (string-escape-sequence | 437 | (string-escape-sequence |
| 438 | (or bytes-escape-sequence | 438 | (or bytes-escape-sequence |
| @@ -556,7 +556,14 @@ the {...} holes that appear within f-strings." | |||
| 556 | "A regular expression matching the start of a not-raw bytes literal.") | 556 | "A regular expression matching the start of a not-raw bytes literal.") |
| 557 | 557 | ||
| 558 | (defconst python--not-raw-string-literal-start-regexp | 558 | (defconst python--not-raw-string-literal-start-regexp |
| 559 | (rx (or bos (not alnum)) (? (or "u" "U" "F" "f")) (or "\"" "\"\"\"" "'" "'''") eos) | 559 | (rx bos (or |
| 560 | ;; Multi-line string literals | ||
| 561 | (seq (? (? (not alnum)) (or "u" "U" "F" "f")) (or "\"\"\"" "'''")) | ||
| 562 | (seq (? anychar) (not alnum) (or "\"\"\"" "'''")) | ||
| 563 | ;; Single line string literals | ||
| 564 | (seq (? (** 0 2 anychar) (not alnum)) (or "u" "U" "F" "f") (or "'" "\"")) | ||
| 565 | (seq (? (** 0 3 anychar) (not (any "'\"" alnum))) (or "'" "\""))) | ||
| 566 | eos) | ||
| 560 | "A regular expression matching the start of a not-raw string literal.") | 567 | "A regular expression matching the start of a not-raw string literal.") |
| 561 | 568 | ||
| 562 | (defun python--string-bytes-literal-matcher (regexp start-regexp) | 569 | (defun python--string-bytes-literal-matcher (regexp start-regexp) |
| @@ -565,11 +572,12 @@ the {...} holes that appear within f-strings." | |||
| 565 | (cl-loop for result = (re-search-forward regexp limit t) | 572 | (cl-loop for result = (re-search-forward regexp limit t) |
| 566 | for result-valid = (and | 573 | for result-valid = (and |
| 567 | result | 574 | result |
| 568 | (let* ((pos (nth 8 (syntax-ppss))) | 575 | (when-let* ((pos (nth 8 (syntax-ppss))) |
| 569 | (before-quote | 576 | (before-quote |
| 570 | (buffer-substring-no-properties | 577 | (buffer-substring-no-properties |
| 571 | (max (- pos 5) (point-min)) | 578 | (max (- pos 4) (point-min)) |
| 572 | (min (+ pos 1) (point-max))))) | 579 | (min (+ pos 1) (point-max))))) |
| 580 | (backward-char) | ||
| 573 | (string-match-p start-regexp before-quote))) | 581 | (string-match-p start-regexp before-quote))) |
| 574 | until (or (not result) result-valid) | 582 | until (or (not result) result-valid) |
| 575 | finally return (and result-valid result)))) | 583 | finally return (and result-valid result)))) |