From 773122f1ec4d20214f271d70f127f648b6e6e7a7 Mon Sep 17 00:00:00 2001 From: Henrik Lissner Date: Tue, 21 Jun 2022 14:32:13 +0200 Subject: [PATCH] fix(python): syntax highlighting in 28.1 Python syntax highlighting was broken in the 28.1 release. Close: #6414 Co-authored-by: dani84bs --- modules/lang/python/config.el | 85 ++++++++++++++++++++++++++++++++++- 1 file changed, 84 insertions(+), 1 deletion(-) diff --git a/modules/lang/python/config.el b/modules/lang/python/config.el index 4f2b65f31..c51b199ab 100644 --- a/modules/lang/python/config.el +++ b/modules/lang/python/config.el @@ -83,7 +83,90 @@ (advice-add #'pythonic-activate :after-while #'+modeline-update-env-in-all-windows-h) (advice-add #'pythonic-deactivate :after #'+modeline-clear-env-in-all-windows-h)) - (setq-hook! 'python-mode-hook tab-width python-indent-offset)) + (setq-hook! 'python-mode-hook tab-width python-indent-offset) + + ;; HACK Fix syntax highlighting on Emacs 28.1 + ;; DEPRECATED Remove when 28.1 support is dropped + ;; REVIEW Revisit if a 28.2 is released with a fix + (when (= emacs-major-version 28) + (defadvice! +python--font-lock-assignment-matcher-a (regexp) + :override #'python-font-lock-assignment-matcher + (lambda (limit) + (cl-loop while (re-search-forward regexp limit t) + unless (or (python-syntax-context 'paren) + (equal (char-after) ?=)) + return t))) + + (defadvice! +python--rx-a (&rest regexps) + :override #'python-rx + `(rx-let ((block-start (seq symbol-start + (or "def" "class" "if" "elif" "else" "try" + "except" "finally" "for" "while" "with" + ;; Python 3.5+ PEP492 + (and "async" (+ space) + (or "def" "for" "with"))) + symbol-end)) + (dedenter (seq symbol-start + (or "elif" "else" "except" "finally") + symbol-end)) + (block-ender (seq symbol-start + (or + "break" "continue" "pass" "raise" "return") + symbol-end)) + (decorator (seq line-start (* space) ?@ (any letter ?_) + (* (any word ?_)))) + (defun (seq symbol-start + (or "def" "class" + ;; Python 3.5+ PEP492 + (and "async" (+ space) "def")) + symbol-end)) + (if-name-main (seq line-start "if" (+ space) "__name__" + (+ space) "==" (+ space) + (any ?' ?\") "__main__" (any ?' ?\") + (* space) ?:)) + (symbol-name (seq (any letter ?_) (* (any word ?_)))) + (assignment-target (seq (? ?*) + (* symbol-name ?.) symbol-name + (? ?\[ (+ (not ?\])) ?\]))) + (grouped-assignment-target (seq (? ?*) + (* symbol-name ?.) (group symbol-name) + (? ?\[ (+ (not ?\])) ?\]))) + (open-paren (or "{" "[" "(")) + (close-paren (or "}" "]" ")")) + (simple-operator (any ?+ ?- ?/ ?& ?^ ?~ ?| ?* ?< ?> ?= ?%)) + (not-simple-operator (not (or simple-operator ?\n))) + (operator (or "==" ">=" "is" "not" + "**" "//" "<<" ">>" "<=" "!=" + "+" "-" "/" "&" "^" "~" "|" "*" "<" ">" + "=" "%")) + (assignment-operator (or "+=" "-=" "*=" "/=" "//=" "%=" "**=" + ">>=" "<<=" "&=" "^=" "|=" + "=")) + (string-delimiter (seq + ;; Match even number of backslashes. + (or (not (any ?\\ ?\' ?\")) point + ;; Quotes might be preceded by an + ;; escaped quote. + (and (or (not (any ?\\)) point) ?\\ + (* ?\\ ?\\) (any ?\' ?\"))) + (* ?\\ ?\\) + ;; Match single or triple quotes of any kind. + (group (or "\"\"\"" "\"" "'''" "'")))) + (coding-cookie (seq line-start ?# (* space) + (or + ;; # coding= + (: "coding" (or ?: ?=) (* space) + (group-n 1 (+ (or word ?-)))) + ;; # -*- coding: -*- + (: "-*-" (* space) "coding:" (* space) + (group-n 1 (+ (or word ?-))) + (* space) "-*-") + ;; # vim: set fileencoding= : + (: "vim:" (* space) "set" (+ space) + "fileencoding" (* space) ?= (* space) + (group-n 1 (+ (or word ?-))) + (* space) ":"))))) + (rx ,@regexps))))) (use-package! anaconda-mode