Hoàn thành tab không hoạt động cho các đối số khi lệnh là bí danh


7

Tôi có một bí danh, ee, được xác định cho trình soạn thảo yêu thích của tôi, mg. Khi tôi làm một cái gì đó như

mg fo

và sau đó nhấn tab, nếu một tệp foo tồn tại, tôi sẽ hoàn thành tab để:

mg foo

Trên hầu hết các hệ thống tôi sử dụng (ví dụ: tất cả các phiên bản ubfox trong nhiều năm nay và một số bản cài đặt debian),

ee fo

cũng hoàn thành đúng

ee foo

Nhưng trên một hệ thống tôi sử dụng, có bản phát hành Debian 6.0 và GNU bash 4.1.5 (1), việc hoàn thành tab không thành công cho phiên bản có bí danh. Lưu ý rằng đây không phải là vấn đề với việc tự hoàn thành bí danh - đó là vấn đề với việc hoàn thành các đối số của lệnh bí danh. Có cách nào để khắc phục hành vi này trên hệ thống Debian không? Nâng cấp lên bash 4.2.x? Fiddle với tập tin cấu hình?


2
Bạn đã cài đặt gói bash-hoàn thành chưa? Bạn đang tìm nguồn cung ứng /etc/bash_completion?
jordanm

@jordanm: Có, bash-hoàn thành được cài đặt. Tôi không biết liệu tôi có tự động tìm nguồn / etc / bash_completion cho mỗi phiên đăng nhập hay không, nhưng tôi đoán rằng tôi đang ở đâu đó, vì $ BASH_COMPLETION được xác định. Nếu tôi thực hiện một "nguồn / etc / bash_completion" rõ ràng thì nó không khắc phục được vấn đề.
Ben Crowell

Câu trả lời:


4

Chỉnh sửa: OK. Có vẻ như tôi có thể đã đọc sai tình huống. Nghĩ rằng bạn có nghĩa là tùy chọn chương trình như trong:

$ mplayer_alias -pla<tab><tab>
-playing-msg  -playlist
$

nhưng đoán nó là hoàn thành tập tin. Tôi không biết, nhưng hãy thử đi.

Là một sửa chữa nhanh chóng, điều này sẽ làm việc:

complete -f -o default ee

Tặng:

$ ee<tab><tab>
file1 file2 file3
$

kể từ khi lập trình hoàn thành lập trình . Ví dụ, -X patterncó thể hữu ích. Ví dụ: để loại trừ .swp.swocác tệp:

complete -f -X '*.sw[op]' ee

chỉ hiển thị .zip, .ZIP:

complete -f -o default -X '!*.+(zip|ZIP)' my_unzip_alias

một số có thể cần bạn thêm shopt -s extglobvào tập tin cấu hình.



Trả lời:

Bạn có thể thử một cái gì đó như thế này trong của bạn .bash_completion.

Ít nhất là như một khởi đầu.

Ý tưởng cốt lõi là chỉ cần thêm completecho bí danh bằng cách sử dụng tập lệnh hoàn chỉnh hiện có cho chương trình thực . Ở đây tôi giả sử rằng tất cả chúng đều ở định dạng:

complete -F _complete_function_from_original program_name

Bạn có thể có được những gì nó bằng cách thực hiện : complete -p program_name. Tốt nhất để kiểm tra đầu tiên.

Đối với một số phương thức như apt-getngười ta chỉ có thể sử dụng bí danh + tải:

_load_comp_hack apt-get myalias

Đối với những người khác như người mplayerta cần một trình bao bọc hàm, như trong ví dụ:

myalias() { mplayer "$@"; }
                      |
                      +--- Could be messy

Hoàn toàn có thể có một cách tốt hơn để giải quyết vấn đề này, nhưng đã hoạt động tốt cho việc sử dụng của tôi. Tôi chủ yếu sử dụng nó cho các kịch bản lệnh bao bọc, nơi tôi mở rộng chức năng của chương trình gốc. Chưa sử dụng nó trên bí danh.

Tôi không cảm thấy an toàn với vụ hack này, nhưng bạn có thể thấy nếu nó hoạt động.

_load_comp_hack()
{
    local cc=
    # Make sure completion scripts are sourced.
    # Report error if source fail.
    if . "/usr/share/bash-completion/completions/$1" >/dev/null 2>&1; then
        # Extract the completion function used by the "real" program.
        if cc="$(complete -p "$1" | cut -d' ' -f3)"; then
            # Add it to the alias
            complete -F "$cc" "$2"
            return 0
        fi
    fi
    echo "bash-completion '$1' for '$2' not found."
}

_load_comp_hack mplayer mplad
_load_comp_hack apt-get z
                |       |
                |       +----- Alias, script or function
                +------------- Real function

Một số chương trình sử dụng hoàn thành chung hơn như _longopt, trong đó tệp nguồn sẽ không được định vị. Thông thường, nó cũng không cần nguồn, vì vậy một biến thể đơn giản hơn có thể là:

_load_comp_hack()
{
    local cc=
    if cc=$(complete -p "$1" | cut -d' ' -f3); then
            complete -F "$cc" "$2"
    fi
}

Một vấn đề ở đây, IIRC, là một số tập lệnh hoàn thành không được tải cho đến lần chạy đầu tiên, như trong lần đầu tiên :
prog tabtab. Như một sự thay thế có lẽ thêm nó như là một elsenguồn cung cấp tập tin thất bại.


Cám ơn vì sự gợi ý. Chương trình thực tế dường như không có sự hoàn thành của chính nó được xác định; complete -p mgkhông cho kết quả Nhưng tôi vẫn hoàn thành tab khi tôi sử dụng chương trình thực sự ...?
Ben Crowell

@BenCrowell: Hoàn thành như trong tùy chọn chương trình, không phải tệp?
Runium

@BenCrowell: Cập nhật câu trả lời. Bây giờ có đúng không?
Runium

Tuyệt vời, complete -f -o default eelà một sửa chữa. +1, câu trả lời được chấp nhận. Thử nghiệm thêm cũng cho thấy vấn đề ban đầu chỉ xảy ra khi có nhiều lần hoàn thành có thể xảy ra khá dài; trong những điều kiện này, mg đã hoàn thành nhưng ee thì không. Sau khi làm complete -f -o default ee, ee hoạt động theo cách tương tự trên các lần hoàn thành dài là mg.
Ben Crowell

0

Vấn đề của bạn là: bash-xong không hiểu bí danh. Vì vậy, nếu bạn viết một bí danh, nó chỉ đơn giản được xem là một lệnh không xác định và sẽ không được tự động hoàn thành. Bạn có thể dự phòng hoàn thành tên tệp mặc định, nếu đây là những gì bạn muốn. Hoặc, bạn có thể cài đặt chương trình mở rộng bí danh trước khi tự động hoàn thành và hoàn thành bí danh của bạn dưới dạng các lệnh bí danh của chúng.

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.