-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathcli.py
More file actions
158 lines (146 loc) · 6.54 KB
/
Copy pathcli.py
File metadata and controls
158 lines (146 loc) · 6.54 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
# object oriented approach to screen rendering
from log import *
lg.set_fn(__file__)
import math as m
import ti_draw as d
import ti_system as tis
import time as t
import filesys as fs
from format import *
def clamp(_min, x, _max):
return min(_max, max(_min, x))
class cli:
def __init__(s, clisets: dict | None = None, guisets: dict | None = None): # includes cli and gui settings
# Needs refactoring (using dict.get)
# cli settings
s.scrollup = 0 # cursor upward scroll
s.cursorleft = 0 # position of cursor with relation to EOL
s.root = fs.root # link file system to cli for easier integration with terminal.py
try: s.user_name = clisets["user_name"]
except: s.user_name = "root"
try: s.passwd = clisets["passwd"]
except: s.passwd = "1234"
try: s.text_history = clisets["text_history"] # keeping track of history. text_history[-1] is used very often for last line manipulation. Other programs using the cli api could manipulate text_history for multi-line input handling with custom cursor vertical position control and detection, but that could be integrated to cli.py for efficiency i guess
except: s.text_history = []
try: s.cwd = clisets["cwd"] # current working directory
except: s.cwd=s.root # s.cwd: folder
# gui settings
try: s.color = guisets["color"]
except: s.color = (250, 250, 250)
try: s.background_color = guisets["background_color"]
except: s.background_color = (40, 40, 45)
try: s.cursor = guisets["cursor"]
except: s.cursor = "|"
try: s.prompt_end_char = guisets["prompt_end_char"]
except: s.prompt_end_char = "$"
try: s.arrow_list = guisets["arrow_list"]
except: s.arrow_list = {
"up": "^", # this works in ti nspire
"down": "exp",
"left": "left", # left arrow
"right": "right",
}
d.set_window(0, 318, 0, 18)
d.set_color(s.background_color)
d.fill_rect(0, 0, 318, 18)
d.set_color(s.color)
def getPrefix(s):
return s.user_name + ":" + str(s.cwd) + s.prompt_end_char + " "
def setLastLine(s, text: str) -> None:
# lg.call("setLastLine", text)
s.text_history[-1] = text
# lg.end("setLastLine")
def setCwd(s, newCwd: fs.folder): # the `cd` command
s.cwd = newCwd
def clearscreen(s): # fills entire screen with background color
d.set_color(s.background_color)
d.fill_rect(0, 0, 318, 18) # can't change font size on calculator, so 18 lines would fit when the font size is 10 units (in python editor, menu->1->6)
d.set_color(s.color)
def display(s, text: str | None = None):
if text is not None:
s.text_history.append(text)
s.clearscreen()
d.use_buffer()
if len(s.text_history) > 18: # only draw latest 18 (with relation to s.scrollup)
for i in range(1, 19):
d.draw_text(0, 18-i, str(s.text_history[-(18-i) - 1 - s.scrollup]))
# overflow-x
if len(s.text_history[-1]) > 50:
s.display(s.text_history[-1][51:])
else:
for i in range(1, len(s.text_history) + 1):
d.draw_text(0, 18-i, s.text_history[i-1])
d.paint_buffer()
# future:
"""
def blinkCursor(s, numsPerSec: int = 1.5, minlen=0):
# blinks the cursor at a given frequency.
# returns any key that is pressed (apart from del and the arrow keys) -> used
# in other functions like getInput
# will be integrated into the getInput function
"""
def getInput(s, prompt: str) -> str:
lg.call("getInput", prompt)
s.display(prompt)
result = ""
while True:
k = tis.get_key()
if k == "esc":
break
if k == "enter":
return result
if k != "":
if not (k.startswith("del")) and not (k in s.arrow_list.values()):
s.setLastLine(
# from format.py, cleaner syntax than [::]
# signature: (string: str, start: int, end: int)
# start is inclusive, end is exclusive
substr(
s.text_history[-1],
0,
len(s.text_history[-1]) - s.cursorleft - 0 # kept here, try toggling if buggy
) + k + substr(
s.text_history[-1],
len(s.text_history[-1]) - s.cursorleft,
len(s.text_history[-1])
)
)
elif k.startswith("del"):
if len(s.text_history[-1]) > len(prompt):
s.text_history[-1] = substr(
s.text_history[-1],
0, len(s.text_history[-1]) - s.cursorleft - 1
) + substr(
s.text_history[-1],
len(s.text_history[-1]) - s.cursorleft, len(s.text_history[-1])
)
elif k in s.arrow_list.values():
if k == s.arrow_list["up"]:
lg.info("up key")
s.scrollup += 1 if s.scrollup < len(s.text_history) - 18 else 0
elif k == s.arrow_list["down"]:
lg.info("down key")
s.scrollup -= 1 if s.scrollup > 0 else 0
elif k == s.arrow_list["left"]:
lg.info("left key")
s.cursorleft += (1 if s.cursorleft < len(s.text_history[-1]) - len(prompt) else 0)
elif k == s.arrow_list["right"]:
lg.info("right key")
s.cursorleft -= 1 if s.cursorleft > 0 else 0
# end of checking key type (normal, del, arrow)
s.display()
# try patch: clear screen?
# t.sleep(0.01)
# s.clearscreen()
# Doesn't work
# end of checking whether key pressed is empty or not
result = s.text_history[-1][len(prompt):len(s.text_history[-1])]
t.sleep(0.01)
# end of while loop
lg.end(result)
return result
# windows `cls` and unix `clear`
def cls(s, prompt = ""):
s.text_history = []
s.clearscreen()
s.display(prompt)