ocarina/trunk/cline.py

141 lines
3.3 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):
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)