/ / Zwiń katalogi w wierszu poleceń zsh w unikalny sposób - zsh, prompt, pwd

Zwiń katalogi w wierszu poleceń zsh w unikalny sposób - zsh, prompt, pwd

Czy istnieje sposób, aby zwinąć bieżący katalog roboczy w zachęcie zsh w unikalny sposób, tak żebym mógł skopiować i wkleić go do innego terminala, nacisnąć TAB i uzyskać oryginalną ścieżkę?

Powiedzmy, że mamy następujące katalogi:

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

Jeśli monit jest zaprogramowany tak, aby wyświetlał pierwszyznaków, a ja jestem w / b / d, to jest unikalny, z drugiej strony, / a / d nie jest unikalny, więc potrzebowałbym / ad / d, / al / de i / al / do. even / ali / ... zaraz po pojawieniu się alex użytkownika.

Czy można to zhakować bezpośrednio w zsh lub czy muszę napisać skrypt, który znajdzie najkrótszy unikalny początek każdego katalogu nadrzędnego?

Dziękuję za twoje pomysły!

Odpowiedzi:

6 dla odpowiedzi № 1

Nie jestem tego świadomy zsh ma wbudowaną funkcję tego typu, ale powinno być dość łatwe do skryptowania bez uciekania się do pojedynczej podpowłoki lub powolnego rura:

#!/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

Ten skrypt wyświetli najkrótszą ścieżkę do automatycznego uzupełniania.

Możesz rzucić to w swoje .zshrc jako funkcja, a następnie uruchom go z dowolnego katalogu.

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
}

Oto wideo z tego w akcji:

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

Lub jeśli wolisz, niektóre wyniki próbne:

~/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

0 dla odpowiedzi nr 2

Tak, możliwe jest zwinięcie katalogówpierwszą ścieżkę unikatowej litery i po rozwinięciu klawisza Z klawisza Z rozwinąć tę ścieżkę. Po prostu użyłem compinstall (skryptu narzędziowego zsh zainstalowanego z Zsh) do wygenerowania następującego kodu. Ważną częścią, na którą należy zwrócić uwagę przy rozszerzaniu elementów ścieżki, jest element szósty zstyle polecenie, pod koniec, w którym nawias znaków do oddzielnych punktów zakończenia zawiera /, który jest oczywiście separatorem katalogu. Dzięki temu unikalne ścieżki, które zasugerowałeś, wypełnią się jednym naciśnięciem klawisza Tab, tak jak w przypadku * znajdowały się na końcu każdej ścieżki - unikalne litery.

# 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

Jeśli chodzi o tworzenie unikalnej ścieżki w pierwszej kolejności i wstawianie jej do zachęty, jest to możliwe za pomocą skryptu lub funkcji Zsh, a zatem powinien być możliwe także dla edytora lub edytora liniowego, ale po prostu trzymaj się znaku zachęty, dodaj funkcję do $precmd_functions array, która modyfikuje lub dodaje do PS1 zmienna. Ta specjalna tablica jest listą nazw funkcji, które są uruchamiane tuż przed każdym monitem.

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

Aby uzyskać aktualną PWD w skróconej formie, myślę, że ta funkcja jest przejrzysta i łatwa do naśladowania, choć niekoniecznie zoptymalizowana pod kątem niskiego zużycia zasobów.

#!/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

Zauważ, że znajduje unikalne ścieżki z nazwami katalogów ze względu na funkcję Zsh (/) na końcu globtrowania. W ostatnim katalogu (bieżącym) oznacza to, że możesz dopasować coś innego, jeśli istnieje plik o tej samej nazwie i rozszerzeniu.