Làm thế nào để chỉnh sửa và tô màu danh sách hoàn thành tab của bash


8

Sau đây là những gì tôi muốn có. Khi hoàn thành tab không rõ ràng và bash sẽ in danh sách các khả năng. Tôi muốn nó tô màu cho ký tự tiếp theo mà tôi nên nhấn bên trong mỗi từ trong danh sách.

Sau đây là những gì tôi đã làm cho đến nay. Trong .bashrc của tôi, tôi đã xác định hàm sau và đã gọi lệnh hoàn chỉnh

_colourunique() {
    local word=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=($(compgen -f -- "${word}"))
    if [[ "$word" ]] && [[ ${#COMPREPLY[@]} -gt 1 ]]; then
        local  w
        local  i=0
        for ((i=0;i<${#COMPREPLY[@]};i++)) ; do
            w=${COMPREPLY[$i]}
            n=${#word}
            COMPREPLY[$i]="${w:0:n}\033[91m${w:n:1}\033[0m${w:$((n+1))}"
        done
    fi
}

complete -D -F _colourunique

Nhưng nó không hoạt động ... Khi tôi gõ

ls D[TAB]

Nó tự động hoàn thành như

ls D\033[91m

Thay vì liệt kê các khả năng Tài liệu, Máy tính để bàn, vv Điều gì có thể xảy ra ở đây? Hoặc có một số cách trực tiếp khác để thực hiện điều này?

CẬP NHẬT 1:

Tôi nghĩ rằng tôi hiểu những gì đang xảy ra ở đây. Vì tôi thêm \ 033 [91m vào mỗi từ trong COMPREPLY, bash thấy phần này là chung cho tất cả và tự động hoàn thành thuật ngữ chung đó vào chính dấu nhắc lệnh. (thay vì chỉ in danh sách)

Vì vậy, tôi không nghĩ rằng phương pháp chỉnh sửa mảng COMPREPLY này là cách để thực hiện. Có phương pháp nào khác không?

CẬP NHẬT 2:

Để duy trì tính đơn nhất, tôi đã cố gắng thêm $ i và \ b trong chuỗi.

COMPREPLY[$i]="${w:0:n}$i\b\033[91m${w:n:1}\033[0m${w:$((n+1))}"

Bây giờ nó in các tab hoàn thành có thể như sau.

D0\b\033[91mo\033[0mwnloads  D1\b\033[91me\033[0msktop

Có nghĩa là, danh sách được in như vậy. Không có đánh giá về \ b hoặc \ 033 [91m ký tự. :-(

CẬP NHẬT 3:

Vì các câu trả lời trông giống như vậy, không có cách nào để thực hiện những gì tôi muốn trong bash (trừ khi tôi chuyển sang zsh). Tôi quyết định giải quyết cho một lựa chọn khác. Tôi sẽ cố gắng nối các nét phím duy nhất tiếp theo vào cuối mỗi từ để nó nổi bật.

Sau đây là mã cho đến nay.

SanitiseString () {
    local String="$1"
    local j
    for j in \\ \! \@ \# \$ \% \^ \& \* \( \) \+ \{ \[ \] \} \| \; \: \" \' \, \? \ ; do
        String=${String//"$j"/\\"$j"}
    done
    echo "$String"
}

_colourunique() {
    saveIFS=$IFS
    IFS=$'\n'                                   
    local word=${COMP_WORDS[COMP_CWORD]}
    COMPREPLY=($(compgen -f -- "${word}"))
    if [[ "$word" ]] ; then
        local  w
        local  i=0
        for ((i=0;i<${#COMPREPLY[@]};i++)) ; do
            w="${COMPREPLY[$i]}"
            n=${#word}
            w=$(SanitiseString "$w")
            if  [[ ${#COMPREPLY[@]} -gt 1 ]] ; then
                COMPREPLY[$i]="$w :${w:n:1}"
            else
                COMPREPLY[$i]="$w"
            fi
        done
    fi
    IFS=$saveIFS
}

complete -D -F _colourunique

Điều này sẽ in các tùy chọn với tổ hợp phím độc đáo tiếp theo được phân tách bằng:

Nhưng mã vẫn có hai vấn đề khó chịu. mà tôi phải giải quyết

  1. Nó không còn nối thêm / ở cuối thư mục tự động hoàn thành
  2. Nó không còn khoảng cách thông minh sau khi tự động hoàn thành.

Bất kỳ đề xuất?


Tôi không nghĩ bạn có thể làm những gì bạn đang cố gắng. Các chuỗi thoát được sử dụng để định dạng đầu ra thực sự không phải là một phần của đầu ra, mà bashđơn giản là không cung cấp một móc để định dạng tùy chỉnh các hoàn thành có thể.
chepner

1
Câu trả lời dễ dàng là chuyển sang zsh, trong đó đây là một tùy chọn cấu hình.
Gilles 'SO- ngừng trở nên xấu xa'

Vì có vẻ như tôi không thể làm những gì tôi muốn trong bash. Tôi đang cố gắng làm một điều khác thay thế. Tôi đã thêm một bản cập nhật nối thêm từ khóa duy nhất tiếp theo được phân tách bằng: vào danh sách cần in.
Ấn Độjoe

Câu trả lời:


2

Mặc dù đây không phải là chính xác những gì bạn yêu cầu, tôi quyết định đăng câu trả lời này vì ban đầu tôi có cùng ý tưởng với bạn, nhưng cuối cùng tôi giải quyết nó như thế này và tôi thấy nó còn tốt hơn cả tô màu.

Người ta có thể đặt tùy chọn này cho thư viện đọc GNU :

xong-tiền tố-hiển thị-độ dài Độ dài tính bằng ký tự của tiền tố chung của danh sách các lần hoàn thành có thể được hiển thị mà không sửa đổi. Khi được đặt thành giá trị lớn hơn 0, các tiền tố phổ biến dài hơn giá trị này được thay thế bằng dấu chấm lửng khi hiển thị các lần hoàn thành có thể.

Vì vậy, ví dụ dòng này trong ~ / .inputrc :

set completion-prefix-display-length 2

cũng tạo ra mánh khóe (khi tiền tố chung dài hơn hai ký tự).


0

.c của tôi không quá hấp dẫn, nhưng từ việc đọc xung quanh bên trong http://git.savannah.gnu.org/cgit/bash.git/snapshot/bash-master.tar.gz , có vẻ như tôi không thể hiểu thêm hơn dữ liệu văn bản không hành động. iow, thậm chí có một Escape trong đó cuối cùng được in thành một đại diện phi ma thuật / không đặc biệt của các nhân vật chúng ta sử dụng để thể hiện chúng.

thích \033hoặc \ekhông phải là ký tự đơn "Thoát", nhưng bốn hoặc hai ký tự dấu gạch chéo ngược và số không, số ba và Es.

Tôi đã chọc với nhiều lần lặp khác nhau của printf/ echo/ evaltrước khi đi sâu vào .c để xem cách nó thực sự xử lý các giá trị trong COMPREPLY.

có thể sai, nhưng kiểm tra strlist_print()trong lib/sh/stringlist.ctrông giống như COMPREPLY là một cấu trúc kiểu STRINGLIST (theo quy định tại externs.h).


Vậy điều đó có ý nghĩa gì? Có phải bạn đang nói STRINGLIST bởi vì những người đó được xử lý đặc biệt và những người trốn thoát được thoát ra?
Evi1M4chine
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.