2008-10-09 66 views
73

我知道如何在python解釋器(在Unix上)設置python對象的自動完成。如何使蟒蛇,命令行程序自動完成任意東西不解釋器

  • 谷歌顯示了很多關於如何做到這一點的解釋。
  • 不幸的是,有這麼多的參考文獻,很難找到我需要做的,這是略有不同。

我需要知道如何在用python編寫的命令行程序中啓用tab/auto完成任意項目。

我的具體用例是一個需要發送郵件的命令行python程序。我希望能夠在用戶鍵入其中的一部分(並且可選地按下TAB鍵)時自動完成電子郵件地址(我有磁盤上的地址)。

我不需要它在windows或mac上工作,只是linux。

+0

這[博客](http://blog.e-shell.org/ 221)應該使用配置.pythonrc文件來做這些技巧。 – 2017-06-10 01:53:53

回答

46

使用Python的readline綁定。例如,

import readline 

def completer(text, state): 
    options = [i for i in commands if i.startswith(text)] 
    if state < len(options): 
     return options[state] 
    else: 
     return None 

readline.parse_and_bind("tab: complete") 
readline.set_completer(completer) 

官方module docs沒有更詳細,請參閱readline docs更多信息。

+1

請注意,如果你用cmd模塊編寫你的命令行,那麼有更好的方法來完成它。 – 2008-10-09 15:17:36

52

按照cmd documentation,你會被罰款

import cmd 

addresses = [ 
    '[email protected]', 
    '[email protected]', 
    '[email protected]', 
] 

class MyCmd(cmd.Cmd): 
    def do_send(self, line): 
     pass 

    def complete_send(self, text, line, start_index, end_index): 
     if text: 
      return [ 
       address for address in addresses 
       if address.startswith(text) 
      ] 
     else: 
      return addresses 


if __name__ == '__main__': 
    my_cmd = MyCmd() 
    my_cmd.cmdloop() 

輸出的選項卡 - >選項 - >發送 - >選項 - >選項 - >的F - >標籤

(Cmd) 
help send 
(Cmd) send 
[email protected]   [email protected]   [email protected] 
(Cmd) send [email protected] 
(Cmd) 
+0

有什麼方法可以控制readline如何將其輸出列表化?所以我們可以說我想讓它在每個項目之間用兩個空格進行分欄。 – Fnord 2013-11-24 15:55:33

+0

當我運行這個代碼時,標籤只是打印到命令行中。事實上,無論我使用cmd還是直接讀取,都是如此。 – 2016-09-16 04:01:42

24

既然你在你的問題中說「不是解釋器」,我想你不想要涉及python readline和類似的答案。 (編輯:在事後,這顯然並非如此何哼,我認爲這是信息感興趣,無論如何,所以我會離開這裏。)

我想你可能是this後。

這是關於添加shell級完成任意命令,擴展bash自己的製表符完成。

簡而言之,您將創建一個包含shell函數的文件,該文件將生成可能的完成項,並將其保存到/etc/bash_completion.d/中並將其註冊爲命令complete。下面是從鏈接頁面片段:

_foo() 
{ 
    local cur prev opts 
    COMPREPLY=() 
    cur="${COMP_WORDS[COMP_CWORD]}" 
    prev="${COMP_WORDS[COMP_CWORD-1]}" 
    opts="--help --verbose --version" 

    if [[ ${cur} == -* ]] ; then 
     COMPREPLY=($(compgen -W "${opts}" -- ${cur})) 
     return 0 
    fi 
} 
complete -F _foo foo 

在這種情況下,輸入foo --[TAB]會給你的價值觀在變opts,即--help--verbose--version。出於您的目的,您基本上需要自定義放入opts的值。

看看鏈接頁面上的例子,它非常簡單。

+2

其實我是因爲那個而來到這裏 – user1767754 2017-06-03 11:30:52

10

這是一個由ephemient here(謝謝)提供的代碼的完整版本。

import readline 

addrs = ['[email protected]', '[email protected]', '[email protected]'] 

def completer(text, state): 
    options = [x for x in addrs if x.startswith(text)] 
    try: 
     return options[state] 
    except IndexError: 
     return None 

readline.set_completer(completer) 
readline.parse_and_bind("tab: complete") 

while 1: 
    a = raw_input("> ") 
    print "You entered", a 
7
# ~/.pythonrc 
import rlcompleter, readline 
readline.parse_and_bind('tab:complete') 

# ~/.bashrc 
export PYTHONSTARTUP=~/.pythonrc 
17

我很驚訝,沒有人提到argcomplete,這裏是從文檔的例子:

from argcomplete.completers import ChoicesCompleter 

parser.add_argument("--protocol", choices=('http', 'https', 'ssh', 'rsync', 'wss')) 
parser.add_argument("--proto").completer=ChoicesCompleter(('http', 'https', 'ssh', 'rsync', 'wss'))