2012-01-25 33 views
12

Tôi đã viết một công cụ dòng lệnh có sử dụng phụ lệnh giống như Mercurial, Git, Subversion & c, trong đó sử dụng chung của nó là:.Hoàn khi chương trình đã phụ lệnh

>myapp [OPTS] SUBCOMMAND [SUBCOMMAND-OPTS] [ARGS] 

Ví dụ:

>myapp --verbose speak --voice=samantha --quickly "hello there" 

Tôi hiện đang trong quá trình xây dựng hoàn thành Zsh cho nó nhưng đã nhanh chóng phát hiện ra rằng nó là một con thú rất phức tạp. Tôi đã có một cái nhìn tại các sự hoàn thành _hg_git nhưng chúng rất phức tạp và khác nhau trong cách tiếp cận (tôi cố gắng để hiểu chúng), nhưng cả hai dường như xử lý từng lệnh phụ riêng biệt.

Có ai biết nếu có một cách sử dụng được xây dựng trong các chức năng (_arguments, _values, pick_variant & c.) Để xử lý các khái niệm về tiểu lệnh một cách chính xác, kể cả xử lý tùy chọn chung và tùy chọn cụ thể sub-lệnh một cách thích hợp? Hay cách tiếp cận tốt nhất là xử lý thủ công các tùy chọn chung và lệnh phụ?

Ví dụ về tiêu đề sẽ rất được đánh giá cao.

Rất cám ơn.

Trả lời

21

bạn có quyền viết kịch bản hoàn thành viết cho zsh có thể khá khó khăn. Đặt cược tốt nhất của bạn là sử dụng đặt cược hiện tại làm hướng dẫn. Một cho git là quá nhiều cho một người mới bắt đầu, imo. Bạn có thể sử dụng repo này:

https://github.com/zsh-users/zsh-completions

Đối với câu hỏi của bạn, bạn phải sử dụng các khái niệm về nhà nước . Bạn xác định các subcommands của bạn trong một danh sách, và sau đó xác định thông qua $ state lệnh nào bạn đang ở. Sau đó, bạn xác định các tùy chọn cho mỗi lệnh. Bạn có thể thấy điều này trong tập lệnh hoàn thành cho số phát. Một phiên bản đơn giản là bên dưới:

_play() { 
    local ret=1 

    _arguments -C \ 
    '1: :_play_cmds' \ 
    '*::arg:->args' \ 
    && ret=0 

    case $state in 
    (args) 
     case $line[1] in 
     (build-module|list-modules|lm|check|id) 
      _message 'no more arguments' && ret=0 
     ;; 
     (dependencies|deps) 
      _arguments \ 
      '1:: :_play_apps' \ 
      '(--debug)--debug[Debug mode (even more informations logged than in verbose mode)]' \ 
      '(--jpda)--jpda[Listen for JPDA connection. The process will suspended until a client is plugged to the JPDA port.]' \ 
      '(--sync)--sync[Keep lib/ and modules/ directory synced. Delete unknow dependencies.]' \ 
      '(--verbose)--verbose[Verbose Mode]' \ 
      && ret=0 
     ;; 
     esac 
    esac 

(Nếu bạn định dán mã này, hãy sử dụng nguồn gốc vì điều này sẽ không hoạt động).

Có vẻ khó khăn, nhưng ý tưởng chung không phức tạp. Tiểu ban đến trước (_play_cmds là một danh sách các tiểu ban có mô tả cho từng tiểu ban), sau đó đến các đối số. Các đối số được xây dựng dựa trên tiểu ban mà bạn đang chọn. Lưu ý rằng bạn có thể nhóm nhiều tiểu ban, nếu chúng chia sẻ các đối số.

với người đàn ông zshcompsys bạn có thể tìm thêm thông tin về toàn bộ hệ thống, mặc dù nó hơi dày đặc.

+1

Điều đó thật tuyệt vời cảm ơn bạn rất nhiều. Tôi rất vui vì bạn đã nói 'zshcompsys' dày đặc khi tôi bắt đầu nghĩ đó là tôi;) –

+0

Trong 20 năm, mã này sẽ giống như nhị phân hiện nay đối với tôi. – aaaaaa

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