cmdモジュールでファイルパスを補完(readline)

コマンドラインツールを作るとき、外部ファイルを読みだしてゴニョゴニョすることが多々あるかと思いますが、そんなとき、ファイルパスを補完するように書かないと、正直使えません。Pythonのcmd.Cmdを継承すると、そういうことが簡単にできます。そういうことというのは、動画で見てください。

ソースコードは次のようになっています。

#!/usr/bin/env python2.6
#opener.py
import cmd
class CUI(cmd.Cmd):
    prompt = "opener> "
    def do_EOF(self, args):
        self.stdout.write("Exit!\n")
        return 1
    do_quit_ = do_EOF
    def do_open(self, path):
        f = open(path)
        self.stdout.write(f.read())
    def complete_open(self, *args):
        return complate_path(*args)
import dircache
def complate_path(ignore, line, *ignores):
    args = line.split()
    if len(args) < 2:
        path = './'
    else:
        path = args[1]
    fname = ''    
    if path == '' or path == '.':
        path = './'
    else:
        if '/' in path:
            i = path.rfind('/')
            fname = path[i+1:]
            path = path[:i]
        else:
            fname = path
            path = './'
    return [name for name in dircache.listdir(path) if name.startswith(fname)]
if __name__ == '__main__':
    CUI().cmdloop()

cmdの補完機能はreadlineによるものですが、cmdを使うと" xxx"と打ち込んでいるときにタブ(変更可能ですが、標準ではタブ)を押すとcomplate_メソッドが呼び出されます。complate_を実装してあげればファイルパスの補完は簡単に実装できるわけです。今回の場合は="open"ですから、complete_openが補完するための関数です。