/ / Coleta diretórios no prompt zsh de uma forma única - zsh, prompt, pwd

Recolha os diretórios no prompt zsh de uma forma única - zsh, prompt, pwd

Existe uma maneira de recolher o diretório de trabalho atual no prompt zsh de uma maneira única, para que eu possa copiá-lo e colá-lo em outro terminal, aperte TAB e obtenha o caminho original?

Vamos dizer que temos os seguintes diretórios:

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

Se o prompt estiver programado para mostrar o primeirocaracteres, e eu estou em / b / d, então é único. Por outro lado, / a / d não é único, então eu precisaria de / ad / d, / al / de e / al / do. mesmo / ali /… assim que o usuário alex aparecer.

É possível hackear isso diretamente em zsh ou eu preciso escrever um script, que encontra o menor início único de cada diretório pai?

Obrigado por suas idéias!

Respostas:

6 para resposta № 1

Eu não estou ciente de que zsh tem uma função embutida deste tipo, mas deve ser muito fácil criar scripts sem recorrer a um único subshell ou slow pipe:

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

Esse script gerará o caminho mais curto necessário para o preenchimento automático funcionar.

Você pode jogá-lo na sua .zshrc como uma função e, em seguida, executá-lo a partir de qualquer diretório.

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
}

Aqui está um vídeo dele em ação:

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

Ou, se preferir, algum exemplo de saída:

~/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 para resposta № 2

Sim, é possível recolher os diretórios paraum caminho de primeira letra única e ter o Z Shell expandindo esse caminho ao pressionar [Tab]. Eu simplesmente usei o compinstall (script de utilitário zsh instalado com o Zsh) para gerar o seguinte código. A parte importante a ser observada para a expansão dos elementos do caminho está na sexto zstyle comando, perto do fim, onde o colchete de caracteres para separar os pontos de conclusão inclui o /, que é, claro, o separador de diretório. Com isso, os caminhos exclusivos que você sugeriu serão preenchidos com apenas um [Tab] como se o * estavam no final de cada nome de caminho letras únicas.

# 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

Quanto a criar o caminho único em primeiro lugar e inseri-lo no prompt, é possível com um script ou função zsh e, portanto, devemos ser possível para o completer ou line-editor também, mas apenas aderindo ao prompt, você iria adicionar uma função para o $precmd_functions matriz que modifica ou adiciona ao PS1 variável. Essa matriz especial é uma lista de nomes de funções que são executados antes de cada prompt.

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

Para obter o atual PWD de forma abreviada, acho que essa função é clara e fácil de seguir, embora não necessariamente otimizada para baixo uso de recursos.

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

Observe que ele encontra caminhos exclusivos com nomes de diretório por causa do recurso Zsh (/) no final do globbing. No último diretório (atual), isso significa que você pode corresponder a outra coisa se houver um arquivo com o mesmo nome e uma extensão.