7

ドット ファイル管理ユーティリティの bash 補完スクリプトを作成中です。このツールにはdots diff [filename]、インストールされたドット ファイルとソース ドット ファイルの違いを表示するコマンドがあります。dots filesまた、管理されているすべてのドット ファイルのパス (ソース ディレクトリからの相対パス) を一覧表示するコマンドもあります。files コマンドの出力で diff コマンドを完成させたいと思います。

ファイル出力の例を次に示します

X11/xkb/symbols/evan-custom
X11/xorg.conf.d/10-dual-monitors.conf
X11/xorg.conf.d/10-keylayout.conf
bash/aliases
bash/bashrc
bash/completion.d/dots
bash/profiles/standard-user
bash/profiles/systemd-user
bspwm/bspwmrc
compton/compton.conf
fontconfig/fonts.conf
git/config
git/ignore
gtk-2.0/gtkrc
gtk-3.0/settings.ini
mysql/config
mysql/grcat
ncmpcpp/config
pulse/client.conf
pulse/daemon.conf
pulse/default.pa
ssh/config
sublime-text-3/Packages/User/Preferences.sublime-settings
sxhkd/sxhkdrc
termite/config
transmission-daemon/settings.json
vim/vimrc

このようなものを使用して

COMPREPLY=( $(compgen -W "$(dots files)" -- $cur) )

動作しますが、readline が利用可能なオプションを一覧表示すると、完全なパスが一覧表示されます (上記のリスト)。

単語をファイルパスであるかのように扱い、提案をリストするときは最初のスラッシュまでしかリストしないようにしたいと思います。

たとえば、次のように入力dots diff [tab][tab]すると、次のように出力されます

X11/
bash/
bspwm/
compton/
fontconfig/
git/
gtk-2.0/
gtk-3.0/
mysql/
ncmpcpp/
pulse/
ssh/
sublime-text-3/
sxhkd/
termite/
transmission-daemon/
vim/

たとえば、次に入力したdots diff bash/[tab][tab]場合、それは表示されます

aliases
bashrc
completion.d/
profiles/

理想的には、実際にそれをパスとして扱い、readline オプションmark-directoriesを off に変更すると末尾のスラッシュが除外されるようにしたいと考えています。

設定を試みましcompopt -o filenamesたが、最初はパスではなくファイル名が提案されます。

ここに私がこれまでに持っている完了スクリプトがあります

4

3 に答える 3

6

私はこれを解決しました。

秘訣はcompopt -o filename、パスの一部を使用してから切り落とすことでした。これは、完了しているディレクトリのサブディレクトリです。

これがコードです

# Do completion from a passed list of paths
#
# Accepts 2 arguments
# 1. The list of paths to complete from
# 2. The current word being completed
__dots_path_comp()
{
    # This forces readline to only display the last item separated by a slash
    compopt -o filenames

    local IFS=$'\n'
    local k="${#COMPREPLY[@]}"

    for path in $(compgen -W "$1" -- $2)
    do
        local trailing_trim

        # Determine what to trim from the end
        trailing_trim="${path#${2%/*}/}/"
        trailing_trim="${trailing_trim#*/}"
        trailing_trim="${trailing_trim%/}"

        # Don't add a space if there is more to complete
        [[ "$trailing_trim" != "" ]] && compopt -o nospace

        # Remove the slash if mark-directories is off
        if ! _rl_enabled mark-directories
        then
            # If The current typed path doesnt have a slash in it yet check if
            # it is the full first portion of a path and ignore everything after
            # if it is. We don't have to do this once the typed path has a slash
            # in it as the logic above will pick up on it
            [[ "$2" != */* && "$path" == ${2}/* ]] && path="$2/$trailing_trim"    

            trailing_trim="/$trailing_trim"
        fi

        COMPREPLY[k++]="${path%%${trailing_trim}}"
    done
}
于 2013-11-14T09:36:52.700 に答える
0

汚いハックは、あなた$(dots files)

$(dots files | sed 's,/.*/,,' | uniq)

完全なものが次のように読めるように

COMPREPLY=( $(compgen -W "$(dots files | sed 's,/.*/,,' | uniq)" -- "$cur") )

今、私は個人的にこのアプローチがあまり好きではありません。basedirs代わりに、必要なものだけを出力するステートメントなどを受け入れるようにスクリプトを変更できますか?

また、名前にスペースやその他の変な記号が含まれていると、補完が期待どおりに機能しないことに注意してください。

于 2013-11-03T12:24:45.663 に答える