aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--lisp/progmodes/python.el17
-rw-r--r--test/lisp/progmodes/python-tests.el12
2 files changed, 22 insertions, 7 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 147c5f248d2..3247d7ad507 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -546,11 +546,22 @@ The type returned can be `comment', `string' or `paren'."
546 font-lock-string-face) 546 font-lock-string-face)
547 font-lock-comment-face)) 547 font-lock-comment-face))
548 548
549(defconst python--f-string-start-regexp
550 (rx bow
551 (or "f" "F" "fr" "Fr" "fR" "FR" "rf" "rF" "Rf" "RF")
552 (or "\"" "\"\"\"" "'" "'''"))
553 "A regular expression matching the beginning of an f-string.
554
555See URL `https://docs.python.org/3/reference/lexical_analysis.html#string-and-bytes-literals'.")
556
549(defun python--f-string-p (ppss) 557(defun python--f-string-p (ppss)
550 "Return non-nil if the pos where PPSS was found is inside an f-string." 558 "Return non-nil if the pos where PPSS was found is inside an f-string."
551 (and (nth 3 ppss) 559 (and (nth 3 ppss)
552 (let ((spos (1- (nth 8 ppss)))) 560 (let* ((spos (1- (nth 8 ppss)))
553 (and (memq (char-after spos) '(?f ?F)) 561 (before-quote
562 (buffer-substring-no-properties (max (- spos 4) (point-min))
563 (min (+ spos 2) (point-max)))))
564 (and (string-match-p python--f-string-start-regexp before-quote)
554 (or (< (point-min) spos) 565 (or (< (point-min) spos)
555 (not (memq (char-syntax (char-before spos)) '(?w ?_)))))))) 566 (not (memq (char-syntax (char-before spos)) '(?w ?_))))))))
556 567
@@ -569,7 +580,7 @@ the {...} holes that appear within f-strings."
569 (while 580 (while
570 (progn 581 (progn
571 (while (and (not (python--f-string-p ppss)) 582 (while (and (not (python--f-string-p ppss))
572 (re-search-forward "\\<f['\"]" limit 'move)) 583 (re-search-forward python--f-string-start-regexp limit 'move))
573 (setq ppss (syntax-ppss))) 584 (setq ppss (syntax-ppss)))
574 (< (point) limit)) 585 (< (point) limit))
575 (cl-assert (python--f-string-p ppss)) 586 (cl-assert (python--f-string-p ppss))
diff --git a/test/lisp/progmodes/python-tests.el b/test/lisp/progmodes/python-tests.el
index 906f7eca7de..20a7a0132a8 100644
--- a/test/lisp/progmodes/python-tests.el
+++ b/test/lisp/progmodes/python-tests.el
@@ -574,10 +574,14 @@ u\"\\n\""
574 (195 . font-lock-string-face) 574 (195 . font-lock-string-face)
575 (196 . font-lock-constant-face) 575 (196 . font-lock-constant-face)
576 (215 . font-lock-string-face) (218) 576 (215 . font-lock-string-face) (218)
577 (221 . font-lock-string-face) (274) 577 (221 . font-lock-string-face) (254)
578 (277 . font-lock-string-face) (330) 578 (271 . font-lock-string-face) (274)
579 (333 . font-lock-string-face) (386) 579 (277 . font-lock-string-face) (310)
580 (389 . font-lock-string-face) (442) 580 (327 . font-lock-string-face) (330)
581 (333 . font-lock-string-face) (366)
582 (383 . font-lock-string-face) (386)
583 (389 . font-lock-string-face) (422)
584 (439 . font-lock-string-face) (442)
581 (444 . font-lock-string-face) (497) 585 (444 . font-lock-string-face) (497)
582 (499 . font-lock-string-face) (552) 586 (499 . font-lock-string-face) (552)
583 (555 . font-lock-string-face) (608) 587 (555 . font-lock-string-face) (608)