diff --git a/modules/lang/python/autoload/compat-28.1.el b/modules/lang/python/autoload/compat-28.1.el new file mode 100644 index 000000000..5bce50cb7 --- /dev/null +++ b/modules/lang/python/autoload/compat-28.1.el @@ -0,0 +1,94 @@ +;;; lang/python/autoload/compat-28.1.el -*- lexical-binding: t; -*- +;;;###if (versionp! "28.0" <= emacs-version <= "28.1") +;;; Commentary: +;; +;; HACK: 28.1 introduced breakage into the syntax highlighter for `python-mode'. +;; The fix was introduced shortly after, but did not make the 28.1 release. +;; This fix exists solely to patch that issue for 28.1 users. +;; +;; DEPRECATED: Remove when 28.1 support is dropped +;; +;;; Code: + +;;;###autoload +(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))) + +;;;###autoload +(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))) + +;;; compat-28.1.el ends here diff --git a/modules/lang/python/config.el b/modules/lang/python/config.el index 0c8a7615f..49bcfeda0 100644 --- a/modules/lang/python/config.el +++ b/modules/lang/python/config.el @@ -86,90 +86,7 @@ (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) - - ;; 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))))) + (setq-hook! 'python-mode-hook tab-width python-indent-offset)) (use-package! anaconda-mode