pagination with the python cmd module

I'm prototyping a Python app with the cmd module.

Some messages to the user will be quite long and I'd like to paginate them. The first 10 (or a configurable number) lines of the message would appear, and pressing the SPACE bar would display the next page, until the end of the message.

I don't want to reinvent something here, is there a simple mean to implement this feature?

Answers


The simple thing would just be to pipe your script through "less" or a similar command at runtime.

Here's a simple method that does approximately what you want, though:

def print_and_wait(some_long_message):
    lines = some_long_message.split('\n')
    i=0
    while i < len(lines):
        print '\n'.join(lines[i:i+10])
        raw_input("press enter to read more...")
        i += 10

You could also look into using curses.


As Yoni said above the right way to do this is to provide a print method that pages automatically inside your running cmd instance. The constructor of Cmd takes stdin and stdout arguments. So simple provide an object that works like stdout and supports your paging print method.

class PagingStdOut(object):
    def write(self, buffer, lines_before_pause=40):
        # do magic paging here...

I had the same question. There is a pager built in to the pydoc module. I incorporated it thusly (which I find hackish and unsatisfying... I'm open to better ideas though).

I like the idea that it would autopage if there are more than x results and paging is on, which is possible to implement, but not done here.

import cmd
from pydoc import pager
from cStringIO import StringIO
import sys

PAGER = True
class Commander(cmd.Cmd):
    prompt = "> "
    def do_pager(self,line):
        global PAGER
        line = line + " 1"
        tokens = line.lower().split()
        if tokens[0] in ("on","true","t", "1"):
            PAGER = True
            print "# setting PAGER True"
        elif tokens[0] in ("off","false","f","0"):
            PAGER = False
            print "# setting PAGER False"
        else:
            print "# can't set pager:  don't know -> %s" % tokens[0]

    def do_demo(self,line):
        results = dict(a=1,b=2,c=3)
        self.format_commandline_results(results)

    def format_commandline_results(self,results):
        if PAGER:
            ofh = StringIO()
        else:
            ofh = sys.stdout

        for (k,v) in sorted(results.items()):
            print >> ofh, "%s -> %s" % (k,v)

        if PAGER:
            ofh.seek(0)
            pager(ofh.read())

        return None

    def do_EOF(self,line):
        print "",
        return True

if __name__ == "__main__":
    Commander().cmdloop("# try: \n> pager off \n> demo \n> pager on \n> demo \n\n")

Paging subroutines can be found in the genutils.py file of IPython (see page, or page_dumb for a simpler one). The code is a little complicated, but that's probably unavoidable if you are trying to be portable to systems including Windows and the various kinds of terminal emulators.


Need Your Help

How Visual Studio .NET resolves assembly references?

.net visual-studio assemblies reference folder

The project directory. The directories specified in the "ReferencePath" property, which is stored in the .USER file. The .NET Framework directory (see KB306149) The directories specified under the

how to do i get returned data from ajax call

php javascript jquery html ajax

I am getting a undefined on the username from $sql which should be the returned data from the query.

About UNIX Resources Network

Original, collect and organize Developers related documents, information and materials, contains jQuery, Html, CSS, MySQL, .NET, ASP.NET, SQL, objective-c, iPhone, Ruby on Rails, C, SQL Server, Ruby, Arrays, Regex, ASP.NET MVC, WPF, XML, Ajax, DataBase, and so on.