Search code examples
pythoncmdcurses

Can I use Python's curses and cmd libraries together?


In Python, I'd like to write a terminal program using both cmd and curses together, ie. use cmd to accept and decode full input lines, but position the output with curses.

Mashing together examples of both curses and cmd like this :

import curses 
import cmd

class HelloWorld(cmd.Cmd):
    """Simple command processor example."""

    def do_greet(self, line):
        screen.clear()
        screen.addstr(1,1,"hello "+line)
        screen.addstr(0,1,">")
        screen.refresh()

    def do_q(self, line):
        curses.endwin()
        return True

if __name__ == '__main__':
    screen = curses.initscr()   
    HelloWorld().cmdloop()

I find that I'm not seeing anything when I type. curses is presumably waiting for a refresh before displaying anything on the screen. I could switch to using getch() but then I'd lose the value of cmd.

Is there a way to make these work together?


Solution

  • The question seems to be very old... But it attracted enough of attention so i thought to leave my answer behind.. You can check out the site here and clear your doubts..

    Update : this answer links to the gist from the original questioner. Just to save someone having to follow the link ... here's the code in full :

    #!/usr/bin/env python 
    # -*- coding: utf-8 -*- 
    
    import curses 
    import curses.textpad
    import cmd
    
    def maketextbox(h,w,y,x,value="",deco=None,textColorpair=0,decoColorpair=0):
        # thanks to http://stackoverflow.com/a/5326195/8482 for this
        nw = curses.newwin(h,w,y,x)
        txtbox = curses.textpad.Textbox(nw,insert_mode=True)
        if deco=="frame":
            screen.attron(decoColorpair)
            curses.textpad.rectangle(screen,y-1,x-1,y+h,x+w)
            screen.attroff(decoColorpair)
        elif deco=="underline":
            screen.hline(y+1,x,underlineChr,w,decoColorpair)
    
        nw.addstr(0,0,value,textColorpair)
        nw.attron(textColorpair)
        screen.refresh()
        return nw,txtbox
    
    class Commands(cmd.Cmd):
        """Simple command processor example."""
            
        def __init__(self):
            cmd.Cmd.__init__(self)
            self.prompt = "> "
            self.intro  = "Welcome to console!"  ## defaults to None
        
        def do_greet(self, line):
            self.write("hello "+line)
    
        def default(self,line) :
            self.write("Don't understand '" + line + "'")
    
        def do_quit(self, line):
            curses.endwin()
            return True
    
        def write(self,text) :
            screen.clear()
            textwin.clear()
            screen.addstr(3,0,text)
            screen.refresh()
    
    
    if __name__ == '__main__':
        screen = curses.initscr()   
        curses.noecho()
        textwin,textbox = maketextbox(1,40, 1,1,"")
        flag = False
        while not flag :
            text = textbox.edit()
        curses.beep()
        flag = Commands().onecmd(text)