aboutsummaryrefslogtreecommitdiffstats
path: root/lisp/progmodes/python.el
diff options
context:
space:
mode:
authorStefan Monnier2020-10-16 14:03:59 -0400
committerStefan Monnier2020-10-16 14:03:59 -0400
commit3b3274a85c2f5df21d76d82e0d7740005aa84fdf (patch)
treec0840a1dc9f882bc389fed4396cd36209e75f801 /lisp/progmodes/python.el
parentc41c1ac410423243f575e910aef9a1c7645ec216 (diff)
downloademacs-3b3274a85c2f5df21d76d82e0d7740005aa84fdf.tar.gz
emacs-3b3274a85c2f5df21d76d82e0d7740005aa84fdf.zip
* lisp/progmodes/python.el: Teach f-strings to `font-lock`
(python--f-string-p, python--font-lock-f-strings): New functions. (python-font-lock-keywords-maximum-decoration): Use them.
Diffstat (limited to 'lisp/progmodes/python.el')
-rw-r--r--lisp/progmodes/python.el55
1 files changed, 52 insertions, 3 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el
index 76baa4469c7..d1871c93a78 100644
--- a/lisp/progmodes/python.el
+++ b/lisp/progmodes/python.el
@@ -501,6 +501,52 @@ The type returned can be `comment', `string' or `paren'."
501 font-lock-string-face) 501 font-lock-string-face)
502 font-lock-comment-face)) 502 font-lock-comment-face))
503 503
504(defun python--f-string-p (ppss)
505 "Return non-nil if the pos where PPSS was found is inside an f-string."
506 (and (nth 3 ppss)
507 (let ((spos (1- (nth 8 ppss))))
508 (and (memq (char-after spos) '(?f ?F))
509 (or (< (point-min) spos)
510 (not (memq (char-syntax (char-before spos)) '(?w ?_))))))))
511
512(defun python--font-lock-f-strings (limit)
513 "Mark {...} holes as being code.
514Remove the (presumably `font-lock-string-face') `face' property from
515the {...} holes that appear within f-strings."
516 ;; FIXME: This will fail to properly highlight strings appearing
517 ;; within the {...} of an f-string.
518 ;; We could presumably fix it by running
519 ;; `font-lock-fontify-syntactically-region' (as is done in
520 ;; `sm-c--cpp-fontify-syntactically', for example) after removing
521 ;; the `face' property, but I'm not sure it's worth the effort and
522 ;; the risks.
523 (let ((ppss (syntax-ppss)))
524 (while
525 (progn
526 (while (and (not (python--f-string-p ppss))
527 (re-search-forward "\\<f['\"]" limit 'move))
528 (setq ppss (syntax-ppss)))
529 (< (point) limit))
530 (cl-assert (python--f-string-p ppss))
531 (let ((send (save-excursion
532 (goto-char (nth 8 ppss))
533 (condition-case nil
534 (progn (let ((forward-sexp-function nil))
535 (forward-sexp 1))
536 (min limit (1- (point))))
537 (scan-error limit)))))
538 (while (re-search-forward "{" send t)
539 (if (eq ?\{ (char-after))
540 (forward-char 1) ;Just skip over {{
541 (let ((beg (match-beginning 0))
542 (end (condition-case nil
543 (progn (up-list 1) (min send (point)))
544 (scan-error send))))
545 (goto-char end)
546 (put-text-property beg end 'face nil))))
547 (goto-char (min limit (1+ send)))
548 (setq ppss (syntax-ppss))))))
549
504(defvar python-font-lock-keywords-level-1 550(defvar python-font-lock-keywords-level-1
505 `((,(rx symbol-start "def" (1+ space) (group (1+ (or word ?_)))) 551 `((,(rx symbol-start "def" (1+ space) (group (1+ (or word ?_))))
506 (1 font-lock-function-name-face)) 552 (1 font-lock-function-name-face))
@@ -567,7 +613,8 @@ This is the medium decoration level, including everything in
567builtins.") 613builtins.")
568 614
569(defvar python-font-lock-keywords-maximum-decoration 615(defvar python-font-lock-keywords-maximum-decoration
570 `(,@python-font-lock-keywords-level-2 616 `((python--font-lock-f-strings)
617 ,@python-font-lock-keywords-level-2
571 ;; Constants 618 ;; Constants
572 (,(rx symbol-start 619 (,(rx symbol-start
573 (or 620 (or
@@ -575,7 +622,8 @@ builtins.")
575 ;; copyright, license, credits, quit and exit are added by the site 622 ;; copyright, license, credits, quit and exit are added by the site
576 ;; module and they are not intended to be used in programs 623 ;; module and they are not intended to be used in programs
577 "copyright" "credits" "exit" "license" "quit") 624 "copyright" "credits" "exit" "license" "quit")
578 symbol-end) . font-lock-constant-face) 625 symbol-end)
626 . font-lock-constant-face)
579 ;; Decorators. 627 ;; Decorators.
580 (,(rx line-start (* (any " \t")) (group "@" (1+ (or word ?_)) 628 (,(rx line-start (* (any " \t")) (group "@" (1+ (or word ?_))
581 (0+ "." (1+ (or word ?_))))) 629 (0+ "." (1+ (or word ?_)))))
@@ -609,7 +657,8 @@ builtins.")
609 ;; OS specific 657 ;; OS specific
610 "VMSError" "WindowsError" 658 "VMSError" "WindowsError"
611 ) 659 )
612 symbol-end) . font-lock-type-face) 660 symbol-end)
661 . font-lock-type-face)
613 ;; assignments 662 ;; assignments
614 ;; support for a = b = c = 5 663 ;; support for a = b = c = 5
615 (,(lambda (limit) 664 (,(lambda (limit)