-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathshell.py
More file actions
96 lines (76 loc) · 3.41 KB
/
shell.py
File metadata and controls
96 lines (76 loc) · 3.41 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
import tkinter as tk
from utils import Utils
class Shell(tk.Text):
def __init__(self, parent, **kwargs):
tk.Text.__init__(self)
# when a key is pressed on_key_pressed is called with the key
self.bind('<Key>', self.on_key_pressed)
# tracks the last command entered
self.cmd = None
# inits the local classes
self.input = Input(self)
self.show_prompt()
def show_prompt(self):
""" inserts >> on a new line and updates the insert mark to the new EOF """
# inserts the >> at start of line
self.insert_text('>> ', end='')
# updates the insert constant to the end of the prompt
self.mark_set(tk.INSERT, tk.END)
# sets the cursor at the insert insert constant
self.cursor = self.index(tk.INSERT)
def insert_text(self, txt='', end='\n'):
""" inserts the txt param at the bottom of the shell """
# inserts the text input to the end (bottom) of the text box
self.insert(tk.END, txt + end)
# makes sure that the end is visible, not out of text box view
self.see(tk.END)
def on_key_pressed(self, event):
""" determines what happens when keys are pressed"""
key_symbol = event.keysym
if key_symbol == 'Up':
# if the previous command exists
if self.cmd:
# delete the whole thing? and rewrite the old one?
self.delete(self.cursor, tk.END)
self.insert(self.cursor, self.cmd)
return "break"
if key_symbol == 'Down':
return "break"
if key_symbol in ('Left', 'BackSpace'):
current = self.index(tk.INSERT)
if self.compare(current, '==', self.cursor):
return 'break'
if key_symbol == 'Return':
cmd = self.get(self.cursor, tk.END).strip()
self.input.raw_input(cmd)
self.insert_text()
self.show_prompt()
self.cmd = cmd
return 'break'
if key_symbol == 'Escape':
self.master.destroy()
class Input:
def __init__(self, shell):
self.shell = shell
self.base = None
def raw_input(self, raw_command):
if len(raw_command) == 0 or raw_command.isspace():
#TODO add utils error message default
return
# splits the input into a list
with_whitespace = raw_command.strip().split(' ')
# removes the extra whitespace in the list
inputs_list = [word for word in with_whitespace if word != '']
# gets the base command
self.base = inputs_list[0]
if self.base == 'help':
Utils.help(self.shell)
return
# checks if the base function is a valid one by iterating through the function list
for i in range(len(Utils.FUNCTION_LIST)):
if self.base in Utils.FUNCTION_LIST[i]:
# instantiates the new object of whatever type matches the command put in
# passes the shell, the base, and the rest of the parameters if there are any
Utils.CLASS_STRING_TO_CLASS_OBJECT[Utils.CLASS_LIST[i]](self.shell, self.base, inputs_list[1:])
return
Utils.error_message(self.shell, f'{self.base} is not a valid command. To view a list of commands type "help"')