Cách kết hợp tự động hoàn thành zsh cho các đối số hàm bao bọc và lệnh hiện có


40

Tôi làm việc chủ yếu trong gvim và nhiều thiết bị đầu cuối. Ban đầu, tôi thích mở tất cả các tệp của mình trong một ví dụ vim. Vì vậy, tôi đã sử dụng một bí danh để mở các tệp từ thiết bị đầu cuối của mình trong 'máy chủ vim' hiện tại.

alias rv="gvim --remote-silent"

Nhưng việc có nhiều tệp từ nhiều dự án mở trong một ví dụ vim ảnh hưởng đến năng suất của tôi, vì vậy tôi đang nâng cấp bí danh của mình lên một chức năng.

# main function
rv() {
    local args options server

    options=$(getopt -o hils:t: -l "help,info,list,set:,target:" -- "$@")

    if [[ $? -ne 0 ]]; then
        echo "Failed to parse options."
        return 1
    fi

    # a little magic, necessary when using getopt
    eval set -- "$options"

    # go through the options with a case and use shift to analyze one option at a time.
    while true; do
        case "$1" in
            -h|--help)
                echo "Usage: $0 [-hil] [--help] [--info] [--list]";
                echo "       $0 {-s | --set} <name> [<file1 file2...>]";
                echo "       $0 {-t | --target} <name>] <file1 file2...>";
                return 0;;
            -i|--info)
                gvim_show_info;
                return 0;;
            -l|--list)
                gvim_list_servers;
                return 0;;
            -s|--set)
                gvim_set_server_name ${2:u};
                shift 2;;
            -t|--target)
                server="$2";
                shift 2;;
            --)
                shift;
                break;;
        esac
    done

    if [[ "$#" -eq 0 ]]; then
        # if no files specified...
        if [[ -n "$server" ]]; then
            # throw error if --target option was specified.
            echo "Error!  --target requires one or more filenames."
            return 1;
        fi
    else
        # if files were specified...
        if [[ -n "$server" ]]; then
            # if --target was specified
            gvim_run_remote $server "$@"
        else
            gvim_run_remote $(gvim_get_default_server) "$@"
        fi
    fi

    return 0;
}

Bây giờ mới rvnày có tùy chọn riêng của nó. Tôi có thể sử dụng nó để:

  • liệt kê các máy chủ vim có sẵn (-l --list)
  • đặt máy chủ vim mặc định cho trình bao hiện tại (-s --set)
  • hiển thị máy chủ vim mặc định (-i --info)
  • mở tệp trong máy chủ vim cụ thể (-t --target)
  • mở tập tin trong máy chủ vim mặc định: rv files...

Tuy nhiên, vì tôi đang sử dụng một chức năng rvthay vì bí danh, tôi mất hoàn thành zsh mà trước đây tôi rất thích. Tôi đã đọc về việc tạo một chức năng hoàn thành _rv, nó sẽ hiển thị rvcác tùy chọn, nhưng tôi muốn kết hợp các tùy chọn hoàn thành của mình với các tùy chọn hoàn thành vim hiện có. Tôi biết có thể có một số mâu thuẫn với rv's -svim' s -s, nhưng tôi hình dung tôi có thể xử lý mà thanh lịch với các --dấu phân cách.

TLDR; Vì vậy, làm cách nào để tạo tập lệnh hoàn thành kết hợp các _argumentstùy chọn cho cả hai _rv_vim? Tôi thích sử dụng lại _vimnếu có thể thay vì dán sao chép danh sách đối số của nó vào _rv.

Đây là của tôi _rv. Cập nhật 2014/6/10 16:10

#compdef rv

_rv() {
    typeset -A opt_args
    local alternatives

    alternatives=(
        'args:rv options:_rv_options'
        'files:file:_vim_files'
    )

    _alternative $alternatives && return 0

    return 1
}

_rv_options() {
    local arguments

    arguments=(
        '(-i -l -s -t --info --list --set --target)'{-h,--help}'[Print usage info.]'
        '(-h -l -s -t --help --list --set --target)'{-i,--info}'[Print default vim server. As stored in $GVIM_SERVER.]'
        '(-i -h -s -t --info --help --set --target)'{-l,--list}'[Print list of existing vim servers.]'
        '(-i -h -l -t --info --help --list --target)'{-s,--set}'[Set default vim server for the current shell.]:vim servers:_rv_vim_servers'
        '(-i -h -l -s --info --help --list --set)'{-t,--target}'[Open files in a particular vim server.]:vim servers:_rv_vim_servers'
        )

    _arguments -s -C $arguments && return 0

    return 1
}

