Differences

This shows you the differences between two versions of the page.

Link to this comparison view

Both sides previous revision Previous revision
Next revision
Previous revision
codaz:python:shell_readline_avec_cmd [2006/09/06 14:17]
gab
codaz:python:shell_readline_avec_cmd [2010/01/12 13:29] (current)
Line 1: Line 1:
 +
 +un exemple simple de shell qui supporte la completion readline avec sauvegarde de l'​history.
 +
 +<code python>
 +
 +#​!/​usr/​bin/​env python2.4
 +
 +# Copyright (c) 2004 gab <gab @gcu.info>​. ​ All rights reserved.
 +#
 +# Redistribution and use in source and binary forms, with or without
 +# modification,​ are permitted provided that the following conditions
 +# are met:
 +# 1. Redistributions of source code must retain the above copyright
 +#    notice, this list of conditions and the following disclaimer.
 +# 2. Redistributions in binary form must reproduce the above copyright
 +#    notice, this list of conditions and the following disclaimer in the
 +#    documentation and/or other materials provided with the distribution.
 +# 3. All advertising materials mentioning features or use of this software
 +#    must display the following acknowledgement:​
 +#      This product includes software developed by gab.
 +# 4. Neither the name of the author nor the names of any co-contributors
 +#    may be used to endorse or promote products derived from this software
 +#    without specific prior written permission.
 +#
 +# THIS SOFTWARE IS PROVIDED BY gab AND CONTRIBUTORS ``AS IS''​ AND
 +# ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
 +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
 +# ARE DISCLAIMED. ​ IN NO EVENT SHALL gab OR THE VOICES IN HIS HEAD
 +# BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
 +# CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
 +# SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
 +# INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
 +# CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
 +# ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
 +# THE POSSIBILITY OF SUCH DAMAGE.
 +
 +
 +import sys, cmd, readline, os, glob
 +from stat import ST_MODE, S_ISDIR
 +
 +class proutsh(cmd.Cmd):​
 +        def __init__(self):​
 +                cmd.Cmd.__init__(self)
 +                self.prompt = '​proutsh>​ '
 +                self.histfile = os.getenv("​HOME"​) + '/​.proutsh_history'​
 +
 +                try:
 +                        os.stat(self.histfile)
 +                except OSError:
 +                        file(self.histfile,​ "​w"​).close()
 +                readline.read_history_file(self.histfile)
 +
 +                # an internal filenames list
 +                # listable with '​ls'​ and modifiable with '​add'​ and '​del'​
 +                self.items = []
 +
 +        def emptyline(self):​
 +                """​disable the annoying emptyline repeat"""​
 +                pass
 +
 +
 +        def onecmd(self,​ line):
 +                """​catch exceptions generated during a command'​s execution"""​
 +                try:
 +                        cmd.Cmd.onecmd(self,​ line)
 +                except ValueError:
 +                        com = line.split("​ ")[0]
 +                        self.do_help(com)
 +
 +
 +        def complete_items(self,​ text, line, bidx, eidx):
 +                """​complete numeric items in the playlist"""​
 +                return [ str(i) for i in range(0, len(self.items)) ]
 +
 +
 +        def do_ls(self, args):
 +                """​List items in the items list.\nUsage:​ ls"""​
 +                for i in range(0, len(self.items)):​
 +                        if args == ''​ or int(args) == i:
 +                                print "%d: %s" % (i, self.items[i])
 +
 +        complete_ls = complete_items
 +
 +        do_list = do_ls
 +        complete_list = complete_items
 +
 +
 +        def do_add(self,​ args):
 +                """​Add an item to the items list.\nUsage:​ add <file path or URL>"""​
 +                if args.find("://"​) >= 0:
 +                        self.items.append(args)
 +                        return
 +
 +                files = glob.glob(args)
 +                files.sort()
 +                for f in files:
 +                        self.items.append(f)
 +
 +
 +        def complete_add(self,​ text, line, *args):
 +                """​filesystem based completion. XXX: doesn'​t work well with filenames containing spaces"""​
 +                args = line.split()
 +                if len(args) > 1:
 +                        arg = args[1]
 +                else:
 +                        arg = ""​
 +                dirs = arg.split('/'​)
 +                user_elem = dirs[-1]
 +                user_dir = "/"​.join(dirs[:​-1] + [''​])
 +
 +                if user_dir == '':​
 +                        user_dir = '​./'​
 +                flist = [ f for f in os.listdir(user_dir) if f.startswith(user_elem) ]
 +
 +                for i in range(0, len(flist)):​
 +                        if S_ISDIR(os.lstat(user_dir + flist[i])[ST_MODE]):​
 +                                flist[i] += '/'​
 +                        else:
 +                                flist[i] += ' '
 +
 +                return flist
 +
 +
 +        def do_del(self,​ args):
 +                """​Delete an item from the items list.\nUsage:​ del <item index>"""​
 +                self.items.remove(self.items[int(args)])
 +
 +        complete_del = complete_items
 +
 +        def do_flush(self,​ args):
 +                """​Delete all items from the items list.\nUsage:​ flush"""​
 +                self.items = []
 +
 +        # CLI control
 +        def do_history(self,​ args):
 +                """​Dump command line history"""​
 +                for i in range(1, readline.get_current_history_length()):​
 +                        print readline.get_history_item(i)
 +
 +        def do_exit(self,​ args):
 +                """​Exit shell.\nUsage:​ exit"""​
 +                readline.write_history_file(self.histfile)
 +                sys.exit(0)
 +
 +        def do_EOF(self,​ args):
 +                """​Exit shell.\nUsage:​ ^D"""​
 +                print
 +                self.do_exit(args)
 +
 +if __name__ == '​__main__':​
 +        cli = proutsh()
 +        while 1:
 +                try:
 +                        cli.cmdloop()
 +                except KeyboardInterrupt:​
 +                        print
 +</​code>​
  
codaz/python/shell_readline_avec_cmd.txt ยท Last modified: 2010/01/12 13:29 (external edit)