diff options
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 56 |
1 files changed, 54 insertions, 2 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index b8fc7d4c546..27bdbae3113 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -427,7 +427,19 @@ This variant of `rx' supports common Python named REGEXPS." | |||
| 427 | (: "vim:" (* space) "set" (+ space) | 427 | (: "vim:" (* space) "set" (+ space) |
| 428 | "fileencoding" (* space) ?= (* space) | 428 | "fileencoding" (* space) ?= (* space) |
| 429 | (group-n 1 (+ (or word ?-))) | 429 | (group-n 1 (+ (or word ?-))) |
| 430 | (* space) ":"))))) | 430 | (* space) ":")))) |
| 431 | (bytes-escape-sequence | ||
| 432 | (seq (not "\\") | ||
| 433 | (group (or "\\\\" "\\'" "\\a" "\\b" "\\f" | ||
| 434 | "\\n" "\\r" "\\t" "\\v" | ||
| 435 | (seq "\\" (= 3 (in "0-7"))) | ||
| 436 | (seq "\\x" hex hex))))) | ||
| 437 | (string-escape-sequence | ||
| 438 | (or bytes-escape-sequence | ||
| 439 | (seq (not "\\") | ||
| 440 | (or (group-n 1 "\\u" (= 4 hex)) | ||
| 441 | (group-n 1 "\\U" (= 8 hex)) | ||
| 442 | (group-n 1 "\\N{" (*? anychar) "}")))))) | ||
| 431 | (rx ,@regexps))) | 443 | (rx ,@regexps))) |
| 432 | 444 | ||
| 433 | 445 | ||
| @@ -539,6 +551,29 @@ the {...} holes that appear within f-strings." | |||
| 539 | (goto-char (min limit (1+ send))) | 551 | (goto-char (min limit (1+ send))) |
| 540 | (setq ppss (syntax-ppss)))))) | 552 | (setq ppss (syntax-ppss)))))) |
| 541 | 553 | ||
| 554 | (defconst python--not-raw-bytes-literal-start-regexp | ||
| 555 | (rx (or bos (not alnum)) (or "b" "B") (or "\"" "\"\"\"" "'" "'''") eos) | ||
| 556 | "A regular expression matching the start of a not-raw bytes literal.") | ||
| 557 | |||
| 558 | (defconst python--not-raw-string-literal-start-regexp | ||
| 559 | (rx (or bos (not alnum)) (? (or "u" "U" "F" "f")) (or "\"" "\"\"\"" "'" "'''") eos) | ||
| 560 | "A regular expression matching the start of a not-raw string literal.") | ||
| 561 | |||
| 562 | (defun python--string-bytes-literal-matcher (regexp start-regexp) | ||
| 563 | "Match REGEXP within a string or bytes literal whose start matches START-REGEXP." | ||
| 564 | (lambda (limit) | ||
| 565 | (cl-loop for result = (re-search-forward regexp limit t) | ||
| 566 | for result-valid = (and | ||
| 567 | result | ||
| 568 | (let* ((pos (nth 8 (syntax-ppss))) | ||
| 569 | (before-quote | ||
| 570 | (buffer-substring-no-properties | ||
| 571 | (max (- pos 5) (point-min)) | ||
| 572 | (min (+ pos 1) (point-max))))) | ||
| 573 | (string-match-p start-regexp before-quote))) | ||
| 574 | until (or (not result) result-valid) | ||
| 575 | finally return (and result-valid result)))) | ||
| 576 | |||
| 542 | (defvar python-font-lock-keywords-level-1 | 577 | (defvar python-font-lock-keywords-level-1 |
| 543 | `((,(python-rx symbol-start "def" (1+ space) (group symbol-name)) | 578 | `((,(python-rx symbol-start "def" (1+ space) (group symbol-name)) |
| 544 | (1 font-lock-function-name-face)) | 579 | (1 font-lock-function-name-face)) |
| @@ -716,7 +751,24 @@ sign in chained assignment." | |||
| 716 | grouped-assignment-target (* space) | 751 | grouped-assignment-target (* space) |
| 717 | (or ")" "]") (* space) | 752 | (or ")" "]") (* space) |
| 718 | assignment-operator)) | 753 | assignment-operator)) |
| 719 | (1 font-lock-variable-name-face))) | 754 | (1 font-lock-variable-name-face)) |
| 755 | ;; escape sequences within bytes literals | ||
| 756 | ;; "\\" "\'" "\a" "\b" "\f" "\n" "\r" "\t" "\v" | ||
| 757 | ;; "\ooo" character with octal value ooo | ||
| 758 | ;; "\xhh" character with hex value hh | ||
| 759 | (,(python--string-bytes-literal-matcher | ||
| 760 | (python-rx bytes-escape-sequence) | ||
| 761 | python--not-raw-bytes-literal-start-regexp) | ||
| 762 | (1 font-lock-constant-face t)) | ||
| 763 | ;; escape sequences within string literals, the same as appear in bytes | ||
| 764 | ;; literals in addition to: | ||
| 765 | ;; "\uxxxx" Character with 16-bit hex value xxxx | ||
| 766 | ;; "\Uxxxxxxxx" Character with 32-bit hex value xxxxxxxx | ||
| 767 | ;; "\N{name}" Character named name in the Unicode database | ||
| 768 | (,(python--string-bytes-literal-matcher | ||
| 769 | (python-rx string-escape-sequence) | ||
| 770 | python--not-raw-string-literal-start-regexp) | ||
| 771 | (1 'font-lock-constant-face t))) | ||
| 720 | "Font lock keywords to use in `python-mode' for maximum decoration. | 772 | "Font lock keywords to use in `python-mode' for maximum decoration. |
| 721 | 773 | ||
| 722 | This decoration level includes everything in | 774 | This decoration level includes everything in |