/ / Réduire les répertoires dans l'invite zsh de manière unique - zsh, prompt, pwd

Réduire les répertoires dans l'invite zsh de manière unique - zsh, prompt, pwd

Existe-t-il un moyen de réduire le répertoire de travail actuel dans l'invite zsh de manière unique, afin de pouvoir le copier et le coller sur un autre terminal, taper sur TAB et obtenir le chemin d'origine?

Disons que nous avons les répertoires suivants:

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

Si l'invite est programmée pour afficher le premiercaractères, et je "m in / b / d, alors il est unique. D'un autre côté, / a / d n'est pas unique, donc j'aurais besoin de / ad / d, / al / de et / al / do. Et pair / ali /… dès que l'utilisateur alex apparaît.

Est-il possible de le pirater directement dans zsh ou dois-je écrire un script, qui trouve le début unique le plus court de chaque répertoire parent?

Merci pour vos idées!

Réponses:

6 pour la réponse № 1

Je ne suis pas au courant que zsh a une fonction intégrée de ce type, mais il devrait être assez facile de créer des scripts sans recourir à un seul sous-shell ou à un tuyau lent:

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

Ce script affichera le plus court chemin nécessaire pour que l'auto-complétion fonctionne.

Vous pouvez le jeter dans votre .zshrc en tant que fonction, puis l'exécuter depuis n'importe quel répertoire.

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
}

Voici une vidéo de celle-ci en action:

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

Ou si vous préférez, un exemple de sortie:

~/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 pour la réponse № 2

Oui, il est possible de réduire les répertoires àun chemin de première lettre unique et le shell Z étendre ce chemin en appuyant sur [Tab]. J'ai simplement utilisé compinstall (script utilitaire zsh installé avec Zsh) pour générer le code suivant. La partie importante à prendre en compte pour l'expansion des éléments de chemin est sur le sixième zstyle commande, vers la fin, entre crochets de caractères séparant les points d’achèvement avec /, qui est bien sûr le séparateur de répertoires. Avec cela, les chemins uniques que vous avez suggérés se rempliront entièrement avec une seule touche [Tab] comme si le * étaient à la fin de chaque nom de chemin-lettres uniques.

# 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

Comme pour créer le chemin unique en premier lieu et l’insérer dans l’invite, il est possible avec un script ou une fonction zsh, et donc devrait être possible pour le completer ou éditeur de ligne aussi, mais juste coller à l'invite, vous ajouteriez une fonction à la $precmd_functions tableau qui modifie ou ajoute à la PS1 variable. Ce tableau spécial est une liste de noms de fonctions exécutés juste avant chaque invite.

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

Pour que le mot de passe actuel soit raccourci, je pense que cette fonction est claire et facile à suivre, mais pas nécessairement optimisée pour une utilisation réduite des ressources.

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

Notez qu'il trouve des chemins uniques avec des noms de répertoires à cause de la fonctionnalité Zsh (/) à la fin de la globulation. Sur le dernier répertoire (actuel), cela signifie que vous pouvez trouver quelque chose d'autre s'il existe un fichier avec le même nom et une extension.