Pythonのコマンドライン上でタブ補完機能が使いたいなと思い調べたら標準で備わっているらしい。結構簡単に作れたので紹介する。
Pythonには標準でコマンドラインインタプリタを作成できるCmdモジュールがある。また、タブ補完にサブコマンドも実装できるようなのでそれも行う。
必要ライブラリのインストール
環境によってはPyReadlineをインストールしないと反応してくれないのでインストールする。IPytonが入っている場合は既に入っていると思う。
pip install pyreadline
プログラム
適当にサンプルとして作ったプログラムを載せておく。
# -*- coding: utf-8 -*- from cmd import Cmd # 標準 import readline # PyReadline class CommandlineCompletion(Cmd): # Cmd(cmd.py)より継承 intro = '--- コマンドラインでタブ補完 ---\n' # 実行時表示 prompt = '>> ' # 入力時のプロンプト langlist = ['C/C++', 'Go', 'Julia', 'Python'] # likeコマンドの2次候補(サブコマンド) def emptyline(self): # 空行であった場合 print('なにか入力しろよ') pass def do_like(self, line): # likeコマンド "do_" if line and line in self.langlist: #likeコマンドに文字があり、langlistにもあった場合 message = '%sはいいよな\n' %line elif line: #likeコマンドに文字があった場合 message = '%sが好きなのか\n' %line else: message = 'Juliaはいいぞ\n' print(message) pass def complete_like(self, text, line, begidx, endidx): # likeコマンドの2次補完候補表示 "complete_" if not text: # textがなかった場合 completions = self.langlist[:] # langlistをすべて表示 [:] else: completions = [ # langlistから該当するものを表示または補完 n for n in self.langlist if n.startswith(text) ] return completions def help_like(self): # likeコマンドのヘルプ表示 "help like" または "? like" で呼び出し "help_" print('好きなプログラム言語は?なにかを聞いているぞ') def do_exit(self, line): # ループ抜け(ただreturnするだけpassするとループ継続) return True def help_exit(self): print('ループを抜けるん') if __name__ == '__main__': try: CommandlineCompletion().cmdloop() # cmd.pyにある "cmdlopp" 実行でタブ補完ができるループに入る except KeyboardInterrupt: # キーボードによる割り込み print('\nKeyboard Interrupt (Ctrl+C)') pass except: pass
解説
以下の2つはCmdで規定値が指定されているがユーザが上書きできる。
intro
実行時に1回のみ表示される文字列prompt
入力時に表示されるプロンプト
コマンドの実装
do_XYZ
XYZをコマンドとして実装する。XYZ
で実行することができる。complete_XYZ
コマンドXYZのTabキー補完時に動作を実装。help_XYZ
コマンドdo_XYZ
に対するヘルプ。コマンドhelp XYZ
または? XYZ
でヘルプを呼び出す。emptyline
空入力時に呼び出される。オーバーライドしない場合、最後に入力したコマンドを繰り返す。
その他
precmd
をオーバーライドして入力されたコマンドをすべて小文字として処理するなどもできる。
def precmd(self, line): return line.lower()
まとめ
思いのほか簡単にコマンドラインインタプリタが実装できる。このタブによる補完機能を使って簡単なツールをより便利にできそうだなと作っていて思った。