Skip to content

Commit

Permalink
Use pwd -P for a normalized $PWD.
Browse files Browse the repository at this point in the history
Because bobthefish interacts so much with external commands like git and hg, which resolve symlinks and don't do case folding on case-insensitive filesystems, we need to always use a normalized $PWD to compare paths.

Fixes #191
Fixes #181
  • Loading branch information
bobthecow committed Mar 18, 2019
1 parent f49a842 commit 5273c92
Showing 1 changed file with 41 additions and 34 deletions.
75 changes: 41 additions & 34 deletions fish_prompt.fish
Original file line number Diff line number Diff line change
Expand Up @@ -57,6 +57,12 @@ function __bobthefish_dirname -d 'basically dirname, but faster'
string replace -r '/[^/]+/?$' '' -- $argv
end

function __bobthefish_pwd -d 'Get a normalized $PWD'
# The pwd builtin accepts `-P` on at least Fish 3.x, but fall back to $PWD if that doesn't work
builtin pwd -P 2>/dev/null
or echo $PWD
end

function __bobthefish_git_branch -S -d 'Get the current git branch (or commitish)'
set -l ref (command git symbolic-ref HEAD 2>/dev/null)
and begin
Expand Down Expand Up @@ -107,8 +113,7 @@ function __bobthefish_pretty_parent -S -a child_dir -d 'Print a parent directory
string replace -ar '(\.?[^/]{'"$fish_prompt_pwd_dir_length"'})[^/]*/' '$1/' "$parent_dir/"
end

function __bobthefish_ignore_vcs_dir -d 'Check whether the current directory should be ignored as a VCS segment'
set -l real_pwd (realpath $PWD)
function __bobthefish_ignore_vcs_dir -a real_pwd -d 'Check whether the current directory should be ignored as a VCS segment'
for p in $theme_vcs_ignore_paths
set ignore_path (realpath $p 2>/dev/null)
switch $real_pwd/
Expand All @@ -119,12 +124,12 @@ function __bobthefish_ignore_vcs_dir -d 'Check whether the current directory sho
end
end

function __bobthefish_git_project_dir -S -d 'Print the current git project base directory'
function __bobthefish_git_project_dir -S -a real_pwd -d 'Print the current git project base directory'
[ "$theme_display_git" = 'no' ]
and return

set -q theme_vcs_ignore_paths
and [ (__bobthefish_ignore_vcs_dir) ]
and [ (__bobthefish_ignore_vcs_dir $real_pwd) ]
and return

if [ "$theme_git_worktree_support" != 'yes' ]
Expand All @@ -134,14 +139,14 @@ function __bobthefish_git_project_dir -S -d 'Print the current git project base
and return

# If there are no symlinks, just use git toplevel
switch $PWD/
switch $real_pwd/
case $git_toplevel/\*
echo $git_toplevel
return
end

# Otherwise, we need to find the equivalent directory in the $PWD
set -l d $PWD
set -l d $real_pwd
while not [ -z "$d" ]
if [ (realpath "$d") = "$git_toplevel" ]
echo $d
Expand All @@ -160,10 +165,10 @@ function __bobthefish_git_project_dir -S -d 'Print the current git project base
or return

pushd $git_dir
set git_dir $PWD
set git_dir $real_pwd
popd

switch $PWD/
switch $real_pwd/
case $git_dir/\*
# Nothing works quite right if we're inside the git dir
# TODO: fix the underlying issues then re-enable the stuff below
Expand All @@ -181,28 +186,28 @@ function __bobthefish_git_project_dir -S -d 'Print the current git project base

set -l project_dir (__bobthefish_dirname $git_dir)

switch $PWD/
switch $real_pwd/
case $project_dir/\*
echo $project_dir
return
end

set project_dir (command git rev-parse --show-toplevel 2>/dev/null)
switch $PWD/
switch $real_pwd/
case $project_dir/\*
echo $project_dir
end
end

function __bobthefish_hg_project_dir -S -d 'Print the current hg project base directory'
function __bobthefish_hg_project_dir -S -a real_pwd -d 'Print the current hg project base directory'
[ "$theme_display_hg" = 'yes' ]
or return

set -q theme_vcs_ignore_paths
and [ (__bobthefish_ignore_vcs_dir) ]
and [ (__bobthefish_ignore_vcs_dir $real_pwd) ]
and return

set -l d $PWD
set -l d $real_pwd
while not [ -z "$d" ]
if [ -e $d/.hg ]
command hg root --cwd "$d" 2>/dev/null
Expand All @@ -216,11 +221,11 @@ function __bobthefish_hg_project_dir -S -d 'Print the current hg project base di
end
end

function __bobthefish_project_pwd -S -a project_root_dir -d 'Print the working directory relative to project root'
function __bobthefish_project_pwd -S -a project_root_dir -a real_pwd -d 'Print the working directory relative to project root'
set -q theme_project_dir_length
or set -l theme_project_dir_length 0

set -l project_dir (string replace -r '^'"$project_root_dir"'($|/)' '' $PWD)
set -l project_dir (string replace -r '^'"$project_root_dir"'($|/)' '' $real_pwd)

if [ $theme_project_dir_length -eq 0 ]
echo -n $project_dir
Expand Down Expand Up @@ -798,7 +803,7 @@ end
# VCS segments
# ==============================

