diff options
| author | kobarity | 2025-02-05 00:02:05 +0900 |
|---|---|---|
| committer | Stefan Kangas | 2025-02-04 23:28:00 +0100 |
| commit | 999d054dc1e265f1a39c10035a3a3f7f75de8445 (patch) | |
| tree | 7f2b906f03434ce890fdbb6b0db37b6b7843bd19 /lisp/progmodes/python.el | |
| parent | 7d85f678f33029cc874da2aaa89cf95a45403146 (diff) | |
| download | emacs-999d054dc1e265f1a39c10035a3a3f7f75de8445.tar.gz emacs-999d054dc1e265f1a39c10035a3a3f7f75de8445.zip | |
Make it configurable to highlight Python 2 builtins
By default, Python 2-only builtins are not highlighted.
* lisp/progmodes/python.el (python-2-support): New defcustom.
(python-font-lock-builtin-types)
(python-font-lock-builtins-python3)
(python-font-lock-builtins-python2)
(python-font-lock-builtins)
(python-font-lock-special-attributes)
(python-font-lock-builtin-exceptions-python3)
(python-font-lock-builtin-exceptions-python2)
(python-font-lock-builtin-exceptions): New variables.
(python-font-lock-keywords-level-2)
(python-font-lock-keywords-maximum-decoration)
(python--treesit-builtin-types)
(python--treesit-builtins)
(python--treesit-special-attributes)
(python--treesit-exceptions): Use new variables.
Co-authored-by: Konstantin Kharlamov <Hi-Angel@yandex.ru>
Co-authored-by: Stefan Kangas <stefankangas@gmail.com>
Diffstat (limited to 'lisp/progmodes/python.el')
| -rw-r--r-- | lisp/progmodes/python.el | 197 |
1 files changed, 91 insertions, 106 deletions
diff --git a/lisp/progmodes/python.el b/lisp/progmodes/python.el index 3a297a3979c..8a99ff0434d 100644 --- a/lisp/progmodes/python.el +++ b/lisp/progmodes/python.el | |||
| @@ -316,6 +316,16 @@ To customize the Python interpreter for interactive use, modify | |||
| 316 | :version "30.1" | 316 | :version "30.1" |
| 317 | :type 'string) | 317 | :type 'string) |
| 318 | 318 | ||
| 319 | (defcustom python-2-support nil | ||
| 320 | "If non-nil, enable Python 2 support. | ||
| 321 | Currently only affects highlighting. | ||
| 322 | |||
| 323 | After customizing this variable, you must restart Emacs for it to take | ||
| 324 | effect." | ||
| 325 | :version "31.1" | ||
| 326 | :type 'boolean | ||
| 327 | :safe 'booleanp) | ||
| 328 | |||
| 319 | 329 | ||
| 320 | ;;; Bindings | 330 | ;;; Bindings |
| 321 | 331 | ||
| @@ -689,6 +699,40 @@ the {...} holes that appear within f-strings." | |||
| 689 | This is the minimum decoration level, including function and | 699 | This is the minimum decoration level, including function and |
| 690 | class declarations.") | 700 | class declarations.") |
| 691 | 701 | ||
| 702 | (defvar python-font-lock-builtin-types | ||
| 703 | '("bool" "bytearray" "bytes" "complex" "dict" "float" "frozenset" | ||
| 704 | "int" "list" "memoryview" "range" "set" "str" "tuple")) | ||
| 705 | |||
| 706 | (defvar python-font-lock-builtins-python3 | ||
| 707 | '("abs" "aiter" "all" "anext" "any" "ascii" "bin" "breakpoint" | ||
| 708 | "callable" "chr" "classmethod" "compile" "delattr" "dir" "divmod" | ||
| 709 | "enumerate" "eval" "exec" "filter" "format" "getattr" "globals" | ||
| 710 | "hasattr" "hash" "help" "hex" "id" "input" "isinstance" | ||
| 711 | "issubclass" "iter" "len" "locals" "map" "max" "min" "next" | ||
| 712 | "object" "oct" "open" "ord" "pow" "print" "property" "repr" | ||
| 713 | "reversed" "round" "setattr" "slice" "sorted" "staticmethod" "sum" | ||
| 714 | "super" "type" "vars" "zip" "__import__")) | ||
| 715 | |||
| 716 | (defvar python-font-lock-builtins-python2 | ||
| 717 | '("basestring" "cmp" "execfile" "file" "long" "raw_input" "reduce" | ||
| 718 | "reload" "unichr" "unicode" "xrange" "apply" "buffer" "coerce" | ||
| 719 | "intern")) | ||
| 720 | |||
| 721 | (defvar python-font-lock-builtins | ||
| 722 | (append python-font-lock-builtins-python3 | ||
| 723 | (when python-2-support | ||
| 724 | python-font-lock-builtins-python2))) | ||
| 725 | |||
| 726 | (defvar python-font-lock-special-attributes | ||
| 727 | '(;; https://docs.python.org/3/reference/datamodel.html | ||
| 728 | "__annotations__" "__bases__" "__closure__" "__code__" | ||
| 729 | "__defaults__" "__dict__" "__doc__" "__firstlineno__" | ||
| 730 | "__globals__" "__kwdefaults__" "__name__" "__module__" | ||
| 731 | "__mro__" "__package__" "__qualname__" | ||
| 732 | "__static_attributes__" "__type_params__" | ||
| 733 | ;; Extras: | ||
| 734 | "__all__")) | ||
| 735 | |||
| 692 | (defvar python-font-lock-keywords-level-2 | 736 | (defvar python-font-lock-keywords-level-2 |
| 693 | `(,@python-font-lock-keywords-level-1 | 737 | `(,@python-font-lock-keywords-level-1 |
| 694 | ,(rx symbol-start | 738 | ,(rx symbol-start |
| @@ -711,33 +755,11 @@ class declarations.") | |||
| 711 | "self") | 755 | "self") |
| 712 | symbol-end) | 756 | symbol-end) |
| 713 | ;; Builtins | 757 | ;; Builtins |
| 714 | (,(rx symbol-start | 758 | (,(rx-to-string `(seq symbol-start |
| 715 | (or | 759 | (or ,@(append python-font-lock-builtin-types |
| 716 | "abs" "all" "any" "bin" "bool" "callable" "chr" "classmethod" | 760 | python-font-lock-builtins |
| 717 | "compile" "complex" "delattr" "dict" "dir" "divmod" "enumerate" | 761 | python-font-lock-special-attributes)) |
| 718 | "eval" "filter" "float" "format" "frozenset" "getattr" "globals" | 762 | symbol-end)) . font-lock-builtin-face)) |
| 719 | "hasattr" "hash" "help" "hex" "id" "input" "int" "isinstance" | ||
| 720 | "issubclass" "iter" "len" "list" "locals" "map" "max" "memoryview" | ||
| 721 | "min" "next" "object" "oct" "open" "ord" "pow" "print" "property" | ||
| 722 | "range" "repr" "reversed" "round" "set" "setattr" "slice" "sorted" | ||
| 723 | "staticmethod" "str" "sum" "super" "tuple" "type" "vars" "zip" | ||
| 724 | "__import__" | ||
| 725 | ;; Python 2: | ||
| 726 | "basestring" "cmp" "execfile" "file" "long" "raw_input" "reduce" | ||
| 727 | "reload" "unichr" "unicode" "xrange" "apply" "buffer" "coerce" | ||
| 728 | "intern" | ||
| 729 | ;; Python 3: | ||
| 730 | "aiter" "anext" "ascii" "breakpoint" "bytearray" "bytes" "exec" | ||
| 731 | ;; Special attributes: | ||
| 732 | ;; https://docs.python.org/3/reference/datamodel.html | ||
| 733 | "__annotations__" "__bases__" "__closure__" "__code__" | ||
| 734 | "__defaults__" "__dict__" "__doc__" "__firstlineno__" | ||
| 735 | "__globals__" "__kwdefaults__" "__name__" "__module__" | ||
| 736 | "__mro__" "__package__" "__qualname__" | ||
| 737 | "__static_attributes__" "__type_params__" | ||
| 738 | ;; Extras: | ||
| 739 | "__all__") | ||
| 740 | symbol-end) . font-lock-builtin-face)) | ||
| 741 | "Font lock keywords to use in `python-mode' for level 2 decoration. | 763 | "Font lock keywords to use in `python-mode' for level 2 decoration. |
| 742 | 764 | ||
| 743 | This is the medium decoration level, including everything in | 765 | This is the medium decoration level, including everything in |
| @@ -759,6 +781,41 @@ sign in chained assignment." | |||
| 759 | (equal (char-after) ?=)) | 781 | (equal (char-after) ?=)) |
| 760 | return (progn (backward-char) t)))) | 782 | return (progn (backward-char) t)))) |
| 761 | 783 | ||
| 784 | (defvar python-font-lock-builtin-exceptions-python3 | ||
| 785 | '(;; Python 2 and 3: | ||
| 786 | "ArithmeticError" "AssertionError" "AttributeError" "BaseException" | ||
| 787 | "BufferError" "BytesWarning" "DeprecationWarning" "EOFError" | ||
| 788 | "EnvironmentError" "Exception" "FloatingPointError" "FutureWarning" | ||
| 789 | "GeneratorExit" "IOError" "ImportError" "ImportWarning" | ||
| 790 | "IndentationError" "IndexError" "KeyError" "KeyboardInterrupt" | ||
| 791 | "LookupError" "MemoryError" "NameError" "NotImplementedError" | ||
| 792 | "OSError" "OverflowError" "PendingDeprecationWarning" | ||
| 793 | "ReferenceError" "RuntimeError" "RuntimeWarning" "StopIteration" | ||
| 794 | "SyntaxError" "SyntaxWarning" "SystemError" "SystemExit" "TabError" | ||
| 795 | "TypeError" "UnboundLocalError" "UnicodeDecodeError" | ||
| 796 | "UnicodeEncodeError" "UnicodeError" "UnicodeTranslateError" | ||
| 797 | "UnicodeWarning" "UserWarning" "ValueError" "Warning" | ||
| 798 | "ZeroDivisionError" | ||
| 799 | ;; Python 3: | ||
| 800 | "BlockingIOError" "BrokenPipeError" "ChildProcessError" | ||
| 801 | "ConnectionAbortedError" "ConnectionError" "ConnectionRefusedError" | ||
| 802 | "ConnectionResetError" "EncodingWarning" "FileExistsError" | ||
| 803 | "FileNotFoundError" "InterruptedError" "IsADirectoryError" | ||
| 804 | "NotADirectoryError" "ModuleNotFoundError" "PermissionError" | ||
| 805 | "ProcessLookupError" "PythonFinalizationError" "RecursionError" | ||
| 806 | "ResourceWarning" "StopAsyncIteration" "TimeoutError" | ||
| 807 | "BaseExceptionGroup" "ExceptionGroup" | ||
| 808 | ;; OS specific | ||
| 809 | "VMSError" "WindowsError")) | ||
| 810 | |||
| 811 | (defvar python-font-lock-builtin-exceptions-python2 | ||
| 812 | '("StandardError")) | ||
| 813 | |||
| 814 | (defvar python-font-lock-builtin-exceptions | ||
| 815 | (append python-font-lock-builtin-exceptions-python3 | ||
| 816 | (when python-2-support | ||
| 817 | python-font-lock-builtin-exceptions-python2))) | ||
| 818 | |||
| 762 | (defvar python-font-lock-keywords-maximum-decoration | 819 | (defvar python-font-lock-keywords-maximum-decoration |
| 763 | `((python--font-lock-f-strings) | 820 | `((python--font-lock-f-strings) |
| 764 | ,@python-font-lock-keywords-level-2 | 821 | ,@python-font-lock-keywords-level-2 |
| @@ -776,38 +833,9 @@ sign in chained assignment." | |||
| 776 | (0+ "." (1+ (or word ?_))))) | 833 | (0+ "." (1+ (or word ?_))))) |
| 777 | (1 font-lock-type-face)) | 834 | (1 font-lock-type-face)) |
| 778 | ;; Builtin Exceptions | 835 | ;; Builtin Exceptions |
| 779 | (,(rx symbol-start | 836 | (,(rx-to-string `(seq symbol-start |
| 780 | (or | 837 | (or ,@python-font-lock-builtin-exceptions) |
| 781 | ;; Python 2 and 3: | 838 | symbol-end)) . font-lock-type-face) |
| 782 | "ArithmeticError" "AssertionError" "AttributeError" "BaseException" | ||
| 783 | "BufferError" "BytesWarning" "DeprecationWarning" "EOFError" | ||
| 784 | "EnvironmentError" "Exception" "FloatingPointError" "FutureWarning" | ||
| 785 | "GeneratorExit" "IOError" "ImportError" "ImportWarning" | ||
| 786 | "IndentationError" "IndexError" "KeyError" "KeyboardInterrupt" | ||
| 787 | "LookupError" "MemoryError" "NameError" "NotImplementedError" | ||
| 788 | "OSError" "OverflowError" "PendingDeprecationWarning" | ||
| 789 | "ReferenceError" "RuntimeError" "RuntimeWarning" "StopIteration" | ||
| 790 | "SyntaxError" "SyntaxWarning" "SystemError" "SystemExit" "TabError" | ||
| 791 | "TypeError" "UnboundLocalError" "UnicodeDecodeError" | ||
| 792 | "UnicodeEncodeError" "UnicodeError" "UnicodeTranslateError" | ||
| 793 | "UnicodeWarning" "UserWarning" "ValueError" "Warning" | ||
| 794 | "ZeroDivisionError" | ||
| 795 | ;; Python 2: | ||
| 796 | "StandardError" | ||
| 797 | ;; Python 3: | ||
| 798 | "BlockingIOError" "BrokenPipeError" "ChildProcessError" | ||
| 799 | "ConnectionAbortedError" "ConnectionError" "ConnectionRefusedError" | ||
| 800 | "ConnectionResetError" "EncodingWarning" "FileExistsError" | ||
| 801 | "FileNotFoundError" "InterruptedError" "IsADirectoryError" | ||
| 802 | "NotADirectoryError" "ModuleNotFoundError" "PermissionError" | ||
| 803 | "ProcessLookupError" "PythonFinalizationError" "RecursionError" | ||
| 804 | "ResourceWarning" "StopAsyncIteration" "TimeoutError" | ||
| 805 | "BaseExceptionGroup" "ExceptionGroup" | ||
| 806 | ;; OS specific | ||
| 807 | "VMSError" "WindowsError" | ||
| 808 | ) | ||
| 809 | symbol-end) | ||
| 810 | . font-lock-type-face) | ||
| 811 | ;; single assignment with/without type hints, e.g. | 839 | ;; single assignment with/without type hints, e.g. |
| 812 | ;; a: int = 5 | 840 | ;; a: int = 5 |
| 813 | ;; b: Tuple[Optional[int], Union[Sequence[str], str]] = (None, 'foo') | 841 | ;; b: Tuple[Optional[int], Union[Sequence[str], str]] = (None, 'foo') |
| @@ -1015,8 +1043,7 @@ It makes underscores and dots word constituent chars.") | |||
| 1015 | "and" "in" "is" "not" "or" "not in" "is not")) | 1043 | "and" "in" "is" "not" "or" "not in" "is not")) |
| 1016 | 1044 | ||
| 1017 | (defvar python--treesit-builtin-types | 1045 | (defvar python--treesit-builtin-types |
| 1018 | '("int" "float" "complex" "bool" "list" "tuple" "range" "str" | 1046 | python-font-lock-builtin-types) |
| 1019 | "bytes" "bytearray" "memoryview" "set" "frozenset" "dict")) | ||
| 1020 | 1047 | ||
| 1021 | (defvar python--treesit-type-regex | 1048 | (defvar python--treesit-type-regex |
| 1022 | (rx-to-string `(seq bol (or | 1049 | (rx-to-string `(seq bol (or |
| @@ -1025,17 +1052,7 @@ It makes underscores and dots word constituent chars.") | |||
| 1025 | eol))) | 1052 | eol))) |
| 1026 | 1053 | ||
| 1027 | (defvar python--treesit-builtins | 1054 | (defvar python--treesit-builtins |
| 1028 | (append python--treesit-builtin-types | 1055 | python-font-lock-builtins) |
| 1029 | '("abs" "aiter" "all" "anext" "any" "ascii" "bin" "breakpoint" | ||
| 1030 | "callable" "chr" "classmethod" "compile" | ||
| 1031 | "delattr" "dir" "divmod" "enumerate" "eval" "exec" | ||
| 1032 | "filter" "format" "getattr" "globals" | ||
| 1033 | "hasattr" "hash" "help" "hex" "id" "input" "isinstance" | ||
| 1034 | "issubclass" "iter" "len" "locals" "map" "max" | ||
| 1035 | "min" "next" "object" "oct" "open" "ord" "pow" | ||
| 1036 | "print" "property" "repr" "reversed" "round" | ||
| 1037 | "setattr" "slice" "sorted" "staticmethod" "sum" "super" | ||
| 1038 | "type" "vars" "zip" "__import__"))) | ||
| 1039 | 1056 | ||
| 1040 | (defvar python--treesit-constants | 1057 | (defvar python--treesit-constants |
| 1041 | '("Ellipsis" "False" "None" "NotImplemented" "True" "__debug__" | 1058 | '("Ellipsis" "False" "None" "NotImplemented" "True" "__debug__" |
| @@ -1047,42 +1064,10 @@ It makes underscores and dots word constituent chars.") | |||
| 1047 | ">>" ">>=" "|" "|=" "~" "@" "@=")) | 1064 | ">>" ">>=" "|" "|=" "~" "@" "@=")) |
| 1048 | 1065 | ||
| 1049 | (defvar python--treesit-special-attributes | 1066 | (defvar python--treesit-special-attributes |
| 1050 | '("__annotations__" "__bases__" "__closure__" "__code__" | 1067 | python-font-lock-special-attributes) |
| 1051 | "__defaults__" "__dict__" "__doc__" "__firstlineno__" | ||
| 1052 | "__globals__" "__kwdefaults__" "__name__" "__module__" | ||
| 1053 | "__mro__" "__package__" "__qualname__" | ||
| 1054 | "__static_attributes__" "__type_params__" | ||
| 1055 | "__all__")) | ||
| 1056 | 1068 | ||
| 1057 | (defvar python--treesit-exceptions | 1069 | (defvar python--treesit-exceptions |
| 1058 | '(;; Python 2 and 3: | 1070 | python-font-lock-builtin-exceptions) |
| 1059 | "ArithmeticError" "AssertionError" "AttributeError" "BaseException" | ||
| 1060 | "BufferError" "BytesWarning" "DeprecationWarning" "EOFError" | ||
| 1061 | "EnvironmentError" "Exception" "FloatingPointError" "FutureWarning" | ||
| 1062 | "GeneratorExit" "IOError" "ImportError" "ImportWarning" | ||
| 1063 | "IndentationError" "IndexError" "KeyError" "KeyboardInterrupt" | ||
| 1064 | "LookupError" "MemoryError" "NameError" "NotImplementedError" | ||
| 1065 | "OSError" "OverflowError" "PendingDeprecationWarning" | ||
| 1066 | "ReferenceError" "RuntimeError" "RuntimeWarning" "StopIteration" | ||
| 1067 | "SyntaxError" "SyntaxWarning" "SystemError" "SystemExit" "TabError" | ||
| 1068 | "TypeError" "UnboundLocalError" "UnicodeDecodeError" | ||
| 1069 | "UnicodeEncodeError" "UnicodeError" "UnicodeTranslateError" | ||
| 1070 | "UnicodeWarning" "UserWarning" "ValueError" "Warning" | ||
| 1071 | "ZeroDivisionError" | ||
| 1072 | ;; Python 2: | ||
| 1073 | "StandardError" | ||
| 1074 | ;; Python 3: | ||
| 1075 | "BlockingIOError" "BrokenPipeError" "ChildProcessError" | ||
| 1076 | "ConnectionAbortedError" "ConnectionError" "ConnectionRefusedError" | ||
| 1077 | "ConnectionResetError" "EncodingWarning" "FileExistsError" | ||
| 1078 | "FileNotFoundError" "InterruptedError" "IsADirectoryError" | ||
| 1079 | "NotADirectoryError" "ModuleNotFoundError" "PermissionError" | ||
| 1080 | "ProcessLookupError" "PythonFinalizationError" "RecursionError" | ||
| 1081 | "ResourceWarning" "StopAsyncIteration" "TimeoutError" | ||
| 1082 | "BaseExceptionGroup" "ExceptionGroup" | ||
| 1083 | ;; OS specific | ||
| 1084 | "VMSError" "WindowsError" | ||
| 1085 | )) | ||
| 1086 | 1071 | ||
| 1087 | (defun python--treesit-fontify-string (node override start end &rest _) | 1072 | (defun python--treesit-fontify-string (node override start end &rest _) |
| 1088 | "Fontify string. | 1073 | "Fontify string. |