GOAL
I'm trying to create a shortened path for my terminal prompt that is relative to the repository in which I'm in. Similar to what I already have for my root & home directory shown below.
The last directory shown in the following terminal prompts' paths is always the current working directory.
root:
/ %
/rootDir %
/rootDir/dir1/dir2 %
/rootDir/.../dir2/dir3 %
/rootDir/.../dir3/dir4 %
home:
~ %
~/dir1/dir2 %
~/.../dir2/dir3 %
~/.../dir3/dir4 %
And I'm trying to figure a way to have it work the same way when I'm in a repository. Where the repository is the "root" instead of the actual root or home being the "root" of the path.
repository:
|repo %
|repo/dir1/dir2 %
|repo/.../dir2/dir3 %
|repo/.../dir3/dir4 %
WHAT I'VE DONE
my .zshrc code:
autoload -Uz vcs_info
zstyle ':vcs_info:git:*' formats '|%r'
zstyle ':vcs_info:git:*' check-for-changes true
setopt PROMPT_SUBST
precmd()
{
vcs_info
if [ -d .git ];
then
PROMPT='${vcs_info_msg_0_}'
elif $(git rev-parse > /dev/null 2>&1);
then
PROMPT='${vcs_info_msg_0_}/%c'
else
PROMPT='%(4~|%-1~/.../%2~|%3~)'
fi
PROMPT+=' %# '
}
The solution for the path when in the root or home directory is pretty simple:
PROMPT='%(4~|%-1~/.../%2~|%3~)'
This checks the length of the path from the working directory to the which ever is the closest, root or home and displays one of two different paths depending on how many directories long the relative path is.
I couldn't figure out a way to modify this for the repository however. As I have it now it uses an if..else which checks whether my working directory is the "root" of the repo or if I'm further inside of the repo. And use these to either display just the name of the repo or the name and the current working directory. To make it work like with the root & home directories however I would need to have the current length between the repo and working directory or some other simpler solution which I might have missed.
Finally got around to this again. I ended up working out a solution that does the intended:
autoload -Uz vcs_info
zstyle ':vcs_info:git:*' formats '|%r'
zstyle ':vcs_info:git:*' check-for-changes true
setopt PROMPT_SUBST
precmd()
{
vcs_info
# in git repo
if [[ -n $(git rev-parse --git-dir 2> /dev/null) ]]; then
# in root of git repo
if [ -d .git ];
then
PROMPT='${vcs_info_msg_0_}'
# in first subfolder of git repo
elif [ -d ../.git ];
then
PROMPT='${vcs_info_msg_0_}/%c'
# in second subfolder of git repo
elif [ -d ../../.git ];
then
PROMPT='${vcs_info_msg_0_}/%2c'
# in deeper subfolder of git repo
else
PROMPT='${vcs_info_msg_0_}/.../%2c'
fi
# not in git repo
else
PROMPT='%(4~|%-1~/.../%2~|%3~)'
fi
PROMPT+=' %# '
}
Not the most elegant of hacks but not being very familiar with the syntax this is what I came up with.
Now the function checks the working directory's relative position to the .git file that is found at the root of every git repository. To reduce the amount of checks done by the function it firstly has an if statement that checks whether the current directory is anywhere inside of a git repository. If not, the previous solution from the original post for the home and root paths is used instead.