151 lines
3.6 KiB
Python
151 lines
3.6 KiB
Python
import threading
|
|
import curses
|
|
|
|
################################################################################
|
|
# Command line class, will run in its own thread #
|
|
# Does not contain any actual commands, this just takes user input #
|
|
# Commands must be registered before they can be used #
|
|
# When registering a command: pass the key, a poiner to the function, and #
|
|
# a help message #
|
|
# This does have a built-in help function, which displays the help messages #
|
|
# for registered commands. The help function can be overridden if needed #
|
|
################################################################################
|
|
|
|
|
|
class CLine(threading.Thread):
|
|
# Initialize ncurses stuff
|
|
def __init__(self):
|
|
threading.Thread.__init__(self)
|
|
self.stdscr = curses.initscr()
|
|
self.maxSize = self.stdscr.getmaxyx()
|
|
curses.cbreak()
|
|
curses.noecho()
|
|
self.stdscr.keypad(1)
|
|
self.input = ""
|
|
self.pos = (0,0) # REMEMBER: (y,x)
|
|
self.start()
|
|
self.cmnds = dict()
|
|
|
|
|
|
# Reverse ncurses stuff (returns screen to normal)
|
|
# THIS MUST BE CALLED BEFORE EXITING!!!
|
|
def quit(self):
|
|
curses.nocbreak()
|
|
curses.echo()
|
|
self.stdscr.keypad(0)
|
|
curses.endwin()
|
|
|
|
|
|
# Print the prompt
|
|
def prompt(self):
|
|
(y,x) = self.stdscr.getyx()
|
|
self.stdscr.addstr(y,0,">>> ")
|
|
self.stdscr.refresh()
|
|
|
|
|
|
# Run the command line
|
|
def run(self):
|
|
try:
|
|
self.prompt()
|
|
while(True):
|
|
# Enter key pressed
|
|
c = self.stdscr.getch()
|
|
if c==10:
|
|
self.enter()
|
|
elif c==127:
|
|
self.backspace()
|
|
else:
|
|
self.input+=curses.keyname(c)
|
|
self.changeline()
|
|
finally:
|
|
self.quit()
|
|
|
|
|
|
# Enter key pressed
|
|
# Returns true if we keep going
|
|
def enter(self):
|
|
args = self.input.strip().split(' ',1)
|
|
self.input = args[0].lower()
|
|
input = ""
|
|
if len(args) > 1:
|
|
input = args[1].strip()
|
|
#self.printLine(self.input+"\t"+input)
|
|
#self.input = self.input.strip().lower()
|
|
if self.input=="":
|
|
return
|
|
elif self.input in self.cmnds.keys():
|
|
self.cmnds[self.input][0](input)
|
|
self.advanceLine()
|
|
self.prompt()
|
|
self.input = ""
|
|
elif self.input == "help":
|
|
self.printHelp()
|
|
self.input = ""
|
|
|
|
|
|
# Backspace key pressed
|
|
def backspace(self):
|
|
(y,x) = self.stdscr.getyx()
|
|
if self.input != "":
|
|
self.stdscr.move(y,x-1)
|
|
self.stdscr.delch()
|
|
self.input=self.input[0:len(self.input)-1]
|
|
|
|
|
|
# Advance cursor to next line
|
|
def advanceLine(self):
|
|
(y,x) = self.stdscr.getyx()
|
|
if y==self.maxSize[0]-1:
|
|
self.stdscr.move(0,0)
|
|
self.stdscr.deleteln()
|
|
else:
|
|
y+=1
|
|
self.stdscr.move(y,0)
|
|
|
|
|
|
# Change the current line to reflect self.input
|
|
def changeline(self):
|
|
(y,x) = self.stdscr.getyx()
|
|
self.stdscr.deleteln()
|
|
self.stdscr.move(y,0)
|
|
self.prompt()
|
|
self.stdscr.addstr(self.input)
|
|
|
|
|
|
# Print lines to the screen
|
|
def printLines(self,lines):
|
|
#self.advanceLine()
|
|
for line in lines:
|
|
self.printLine(line)
|
|
self.advanceLine()
|
|
self.prompt()
|
|
|
|
|
|
# Print a single line on the screen
|
|
def printLine(self,line):
|
|
(y,x) = self.stdscr.getyx()
|
|
self.advanceLine()
|
|
(y,x) = self.stdscr.getyx()
|
|
if len(line) > (self.maxSize[1]-1):
|
|
self.stdscr.addstr(line[0:(self.maxSize[1]-1)])
|
|
self.printLine(line[self.maxSize[1]-1:len(line)])
|
|
else:
|
|
self.stdscr.addstr(line)
|
|
#self.stdscr.move(y+1,x)
|
|
self.stdscr.refresh()
|
|
|
|
|
|
# Associate a command with a function
|
|
def register(self,command,func,help):
|
|
self.cmnds[command]=(func,help)
|
|
|
|
|
|
# Scan through keys and print help messages
|
|
def printHelp(self):
|
|
lines = []
|
|
keys = self.cmnds.keys()
|
|
keys.sort()
|
|
for cmnd in keys:
|
|
lines+=[cmnd+"\t"+self.cmnds[cmnd][1]]
|
|
self.printLines(lines)
|