26

カスタム補完から次の動作を取得したい

与えられた

$ mkdir foo
$ touch foo faz/bar faz/baz

これを手に入れたい

$ foo -u <tab><tab> =>
foo faz/

$ foo -u fa<tab><tab> =>
foo -u faz/

$ foo -u faz/<tab><tab> =>
bar baz

compgen -f fが出力されると思いましたがfoo faz/foo fazあまり役に立ちません。

出力を後処理する必要がありますか、それとも機能する compgen のオプションの魔法の組み合わせがありますか?

4

6 に答える 6

24

私は同じ問題に遭遇しました。私が使用している回避策は次のとおりです。

  1. -o defaultで補完関数を登録しcomplete -o default -F _my_completionます。
  2. ファイル名を完成させたいときは、設定COMPREPLY=()して Readline に引き継がせてください (これが の-o default動作です)。

これには潜在的な問題がありますCOMPREPLY=()。不適切な場合に完了を拒否するために使用している可能性があり、現在はそれが機能しなくなりました。compoptBash 4.0 以降では、次のように使用してこれを回避できます。

  1. 補完関数の先頭で、常に を実行しますcompopt +o defaultCOMPREPLYこれにより、が空の場合、Readline ファイル名の補完が無効になります。
  2. ファイル名を完成させたいときは、compopt -o default; COMPREPLY=(). つまり、必要な場合にのみ Readline ファイル名の補完を有効にします。

4.0 より前の Bash の完全な回避策はまだわかっていませんが、私には十分に機能するものがあります。誰かが本当に気にかけているなら、私はこれを説明することができますが、うまくいけば、これらの古いバージョンの Bash はすぐに一般的に使用されなくなります.

于 2013-09-28T03:35:46.520 に答える
5

この動作はreadline変数mark-directories(および関連するmark-symlinked-directories) の影響を受けます。ディレクトリ名の末尾にスラッシュを出力するには、変数をオンに設定する必要があると思いcompleteます(bash v3.00.16のデフォルト)。の関連する動作は、compgenディレクトリ名にスラッシュを追加しないようです:-\

mark-directories交互に値を設定してから、テストonoff再試行してください:-

bind 'set mark-directories on'
bind 'set mark-directories off'

の将来の呼び出しのために変更を永続的にbashするには、次を INPUTRC ファイルに追加します。通常は次のとおりです~/.inputrc

$if Bash
# append '/' to dirnames
set mark-directories on
$endif

現在のシェルで readline 変数を設定するためのヒントは、https ://unix.stackexchange.com/a/27545 にあります。readline 変数の現在の値をテストする方法がわかりませんでした。

追加のアイデア

おそらく学問的な興味だけ...

ディレクトリ名のみのリストを作成し、スラッシュを追加します:-

compgen -d -S / f
于 2012-10-17T17:02:17.480 に答える
2

ディレクティブ-o filenamesに渡されたオプションを使用します。completeの内容COMPREPLYが有効なパスである限り、ディレクトリ以外の一致の完了後にスペースを追加しながら、スラッシュが適切に追加されます。(bash 3.2 で動作します。)

_cmd() {
  COMPREPLY=( $( compgen -f -- "$cur" ))
  COMPREPLY=( $( compgen -A file -- "$cur" ))  # same thing
}

complete -o filenames -F _cmd cmd

参照info -n "(bash)Programmable Completion Builtins":

完了

... -o COMP-OPTION ...

     filenames
           Tell Readline that the compspec generates filenames, so
           it can perform any filename-specific processing (like
           adding a slash to directory names or suppressing
           trailing spaces).  This option is intended to be used
           with shell functions specified with `-F'.

と:

-A ACTION

... 'ファイル'

           File names.  May also be specified as -f.

注:compgencompleteは同じ引数を持ちます。

于 2019-08-07T00:17:10.507 に答える
0

ディレクトリが完成した後も引き続きタブを使用できるようにしたい場合。完全なソリューションは次のとおりです。

cur=${COMP_WORDS[COMP_CWORD]}
COMPREPLY=( $(compgen -S "/" -d -- ${cur}) ); 
compopt -o nospace;

最初に、回答の末尾にスラッシュを追加します。次に、compopt -o nospaceコマンドを実行して末尾のスペースを削除します。ディレクトリにしかない場合はfoo/bar、それらを入力するのに 2 つのタブで十分です。

于 2014-11-28T07:29:07.703 に答える