zshでavfs偽のディレクトリを完成

zshでavfs偽のディレクトリを完成

場合によっては、「偽」ファイルを完成させるためにzshの完成システムをどのように調整できますか?

より正確には、AVFSファイルシステムは、各アーカイブの隣に「偽のディレクトリ」を作成し、アーカイブをディレクトリとして公開します。デフォルトでは、マウントポイントの下にあるディレクトリ階層全体をコピーします~/.avfs。また、以下には、~/.avfs各アーカイブファイル(たとえば)の/tmp/foo.zipアーカイブファイル自体に加えて、アーカイブの内容を公開するという~/.avfs/tmp/foo.zipディレクトリもあります。~/.avfs/tmp/foo.zip#ただし、この追加のディレクトリはリストに表示されず、明示的~/.avfs/tmpに要求された場合にのみ存在します。 (これはいくつかの自動インストーラの仕組みと似ています。)

mountavfs
cd ~/.avfs/tmp/foo.zip\#

上記のコマンドを入力しても、対応するディレクトリがなく、完了foo.zip#としてマークされません。フルパスが1に~/.avfs/tmp/一致するファイルがあるたびに、というディレクトリがあるかのように偽装する必要があることをzshにどのように指示しますか?$arc~/.avfs/**/*.(tgz|zip)${arc}#

(コマンドだけでなく、_filesorへのすべての呼び出しに補完機能を適用したいのですが、可能であれば関数のコードを繰り返す必要はありません。)_dirscd_files

そして残りのすべての拡張

答え1

この偽の質問に対する偽の答えは十分ではないようです。 zshの自動マウントディレクトリの組み込みサポートは、ディレクトリfake-files dir:names()内のファイルモードではなく機能します。これは、ディレクトリに特別に名前付きファイルを追加するのに便利です。これは、インストールするディレクトリが既知の静的名前であるNetAppタイプのautomount設定に適しています。sshfs.snapshotALAS

autoload -U compinit
compinit
zstyle ':completion:*' fake-files $HOME/.avfs:'ALAS POOR YORICK'

zshall(1)「名前」が文字列であると言うと、実験によると、メタ文字(たとえば、または)が#さまざまな方法で「機能しない」と表示されるため、ステートメントの名前部分に塊をこっそり入れる方法がわかりません。 (もっと深く掘り下げると、名前が正確に何を意味するのかがわかりますが、より多くの作業が必要です。)確認する必要があります。\#'*(e:"echo hi":)'fake-filesSrc/Zle/computil.cfake-files

を使用すると、ディレクトリ完了ステータスを一覧compdef表示できます。.avfs

compdef '_files -g $HOME/.avfs/\*' -p \^
function andthehash {
  reply=($REPLY $REPLY\#)
}
compdef "_files -g $HOME/.avfs/'*(+andthehash)'" -p \^

ただし、これは#重要でないファイルのみを表示して完了できないため、失敗します。 (このフォームは生産的な用途によく使用されますが、この例には適用されません。)

次のように使用すると、zstyleより近づくことがあります.zshrc

autoload -U compinit
compinit

function UnderAVFS {
  local pdir
  [[ -z $1 ]] && return 1
  pdir=$1:a
  [[ ! -d $pdir ]] && pdir=$pdir:h
  [[ ! -d $pdir || $pdir == . ]] && return 1
  while [[ $pdir != / ]]; do
    [[ $pdir == $HOME/.avfs ]] && return 0
    pdir=$pdir:h
  done
  return 1
}

function AVFSExtras {
  if UnderAVFS $REPLY; then
    reply=($REPLY)
    # TODO embiggen list of archive suffixes
    [[ $REPLY == *.(bz2|tbz2) ]] && reply+=($REPLY\#)
  fi
}

# Try to match avfs, otherwise the default pattern. Probably could greatly
# benefit from caching, to avoid hits on UnderAVFS function.
zstyle ':completion:*' file-patterns '*(+AVFSExtras):avfs-files' '%p:all-files'

ただし、その\#/ビット(デフォルトのavfs設定を使用するdebian squeeze virtの場合)のみを完了でき、アーカイブの仮想ファイルシステムは完了できないため、アーカイブを完了するには追加の作業が必要です。存在しないディレクトリが実際に存在すると信じられるよりエレガントな方法がない場合は、via_call_program ... lsまたは同様のものがビットを実行できると推測します。\#zsh

悪いニュース!_path_files偽のディレクトリの場合、完了は成功しません。これはzsh globbingに関連しているようです。この問題は、zsh 4.something onとzsh 5.0.8の両方で発生します。したがって、完全な修正を行うには、パッチを適用したり、_path_filesこれらの偽のディレクトリに対して実行できる他の内容を作成する必要があると考えられます。誰もが失敗の原因を把握したい場合は、ls /root/.avfs/root/sometar.gz\#/入力してその入力の最後に入力してから、対応するキーの組み合わせをcontrol-x想定し?てバインドして完了デバッグトレースを生成できます。bindkey -e_complete_debug

答え2

zshでは、compctl -K独自の関数登録を使用して完了オプションを生成できます。たとえば、

compctl -f -c -u -r -K myAVFScompletion "*" -tn

その後、独自の関数を定義する必要があります。

myAVFScompletion () {
    read -c COMMAND ARGS

    # Decide what paths you want to suggest completion for
    # by looking inside the ~/.avfs folder.

    # Place your suggestions into an array:
    reply=( a_path b_path ... )
}

明らかに、上記の作業にはより多くの作業が必要ですが、開始に過ぎません。

同様ですが、他のカスタム補完機能をBashに登録できます。

これはBashとzshの実装例。 (コマンドマニュアルページでオプションを選択してコマンドラインオプションを完成させます。)

以下は、完成関数で動作することができる操作のいくつかの簡単な推測です。

if [[ -d "$ARGS#" ]]
then reply=( "$ARGS#" )
else reply=
fi

または、次のようなものかもしれません。

reply=( $(find ~/.avfs -type f -name "*.tgz" -or -name "*.zip" | sed 's+$+#+') )

頑張ってください!

関連情報