/ zshプロンプトのディレクトリを独自の方法で折りたたむ - zsh、prompt、pwd

独自の方法でzshプロンプトのディレクトリを折りたたむ - zsh、prompt、pwd

コピーして別の端末に貼り付け、TABキーを押して元のパスを取得できるように、zshプロンプトの現在の作業ディレクトリを独自の方法で折りたたむ方法はありますか?

以下のディレクトリがあるとしましょう。

/adam/devl
/alice/devl
/alice/docs
/bob/docs

プロンプトが最初のメッセージを表示するようにプログラムされている場合/ b / dに入り、それは一意です。一方、/ a / dは一意ではないため、/ ad / d、/ al / de、および/ al / doが必要です。ユーザーalexが表示されるとすぐに、/ ali /…と表示されます。

これをzshで直接ハックすることは可能ですか、それともスクリプトを作成する必要がありますか。それは、各親ディレクトリの最も短い一意の先頭を見つけます。

あなたのアイデアをありがとう!

回答:

回答№1は6

気づいてない zsh この種の組み込み関数を持っていますが、単一のサブシェルや遅いパイプに頼ることなくスクリプトを書くのはかなり簡単なはずです:

#!/bin/zsh

paths=(${(s:/:)PWD})

cur_path="/"
cur_short_path="/"
for directory in ${paths[@]}
do
cur_dir=""
for (( i=0; i<${#directory}; i++ )); do
cur_dir+="${directory:$i:1}"
matching=("$cur_path"/"$cur_dir"*/)
if [[ ${#matching[@]} -eq 1 ]]; then
break
fi
done
cur_short_path+="$cur_dir/"
cur_path+="$directory/"
done

printf %q "${cur_short_path: : -1}"
echo

このスクリプトは自動補完が機能するのに必要な最短パスを出力します。

あなたはあなたの中にそれを投げることができます .zshrc 関数としてしてから任意のディレクトリから実行します。

function spwd {
paths=(${(s:/:)PWD})

cur_path="/"
cur_short_path="/"
for directory in ${paths[@]}
do
cur_dir=""
for (( i=0; i<${#directory}; i++ )); do
cur_dir+="${directory:$i:1}"
matching=("$cur_path"/"$cur_dir"*/)
if [[ ${#matching[@]} -eq 1 ]]; then
break
fi
done
cur_short_path+="$cur_dir/"
cur_path+="$directory/"
done

printf %q "${cur_short_path: : -1}"
echo
}

これが実際のビデオです。

https://asciinema.org/a/0TyL8foqvQ8ec5ZHS3c1mn5LH

あるいは、もし望むなら、いくつかの出力例

~/t $ ls
adam  alice  bob  getshortcwd.zsh

~/t $ ls adam
devl

~/t $ ls alice
devl  docs

~/t $ spwd
/h/v/t

~/t $ cd adam/devl

~/t/adam/devl $ spwd
/h/v/t/ad/d

~/t/adam/devl $ cd ../../alice/devl

~/t/alice/devl $ spwd
/h/v/t/al/de

~/t/alice/devl $ cd ../docs

~/t/alice/docs $ spwd
/h/v/t/al/do

~/t/alice/docs $ `spwd` [TAB]
~/t/alice/docs $ /h/v/t/al/do [TAB]
~/t/alice/docs $ /home/vsimonian/t/alice/docs

回答№2の場合は0

はい、ディレクトリを折りたたむことは可能ですTabキーを押すと、Zシェルにそのパスを拡張させます。私は単にcompinstall(Zshと一緒にインストールされたzshユーティリティスクリプト)を使って次のコードを生成しました。パス要素を拡張するために注意する必要がある重要な部分は、 第六 zstyle 末尾近くのコマンド補完ポイントを区切るための文字の大括弧には、 /これは、もちろん、ディレクトリ区切り文字です。これで、あなたが提案したユニークなパスはまるでまるで1回の[Tab]プレスで完全に記入されます。 * 各パス名の末尾には固有の文字があります。

# The following lines were added by compinstall

zstyle ":completion:*" add-space true
zstyle ":completion:*" completer _list _expand _complete _ignored _match _correct _approximate _prefix
zstyle ":completion:*" completions 1
zstyle ":completion:*" list-colors ${(s.:.)LS_COLORS}
zstyle ":completion:*" matcher-list "m:{[:lower:]}={[:upper:]} r:|[._-]=* r:|=*" "m:{[:lower:]}={[:upper:]} m:{[:lower:][:upper:]}={[:upper:][:lower:]} r:|[._-]=* r:|=*" "r:|[._-/]=* r:|=*" "l:|=* r:|=*"
zstyle ":completion:*" match-original both
zstyle :compinstall filename "/home/micah/.zsh/.zshrc"

autoload -Uz compinit
compinit
# End of lines added by compinstall

最初に固有のパスを作成してそれをプロンプトに挿入することに関しては、zshスクリプトまたは関数を使用することが可能です。 〜すべき コンプリータやラインエディタでも可能ですが、プロンプトにこだわるだけで、 $precmd_functions 変更または追加する配列 PS1 変数。この特別な配列は各プロンプトの直前に実行される関数名のリストです。

function precmd_unique_pwd {
local pwd_string="$(upwd)"
PS1="%B%n@%m $pwd_string => %b"
}
precmd_functions+=( precmd_unique_pwd )

現在の障害を短縮した形で理解するために、この機能は明確でわかりやすいと思いますが、必ずしもリソース使用量が少なくなるように最適化されているとは限りません。

#!/bin/zsh
function upwd {
emulate -LR zsh -o nullglob
local dir Path
local -a newpwd tmp stack
local -i length=1 Flag=0
newpwd=( ${(s./.)PWD} )
foreach dir ( $newpwd )
(( length=0, Flag=0 ))
repeat $#dir
do
(( length += 1 ))
tmp=( ${(j.*/.)~stack}/$dir[1,$length]*(/) )
if
(( $#tmp == 1 ))
then
Path=$Path/$dir[1,$length]
stack+=( /$dir )
(( Flag=1 ))
break
fi
done
if
(( Flag ))
then
continue
else
Path=$Path/$dir
fi
end
print -- $Path
}
upwd

Zsh機能により、ディレクトリ名を含む一意のパスが見つかることに注意してください。 (/) 爆発の終わりに。最後のディレクトリ(現在)では、同じ名前に拡張子を加えたファイルがある場合、他のものと一致する可能性があります。