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): self.input = self.input.strip().lower() if self.input=="": return elif self.input in self.cmnds.keys(): self.cmnds[self.input][0]() 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() 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)