1
1
import builtins
2
2
from pathlib import Path
3
3
from types import ModuleType
4
- from typing import Type , Optional , Set
5
- from pygments .lexers .python import NumPyLexer
4
+ from pygments .token import Name , Keyword
5
+ from typing import Type , Optional , Set , Any
6
+ from pygments .lexers .python import PythonLexer
6
7
from inspect import getmembers , isfunction , ismethod , ismodule , isclass , isbuiltin , ismethoddescriptor
7
8
8
9
@@ -69,22 +70,30 @@ def get_funcs_from_external_module(module: ModuleType, funcs_meths: Set[str]):
69
70
return funcs_meths
70
71
71
72
72
- def get_builtin_funcs ():
73
+ def get_funcs (of : Any ) -> Set [str ]:
74
+ members = getmembers (of , lambda obj : isfunction (obj ) or ismethod (obj ))
75
+ return set (dict (members ))
76
+
77
+
78
+ def get_builtins ():
73
79
funcs_meths = set (dict (getmembers (builtins , isbuiltin )))
80
+ classes = set ()
74
81
75
82
for class_name , _class in getmembers (builtins , isclass ):
76
83
methods = getmembers (_class , ismethoddescriptor )
77
- funcs_meths .update (set (dict (methods )))
84
+ funcs_meths .update (dict (methods ))
85
+ classes .add (class_name )
78
86
79
- return funcs_meths
87
+ return {
88
+ 'funcs' : funcs_meths ,
89
+ 'classes' : classes
90
+ }
80
91
81
92
82
- def get_funcs (of ):
83
- members = getmembers (of , lambda obj : isfunction (obj ) or ismethod (obj ))
84
- return set (dict (members ))
93
+ BUILTINS = get_builtins ()
85
94
86
95
87
- class TDKMethLexer (NumPyLexer ):
96
+ class TDKMethLexer (PythonLexer ):
88
97
"""Adds syntax highlighting for methods and functions within a python Package
89
98
90
99
"""
@@ -93,7 +102,8 @@ class TDKMethLexer(NumPyLexer):
93
102
aliases = ['tdk' ]
94
103
95
104
TOP_LEVEL = None
96
- EXTRA_KEYWORDS = get_builtin_funcs ()
105
+ FUNCS = BUILTINS ['funcs' ]
106
+ CLASSES = BUILTINS ['classes' ]
97
107
98
108
@classmethod
99
109
def get_pkg_lexer (cls , pkg_name : Optional [str ] = None ) -> Type ["TDKMethLexer" ]:
@@ -104,8 +114,30 @@ def get_pkg_lexer(cls, pkg_name: Optional[str] = None) -> Type["TDKMethLexer"]:
104
114
raise ValueError ('Must provide a package name' )
105
115
106
116
pkg = __import__ (cls .TOP_LEVEL )
117
+
118
+ # Add names of all funcs/meths in the package
107
119
funcs = get_pkg_funcs (pkg , cls .TOP_LEVEL )
108
- cls .EXTRA_KEYWORDS .update (funcs )
120
+ cls .FUNCS .update (funcs )
109
121
return cls
110
122
123
+ def get_tokens_unprocessed (self , text ):
124
+ tokens = list (PythonLexer .get_tokens_unprocessed (self , text ))
125
+
126
+ for token_idx , (index , token , value ) in enumerate (tokens ):
127
+ if token is Name .Builtin and value in self .CLASSES :
128
+ if tokens [token_idx + 1 ][- 1 ] == '(' :
129
+ yield index , Name .Builtin , value # Highlight as function call
130
+ else :
131
+ yield index , Name .Builtin .Pseudo , value # Highlight as type hint
111
132
133
+ elif token is Name and value in self .FUNCS :
134
+ if tokens [token_idx + 1 ][- 1 ] == '(' :
135
+ yield index , Keyword .Pseudo , value
136
+ else :
137
+ yield index , Name , value
138
+
139
+ elif token is Name and value [0 ].isupper ():
140
+ yield index , Name .Class , value
141
+
142
+ else :
143
+ yield index , token , value
0 commit comments