Reputation: 53
I am currently using ZSH, but I have seen that the Fish Shell has a feature called prompt_pwd which is a function. It displays the prompt path similar as this:
// normally this would apper like this:
$ /my/computer/User/Local/Documents/Something
// prompt_pwd function on fish shell:
$ /m/c/U/L/Documents cd Something
$ /m/c/U/L/D/Something
According you navigates through your file system the full name of them changes to only the first letter of its name and the only full name will be displayed on the current directory...
Do you know how I can achieve this in ZSH?
Thanks!
This is the full code extracted from the fish_config wizard:
# Defined in /opt/homebrew/Cellar/fish/3.5.1/share/fish/functions/prompt_pwd.fish @ line 1 function prompt_pwd --description 'short CWD for the prompt'
set -l options h/help d/dir-length= D/full-length-dirs=
argparse -n prompt_pwd $options -- $argv
or return
if set -q _flag_help
__fish_print_help prompt_pwd
return 0
end
set -q argv[1]
or set argv $PWD
set -ql _flag_d
and set -l fish_prompt_pwd_dir_length $_flag_d
set -q fish_prompt_pwd_dir_length
or set -l fish_prompt_pwd_dir_length 1
set -l fulldirs 0
set -ql _flag_D
and set fish_prompt_pwd_full_dirs $_flag_D
set -q fish_prompt_pwd_full_dirs
or set -l fish_prompt_pwd_full_dirs 1
for path in $argv
# Replace $HOME with "~"
set -l realhome ~
set -l tmp (string replace -r '^'"$realhome"'($|/)' '~$1' $path)
if test "$fish_prompt_pwd_dir_length" -eq 0
echo $tmp
else
# Shorten to at most $fish_prompt_pwd_dir_length characters per directory
# with full-length-dirs components left at full length.
set -l full
if test $fish_prompt_pwd_full_dirs -gt 0
set -l all (string split -m (math $fish_prompt_pwd_full_dirs - 1) -r / $tmp)
set tmp $all[1]
set full $all[2..]
else if test $fish_prompt_pwd_full_dirs -eq 0
# 0 means not even the last component is kept
string replace -ar '(\.?[^/]{'"$fish_prompt_pwd_dir_length"'})[^/]*' '$1' $tmp
continue
end
string join / (string replace -ar '(\.?[^/]{'"$fish_prompt_pwd_dir_length"'})[^/]*/' '$1/' $tmp) $full
end
end end
Upvotes: 2
Views: 677
Reputation: 1
setopt extended_glob
print ${(j:/:)${(s: :):-${${(s:/:)${(A)pwd::=${PWD/#$HOME/\~}}}[1,-2]//(#m)^.?*/${MATCH[1]}} ${${pwd:t}:-/}}}
Upvotes: 0
Reputation: 428
prompt_pwd ()
psvar[1]="${(@j[/]M)${(@s[/]M)PWD##*/}#?}$PWD:t"
precmd_functions+=( prompt_pwd )
PS1='%1v%# '
This approach does not perform tilde replacement like the %~
prompt sequence does. It shortens the $PWD
variable by splitting it into its components, keeping only the first character of each component by using #?
with the (M)
flag, then joins them together. This process is only applied to the part before the last /
separator. The "tail" component is appended to the end.
With ~
replacement for the home directory, and extending #?
to ##(.|)?
so that the first character after the dot is shown for dot-directories:
prompt_pwd () {
local p=${${PWD:/~/\~}/#~\//\~/}
psvar[1]="${(@j[/]M)${(@s[/]M)p##*/}##(.|)?}$p:t"
}
Upvotes: 2
Reputation: 2981
This should match your initial text example; add it to ~/.zshrc
:
setopt prompt_subst
PROMPT='\$ /$(printf "%.1s/" ${(s./.)PWD:h})${PWD:t} '
(s./.)
- splits a path at /
.printf "%.1s/"
- prints the first character of each directory piece.${PWD:h}
- the 'head' of the current directory, i.e. everything but the last element.${PWD:t}
- the tail / last element in the directory path.Adding colors and other characters is a bit more involved. When building a complicated prompt, it's often easier to use a precmd
; some of the many posts that discuss prompt colors and precmds are here, here, and here.
Edited to add:
As @rowboat noted, the code above will include an extra /
in top-level directories like /tmp
. This is due to printf
always including at least one result even when there are zero parent directories. One fix is a substitution to convert double //
to /
:
PROMPT='\$ ${${:-$(printf "/%.1s" ${(s./.)PWD:h})/${PWD:t}}/\/\///} '
Similarly, another substitution can be added to escape %
as %%
, if you need to handle directory names that start with a percent sign:
PROMPT='\$ ${${${:-$(printf "/%.1s" ${(s./.)PWD:h})/${PWD:t}}/\/\///}//\%/%%} '
Upvotes: 1