function __bobthefish_prompt_hg -S -a hg_root_dir -d 'Display the actual hg state'
function __bobthefish_prompt_hg -S -a hg_root_dir -a real_pwd -d 'Display the actual hg state'
set -l dirty (command hg stat; or echo -n '*')

set -l flags "$dirty"
Expand All @@ -819,9 +824,9 @@ function __bobthefish_prompt_hg -S -a hg_root_dir -d 'Display the actual hg stat
echo -ns (__bobthefish_hg_branch) $flags ' '
set_color normal

set -l project_pwd (__bobthefish_project_pwd $hg_root_dir)
set -l project_pwd (__bobthefish_project_pwd $hg_root_dir $real_pwd)
if [ "$project_pwd" ]
if [ -w "$PWD" ]
if [ -w "$real_pwd" ]
__bobthefish_start_segment $color_path
else
__bobthefish_start_segment $color_path_nowrite
Expand All @@ -831,7 +836,7 @@ function __bobthefish_prompt_hg -S -a hg_root_dir -d 'Display the actual hg stat
end
end

function __bobthefish_prompt_git -S -a git_root_dir -d 'Display the actual git state'
function __bobthefish_prompt_git -S -a git_root_dir -a real_pwd -d 'Display the actual git state'
set -l dirty ''
if [ "$theme_display_git_dirty" != 'no' ]
set -l show_dirty (command git config --bool bash.showDirtyState 2>/dev/null)
Expand Down Expand Up @@ -877,9 +882,9 @@ function __bobthefish_prompt_git -S -a git_root_dir -d 'Display the actual git s
set_color normal

if [ "$theme_git_worktree_support" != 'yes' ]
set -l project_pwd (__bobthefish_project_pwd $git_root_dir)
set -l project_pwd (__bobthefish_project_pwd $git_root_dir $real_pwd)
if [ "$project_pwd" ]
if [ -w "$PWD" ]
if [ -w "$real_pwd" ]
__bobthefish_start_segment $color_path
else
__bobthefish_start_segment $color_path_nowrite
Expand All @@ -895,7 +900,7 @@ function __bobthefish_prompt_git -S -a git_root_dir -d 'Display the actual git s

# only show work dir if it's a parent…
if [ "$work_dir" ]
switch $PWD/
switch $real_pwd/
case $work_dir/\*
string match "$git_root_dir*" $work_dir >/dev/null
and set work_dir (string sub -s (math 1 + (string length $git_root_dir)) $work_dir)
Expand All @@ -906,7 +911,7 @@ function __bobthefish_prompt_git -S -a git_root_dir -d 'Display the actual git s

if [ "$project_pwd" -o "$work_dir" ]
set -l colors $color_path
if not [ -w "$PWD" ]
if not [ -w "$real_pwd" ]
set colors $color_path_nowrite
end

Expand All @@ -931,7 +936,7 @@ function __bobthefish_prompt_git -S -a git_root_dir -d 'Display the actual git s

echo -ns $project_pwd ' '
else
set project_pwd $PWD
set project_pwd $real_pwd

string match "$git_root_dir*" $project_pwd >/dev/null
and set project_pwd (string sub -s (math 1 + (string length $git_root_dir)) $project_pwd)
Expand All @@ -940,7 +945,7 @@ function __bobthefish_prompt_git -S -a git_root_dir -d 'Display the actual git s

if [ "$project_pwd" ]
set -l colors $color_path
if not [ -w "$PWD" ]
if not [ -w "$real_pwd" ]
set colors $color_path_nowrite
end

Expand All @@ -951,8 +956,8 @@ function __bobthefish_prompt_git -S -a git_root_dir -d 'Display the actual git s
end
end

function __bobthefish_prompt_dir -S -d 'Display a shortened form of the current directory'
__bobthefish_path_segment "$PWD"
function __bobthefish_prompt_dir -S -a real_pwd -d 'Display a shortened form of the current directory'
__bobthefish_path_segment "$real_pwd"
end


Expand Down Expand Up @@ -991,24 +996,26 @@ function fish_prompt -d 'bobthefish, a fish theme optimized for awesome'
__bobthefish_prompt_virtualfish
__bobthefish_prompt_virtualgo

set -l real_pwd (__bobthefish_pwd)

# VCS
set -l git_root_dir (__bobthefish_git_project_dir)
set -l hg_root_dir (__bobthefish_hg_project_dir)
set -l git_root_dir (__bobthefish_git_project_dir $real_pwd)
set -l hg_root_dir (__bobthefish_hg_project_dir $real_pwd)

if [ "$git_root_dir" -a "$hg_root_dir" ]
# only show the closest parent
switch $git_root_dir
case $hg_root_dir\*
__bobthefish_prompt_git $git_root_dir
__bobthefish_prompt_git $git_root_dir $real_pwd
case \*
__bobthefish_prompt_hg $hg_root_dir
__bobthefish_prompt_hg $hg_root_dir $real_pwd
end
else if [ "$git_root_dir" ]
__bobthefish_prompt_git $git_root_dir
__bobthefish_prompt_git $git_root_dir $real_pwd
else if [ "$hg_root_dir" ]
__bobthefish_prompt_hg $hg_root_dir
__bobthefish_prompt_hg $hg_root_dir $real_pwd
else
__bobthefish_prompt_dir
__bobthefish_prompt_dir $real_pwd
end

__bobthefish_finish_segments
Expand Down

0 comments on commit 5273c92

Please sign in to comment.