/ / Zbaliť adresáre v výzve zsh jedinečným spôsobom - zsh, prompt, pwd

Zbaliť adresáre v zsh výzve jedinečným spôsobom - zsh, prompt, pwd

Existuje spôsob, ako jedinečným spôsobom zbaliť aktuálny pracovný adresár v výzve zsh, aby som ho mohol skopírovať a vložiť do iného terminálu, stlačiť kláves TAB a získať pôvodnú cestu?

Povedzme, že máme nasledujúce adresáre:

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

Ak je výzva naprogramovaná, zobrazí sa prváznaky, a ja "m in / b / d, potom je to jedinečné. Na druhej strane, / a / d nie je jedinečné, takže by som potreboval / ad / d, / al / de a / al / do. even / ali /…, akonáhle sa objaví užívateľ alex.

Je možné hack to priamo v zsh, alebo musím napísať skript, ktorý nájde najkratší jedinečný začiatok každého rodičovského adresára?

Ďakujeme za vaše nápady!

odpovede:

6 pre odpoveď č. 1

Nie som si toho vedomý zsh má vstavanú funkciu tohto druhu, ale mal by byť ľahko skriptovateľný bez použitia jediného subshell alebo pomalého potrubia:

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

Tento skript vygeneruje najkratšiu cestu potrebnú na automatické dokončenie práce.

Môžete ho hodiť do svojho .zshrc ako funkciu a potom ho spustite z ľubovoľného adresára.

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
}

Tu je video z akcie:

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

Alebo ak dávate prednosť, ukážkový výstup:

~/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 pre odpoveď č. 2

Áno, je možné zbaliť adresárecesta s prvým písmenom a má Z Shell rozšíriť túto cestu po stlačení [Tab]. Jednoducho som použil compinstall (zsh utility skript nainštalovaný so Zsh) na vytvorenie nasledujúceho kódu. Dôležitá časť, ktorú je potrebné vziať do úvahy pre rozširujúce sa prvky cesty, je na šiesty zstyle príkaz, blízko konca, kde zátvorka znakov na oddelené body dokončenia s /, čo je samozrejme oddeľovač adresárov. Týmto spôsobom budú jedinečné cesty, ktoré ste navrhli, úplne vyplnené len jedným stlačením tlačidla [Tab], ako keby * boli na konci každého jedinečného písmena názvu cesty.

# 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

Pokiaľ ide o vytvorenie jedinečnej cesty na prvom mieste a jej vloženie do výzvy, je možné pomocou skriptu zsh alebo funkcie, a preto mali by byť možné aj pre úplného alebo riadiaceho editora, ale len pridržiavaním sa výzvy by ste pridali funkciu $precmd_functions pole, ktoré modifikuje alebo pridáva PS1 variabilné. Toto špeciálne pole je zoznam názvov funkcií, ktoré sa spúšťajú priamo pred každou výzvou.

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

Pre získanie súčasnej PWD v skrátenej forme si myslím, že táto funkcia je jasná a ľahko sa sleduje, aj keď nie je nevyhnutne optimalizovaná pre nízke využitie zdrojov.

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

Všimnite si, že na základe funkcie Zsh nájde jedinečné cesty s názvami adresárov (/) na konci goliera. V poslednom adresári (aktuálny) to znamená, že sa môže zhodovať s niečím iným, ak existuje súbor s rovnakým názvom a rozšírením.