From 5273c92fa56cc20338ab4a834ef07427acee07b7 Mon Sep 17 00:00:00 2001 From: Justin Hileman Date: Mon, 18 Mar 2019 07:43:13 -0700 Subject: [PATCH] Use `pwd -P` for a normalized $PWD. 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 --- fish_prompt.fish | 75 ++++++++++++++++++++++++++---------------------- 1 file changed, 41 insertions(+), 34 deletions(-) diff --git a/fish_prompt.fish b/fish_prompt.fish index 6a8a61a..54adaac 100644 --- a/fish_prompt.fish +++ b/fish_prompt.fish @@ -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 @@ -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/ @@ -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' ] @@ -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 @@ -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 @@ -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 @@ -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 @@ -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" @@ -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 @@ -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) @@ -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 @@ -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) @@ -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 @@ -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) @@ -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 @@ -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 @@ -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