_rv_vim_servers() {
    local -a servers
    servers=( ${(f)"$(_call_program servers vim --serverlist 2>/dev/null)"} )
    _wanted servers expl server compadd -M 'm:{a-z}={A-Z}' -a servers && return
}

# invoke the completion command during autoload
_rv "$@"

Hành vi hiện tại

Hiện tại _rvhoàn thành sẽ có thể sử dụng, nhưng không lý tưởng.

  • Khi tôi gõ rv <TAB>, tôi không thấy các tùy chọn vim. Chỉ có các tùy chọn rv và đường dẫn tệp được hiển thị. _vimđang hoàn thành đường dẫn tập tin cho tôi, vì vậy hãy hoan nghênh điều đó!
  • Khi tôi gõ rv -s <TAB>, tôi thấy danh sách các máy chủ vim, nhưng cũng có các đường dẫn tệp được hiển thị. Một tệp không được phép tại thời điểm này trong lệnh và sẽ không xuất hiện trong tự động hoàn tất.

Hành vi dự kiến

  • Khi tôi gõ rv <TAB>, tôi sẽ thấy: 1) tùy chọn rv, 2) tùy chọn vim, 3) danh sách đường dẫn tệp
  • Khi tôi gõ rv -s <TAB>, tôi sẽ thấy: 1) tên máy chủ vim (như được cung cấp bởi _rv_vim_servers.
  • Khi tôi gõ rv /valid/file/path/<TAB>, tôi sẽ chỉ thấy một danh sách đường dẫn tệp. Vì _vimđã có khả năng này, tôi muốn dựa vào nó.

1
Điều này unix.stackexchange.com/questions/128199/ có thể hữu ích.
clobrano

1
compdefcó một -ntùy chọn cho biết nó "ngăn chặn mọi sự hoàn thành đã được xác định cho lệnh hoặc ngữ cảnh không bị ghi đè". Vì vậy, bạn đã thử làm compdef _vim rvtheo compdev -n _rv rv?
Lqueryvg

3
28 câu trả lời và không có câu trả lời ... và đó là một câu hỏi về zsh ... Tôi sẽ cố gắng gọi @ StéphaneChazelas cho bạn ^^ (Tôi cố gắng không lạm dụng điều này, nhưng thật vui. làm điều này ... và tôi sẽ xóa nó và không bao giờ làm điều đó nữa) ... Nếu ai đó ở đây có thể biết câu trả lời, thì đó phải là anh ta
Olivier Dulac

1
@OlivierDulac Tôi nghĩ bạn chỉ nhận được thông báo nếu bạn đã đăng trong chuỗi. (Tên trùng lặp được cho phép, vì vậy điều này có ý nghĩa.) Mặc dù vậy, bạn có thể tìm thấy anh ấy trong trò chuyện.
Sparhawk

Có thể nguồn _vim tệp gốc , nhưng trước khi thực hiện ghi đè _argumentschức năng với một chức năng cục bộ tùy chỉnh? Bằng cách làm như vậy, bạn sẽ nhận được các đối số từ _vim. Có thể với một quá trình zsh riêng.
Raphael AhDR

Câu trả lời:


1

Tôi đã tìm thấy / usr / share / zsh / chức năng / Hoàn thành / Unix / _git trong đó có một số mẹo cho các bí danh như thế này và cuối cùng đã xác định các hàm này cho các bí danh:

_git-ls () {
  # Just return the _git-ls-files autocomplete function
  _git-ls-files
}

Sau đó, thực hiện một compdef thẳng g = git. Hệ thống tự động hoàn thành sẽ thấy rằng bạn đang chạy, ví dụ, g ls và sử dụng chức năng tự động hoàn thành _git-ls.

Như được tìm thấy ở đây


cảm ơn, nhưng không hoàn toàn giải pháp của bạn cho rằng tôi chỉ muốn tự động hoàn thành _git-ls-files. Câu hỏi này có một git-ls(để gắn với quy ước của bạn) với các tùy chọn riêng và một số tùy chọn đó trùng lặp với git-ls-files. Thay vì viết tự động hoàn tất cho tất cả các tùy chọn git-ls, làm cách nào để tôi viết tự động hoàn thành lấy tự động hoàn thành từ _git-ls-files(bao gồm 90%) và kết hợp chúng với tự động hoàn thành của các tùy chọn còn lại (giả sử 10%)?
Justin C
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.