2008-10-09 15 views
73

Tôi biết cách thiết lập tự động hoàn thành các đối tượng python trong trình thông dịch python (trên Unix).Làm thế nào để tạo một chương trình con trăn, dòng lệnh tự động hoàn thành những thứ tùy ý NOT interpreter

  • Google hiển thị nhiều lần truy cập để được giải thích về cách thực hiện việc này.
  • Thật không may, có rất nhiều tài liệu tham khảo cho rằng rất khó để tìm thấy những gì tôi cần làm, đó là hơi khác nhau.

Tôi cần biết cách bật, tab/tự động hoàn tất các mục tùy ý trong chương trình dòng lệnh được viết bằng python.

Trường hợp sử dụng cụ thể của tôi là chương trình python dòng lệnh cần gửi email. Tôi muốn có thể tự động hoàn thành địa chỉ email (tôi có địa chỉ trên đĩa) khi người dùng nhập một phần của nó (và tùy chọn nhấn phím TAB).

Tôi không cần nó để làm việc trên cửa sổ hoặc mac, chỉ cần linux.

+0

này [blog] (http://blog.e-shell.org/ 221) nên làm các thủ thuật với cấu hình tập tin .pythonrc. –

Trả lời

46

Sử dụng các ràng buộc readline của Python. Ví dụ,

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) 

Quan chức module docs không có nhiều chi tiết hơn, vui lòng xem readline docs để biết thêm.

+1

lưu ý rằng nếu bạn viết dòng lệnh của bạn với mô-đun cmd có cách tốt hơn để làm điều đó. –

52

Thực hiện theo các cmd documentation và bạn sẽ bị phạt

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() 

Output cho tab -> tab -> gửi -> tab -> tab -> f -> tab

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

Có cách nào để kiểm soát cách readline cột đầu ra của nó? Vì vậy, cho phép nói rằng tôi muốn nó cột với hai không gian giữa mỗi mục. – Fnord

+0

Khi tôi chạy mã này, các tab được in đơn giản vào dòng lệnh. Trong thực tế điều này là đúng bất kể nếu tôi sử dụng cmd hoặc readline thẳng. –

24

Vì bạn nói "KHÔNG thông dịch viên" trong câu hỏi của bạn, tôi đoán bạn không muốn câu trả lời liên quan đến python readline và likelike. (chỉnh sửa: trong nhận thức muộn màng, đó là rõ ràng không phải là trường hợp Hồ hum Tôi nghĩ rằng thông tin này là thú vị dù sao, vì vậy tôi sẽ để nó ở đây...)

Tôi nghĩ rằng bạn có thể là sau khi this.

Đó là về việc thêm hoàn thành cấp độ vỏ vào các lệnh tùy ý, mở rộng hoàn thành tab của chính bash.

Tóm lại, bạn sẽ tạo một tệp có chứa hàm vỏ sẽ tạo các lần hoàn thành có thể có, lưu nó vào /etc/bash_completion.d/ và đăng ký nó bằng lệnh complete. Dưới đây là một đoạn trích từ trang liên kết:

_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 

Trong trường hợp này, gõ foo --[TAB] sẽ cung cấp cho bạn các giá trị trong biến opts, ví dụ: --help, --verbose--version. Vì mục đích của bạn, về cơ bản bạn sẽ muốn tùy chỉnh các giá trị được đưa vào opts.

Hãy xem ví dụ trên trang được liên kết, tất cả đều khá đơn giản.

+2

Thực ra tôi đến đây vì điều đó – user1767754

10

Đây là phiên bản đầy đủ của mã được cung cấp bởi số here (cảm ơn).

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

Tôi ngạc nhiên là không ai có đề cập argcomplete, đây là một ví dụ từ các tài liệu:

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')) 
+0

Đó là một bài đăng cũ, có lẽ lý do đã không tồn tại trở lại sau đó? Cảm ơn đã đề cập đến nó mặc dù, tôi nghĩ rằng đó là chính xác những gì dự án của tôi cần! – FrustratedWithFormsDesigner

Các vấn đề liên quan