liveConsole 1.2.0__py3-none-any.whl → 1.3.1__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- liveConsole.py +59 -44
- {liveconsole-1.2.0.dist-info → liveconsole-1.3.1.dist-info}/METADATA +1 -1
- liveconsole-1.3.1.dist-info/RECORD +7 -0
- liveconsole-1.2.0.dist-info/RECORD +0 -7
- {liveconsole-1.2.0.dist-info → liveconsole-1.3.1.dist-info}/WHEEL +0 -0
- {liveconsole-1.2.0.dist-info → liveconsole-1.3.1.dist-info}/licenses/LICENSE +0 -0
- {liveconsole-1.2.0.dist-info → liveconsole-1.3.1.dist-info}/top_level.txt +0 -0
liveConsole.py
CHANGED
@@ -30,7 +30,9 @@ class StdoutRedirect(io.StringIO):
|
|
30
30
|
class CodeSuggestionManager:
|
31
31
|
"""Manages code suggestions and autocomplete functionality."""
|
32
32
|
|
33
|
-
def __init__(self, textWidget):
|
33
|
+
def __init__(self, textWidget, userLocals, userGlobals):
|
34
|
+
self.userLocals = userLocals
|
35
|
+
self.userGlobals = userGlobals
|
34
36
|
self.textWidget = textWidget
|
35
37
|
self.suggestionWindow = None
|
36
38
|
self.suggestionListbox = None
|
@@ -42,60 +44,72 @@ class CodeSuggestionManager:
|
|
42
44
|
self.builtins = [name for name in dir(builtins) if not name.startswith('_')]
|
43
45
|
|
44
46
|
def getCurrentWord(self):
|
45
|
-
"""Extract the word being typed at cursor position."""
|
47
|
+
"""Extract the word being typed at cursor position and suggest dir() if applicable."""
|
48
|
+
suggestions = []
|
46
49
|
cursorPos = self.textWidget.index(tk.INSERT)
|
47
50
|
lineStart = self.textWidget.index(f"{cursorPos} linestart")
|
48
51
|
currentLine = self.textWidget.get(lineStart, cursorPos)
|
49
|
-
|
52
|
+
|
50
53
|
# Find the current word
|
51
54
|
words = currentLine.split()
|
52
55
|
if not words:
|
53
|
-
return ""
|
54
|
-
|
56
|
+
return "", suggestions
|
57
|
+
|
55
58
|
currentWord = words[-1]
|
56
|
-
|
59
|
+
|
60
|
+
|
61
|
+
# If the word contains a dot, try to evaluate the base and get its dir()
|
62
|
+
if '.' in currentWord:
|
63
|
+
try:
|
64
|
+
base_expr = '.'.join(currentWord.split('.')[:-1])
|
65
|
+
obj = eval(base_expr, self.userLocals, self.userGlobals)
|
66
|
+
suggestions = dir(obj)
|
67
|
+
except Exception as e:
|
68
|
+
print(e)
|
57
69
|
for char in "([{,.":
|
58
70
|
if char in currentWord:
|
59
71
|
currentWord = currentWord.split(char)[-1]
|
60
|
-
|
61
|
-
return currentWord
|
72
|
+
|
73
|
+
return currentWord, suggestions
|
62
74
|
|
63
|
-
def getSuggestions(self, partialWord):
|
75
|
+
def getSuggestions(self, partialWord, suggestions=[]):
|
64
76
|
"""Get code suggestions for partial word."""
|
65
77
|
if len(partialWord) < 2:
|
66
|
-
return
|
67
|
-
|
68
|
-
suggestions = []
|
69
|
-
|
70
|
-
# Add matching keywords
|
71
|
-
for kw in self.keywords:
|
72
|
-
if kw.startswith(partialWord.lower()):
|
73
|
-
suggestions.append(kw)
|
74
|
-
|
75
|
-
# Add matching builtins
|
76
|
-
for builtin in self.builtins:
|
77
|
-
if builtin.startswith(partialWord):
|
78
|
-
suggestions.append(builtin)
|
79
|
-
|
80
|
-
# Add matching variables from namespace
|
81
|
-
master = self.textWidget.master
|
82
|
-
if hasattr(master, 'userLocals'):
|
83
|
-
for var in master.userLocals:
|
84
|
-
if var.startswith(partialWord) and not var.startswith('_'):
|
85
|
-
suggestions.append(var)
|
78
|
+
return suggestions
|
86
79
|
|
87
|
-
|
88
|
-
|
89
|
-
|
90
|
-
|
80
|
+
# print(partialWord)
|
81
|
+
if suggestions != []:
|
82
|
+
suggestions = [suggestion for suggestion in suggestions if suggestion.lower().startswith(partialWord.lower())]
|
83
|
+
else:
|
84
|
+
# Add matching keywords
|
85
|
+
for kw in self.keywords:
|
86
|
+
if kw.startswith(partialWord.lower()):
|
87
|
+
suggestions.append(kw)
|
88
|
+
|
89
|
+
# Add matching builtins
|
90
|
+
for builtin in self.builtins:
|
91
|
+
if builtin.startswith(partialWord):
|
92
|
+
suggestions.append(builtin)
|
93
|
+
|
94
|
+
# Add matching variables from namespace
|
95
|
+
master = self.textWidget.master
|
96
|
+
if hasattr(master, 'userLocals'):
|
97
|
+
for var in master.userLocals:
|
98
|
+
if var.startswith(partialWord) and not var.startswith('_'):
|
99
|
+
suggestions.append(var)
|
100
|
+
|
101
|
+
if hasattr(master, 'userGlobals'):
|
102
|
+
for var in master.userGlobals:
|
103
|
+
if var.startswith(partialWord) and not var.startswith('_'):
|
104
|
+
suggestions.append(var)
|
91
105
|
|
92
106
|
# Remove duplicates and sort
|
93
|
-
return sorted(list(set(suggestions)))
|
107
|
+
return sorted(list(set(suggestions)))
|
94
108
|
|
95
109
|
def showSuggestions(self):
|
96
110
|
"""Display the suggestions popup."""
|
97
|
-
currentWord = self.getCurrentWord()
|
98
|
-
suggestions = self.getSuggestions(currentWord)
|
111
|
+
currentWord, extraSuggestions = self.getCurrentWord()
|
112
|
+
suggestions = self.getSuggestions(currentWord, extraSuggestions)
|
99
113
|
|
100
114
|
if not suggestions:
|
101
115
|
self.hideSuggestions()
|
@@ -155,12 +169,11 @@ class CodeSuggestionManager:
|
|
155
169
|
if not suggestion:
|
156
170
|
return
|
157
171
|
|
158
|
-
currentWord = self.getCurrentWord()
|
159
|
-
|
160
|
-
|
161
|
-
|
162
|
-
|
163
|
-
self.textWidget.insert(cursorPos, missingPart)
|
172
|
+
currentWord, _ = self.getCurrentWord()
|
173
|
+
# Only insert the missing part
|
174
|
+
missingPart = suggestion[len(currentWord):]
|
175
|
+
cursorPos = self.textWidget.index(tk.INSERT)
|
176
|
+
self.textWidget.insert(cursorPos, missingPart)
|
164
177
|
|
165
178
|
self.hideSuggestions()
|
166
179
|
|
@@ -220,11 +233,11 @@ class InteractiveConsoleText(tk.Text):
|
|
220
233
|
PROMPT = ">>> "
|
221
234
|
PROMPT_LENGTH = 4
|
222
235
|
|
223
|
-
def __init__(self, master, **kwargs):
|
236
|
+
def __init__(self, master, userLocals=None, userGlobals=None, **kwargs):
|
224
237
|
super().__init__(master, **kwargs)
|
225
238
|
|
226
239
|
# Initialize components
|
227
|
-
self.suggestionManager = CodeSuggestionManager(self)
|
240
|
+
self.suggestionManager = CodeSuggestionManager(self, userLocals=userLocals, userGlobals=userGlobals)
|
228
241
|
|
229
242
|
self.navigatingHistory = False
|
230
243
|
self.history = CommandHistory()
|
@@ -602,6 +615,8 @@ class InteractiveConsole(ctk.CTk):
|
|
602
615
|
# Console text widget
|
603
616
|
self.console = InteractiveConsoleText(
|
604
617
|
frame,
|
618
|
+
userGlobals=self.userGlobals,
|
619
|
+
userLocals=self.userLocals,
|
605
620
|
wrap="word",
|
606
621
|
bg="#1e1e1e",
|
607
622
|
fg="white",
|
@@ -0,0 +1,7 @@
|
|
1
|
+
__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
+
liveConsole.py,sha256=WcLmiqUR5x1HMMhkW0-O2ya0kfkt6lPD7Zcn3OX2yGk,23198
|
3
|
+
liveconsole-1.3.1.dist-info/licenses/LICENSE,sha256=7dZ0zL72aGaFE0C9DxacOpnaSkC5jajhG6iL7lqhWmU,1064
|
4
|
+
liveconsole-1.3.1.dist-info/METADATA,sha256=t5baVSG6jIMuw7Tje8DrAf7MjshBrFm5z0mpWyJg-54,3264
|
5
|
+
liveconsole-1.3.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
6
|
+
liveconsole-1.3.1.dist-info/top_level.txt,sha256=0gva5OCe9lWcj5T88SwGimDDbqsdVqIGQNs98NBH1K0,21
|
7
|
+
liveconsole-1.3.1.dist-info/RECORD,,
|
@@ -1,7 +0,0 @@
|
|
1
|
-
__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
2
|
-
liveConsole.py,sha256=xpGmtFXzYhPNSN2_SLn4ZNfkqs0N-ZTPCHOzfh3I-X4,22333
|
3
|
-
liveconsole-1.2.0.dist-info/licenses/LICENSE,sha256=7dZ0zL72aGaFE0C9DxacOpnaSkC5jajhG6iL7lqhWmU,1064
|
4
|
-
liveconsole-1.2.0.dist-info/METADATA,sha256=Kjpd8EstbIfYrfedOMg8kRFKYwR2pawG_Lviu_IemvM,3264
|
5
|
-
liveconsole-1.2.0.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
6
|
-
liveconsole-1.2.0.dist-info/top_level.txt,sha256=0gva5OCe9lWcj5T88SwGimDDbqsdVqIGQNs98NBH1K0,21
|
7
|
-
liveconsole-1.2.0.dist-info/RECORD,,
|
File without changes
|
File without changes
|
File without changes
|