liveConsole 1.6.2__py3-none-any.whl → 1.7.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.
Potentially problematic release.
This version of liveConsole might be problematic. Click here for more details.
- {liveconsole-1.6.2.dist-info → liveconsole-1.7.1.dist-info}/METADATA +21 -1
- liveconsole-1.7.1.dist-info/RECORD +18 -0
- pysole/mainConsole.py +41 -21
- pysole/pysole.py +81 -14
- pysole/settings.json +1 -0
- pysole/styledTextbox.py +1 -0
- pysole/themes.json +4 -0
- pysole/utils.py +6 -0
- liveconsole-1.6.2.dist-info/RECORD +0 -18
- {liveconsole-1.6.2.dist-info → liveconsole-1.7.1.dist-info}/WHEEL +0 -0
- {liveconsole-1.6.2.dist-info → liveconsole-1.7.1.dist-info}/entry_points.txt +0 -0
- {liveconsole-1.6.2.dist-info → liveconsole-1.7.1.dist-info}/licenses/LICENSE +0 -0
- {liveconsole-1.6.2.dist-info → liveconsole-1.7.1.dist-info}/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: liveConsole
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.7.1
|
|
4
4
|
Summary: An IDLE-like debugger to allow for real-time command injection for debugging and testing python code
|
|
5
5
|
Author-email: Tzur Soffer <tzur.soffer@gmail.com>
|
|
6
6
|
License: MIT
|
|
@@ -21,6 +21,8 @@ A fully-featured, **live Python console GUI** built with **CustomTkinter** and *
|
|
|
21
21
|
* Python syntax highlighting via **Pygments**
|
|
22
22
|
|
|
23
23
|
* Autocomplete for **keywords, built-ins, and local/global variables**
|
|
24
|
+
|
|
25
|
+
* Run code at startup for easier debugging
|
|
24
26
|
|
|
25
27
|
* Thread-safe execution of Python code
|
|
26
28
|
|
|
@@ -52,6 +54,15 @@ A fully-featured, **live Python console GUI** built with **CustomTkinter** and *
|
|
|
52
54
|
|
|
53
55
|
* Highlights Python keywords, built-ins, and expressions in the console.
|
|
54
56
|
|
|
57
|
+
### Run Code at Startup
|
|
58
|
+
|
|
59
|
+
* Pysole can automatically execute Python code when the console launches.
|
|
60
|
+
|
|
61
|
+
* Use the runRemainingCode=True argument in pysole.probe() to run all remaining lines in the calling script after the probe() call.
|
|
62
|
+
|
|
63
|
+
* The printStartupCode flag controls whether these lines are printed in the console as they execute (True) or run silently (False).
|
|
64
|
+
|
|
65
|
+
* Useful for initializing variables, importing libraries, or setting up your environment automatically.
|
|
55
66
|
|
|
56
67
|
### Autocomplete
|
|
57
68
|
|
|
@@ -110,6 +121,15 @@ A fully-featured, **live Python console GUI** built with **CustomTkinter** and *
|
|
|
110
121
|
import pysole
|
|
111
122
|
pysole.probe()
|
|
112
123
|
```
|
|
124
|
+
or for also running some code at the startup of the pysole
|
|
125
|
+
```
|
|
126
|
+
import pysole
|
|
127
|
+
pysole.probe(runRemainingCode=True, #< for executing the code below probe
|
|
128
|
+
printStartupCode=True #< for printing the command as well as it output
|
|
129
|
+
)
|
|
130
|
+
x = 1 #< initialize some variable
|
|
131
|
+
print(x) #< print the variable on the console
|
|
132
|
+
```
|
|
113
133
|
|
|
114
134
|
* Type Python commands in the `>>>` prompt and see live output.
|
|
115
135
|
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
liveconsole-1.7.1.dist-info/licenses/LICENSE,sha256=7dZ0zL72aGaFE0C9DxacOpnaSkC5jajhG6iL7lqhWmU,1064
|
|
2
|
+
pysole/__init__.py,sha256=SfaSBmFVSmhyf55UedBCqhi2Ss6Tre-BCKtZb3bSr2k,60
|
|
3
|
+
pysole/__main__.py,sha256=QvVFH8J2yzgQaF9MosQ6ajCW67uiRbYliePsTEUCIAg,82
|
|
4
|
+
pysole/commandHistory.py,sha256=xJtWbJ_vgJo2QGgaZJsApTOi_Hm8Yz0V9_zqQUCItj8,1084
|
|
5
|
+
pysole/helpTab.py,sha256=o0uSY-8sw7FuuBrt0FQwcgK6ljNVx3IgRnW7heZ6GvY,2454
|
|
6
|
+
pysole/liveConsole.py,sha256=lzS3dphAQ1i8pQC4E2FY-FyMMSKi-dAN0xr6XUgrNmo,168
|
|
7
|
+
pysole/mainConsole.py,sha256=AzAUSP5W1jUhYnnGUNOG8LUGPkRW8jOqOHlk-pJC_V4,15053
|
|
8
|
+
pysole/pysole.py,sha256=anitwu82nowLlW1e3ukD3pde1zLu7CLfJ0YTXnqe5aU,11994
|
|
9
|
+
pysole/settings.json,sha256=oFguWetRe_vGXUrqWSFUvY3JmGIArUZYpSiA8YZgRU8,722
|
|
10
|
+
pysole/styledTextbox.py,sha256=qWnwGAKjl7R2HYPXQOr8GrGYIr4JC8PzmeioOCH7hGo,2236
|
|
11
|
+
pysole/suggestionManager.py,sha256=EUFeCQoZnLS8EjPPNuZpzjY0BR07m2KP5TloyaMDVGY,6457
|
|
12
|
+
pysole/themes.json,sha256=wv56r5XOV-ao7dY4_5Yjsio9VvJ58vHOI9nT7MEbXKY,2525
|
|
13
|
+
pysole/utils.py,sha256=-mGHAp0MkbMPQ9eYzPmo5AGHDLuQ9NfPio_2_iaiCuY,294
|
|
14
|
+
liveconsole-1.7.1.dist-info/METADATA,sha256=UogN-5fZCBKdaIJLDYm-DiDQ2XYjvOCGxbf7VFrNYLs,4955
|
|
15
|
+
liveconsole-1.7.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
16
|
+
liveconsole-1.7.1.dist-info/entry_points.txt,sha256=qtvuJHcex4QqM97x_UawFWJYnfhQRl0jhqLcWRpnAGo,84
|
|
17
|
+
liveconsole-1.7.1.dist-info/top_level.txt,sha256=DlpA93ScJbRZcF8kGSc5YoO8Ntu1ib1_MEZMb4xea_Q,7
|
|
18
|
+
liveconsole-1.7.1.dist-info/RECORD,,
|
pysole/mainConsole.py
CHANGED
|
@@ -3,6 +3,7 @@ import traceback
|
|
|
3
3
|
from .suggestionManager import CodeSuggestionManager
|
|
4
4
|
from .commandHistory import CommandHistory
|
|
5
5
|
from .styledTextbox import StyledTextWindow
|
|
6
|
+
from .utils import stdPrint
|
|
6
7
|
|
|
7
8
|
import tkinter as tk
|
|
8
9
|
|
|
@@ -11,16 +12,16 @@ class InteractiveConsoleText(StyledTextWindow):
|
|
|
11
12
|
def __init__(self, master, helpTab, theme, font, behavior, userLocals=None, userGlobals=None, **kwargs):
|
|
12
13
|
super().__init__(master, theme=theme, font=font, **kwargs)
|
|
13
14
|
self.font=(font["FONT"], font["FONT_SIZE"])
|
|
14
|
-
|
|
15
|
+
|
|
15
16
|
# Initialize components
|
|
16
17
|
self.PROMPT = behavior["PRIMARY_PROMPT"]
|
|
17
18
|
self.PROMPT_LENGTH = len(self.PROMPT)
|
|
18
19
|
self.suggestionManager = CodeSuggestionManager(self, userLocals=userLocals, userGlobals=userGlobals, theme=theme, font=font)
|
|
19
20
|
self.helpTab = helpTab
|
|
20
|
-
|
|
21
|
+
|
|
21
22
|
self.navigatingHistory = False
|
|
22
23
|
self.history = CommandHistory()
|
|
23
|
-
|
|
24
|
+
|
|
24
25
|
self.inputVar = tk.StringVar()
|
|
25
26
|
self.waitingForInput = False
|
|
26
27
|
self.inputLine = "1.0"
|
|
@@ -28,10 +29,10 @@ class InteractiveConsoleText(StyledTextWindow):
|
|
|
28
29
|
# Track current command
|
|
29
30
|
self.currentCommandLine = 1
|
|
30
31
|
self.isExecuting = False
|
|
31
|
-
|
|
32
|
+
|
|
32
33
|
# Setup bindings
|
|
33
34
|
self._setupBindings()
|
|
34
|
-
|
|
35
|
+
|
|
35
36
|
# Initialize with first prompt
|
|
36
37
|
self.addPrompt()
|
|
37
38
|
|
|
@@ -52,11 +53,14 @@ class InteractiveConsoleText(StyledTextWindow):
|
|
|
52
53
|
def getCurrentLineNumber(self):
|
|
53
54
|
"""Get the line number where current command starts."""
|
|
54
55
|
return(int(self.index("end-1c").split(".")[0]))
|
|
55
|
-
|
|
56
|
+
|
|
57
|
+
def resetCurrentLineNumber(self):
|
|
58
|
+
self.currentCommandLine = self.getCurrentLineNumber()
|
|
59
|
+
|
|
56
60
|
def getCommandStartPosition(self):
|
|
57
61
|
"""Get the starting position of the current command."""
|
|
58
62
|
return(f"{self.currentCommandLine}.0")
|
|
59
|
-
|
|
63
|
+
|
|
60
64
|
def replaceCurrentCommand(self, newCommand):
|
|
61
65
|
"""Replace the current command with new text."""
|
|
62
66
|
if self.isExecuting:
|
|
@@ -73,6 +77,16 @@ class InteractiveConsoleText(StyledTextWindow):
|
|
|
73
77
|
# Ensure styling/lexer applied after programmatic change:
|
|
74
78
|
self.updateStyling(start=self.getPromptPosition())
|
|
75
79
|
|
|
80
|
+
def runCommand(self, command, printCommand=False):
|
|
81
|
+
"""Insert code into the console prompt and execute it as if Enter was pressed."""
|
|
82
|
+
if self.isExecuting:
|
|
83
|
+
return(False)
|
|
84
|
+
if printCommand:
|
|
85
|
+
self.replaceCurrentCommand(command) #< Replace current command with the new code
|
|
86
|
+
self.onEnter(None) #< Simulate pressing Enter to run the command
|
|
87
|
+
else:
|
|
88
|
+
self.executeCommandThreaded(command, addPrompt=False)
|
|
89
|
+
|
|
76
90
|
def isCursorInEditableArea(self):
|
|
77
91
|
"""Check if cursor is in the editable command area."""
|
|
78
92
|
if self.isExecuting:
|
|
@@ -94,25 +108,26 @@ class InteractiveConsoleText(StyledTextWindow):
|
|
|
94
108
|
self.inputVar.set(line)
|
|
95
109
|
self.waitingForInput = False
|
|
96
110
|
return("break")
|
|
97
|
-
|
|
111
|
+
|
|
98
112
|
if self.isExecuting:
|
|
99
113
|
return("break")
|
|
100
|
-
|
|
114
|
+
|
|
101
115
|
command = self.getCurrentCommand()
|
|
102
|
-
|
|
116
|
+
# print(command)
|
|
117
|
+
|
|
103
118
|
if not command.strip():
|
|
104
119
|
return("break")
|
|
105
|
-
|
|
120
|
+
|
|
106
121
|
# Check if statement is incomplete
|
|
107
122
|
if self.isIncompleteStatement(command):
|
|
108
123
|
return(self.onShiftEnter(event))
|
|
109
|
-
|
|
124
|
+
|
|
110
125
|
# Execute the command
|
|
111
126
|
self.history.add(command)
|
|
112
127
|
self.mark_set("insert", "end")
|
|
113
128
|
self.insert("end", "\n")
|
|
114
129
|
self.see("end")
|
|
115
|
-
|
|
130
|
+
|
|
116
131
|
# Execute in thread
|
|
117
132
|
self.isExecuting = True
|
|
118
133
|
threading.Thread(
|
|
@@ -120,7 +135,7 @@ class InteractiveConsoleText(StyledTextWindow):
|
|
|
120
135
|
args=(command,),
|
|
121
136
|
daemon=True
|
|
122
137
|
).start()
|
|
123
|
-
|
|
138
|
+
|
|
124
139
|
return("break")
|
|
125
140
|
|
|
126
141
|
def readInput(self):
|
|
@@ -324,13 +339,17 @@ class InteractiveConsoleText(StyledTextWindow):
|
|
|
324
339
|
|
|
325
340
|
return(currentIndent)
|
|
326
341
|
|
|
327
|
-
def writeOutput(self, text, tag="output"):
|
|
342
|
+
def writeOutput(self, text, tag="output", loc="end"):
|
|
328
343
|
"""Write output to the console (thread-safe)."""
|
|
329
344
|
def _write():
|
|
330
|
-
self.insert(
|
|
345
|
+
self.insert(loc, text + "\n", tag)
|
|
331
346
|
self.see("end")
|
|
332
347
|
|
|
333
348
|
self.after(0, _write)
|
|
349
|
+
|
|
350
|
+
def newline(self):
|
|
351
|
+
"""Insert a newline at the end."""
|
|
352
|
+
self.writeOutput("")
|
|
334
353
|
|
|
335
354
|
def getPromptPosition(self):
|
|
336
355
|
"""Get the position right after the prompt on current command line."""
|
|
@@ -357,16 +376,15 @@ class InteractiveConsoleText(StyledTextWindow):
|
|
|
357
376
|
self.mark_set("insert", "end")
|
|
358
377
|
self.see("end")
|
|
359
378
|
self.isExecuting = False
|
|
360
|
-
|
|
379
|
+
|
|
361
380
|
if self.isExecuting:
|
|
362
381
|
self.after(0, _add)
|
|
363
382
|
else:
|
|
364
383
|
_add()
|
|
365
384
|
|
|
366
|
-
def executeCommandThreaded(self, command):
|
|
385
|
+
def executeCommandThreaded(self, command, addPrompt=True):
|
|
367
386
|
"""Execute a command in a separate thread."""
|
|
368
387
|
try:
|
|
369
|
-
# Try eval first for expressions
|
|
370
388
|
result = eval(command, self.master.userGlobals, self.master.userLocals)
|
|
371
389
|
if result is not None:
|
|
372
390
|
self.writeOutput(str(result), "result")
|
|
@@ -380,5 +398,7 @@ class InteractiveConsoleText(StyledTextWindow):
|
|
|
380
398
|
except Exception:
|
|
381
399
|
self.writeOutput(traceback.format_exc(), "error")
|
|
382
400
|
|
|
383
|
-
|
|
384
|
-
|
|
401
|
+
if addPrompt:
|
|
402
|
+
self.addPrompt()
|
|
403
|
+
else:
|
|
404
|
+
self.isExecuting = False
|
pysole/pysole.py
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import threading
|
|
2
|
+
import time
|
|
1
3
|
import customtkinter as ctk
|
|
2
4
|
import tkinter as tk
|
|
3
5
|
from tkinter import messagebox
|
|
@@ -6,7 +8,7 @@ import sys
|
|
|
6
8
|
import io
|
|
7
9
|
import json
|
|
8
10
|
|
|
9
|
-
from .utils import settingsPath, themesPath
|
|
11
|
+
from .utils import settingsPath, themesPath, stdPrint
|
|
10
12
|
from .helpTab import HelpTab
|
|
11
13
|
from .mainConsole import InteractiveConsoleText
|
|
12
14
|
|
|
@@ -35,23 +37,30 @@ class StdinRedirect(io.StringIO):
|
|
|
35
37
|
|
|
36
38
|
class InteractiveConsole(ctk.CTk):
|
|
37
39
|
"""Main console window application."""
|
|
38
|
-
|
|
39
|
-
def __init__(self, userGlobals=None, userLocals=None, callerFrame=None,
|
|
40
|
+
|
|
41
|
+
def __init__(self, userGlobals=None, userLocals=None, callerFrame=None,
|
|
42
|
+
defaultSize=None, primaryPrompt=None, font=None, fontSize=None,
|
|
43
|
+
runRemainingCode=False, printStartupCode=False,
|
|
44
|
+
removeWaterMark=False):
|
|
40
45
|
super().__init__()
|
|
41
46
|
with open(settingsPath, "r") as f:
|
|
42
47
|
settings = json.load(f)
|
|
43
48
|
self.THEME = settings["THEME"]
|
|
44
49
|
self.FONT = self.THEME["FONT"]
|
|
45
50
|
self.BEHAVIOR = settings["BEHAVIOR"]
|
|
46
|
-
|
|
51
|
+
|
|
47
52
|
if primaryPrompt != None:
|
|
48
53
|
self.BEHAVIOR["PRIMARY_PROMPT"] = primaryPrompt
|
|
49
54
|
if defaultSize != None:
|
|
50
55
|
self.BEHAVIOR["DEFAULT_SIZE"] = defaultSize
|
|
56
|
+
if font != None:
|
|
57
|
+
self.FONT["FONT"] = font
|
|
58
|
+
if fontSize != None:
|
|
59
|
+
self.FONT["FONT_SIZE"] = fontSize
|
|
51
60
|
|
|
52
61
|
self.title("Live Interactive Console")
|
|
53
62
|
self.geometry(self.BEHAVIOR["DEFAULT_SIZE"])
|
|
54
|
-
|
|
63
|
+
|
|
55
64
|
ctk.set_appearance_mode(self.THEME["APPEARANCE"])
|
|
56
65
|
ctk.set_default_color_theme("blue")
|
|
57
66
|
|
|
@@ -63,17 +72,32 @@ class InteractiveConsole(ctk.CTk):
|
|
|
63
72
|
userGlobals = callerFrame.f_globals
|
|
64
73
|
if userLocals is None:
|
|
65
74
|
userLocals = callerFrame.f_locals
|
|
66
|
-
|
|
75
|
+
|
|
67
76
|
self.userGlobals = userGlobals
|
|
68
77
|
self.userLocals = userLocals
|
|
69
|
-
|
|
78
|
+
|
|
70
79
|
# Create UI
|
|
71
80
|
self._createMenu()
|
|
72
81
|
self._createUi()
|
|
73
|
-
|
|
82
|
+
|
|
74
83
|
# Redirect stdout/stderr
|
|
75
84
|
self._setupOutputRedirect()
|
|
76
85
|
self._setupInputRedirect()
|
|
86
|
+
|
|
87
|
+
self.runRemainingCode = runRemainingCode
|
|
88
|
+
self.printStartupCode = printStartupCode
|
|
89
|
+
self.removeWaterMark = removeWaterMark
|
|
90
|
+
self.startupCode = ()
|
|
91
|
+
if runRemainingCode:
|
|
92
|
+
code_obj = callerFrame.f_code
|
|
93
|
+
filename = code_obj.co_filename
|
|
94
|
+
|
|
95
|
+
# Read the rest of the file after the call to probe()
|
|
96
|
+
with open(filename, "r", encoding="utf-8") as f:
|
|
97
|
+
lines = f.readlines()
|
|
98
|
+
|
|
99
|
+
startLine = callerFrame.f_lineno
|
|
100
|
+
self.startupCode = lines[startLine:]
|
|
77
101
|
|
|
78
102
|
def _createMenu(self):
|
|
79
103
|
"""Create a menu bar using CTkOptionMenu."""
|
|
@@ -99,7 +123,7 @@ class InteractiveConsole(ctk.CTk):
|
|
|
99
123
|
self._editSettings()
|
|
100
124
|
elif choice == "Load Theme":
|
|
101
125
|
self._loadTheme()
|
|
102
|
-
|
|
126
|
+
|
|
103
127
|
def _loadTheme(self):
|
|
104
128
|
"""
|
|
105
129
|
Open a CTk popup to let the user choose a theme from themes.json.
|
|
@@ -218,28 +242,71 @@ class InteractiveConsole(ctk.CTk):
|
|
|
218
242
|
self.console.pack(fill="both", expand=True, padx=5, pady=5)
|
|
219
243
|
self.console.master = self
|
|
220
244
|
|
|
221
|
-
|
|
222
245
|
def _setupOutputRedirect(self):
|
|
223
246
|
"""Setup stdout/stderr redirection to console."""
|
|
224
247
|
sys.stdout = StdoutRedirect(self.console.writeOutput)
|
|
225
248
|
sys.stderr = StdoutRedirect(
|
|
226
|
-
lambda text, tag: self.console.writeOutput(text, "error")
|
|
249
|
+
lambda text, tag: self.console.writeOutput(text, "error", "end")
|
|
227
250
|
)
|
|
228
251
|
|
|
229
252
|
def _setupInputRedirect(self):
|
|
230
253
|
"""Setup stdin redirection to console."""
|
|
231
254
|
sys.stdin = StdinRedirect(self.console.readInput)
|
|
232
|
-
|
|
255
|
+
|
|
256
|
+
def onClose(self):
|
|
257
|
+
sys.stdout = sys.__stdout__
|
|
258
|
+
sys.stderr = sys.__stderr__
|
|
259
|
+
self.destroy()
|
|
260
|
+
|
|
233
261
|
def probe(self, *args, **kwargs):
|
|
234
262
|
"""Start the console main loop."""
|
|
263
|
+
def runStartup():
|
|
264
|
+
if not self.removeWaterMark:
|
|
265
|
+
m = (
|
|
266
|
+
"Welcome to Pysole, if you find me useful, please star me on GitHub:\n"
|
|
267
|
+
"https://github.com/TzurSoffer/Pysole"
|
|
268
|
+
)
|
|
269
|
+
stdPrint(m)
|
|
270
|
+
self.console.newline()
|
|
271
|
+
self.console.writeOutput(m, "instruction")
|
|
272
|
+
time.sleep(0.1)
|
|
273
|
+
if self.runRemainingCode:
|
|
274
|
+
if self.printStartupCode:
|
|
275
|
+
self.console.addPrompt()
|
|
276
|
+
else:
|
|
277
|
+
self.console.newline()
|
|
278
|
+
else:
|
|
279
|
+
self.console.addPrompt()
|
|
280
|
+
elif self.runRemainingCode == True and self.printStartupCode == False:
|
|
281
|
+
self.console.newline()
|
|
282
|
+
|
|
283
|
+
for line in self.startupCode:
|
|
284
|
+
line = line.rstrip()
|
|
285
|
+
while self.console.isExecuting:
|
|
286
|
+
time.sleep(0.01)
|
|
287
|
+
if self.printStartupCode:
|
|
288
|
+
# self.console.writeOutput(line)
|
|
289
|
+
self.console.runCommand(line, printCommand=True)
|
|
290
|
+
else:
|
|
291
|
+
# self.console.writeOutput(line)
|
|
292
|
+
self.console.runCommand(line, printCommand=False)
|
|
293
|
+
|
|
294
|
+
if self.runRemainingCode == True and self.printStartupCode == False:
|
|
295
|
+
self.console.resetCurrentLineNumber()
|
|
296
|
+
self.console.addPrompt()
|
|
297
|
+
threading.Thread(target=runStartup).start()
|
|
235
298
|
self.mainloop(*args, **kwargs)
|
|
236
299
|
|
|
237
|
-
def probe(userGlobals=None, userLocals=None, callerFrame=None
|
|
300
|
+
def probe(userGlobals=None, userLocals=None, callerFrame=None,
|
|
301
|
+
runRemainingCode=False, printStartupCode=False, **kwargs):
|
|
238
302
|
if callerFrame == None:
|
|
239
303
|
callerFrame = inspect.currentframe().f_back
|
|
240
304
|
InteractiveConsole(userGlobals=userGlobals,
|
|
241
305
|
userLocals=userLocals,
|
|
242
|
-
callerFrame=callerFrame
|
|
306
|
+
callerFrame=callerFrame,
|
|
307
|
+
runRemainingCode=runRemainingCode,
|
|
308
|
+
printStartupCode=printStartupCode,
|
|
309
|
+
**kwargs).probe()
|
|
243
310
|
|
|
244
311
|
def _standalone():
|
|
245
312
|
import pysole
|
pysole/settings.json
CHANGED
pysole/styledTextbox.py
CHANGED
|
@@ -19,6 +19,7 @@ class StyledTextWindow(tk.Text):
|
|
|
19
19
|
self.tag_configure("output", foreground=theme["OUTPUT"], font=(font["FONT"], font["FONT_SIZE"]))
|
|
20
20
|
self.tag_configure("error", foreground=theme["ERROR"], font=(font["FONT"], font["FONT_SIZE"]))
|
|
21
21
|
self.tag_configure("result", foreground=theme["RESULT"], font=(font["FONT"], font["FONT_SIZE"]))
|
|
22
|
+
self.tag_configure("instruction", foreground=theme["INSTRUCTION"], font=(font["FONT"], font["FONT_SIZE"]))
|
|
22
23
|
|
|
23
24
|
# Configure syntax highlighting tags
|
|
24
25
|
for token, style in self.style:
|
pysole/themes.json
CHANGED
|
@@ -11,6 +11,7 @@
|
|
|
11
11
|
"OUTPUT": "#ffffff",
|
|
12
12
|
"ERROR": "#ff0000",
|
|
13
13
|
"RESULT": "#66ccff",
|
|
14
|
+
"INSTRUCTION": "#ffff00",
|
|
14
15
|
"SUGGESTION_BOX_BG": "#2d2d2d",
|
|
15
16
|
"SUGGESTION_BOX_SELECTION_BG": "#0066cc",
|
|
16
17
|
"FONT": {
|
|
@@ -30,6 +31,7 @@
|
|
|
30
31
|
"OUTPUT": "#000000",
|
|
31
32
|
"ERROR": "#ff0000",
|
|
32
33
|
"RESULT": "#0066cc",
|
|
34
|
+
"INSTRUCTION": "#ffff00",
|
|
33
35
|
"SUGGESTION_BOX_BG": "#f0f0f0",
|
|
34
36
|
"SUGGESTION_BOX_SELECTION_BG": "#cce6ff",
|
|
35
37
|
"FONT": {
|
|
@@ -49,6 +51,7 @@
|
|
|
49
51
|
"OUTPUT": "#586e75",
|
|
50
52
|
"ERROR": "#dc322f",
|
|
51
53
|
"RESULT": "#2aa198",
|
|
54
|
+
"INSTRUCTION": "#ffff00",
|
|
52
55
|
"SUGGESTION_BOX_BG": "#eee8d5",
|
|
53
56
|
"SUGGESTION_BOX_SELECTION_BG": "#b58900",
|
|
54
57
|
"FONT": {
|
|
@@ -68,6 +71,7 @@
|
|
|
68
71
|
"OUTPUT": "#f8f8f2",
|
|
69
72
|
"ERROR": "#ff5555",
|
|
70
73
|
"RESULT": "#8be9fd",
|
|
74
|
+
"INSTRUCTION": "#ffff00",
|
|
71
75
|
"SUGGESTION_BOX_BG": "#44475a",
|
|
72
76
|
"SUGGESTION_BOX_SELECTION_BG": "#6272a4",
|
|
73
77
|
"FONT": {
|
pysole/utils.py
CHANGED
|
@@ -1,4 +1,10 @@
|
|
|
1
1
|
import os
|
|
2
|
+
import sys
|
|
2
3
|
|
|
3
4
|
settingsPath = os.path.join(os.path.dirname(__file__), "settings.json")
|
|
4
5
|
themesPath = os.path.join(os.path.dirname(__file__), "themes.json")
|
|
6
|
+
|
|
7
|
+
def stdPrint(text):
|
|
8
|
+
"""Print text to the terminal."""
|
|
9
|
+
sys.__stdout__.write(f"{text}\n")
|
|
10
|
+
sys.__stdout__.flush()
|
|
@@ -1,18 +0,0 @@
|
|
|
1
|
-
liveconsole-1.6.2.dist-info/licenses/LICENSE,sha256=7dZ0zL72aGaFE0C9DxacOpnaSkC5jajhG6iL7lqhWmU,1064
|
|
2
|
-
pysole/__init__.py,sha256=SfaSBmFVSmhyf55UedBCqhi2Ss6Tre-BCKtZb3bSr2k,60
|
|
3
|
-
pysole/__main__.py,sha256=QvVFH8J2yzgQaF9MosQ6ajCW67uiRbYliePsTEUCIAg,82
|
|
4
|
-
pysole/commandHistory.py,sha256=xJtWbJ_vgJo2QGgaZJsApTOi_Hm8Yz0V9_zqQUCItj8,1084
|
|
5
|
-
pysole/helpTab.py,sha256=o0uSY-8sw7FuuBrt0FQwcgK6ljNVx3IgRnW7heZ6GvY,2454
|
|
6
|
-
pysole/liveConsole.py,sha256=lzS3dphAQ1i8pQC4E2FY-FyMMSKi-dAN0xr6XUgrNmo,168
|
|
7
|
-
pysole/mainConsole.py,sha256=CkZGUOxLhHRRb21gHfxRmuGOwf-H2T0feI9KDskXdgg,14397
|
|
8
|
-
pysole/pysole.py,sha256=vTmPvS4nzapVudNPtf2JrnwBWB-x_n-XxBsr4jW7MK8,9230
|
|
9
|
-
pysole/settings.json,sha256=6wCdMlemV6PblPKeQQsIiCrGWPLDLOMFD3hLMVAXL24,687
|
|
10
|
-
pysole/styledTextbox.py,sha256=zpbaN0qX5FduhNyuWGU7y8Ll8J9p9YqczpSuRLo4PX0,2120
|
|
11
|
-
pysole/suggestionManager.py,sha256=EUFeCQoZnLS8EjPPNuZpzjY0BR07m2KP5TloyaMDVGY,6457
|
|
12
|
-
pysole/themes.json,sha256=2RG3ohn2ZBc2-h9bdooQZD6hW5pD41a5c2jdaKDA4MA,2385
|
|
13
|
-
pysole/utils.py,sha256=VN42ukHMJpOvGb7ZV-qhF_zRUt13hzJKV_uRn9t6580,155
|
|
14
|
-
liveconsole-1.6.2.dist-info/METADATA,sha256=WSL_DMarxOF1Gvz0BzC1aL8PgyI_1WFP6LuIm2nAatw,4011
|
|
15
|
-
liveconsole-1.6.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
16
|
-
liveconsole-1.6.2.dist-info/entry_points.txt,sha256=qtvuJHcex4QqM97x_UawFWJYnfhQRl0jhqLcWRpnAGo,84
|
|
17
|
-
liveconsole-1.6.2.dist-info/top_level.txt,sha256=DlpA93ScJbRZcF8kGSc5YoO8Ntu1ib1_MEZMb4xea_Q,7
|
|
18
|
-
liveconsole-1.6.2.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|