mirror of
https://github.com/oh-my-fish/theme-bobthefish.git
synced 2026-09-22 11:54:08 +00:00
Improve git prompt performance
This commit is contained in:
@@ -208,6 +208,14 @@ This feature is disabled by default. Use `yes` to show the currently executing [
|
||||
|
||||
Use `no` to disable Git integration. If you're doing this for performance reasons, try some of the options below before disabling it entirely!
|
||||
|
||||
#### `set -g theme_display_git_async no`
|
||||
|
||||
Git status is rendered asynchronously by default in interactive shells. Bobthefish shows the prompt immediately, computes branch and status flags in the background, then repaints the prompt when the Git metadata is ready. Use `no` to restore synchronous Git rendering. Async rendering is currently disabled when `theme_git_worktree_support` is `yes`.
|
||||
|
||||
#### `set -g theme_git_async_refresh_interval 0`
|
||||
|
||||
Bobthefish waits at least one second between async Git refresh workers by default. If a prompt render is skipped during that interval, Bobthefish schedules one trailing refresh. Set this to `0` to check Git state on every prompt render.
|
||||
|
||||
#### `set -g theme_display_git_dirty no`
|
||||
|
||||
Use `no` to hide Git dirty state. Set the Git `bash.showDirtyState` option on a per-repository basis to disable it just for especially large repos.
|
||||
|
||||
@@ -19,6 +19,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo green $colorfg
|
||||
set -x color_repo_work_tree black $colorfg --bold
|
||||
set -x color_repo_pending black $colorfg --bold
|
||||
set -x color_repo_dirty brred $colorfg
|
||||
set -x color_repo_staged yellow $colorfg
|
||||
|
||||
@@ -55,6 +56,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo green $colorfg
|
||||
set -x color_repo_work_tree white $colorfg --bold
|
||||
set -x color_repo_pending white $colorfg --bold
|
||||
set -x color_repo_dirty brred $colorfg
|
||||
set -x color_repo_staged yellow $colorfg
|
||||
|
||||
@@ -91,6 +93,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo green $colorfg
|
||||
set -x color_repo_work_tree brgrey $colorfg --bold
|
||||
set -x color_repo_pending brgrey $colorfg --bold
|
||||
set -x color_repo_dirty brred $colorfg
|
||||
set -x color_repo_staged yellow $colorfg
|
||||
|
||||
@@ -127,6 +130,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo green $colorfg
|
||||
set -x color_repo_work_tree grey $colorfg --bold
|
||||
set -x color_repo_pending grey $colorfg --bold
|
||||
set -x color_repo_dirty brred $colorfg
|
||||
set -x color_repo_staged yellow $colorfg
|
||||
|
||||
@@ -169,6 +173,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $green $grey
|
||||
set -x color_repo_work_tree $grey $grey --bold
|
||||
set -x color_repo_pending $grey $grey --bold
|
||||
set -x color_repo_dirty $red $grey
|
||||
set -x color_repo_staged $yellow $grey
|
||||
|
||||
@@ -222,6 +227,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $base0B $colorfg
|
||||
set -x color_repo_work_tree $base06 $colorfg --bold
|
||||
set -x color_repo_pending $base06 $colorfg --bold
|
||||
set -x color_repo_dirty $base08 $colorfg
|
||||
set -x color_repo_staged $base09 $colorfg
|
||||
|
||||
@@ -275,6 +281,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $base0B $colorfg
|
||||
set -x color_repo_work_tree $base02 $colorfg --bold
|
||||
set -x color_repo_pending $base02 $colorfg --bold
|
||||
set -x color_repo_dirty $base08 $colorfg
|
||||
set -x color_repo_staged $base09 $colorfg
|
||||
|
||||
@@ -328,6 +335,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $green $colorfg
|
||||
set -x color_repo_work_tree $base2 $colorfg --bold
|
||||
set -x color_repo_pending $base2 $colorfg --bold
|
||||
set -x color_repo_dirty $red $colorfg
|
||||
set -x color_repo_staged $yellow $colorfg
|
||||
|
||||
@@ -381,6 +389,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $green $colorfg
|
||||
set -x color_repo_work_tree $base02 $colorfg --bold
|
||||
set -x color_repo_pending $base02 $colorfg --bold
|
||||
set -x color_repo_dirty $red $colorfg
|
||||
set -x color_repo_staged $yellow $colorfg
|
||||
|
||||
@@ -427,6 +436,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $green[1] $green[3]
|
||||
set -x color_repo_work_tree $grey[1] $white --bold
|
||||
set -x color_repo_pending $grey[1] $white --bold
|
||||
set -x color_repo_dirty $red[2] $white
|
||||
set -x color_repo_staged $orange[1] $orange[3]
|
||||
|
||||
@@ -472,6 +482,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $green[2] $bg[1]
|
||||
set -x color_repo_work_tree $bg[1] $fg[2] --bold
|
||||
set -x color_repo_pending $bg[1] $fg[2] --bold
|
||||
set -x color_repo_dirty $red[2] $fg[2]
|
||||
set -x color_repo_staged $yellow[1] $bg[1]
|
||||
|
||||
@@ -516,7 +527,8 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
set -x color_path_nowrite_basename $red[1] $bg[2] --bold
|
||||
|
||||
set -x color_repo $green[2] $fg[1]
|
||||
set -x color_repo_work_tree $bg[1] $fg[2] --bold
|
||||
set -x color_repo_work_tree $bg[1] $fg[2] --bold
|
||||
set -x color_repo_pending $bg[1] $fg[2] --bold
|
||||
set -x color_repo_dirty $orange[2] $bg[2]
|
||||
set -x color_repo_staged $yellow[1] $bg[1]
|
||||
|
||||
@@ -562,6 +574,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $green $bg
|
||||
set -x color_repo_work_tree $selection $fg --bold
|
||||
set -x color_repo_pending $selection $fg --bold
|
||||
set -x color_repo_dirty $red $bg
|
||||
set -x color_repo_staged $yellow $bg
|
||||
|
||||
@@ -615,6 +628,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $base0E $colorfg
|
||||
set -x color_repo_work_tree $base02 $colorfg --bold
|
||||
set -x color_repo_pending $base02 $colorfg --bold
|
||||
set -x color_repo_dirty $base0B $colorfg
|
||||
set -x color_repo_staged $base0D $colorfg
|
||||
|
||||
@@ -675,6 +689,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $green $mantle
|
||||
set -x color_repo_work_tree $surface2 $mantle --bold
|
||||
set -x color_repo_pending $surface2 $mantle --bold
|
||||
set -x color_repo_dirty $red $mantle
|
||||
set -x color_repo_staged $yellow $mantle
|
||||
|
||||
@@ -736,6 +751,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $green $mantle
|
||||
set -x color_repo_work_tree $surface2 $mantle --bold
|
||||
set -x color_repo_pending $surface2 $mantle --bold
|
||||
set -x color_repo_dirty $red $mantle
|
||||
set -x color_repo_staged $yellow $mantle
|
||||
|
||||
@@ -797,6 +813,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $green $mantle
|
||||
set -x color_repo_work_tree $surface2 $mantle --bold
|
||||
set -x color_repo_pending $surface2 $mantle --bold
|
||||
set -x color_repo_dirty $red $mantle
|
||||
set -x color_repo_staged $yellow $mantle
|
||||
|
||||
@@ -858,6 +875,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $green $mantle
|
||||
set -x color_repo_work_tree $surface2 $mantle --bold
|
||||
set -x color_repo_pending $surface2 $mantle --bold
|
||||
set -x color_repo_dirty $red $mantle
|
||||
set -x color_repo_staged $yellow $mantle
|
||||
|
||||
@@ -917,7 +935,8 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
set -x color_path_nowrite_basename $dark_grey $red_orange --bold
|
||||
|
||||
set -x color_repo $light_green $darker_grey
|
||||
set -x color_repo_work_tree $dark_grey $light_grey --bold
|
||||
set -x color_repo_work_tree $dark_grey $light_grey --bold
|
||||
set -x color_repo_pending $dark_grey $light_grey --bold
|
||||
set -x color_repo_dirty $red $darker_grey
|
||||
set -x color_repo_staged $pale_gold $darker_grey
|
||||
|
||||
@@ -962,6 +981,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $green[3] $white[4]
|
||||
set -x color_repo_work_tree $grey[4] $grey[4] --bold
|
||||
set -x color_repo_pending $grey[4] $grey[4] --bold
|
||||
set -x color_repo_dirty $red[3] $grey[4]
|
||||
set -x color_repo_staged $yellow[3] $grey[4]
|
||||
|
||||
@@ -1009,6 +1029,7 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
|
||||
set -x color_repo $green[1] $green[3]
|
||||
set -x color_repo_work_tree $grey[3] $white --bold
|
||||
set -x color_repo_pending $grey[3] $white --bold
|
||||
set -x color_repo_dirty $red[2] $white
|
||||
set -x color_repo_staged $orange[1] $orange[3]
|
||||
|
||||
@@ -1030,6 +1051,9 @@ function __bobthefish_colors -S -a color_scheme -d 'Define colors used by bobthe
|
||||
set -x color_desk $blue[2] $grey[1] --bold
|
||||
set -x color_nix $blue[2] $grey[1] --bold
|
||||
end
|
||||
|
||||
set -q color_repo_pending
|
||||
or set -x color_repo_pending $color_repo_work_tree
|
||||
end
|
||||
|
||||
function __bobthefish_user_color_scheme_deprecated
|
||||
@@ -1043,6 +1067,7 @@ function __bobthefish_user_color_scheme_deprecated
|
||||
set -q __color_path_nowrite_basename; or set -l __color_path_nowrite_basename 660000 cc9999 --bold
|
||||
set -q __color_repo; or set -l __color_repo addc10 0c4801
|
||||
set -q __color_repo_work_tree; or set -l __color_repo_work_tree 333333 ffffff --bold
|
||||
set -q __color_repo_pending; or set -l __color_repo_pending 333333 ffffff --bold
|
||||
set -q __color_repo_dirty; or set -l __color_repo_dirty ce000f ffffff
|
||||
set -q __color_repo_staged; or set -l __color_repo_staged f6b117 3a2a03
|
||||
set -q __color_vi_mode_default; or set -l __color_vi_mode_default 999999 333333 --bold
|
||||
@@ -1081,6 +1106,7 @@ function __bobthefish_user_color_scheme_deprecated
|
||||
set -x color_path_nowrite_basename $__color_path_nowrite_basename
|
||||
set -x color_repo $__color_repo
|
||||
set -x color_repo_work_tree $__color_repo_work_tree
|
||||
set -x color_repo_pending $__color_repo_pending
|
||||
set -x color_repo_dirty $__color_repo_dirty
|
||||
set -x color_repo_staged $__color_repo_staged
|
||||
set -x color_vi_mode_default $__color_vi_mode_default
|
||||
|
||||
210
functions/__bobthefish_git_async_enabled.fish
Normal file
210
functions/__bobthefish_git_async_enabled.fish
Normal file
@@ -0,0 +1,210 @@
|
||||
function __bobthefish_git_async_enabled -S -d 'Check whether async git prompt updates should be used'
|
||||
if [ "$argv[1]" = --init ]
|
||||
if status is-interactive; and __bobthefish_version_at_least 3.0.0 $version
|
||||
# The git metadata var must be universal: the detached background fish
|
||||
# writes it, and a universal variable is the only channel that can deliver
|
||||
# a value back into this (the parent) shell. It's namespaced by pid so
|
||||
# concurrent sessions don't clobber each other.
|
||||
set -g __bobthefish_git_async_var __bobthefish_git_async_$fish_pid
|
||||
set -U $__bobthefish_git_async_var
|
||||
|
||||
# Fires when the background worker publishes new metadata. The pending
|
||||
# flag tells the next fish_prompt that this render is the async repaint
|
||||
# (so it must not spawn another worker).
|
||||
function __bobthefish_git_async_repaint --on-variable $__bobthefish_git_async_var
|
||||
set -g __bobthefish_git_async_repaint_pending 1
|
||||
commandline --function repaint
|
||||
end
|
||||
|
||||
function __bobthefish_git_async_cleanup --on-event fish_exit
|
||||
set -q __bobthefish_git_async_pid
|
||||
and command kill $__bobthefish_git_async_pid 2>/dev/null
|
||||
set -q __bobthefish_git_async_trailing_pid
|
||||
and command kill $__bobthefish_git_async_trailing_pid 2>/dev/null
|
||||
|
||||
set -q __bobthefish_git_async_var
|
||||
and set -e $__bobthefish_git_async_var
|
||||
end
|
||||
|
||||
__bobthefish_git_async_gc
|
||||
end
|
||||
|
||||
# The git metadata var must be universal: the detached background fish
|
||||
# writes it, and a universal variable is the only channel that can deliver
|
||||
# a value back into this (the parent) shell. It's namespaced by pid so
|
||||
# concurrent sessions don't clobber each other.
|
||||
set -g __bobthefish_git_async_var __bobthefish_git_async_$fish_pid
|
||||
set -U $__bobthefish_git_async_var
|
||||
|
||||
# Fires when the background worker publishes new metadata. The pending
|
||||
# flag tells the next fish_prompt that this render is the async repaint
|
||||
# (so it must not spawn another worker).
|
||||
function __bobthefish_git_async_repaint --on-variable $__bobthefish_git_async_var
|
||||
set -g __bobthefish_git_async_repaint_pending 1
|
||||
commandline --function repaint
|
||||
end
|
||||
|
||||
function __bobthefish_git_async_cleanup --on-event fish_exit
|
||||
set -q __bobthefish_git_async_pid
|
||||
and command kill $__bobthefish_git_async_pid 2>/dev/null
|
||||
set -q __bobthefish_git_async_trailing_pid
|
||||
and command kill $__bobthefish_git_async_trailing_pid 2>/dev/null
|
||||
set -q __bobthefish_git_async_poll_pid
|
||||
and command kill $__bobthefish_git_async_poll_pid 2>/dev/null
|
||||
|
||||
set -q __bobthefish_git_async_var
|
||||
and set -e $__bobthefish_git_async_var
|
||||
end
|
||||
|
||||
__bobthefish_git_async_gc
|
||||
end
|
||||
|
||||
function __bobthefish_git_async_enabled -S -d 'Check whether async git prompt updates should be used'
|
||||
[ "$theme_display_git_async" = no ]
|
||||
and return 1
|
||||
|
||||
[ "$theme_git_worktree_support" = yes ]
|
||||
and return 1
|
||||
|
||||
__bobthefish_version_at_least 3.0.0 $version
|
||||
and status is-interactive
|
||||
and set -q __bobthefish_git_async_var
|
||||
and command -q fish
|
||||
and __bobthefish_git_async_worker_path >/dev/null
|
||||
end
|
||||
|
||||
function __bobthefish_git_async_worker_path -S -d 'Resolve and cache the async git worker file'
|
||||
set -q __bobthefish_git_async_worker_path_cache
|
||||
and echo $__bobthefish_git_async_worker_path_cache
|
||||
and return
|
||||
|
||||
set -l prompt_path (functions --details fish_prompt)
|
||||
[ -f "$prompt_path" ]
|
||||
or return
|
||||
|
||||
set -l resolved (dirname "$prompt_path")/__bobthefish_git_async_worker.fish
|
||||
[ -f "$resolved" ]
|
||||
or return
|
||||
|
||||
set -g __bobthefish_git_async_worker_path_cache $resolved
|
||||
echo $resolved
|
||||
end
|
||||
|
||||
function __bobthefish_git_async_fish -S -d 'Resolve and cache the fish binary used for async git workers'
|
||||
set -q __bobthefish_git_async_fish_path
|
||||
or set -g __bobthefish_git_async_fish_path (command -s fish)
|
||||
echo $__bobthefish_git_async_fish_path
|
||||
end
|
||||
|
||||
function __bobthefish_git_async_gc -S -d 'Remove async git metadata left behind by dead fish sessions'
|
||||
set -l prefix __bobthefish_git_async_
|
||||
for var in (set --names --universal | string match "$prefix*")
|
||||
[ "$var" = "$__bobthefish_git_async_var" ]
|
||||
and continue
|
||||
|
||||
set -l pid (string replace $prefix '' -- $var)
|
||||
string match -qr '^\d+$' -- "$pid"
|
||||
or continue
|
||||
|
||||
command kill -0 $pid 2>/dev/null
|
||||
or set -e $var
|
||||
end
|
||||
end
|
||||
|
||||
function __bobthefish_git_async_refresh_interval -S -d 'Get the minimum seconds between async git workers'
|
||||
set -l interval 1
|
||||
string match -qr '^\d+$' -- "$theme_git_async_refresh_interval"
|
||||
and set interval $theme_git_async_refresh_interval
|
||||
|
||||
echo $interval
|
||||
end
|
||||
|
||||
function __bobthefish_git_async_schedule_trailing -S -a git_root_dir -a delay -d 'Schedule a trailing async git refresh'
|
||||
[ "$delay" -gt 0 ]
|
||||
or return
|
||||
set -q __bobthefish_git_async_var
|
||||
or return
|
||||
|
||||
set -l worker_path (__bobthefish_git_async_worker_path)
|
||||
or return
|
||||
set -l fish_bin (__bobthefish_git_async_fish)
|
||||
|
||||
if set -q __bobthefish_git_async_trailing_pid
|
||||
command kill -0 $__bobthefish_git_async_trailing_pid 2>/dev/null
|
||||
and [ "$__bobthefish_git_async_trailing_root_dir" = "$git_root_dir" ]
|
||||
and return
|
||||
|
||||
__bobthefish_git_async_clear_trailing
|
||||
end
|
||||
|
||||
command $fish_bin --private -c '
|
||||
sleep $argv[1]
|
||||
source $argv[2]
|
||||
__bobthefish_git_async_worker $argv[3] $argv[4] $argv[5] $argv[6] $argv[7] $argv[8]
|
||||
' $delay $worker_path $__bobthefish_git_async_var $git_root_dir "$theme_display_git_dirty" "$theme_display_git_dirty_verbose" "$theme_display_git_untracked" "$theme_display_git_stashed_verbose" &
|
||||
builtin -q disown
|
||||
and builtin disown
|
||||
set -g __bobthefish_git_async_trailing_pid $last_pid
|
||||
set -g __bobthefish_git_async_trailing_root_dir $git_root_dir
|
||||
end
|
||||
|
||||
function __bobthefish_git_async_start -S -a git_root_dir -d 'Start a background git prompt metadata update'
|
||||
set -q __bobthefish_git_async_var
|
||||
or return
|
||||
|
||||
# Keep at most one worker active per prompt session. Re-rendering while a
|
||||
# worker is still collecting git state should not kill the worker that will
|
||||
# publish the fresh cache.
|
||||
if set -q __bobthefish_git_async_pid
|
||||
if command kill -0 $__bobthefish_git_async_pid 2>/dev/null
|
||||
[ "$__bobthefish_git_async_root_dir" = "$git_root_dir" ]
|
||||
and return
|
||||
|
||||
command kill $__bobthefish_git_async_pid 2>/dev/null
|
||||
end
|
||||
|
||||
set -e __bobthefish_git_async_pid
|
||||
end
|
||||
|
||||
if set -q __bobthefish_git_async_trailing_pid
|
||||
if [ "$__bobthefish_git_async_trailing_root_dir" != "$git_root_dir" ]
|
||||
__bobthefish_git_async_clear_trailing
|
||||
else if not command kill -0 $__bobthefish_git_async_trailing_pid 2>/dev/null
|
||||
set -e __bobthefish_git_async_trailing_pid
|
||||
end
|
||||
end
|
||||
|
||||
set -l now (date +%s)
|
||||
set -l interval (__bobthefish_git_async_refresh_interval)
|
||||
# Git state can change inside a repo between prompts, so this is a short
|
||||
# debounce rather than a same-repo cache. Set theme_git_async_refresh_interval
|
||||
# to 0 to spawn a worker on every eligible prompt render.
|
||||
if [ "$interval" -gt 0 -a "$__bobthefish_git_async_root_dir" = "$git_root_dir" -a -n "$__bobthefish_git_async_last_start" ]
|
||||
set -l elapsed (math $now - $__bobthefish_git_async_last_start)
|
||||
if [ "$elapsed" -lt "$interval" ]
|
||||
__bobthefish_git_async_schedule_trailing $git_root_dir (math $interval - $elapsed)
|
||||
return
|
||||
end
|
||||
end
|
||||
|
||||
__bobthefish_git_async_clear_trailing
|
||||
|
||||
set -l worker_path (__bobthefish_git_async_worker_path)
|
||||
or return
|
||||
set -l fish_bin (__bobthefish_git_async_fish)
|
||||
|
||||
set -l cmd source (string escape -- $worker_path) ';' __bobthefish_git_async_worker \
|
||||
(string escape -- $__bobthefish_git_async_var) \
|
||||
(string escape -- $git_root_dir) \
|
||||
(string escape -- "$theme_display_git_dirty") \
|
||||
(string escape -- "$theme_display_git_dirty_verbose") \
|
||||
(string escape -- "$theme_display_git_untracked") \
|
||||
(string escape -- "$theme_display_git_stashed_verbose")
|
||||
|
||||
set -g __bobthefish_git_async_root_dir $git_root_dir
|
||||
set -g __bobthefish_git_async_last_start $now
|
||||
command $fish_bin --private --command "$cmd" &
|
||||
builtin -q disown
|
||||
and builtin disown
|
||||
set -g __bobthefish_git_async_pid $last_pid
|
||||
end
|
||||
110
functions/__bobthefish_git_async_worker.fish
Normal file
110
functions/__bobthefish_git_async_worker.fish
Normal file
@@ -0,0 +1,110 @@
|
||||
# __bobthefish_git_async_counts / __bobthefish_git_async_dirty_verbose are
|
||||
# deliberate copies of __bobthefish_git_counts / __bobthefish_git_dirty_verbose
|
||||
# from __bobthefish_prompt_git_sync.fish. The worker runs in a non-interactive
|
||||
# `fish --private -c` that bootstraps by sourcing only this file, so it must not
|
||||
# rely on the theme's autoload path being configured (some shells load omf for
|
||||
# interactive sessions only). Keep these in sync with their sync counterparts.
|
||||
function __bobthefish_git_async_counts -S -d 'Print behind and ahead counts for the current branch'
|
||||
set -l counts (command git rev-list --left-right --count '@{upstream}...HEAD' 2>/dev/null)
|
||||
or return
|
||||
|
||||
set counts (string split \t -- $counts)
|
||||
if [ (count $counts) -lt 2 ]
|
||||
set counts (string split ' ' -- $counts)
|
||||
end
|
||||
|
||||
[ (count $counts) -ge 2 ]
|
||||
or return
|
||||
|
||||
printf '%s\n%s\n' $counts[1] $counts[2]
|
||||
end
|
||||
|
||||
function __bobthefish_git_async_dirty_verbose -S -d 'Print a more verbose dirty state for the current working tree'
|
||||
set -l diff_stats (command git diff --numstat)
|
||||
or return
|
||||
|
||||
set -l added 0
|
||||
set -l removed 0
|
||||
for line in $diff_stats
|
||||
set -l fields (string split \t -- $line)
|
||||
string match -rq '^\d+$' -- $fields[1]
|
||||
and set added (math $added + $fields[1])
|
||||
string match -rq '^\d+$' -- $fields[2]
|
||||
and set removed (math $removed + $fields[2])
|
||||
end
|
||||
|
||||
set -l changes "+$added/-$removed"
|
||||
echo "$changes " | string replace -r '(\+0/(-0)?|/-0)' ''
|
||||
end
|
||||
|
||||
function __bobthefish_git_async_worker -S -a git_async_var -a git_root_dir -a display_dirty -a display_dirty_verbose -a display_untracked -a display_stashed_verbose -d 'Compute git prompt metadata in a background fish'
|
||||
set -l tag (command git describe --tags --exact-match 2>/dev/null)
|
||||
set -l branch (command git symbolic-ref --quiet --short HEAD 2>/dev/null)
|
||||
set -l detached
|
||||
[ -z "$tag" -a -z "$branch" ]
|
||||
and set detached (command git rev-parse --short HEAD 2>/dev/null)
|
||||
|
||||
# Only resolve the configured default branch when it's actually needed
|
||||
set -l configured_default_branch
|
||||
[ -n "$branch" -a -z "$theme_git_default_branches" ]
|
||||
and set configured_default_branch (command git config init.defaultBranch 2>/dev/null)
|
||||
|
||||
set -l dirty
|
||||
set -l dirty_stats
|
||||
if [ "$display_dirty" != no ]
|
||||
set -l show_dirty (command git config --bool bash.showDirtyState 2>/dev/null)
|
||||
if [ "$show_dirty" != false ]
|
||||
command git diff --no-ext-diff --quiet --exit-code 2>/dev/null
|
||||
or begin
|
||||
set dirty 1
|
||||
[ "$display_dirty_verbose" = yes ]
|
||||
and set dirty_stats (__bobthefish_git_async_dirty_verbose)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
set -l staged
|
||||
command git diff --cached --no-ext-diff --quiet --exit-code 2>/dev/null
|
||||
or set staged 1
|
||||
|
||||
set -l stashed
|
||||
if [ "$display_stashed_verbose" = yes ]
|
||||
set stashed (command git rev-list --walk-reflogs --count refs/stash 2>/dev/null)
|
||||
or set stashed
|
||||
else
|
||||
command git rev-parse --verify --quiet refs/stash >/dev/null
|
||||
and set stashed 1
|
||||
end
|
||||
|
||||
set -l ahead 0
|
||||
set -l behind 0
|
||||
set -l counts (__bobthefish_git_async_counts)
|
||||
and begin
|
||||
set behind $counts[1]
|
||||
set ahead $counts[2]
|
||||
end
|
||||
|
||||
set -l new
|
||||
if [ "$display_untracked" != no ]
|
||||
set -l show_untracked (command git config --bool bash.showUntrackedFiles 2>/dev/null)
|
||||
if [ "$show_untracked" != false ]
|
||||
set new (command git ls-files --other --exclude-standard --directory --no-empty-directory "$git_root_dir" 2>/dev/null)
|
||||
[ "$new" ]
|
||||
and set new 1
|
||||
end
|
||||
end
|
||||
|
||||
# Field order is a contract shared with __bobthefish_prompt_git_async,
|
||||
# which unpacks these by position. Keep the two in sync.
|
||||
set -l next "$git_root_dir" "$tag" "$branch" "$detached" "$dirty" "$dirty_stats" "$staged" "$stashed" "$ahead" "$behind" "$new" "$configured_default_branch"
|
||||
|
||||
# Skip the universal-variable write (disk I/O + a repaint broadcast to
|
||||
# every fish session) when nothing actually changed since the last run.
|
||||
set -l current $$git_async_var
|
||||
set -l next_key (string join \x1e -- $next)
|
||||
set -l current_key (string join \x1e -- $current)
|
||||
[ "$next_key" = "$current_key" ]
|
||||
and return
|
||||
|
||||
set -U $git_async_var $next
|
||||
end
|
||||
25
functions/__bobthefish_git_branch_from_parts.fish
Normal file
25
functions/__bobthefish_git_branch_from_parts.fish
Normal file
@@ -0,0 +1,25 @@
|
||||
function __bobthefish_git_branch_from_parts -S -a tag -a branch -a detached -a configured_default_branch -d 'Format a git branch from git metadata'
|
||||
[ -n "$tag" ]
|
||||
and echo "$tag_glyph $tag "
|
||||
|
||||
if [ -n "$branch" ]
|
||||
[ -n "$theme_git_default_branches" ]
|
||||
or set -l theme_git_default_branches master main $configured_default_branch
|
||||
|
||||
[ "$theme_display_git_master_branch" != yes -a "$theme_display_git_default_branch" != yes ]
|
||||
and contains $branch $theme_git_default_branches
|
||||
and echo $branch_glyph
|
||||
and return
|
||||
|
||||
set -l truncname $branch
|
||||
[ "$theme_use_abbreviated_branch_name" = yes ]
|
||||
and set truncname (string replace -r '^(.{17}).{3,}(.{5})$' "\$1…\$2" $branch)
|
||||
|
||||
echo $branch_glyph $truncname
|
||||
and return
|
||||
end
|
||||
|
||||
if [ -z "$tag" -a -n "$detached" ]
|
||||
echo "$detached_glyph $detached"
|
||||
end
|
||||
end
|
||||
137
functions/__bobthefish_prompt_git_async.fish
Normal file
137
functions/__bobthefish_prompt_git_async.fish
Normal file
@@ -0,0 +1,137 @@
|
||||
function __bobthefish_git_count_or_zero -S -a count -d 'Normalize a git count for numeric comparisons'
|
||||
string match -qr '^\d+$' -- "$count"
|
||||
and echo $count
|
||||
or echo 0
|
||||
end
|
||||
|
||||
function __bobthefish_git_pending_branch -S -a git_root_dir -d 'Get cheap branch metadata while async git state is pending'
|
||||
# The placeholder is only shown until the worker first publishes for this
|
||||
# repo. Caching by root keeps rapid renders (e.g. holding Enter in a fresh
|
||||
# repo) from re-forking git on every prompt during that brief window.
|
||||
if set -q __bobthefish_git_pending_root
|
||||
and [ "$__bobthefish_git_pending_root" = "$git_root_dir" ]
|
||||
echo $__bobthefish_git_pending_branch_cache
|
||||
return
|
||||
end
|
||||
|
||||
set -l rendered
|
||||
set -l branch (command git symbolic-ref --quiet --short HEAD 2>/dev/null)
|
||||
if [ -n "$branch" ]
|
||||
# Keep the common branch path cheap. We intentionally do not call
|
||||
# `git config init.defaultBranch` here; the worker will apply the full
|
||||
# default-branch rules when it publishes complete metadata.
|
||||
set rendered (__bobthefish_git_branch_from_parts '' "$branch" '')
|
||||
else
|
||||
set -l detached (command git rev-parse --short HEAD 2>/dev/null)
|
||||
[ -n "$detached" ]
|
||||
and set rendered (__bobthefish_git_branch_from_parts '' '' "$detached")
|
||||
end
|
||||
|
||||
set -g __bobthefish_git_pending_root $git_root_dir
|
||||
set -g __bobthefish_git_pending_branch_cache $rendered
|
||||
echo $rendered
|
||||
end
|
||||
|
||||
function __bobthefish_prompt_git_pending -S -a git_root_dir -a real_pwd -d 'Display an indeterminate repo segment while async git state is pending'
|
||||
__bobthefish_path_segment $git_root_dir project
|
||||
|
||||
__bobthefish_start_segment $color_repo_pending
|
||||
echo -ns (__bobthefish_git_pending_branch $git_root_dir) ' '
|
||||
set_color normal
|
||||
|
||||
__bobthefish_prompt_git_pwd $git_root_dir $real_pwd
|
||||
end
|
||||
|
||||
function __bobthefish_prompt_git_async -S -a git_root_dir -a real_pwd -a repaint -d 'Display git state from cached async metadata'
|
||||
if [ "$repaint" != 1 ]
|
||||
__bobthefish_git_async_start $git_root_dir
|
||||
end
|
||||
|
||||
# Field order is the contract published by __bobthefish_git_async_worker.
|
||||
set -l git_data $$__bobthefish_git_async_var
|
||||
if [ "$git_data[1]" != "$git_root_dir" ]
|
||||
if [ "$repaint" = 1 ]
|
||||
__bobthefish_git_async_start $git_root_dir
|
||||
end
|
||||
|
||||
set -l budget_ms (__bobthefish_git_async_first_render_budget_ms)
|
||||
set -l waited_ms 0
|
||||
while [ "$budget_ms" -gt 0 -a "$waited_ms" -lt "$budget_ms" ]
|
||||
sleep 0.01
|
||||
set git_data $$__bobthefish_git_async_var
|
||||
[ "$git_data[1]" = "$git_root_dir" ]
|
||||
and break
|
||||
set waited_ms (math $waited_ms + 10)
|
||||
end
|
||||
end
|
||||
|
||||
if [ "$git_data[1]" != "$git_root_dir" ]
|
||||
__bobthefish_prompt_git_pending $git_root_dir $real_pwd
|
||||
return
|
||||
end
|
||||
|
||||
set -l tag $git_data[2]
|
||||
set -l branch $git_data[3]
|
||||
set -l detached $git_data[4]
|
||||
set -l dirty $git_data[5]
|
||||
set -l dirty_stats $git_data[6]
|
||||
set -l staged $git_data[7]
|
||||
set -l stashed $git_data[8]
|
||||
set -l ahead (__bobthefish_git_count_or_zero $git_data[9])
|
||||
set -l behind (__bobthefish_git_count_or_zero $git_data[10])
|
||||
set -l new $git_data[11]
|
||||
set -l configured_default_branch $git_data[12]
|
||||
|
||||
[ "$dirty" ]
|
||||
and set dirty "$git_dirty_glyph$dirty_stats"
|
||||
[ "$staged" ]
|
||||
and set staged "$git_staged_glyph"
|
||||
if [ "$stashed" ]
|
||||
[ "$theme_display_git_stashed_verbose" = yes ]
|
||||
and set stashed "$git_stashed_glyph$stashed"
|
||||
or set stashed "$git_stashed_glyph"
|
||||
end
|
||||
|
||||
set -l ahead_flag
|
||||
set -l verbose
|
||||
[ "$theme_display_git_ahead_verbose" = yes ]
|
||||
and set verbose 1
|
||||
switch "$ahead $behind"
|
||||
case '0 0' # equal to upstream
|
||||
case '* 0' # ahead of upstream
|
||||
[ -n "$verbose" ]
|
||||
and set ahead_flag "$git_ahead_glyph$ahead"
|
||||
or set ahead_flag "$git_plus_glyph"
|
||||
case '0 *' # behind upstream
|
||||
[ -n "$verbose" ]
|
||||
and set ahead_flag "$git_behind_glyph$behind"
|
||||
or set ahead_flag "$git_minus_glyph"
|
||||
case '*' # diverged from upstream
|
||||
[ -n "$verbose" ]
|
||||
and set ahead_flag "$git_ahead_glyph$ahead$git_behind_glyph$behind"
|
||||
or set ahead_flag "$git_plus_minus_glyph"
|
||||
end
|
||||
|
||||
[ "$new" ]
|
||||
and set new "$git_untracked_glyph"
|
||||
|
||||
set -l flags "$dirty$staged$stashed$ahead_flag$new"
|
||||
|
||||
[ "$flags" ]
|
||||
and set flags " $flags"
|
||||
|
||||
set -l flag_colors $color_repo
|
||||
if [ "$dirty" ]
|
||||
set flag_colors $color_repo_dirty
|
||||
else if [ "$staged" ]
|
||||
set flag_colors $color_repo_staged
|
||||
end
|
||||
|
||||
__bobthefish_path_segment $git_root_dir project
|
||||
|
||||
__bobthefish_start_segment $flag_colors
|
||||
echo -ns (__bobthefish_git_branch_from_parts "$tag" "$branch" "$detached" "$configured_default_branch") $flags ' '
|
||||
set_color normal
|
||||
|
||||
__bobthefish_prompt_git_pwd $git_root_dir $real_pwd
|
||||
end
|
||||
13
functions/__bobthefish_prompt_git_pwd.fish
Normal file
13
functions/__bobthefish_prompt_git_pwd.fish
Normal file
@@ -0,0 +1,13 @@
|
||||
function __bobthefish_prompt_git_pwd -S -a git_root_dir -a real_pwd -d 'Display the in-project path segment'
|
||||
set -l project_pwd (__bobthefish_project_pwd $git_root_dir $real_pwd)
|
||||
[ "$project_pwd" ]
|
||||
or return
|
||||
|
||||
if [ -w "$real_pwd" ]
|
||||
__bobthefish_start_segment $color_path
|
||||
else
|
||||
__bobthefish_start_segment $color_path_nowrite
|
||||
end
|
||||
|
||||
echo -ns $project_pwd ' '
|
||||
end
|
||||
212
functions/__bobthefish_prompt_git_sync.fish
Normal file
212
functions/__bobthefish_prompt_git_sync.fish
Normal file
@@ -0,0 +1,212 @@
|
||||
function __bobthefish_git_counts -S -d 'Print behind and ahead counts for the current branch'
|
||||
set -l counts (command git rev-list --left-right --count '@{upstream}...HEAD' 2>/dev/null)
|
||||
or return
|
||||
|
||||
set counts (string split \t -- $counts)
|
||||
if [ (count $counts) -lt 2 ]
|
||||
set counts (string split ' ' -- $counts)
|
||||
end
|
||||
|
||||
[ (count $counts) -ge 2 ]
|
||||
or return
|
||||
|
||||
printf '%s\n%s\n' $counts[1] $counts[2]
|
||||
end
|
||||
|
||||
function __bobthefish_git_branch -S -d 'Get the current git branch (or commitish)'
|
||||
set -l tag (command git describe --tags --exact-match 2>/dev/null)
|
||||
set -l branch (command git symbolic-ref --quiet --short HEAD 2>/dev/null)
|
||||
|
||||
set -l detached
|
||||
[ -z "$tag" -a -z "$branch" ]
|
||||
and set detached (command git rev-parse --short HEAD 2>/dev/null)
|
||||
|
||||
# Only resolve the configured default branch when it's actually needed
|
||||
set -l configured_default_branch
|
||||
[ -n "$branch" -a -z "$theme_git_default_branches" ]
|
||||
and set configured_default_branch (command git config init.defaultBranch 2>/dev/null)
|
||||
|
||||
__bobthefish_git_branch_from_parts "$tag" "$branch" "$detached" "$configured_default_branch"
|
||||
end
|
||||
|
||||
function __bobthefish_git_ahead -S -d 'Print the ahead/behind state for the current branch'
|
||||
if [ "$theme_display_git_ahead_verbose" = yes ]
|
||||
__bobthefish_git_ahead_verbose
|
||||
return
|
||||
end
|
||||
|
||||
set -l counts (__bobthefish_git_counts)
|
||||
or return
|
||||
|
||||
set -l behind $counts[1]
|
||||
set -l ahead $counts[2]
|
||||
|
||||
if [ $ahead -gt 0 -a $behind -gt 0 ]
|
||||
echo "$git_plus_minus_glyph"
|
||||
else if [ $ahead -gt 0 ]
|
||||
echo "$git_plus_glyph"
|
||||
else if [ $behind -gt 0 ]
|
||||
echo "$git_minus_glyph"
|
||||
end
|
||||
end
|
||||
|
||||
function __bobthefish_git_ahead_verbose -S -d 'Print a more verbose ahead/behind state for the current branch'
|
||||
set -l counts (__bobthefish_git_counts)
|
||||
or return
|
||||
|
||||
set -l behind $counts[1]
|
||||
set -l ahead $counts[2]
|
||||
|
||||
switch "$ahead $behind"
|
||||
case '' # no upstream
|
||||
case '0 0' # equal to upstream
|
||||
return
|
||||
case '* 0' # ahead of upstream
|
||||
echo "$git_ahead_glyph$ahead"
|
||||
case '0 *' # behind upstream
|
||||
echo "$git_behind_glyph$behind"
|
||||
case '*' # diverged from upstream
|
||||
echo "$git_ahead_glyph$ahead$git_behind_glyph$behind"
|
||||
end
|
||||
end
|
||||
|
||||
function __bobthefish_git_dirty_verbose -S -d 'Print a more verbose dirty state for the current working tree'
|
||||
set -l diff_stats (command git diff --numstat)
|
||||
or return
|
||||
|
||||
set -l added 0
|
||||
set -l removed 0
|
||||
for line in $diff_stats
|
||||
set -l fields (string split \t -- $line)
|
||||
string match -rq '^\d+$' -- $fields[1]
|
||||
and set added (math $added + $fields[1])
|
||||
string match -rq '^\d+$' -- $fields[2]
|
||||
and set removed (math $removed + $fields[2])
|
||||
end
|
||||
|
||||
set -l changes "+$added/-$removed"
|
||||
echo "$changes " | string replace -r '(\+0/(-0)?|/-0)' ''
|
||||
end
|
||||
|
||||
function __bobthefish_git_stashed -S -d 'Print the stashed state for the current branch'
|
||||
if [ "$theme_display_git_stashed_verbose" = yes ]
|
||||
set -l stashed (command git rev-list --walk-reflogs --count refs/stash 2>/dev/null)
|
||||
or return
|
||||
|
||||
echo -n "$git_stashed_glyph$stashed"
|
||||
else
|
||||
command git rev-parse --verify --quiet refs/stash >/dev/null
|
||||
and echo -n "$git_stashed_glyph"
|
||||
end
|
||||
end
|
||||
|
||||
function __bobthefish_prompt_git_sync -S -a git_root_dir -a real_pwd -d 'Display the actual git state synchronously'
|
||||
set -l dirty ''
|
||||
if [ "$theme_display_git_dirty" != no ]
|
||||
set -l show_dirty (command git config --bool bash.showDirtyState 2>/dev/null)
|
||||
if [ "$show_dirty" != false ]
|
||||
set dirty (command git diff --no-ext-diff --quiet --exit-code 2>/dev/null; or echo -n "$git_dirty_glyph")
|
||||
if [ "$dirty" -a "$theme_display_git_dirty_verbose" = yes ]
|
||||
set dirty "$dirty"(__bobthefish_git_dirty_verbose)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
set -l staged (command git diff --cached --no-ext-diff --quiet --exit-code 2>/dev/null; or echo -n "$git_staged_glyph")
|
||||
set -l stashed (__bobthefish_git_stashed)
|
||||
set -l ahead (__bobthefish_git_ahead)
|
||||
|
||||
set -l new ''
|
||||
if [ "$theme_display_git_untracked" != no ]
|
||||
set -l show_untracked (command git config --bool bash.showUntrackedFiles 2>/dev/null)
|
||||
if [ "$show_untracked" != false ]
|
||||
set new (command git ls-files --other --exclude-standard --directory --no-empty-directory "$git_root_dir" 2>/dev/null)
|
||||
if [ "$new" ]
|
||||
set new "$git_untracked_glyph"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
set -l flags "$dirty$staged$stashed$ahead$new"
|
||||
|
||||
[ "$flags" ]
|
||||
and set flags " $flags"
|
||||
|
||||
set -l flag_colors $color_repo
|
||||
if [ "$dirty" ]
|
||||
set flag_colors $color_repo_dirty
|
||||
else if [ "$staged" ]
|
||||
set flag_colors $color_repo_staged
|
||||
end
|
||||
|
||||
__bobthefish_path_segment $git_root_dir project
|
||||
|
||||
__bobthefish_start_segment $flag_colors
|
||||
echo -ns (__bobthefish_git_branch) $flags ' '
|
||||
set_color normal
|
||||
|
||||
if [ "$theme_git_worktree_support" != yes ]
|
||||
__bobthefish_prompt_git_pwd $git_root_dir $real_pwd
|
||||
return
|
||||
end
|
||||
|
||||
set -l project_pwd (command git rev-parse --show-prefix 2>/dev/null | string trim --right --chars=/)
|
||||
set -l work_dir (command git rev-parse --show-toplevel 2>/dev/null)
|
||||
|
||||
# only show work dir if it's a parent…
|
||||
if [ "$work_dir" ]
|
||||
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)
|
||||
case \*
|
||||
set -e work_dir
|
||||
end
|
||||
end
|
||||
|
||||
if [ "$project_pwd" -o "$work_dir" ]
|
||||
set -l colors $color_path
|
||||
if not [ -w "$real_pwd" ]
|
||||
set colors $color_path_nowrite
|
||||
end
|
||||
|
||||
__bobthefish_start_segment $colors
|
||||
|
||||
# handle work_dir != project dir
|
||||
if [ "$work_dir" ]
|
||||
set -l work_parent (__bobthefish_dirname $work_dir)
|
||||
if [ "$work_parent" ]
|
||||
echo -n "$work_parent/"
|
||||
end
|
||||
|
||||
set_color normal
|
||||
set_color -b $color_repo_work_tree
|
||||
echo -n (__bobthefish_basename $work_dir)
|
||||
|
||||
set_color normal
|
||||
set_color -b $colors
|
||||
[ "$project_pwd" ]
|
||||
and echo -n /
|
||||
end
|
||||
|
||||
echo -ns $project_pwd ' '
|
||||
else
|
||||
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)
|
||||
|
||||
set project_pwd (string trim --left --chars=/ -- $project_pwd)
|
||||
|
||||
if [ "$project_pwd" ]
|
||||
set -l colors $color_path
|
||||
if not [ -w "$real_pwd" ]
|
||||
set colors $color_path_nowrite
|
||||
end
|
||||
|
||||
__bobthefish_start_segment $colors
|
||||
|
||||
echo -ns $project_pwd ' '
|
||||
end
|
||||
end
|
||||
end
|
||||
@@ -65,35 +65,7 @@ function __bobthefish_version_at_least -S -a required -a actual -d 'Compare dott
|
||||
return 0
|
||||
end
|
||||
|
||||
function __bobthefish_git_branch -S -d 'Get the current git branch (or commitish)'
|
||||
set -l tag (command git describe --tags --exact-match 2>/dev/null)
|
||||
and echo "$tag_glyph $tag "
|
||||
|
||||
set -l branch (command git symbolic-ref --quiet --short HEAD 2>/dev/null)
|
||||
and begin
|
||||
[ -n "$theme_git_default_branches" ]
|
||||
or set -l theme_git_default_branches master main (command git config init.defaultBranch 2>/dev/null)
|
||||
|
||||
[ "$theme_display_git_master_branch" != yes -a "$theme_display_git_default_branch" != yes ]
|
||||
and contains $branch $theme_git_default_branches
|
||||
and echo $branch_glyph
|
||||
and return
|
||||
|
||||
# truncate the middle of the branch name, but only if it's 25+ characters
|
||||
set -l truncname $branch
|
||||
[ "$theme_use_abbreviated_branch_name" = yes ]
|
||||
and set truncname (string replace -r '^(.{17}).{3,}(.{5})$' "\$1…\$2" $branch)
|
||||
|
||||
echo $branch_glyph $truncname
|
||||
and return
|
||||
end
|
||||
|
||||
# If we've already shown a tag we don't need to show a detached branch
|
||||
if [ -z "$tag" ]
|
||||
set -l branch (command git rev-parse --short HEAD 2>/dev/null)
|
||||
echo "$detached_glyph $branch"
|
||||
end
|
||||
end
|
||||
__bobthefish_git_async_init
|
||||
|
||||
function __bobthefish_fossil_branch -S -d 'Get the current fossil branch'
|
||||
set -l branch (command fossil branch 2>/dev/null | string trim --left --chars=' *')
|
||||
@@ -271,96 +243,6 @@ function __bobthefish_project_pwd -S -a project_root_dir -a real_pwd -d 'Print t
|
||||
string replace -ar '(\.?[^/]{'"$theme_project_dir_length"'})[^/]*/' '$1/' $project_dir
|
||||
end
|
||||
|
||||
function __bobthefish_git_ahead -S -d 'Print the ahead/behind state for the current branch'
|
||||
if [ "$theme_display_git_ahead_verbose" = yes ]
|
||||
__bobthefish_git_ahead_verbose
|
||||
return
|
||||
end
|
||||
|
||||
set -l ahead 0
|
||||
set -l behind 0
|
||||
for line in (command git rev-list --left-right '@{upstream}...HEAD' 2>/dev/null)
|
||||
switch "$line"
|
||||
case '>*'
|
||||
if [ $behind -eq 1 ]
|
||||
echo '±'
|
||||
return
|
||||
end
|
||||
set ahead 1
|
||||
case '<*'
|
||||
if [ $ahead -eq 1 ]
|
||||
echo "$git_plus_minus_glyph"
|
||||
return
|
||||
end
|
||||
set behind 1
|
||||
end
|
||||
end
|
||||
|
||||
if [ $ahead -eq 1 ]
|
||||
echo "$git_plus_glyph"
|
||||
else if [ $behind -eq 1 ]
|
||||
echo "$git_minus_glyph"
|
||||
end
|
||||
end
|
||||
|
||||
function __bobthefish_git_ahead_verbose -S -d 'Print a more verbose ahead/behind state for the current branch'
|
||||
set -l commits (command git rev-list --left-right '@{upstream}...HEAD' 2>/dev/null)
|
||||
or return
|
||||
|
||||
set -l behind 0
|
||||
set -l ahead 0
|
||||
for commit in $commits
|
||||
switch "$commit"
|
||||
case '<*'
|
||||
set behind (math $behind + 1)
|
||||
case '>*'
|
||||
set ahead (math $ahead + 1)
|
||||
end
|
||||
end
|
||||
|
||||
switch "$ahead $behind"
|
||||
case '' # no upstream
|
||||
case '0 0' # equal to upstream
|
||||
return
|
||||
case '* 0' # ahead of upstream
|
||||
echo "$git_ahead_glyph$ahead"
|
||||
case '0 *' # behind upstream
|
||||
echo "$git_behind_glyph$behind"
|
||||
case '*' # diverged from upstream
|
||||
echo "$git_ahead_glyph$ahead$git_behind_glyph$behind"
|
||||
end
|
||||
end
|
||||
|
||||
function __bobthefish_git_dirty_verbose -S -d 'Print a more verbose dirty state for the current working tree'
|
||||
set -l diff_stats (command git diff --numstat)
|
||||
or return
|
||||
|
||||
set -l added 0
|
||||
set -l removed 0
|
||||
for line in $diff_stats
|
||||
set -l fields (string split \t -- $line)
|
||||
string match -rq '^\d+$' -- $fields[1]
|
||||
and set added (math $added + $fields[1])
|
||||
string match -rq '^\d+$' -- $fields[2]
|
||||
and set removed (math $removed + $fields[2])
|
||||
end
|
||||
|
||||
set -l changes "+$added/-$removed"
|
||||
echo "$changes " | string replace -r '(\+0/(-0)?|/-0)' ''
|
||||
end
|
||||
|
||||
function __bobthefish_git_stashed -S -d 'Print the stashed state for the current branch'
|
||||
if [ "$theme_display_git_stashed_verbose" = yes ]
|
||||
set -l stashed (command git rev-list --walk-reflogs --count refs/stash 2>/dev/null)
|
||||
or return
|
||||
|
||||
echo -n "$git_stashed_glyph$stashed"
|
||||
else
|
||||
command git rev-parse --verify --quiet refs/stash >/dev/null
|
||||
and echo -n "$git_stashed_glyph"
|
||||
end
|
||||
end
|
||||
|
||||
# ==============================
|
||||
# Segment functions
|
||||
# ==============================
|
||||
@@ -1179,123 +1061,11 @@ function __bobthefish_prompt_screen -S -d 'Display the screen name'
|
||||
set_color normal
|
||||
end
|
||||
|
||||
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)
|
||||
if [ "$show_dirty" != false ]
|
||||
set dirty (command git diff --no-ext-diff --quiet --exit-code 2>/dev/null; or echo -n "$git_dirty_glyph")
|
||||
if [ "$dirty" -a "$theme_display_git_dirty_verbose" = yes ]
|
||||
set dirty "$dirty"(__bobthefish_git_dirty_verbose)
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
set -l staged (command git diff --cached --no-ext-diff --quiet --exit-code 2>/dev/null; or echo -n "$git_staged_glyph")
|
||||
set -l stashed (__bobthefish_git_stashed)
|
||||
set -l ahead (__bobthefish_git_ahead)
|
||||
|
||||
set -l new ''
|
||||
if [ "$theme_display_git_untracked" != no ]
|
||||
set -l show_untracked (command git config --bool bash.showUntrackedFiles 2>/dev/null)
|
||||
if [ "$show_untracked" != false ]
|
||||
set new (command git ls-files --other --exclude-standard --directory --no-empty-directory "$git_root_dir" 2>/dev/null)
|
||||
if [ "$new" ]
|
||||
set new "$git_untracked_glyph"
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
set -l flags "$dirty$staged$stashed$ahead$new"
|
||||
|
||||
[ "$flags" ]
|
||||
and set flags " $flags"
|
||||
|
||||
set -l flag_colors $color_repo
|
||||
if [ "$dirty" ]
|
||||
set flag_colors $color_repo_dirty
|
||||
else if [ "$staged" ]
|
||||
set flag_colors $color_repo_staged
|
||||
end
|
||||
|
||||
__bobthefish_path_segment $git_root_dir project
|
||||
|
||||
__bobthefish_start_segment $flag_colors
|
||||
echo -ns (__bobthefish_git_branch) $flags ' '
|
||||
set_color normal
|
||||
|
||||
if [ "$theme_git_worktree_support" != yes ]
|
||||
set -l project_pwd (__bobthefish_project_pwd $git_root_dir $real_pwd)
|
||||
if [ "$project_pwd" ]
|
||||
if [ -w "$real_pwd" ]
|
||||
__bobthefish_start_segment $color_path
|
||||
else
|
||||
__bobthefish_start_segment $color_path_nowrite
|
||||
end
|
||||
|
||||
echo -ns $project_pwd ' '
|
||||
end
|
||||
return
|
||||
end
|
||||
|
||||
set -l project_pwd (command git rev-parse --show-prefix 2>/dev/null | string trim --right --chars=/)
|
||||
set -l work_dir (command git rev-parse --show-toplevel 2>/dev/null)
|
||||
|
||||
# only show work dir if it's a parent…
|
||||
if [ "$work_dir" ]
|
||||
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)
|
||||
case \*
|
||||
set -e work_dir
|
||||
end
|
||||
end
|
||||
|
||||
if [ "$project_pwd" -o "$work_dir" ]
|
||||
set -l colors $color_path
|
||||
if not [ -w "$real_pwd" ]
|
||||
set colors $color_path_nowrite
|
||||
end
|
||||
|
||||
__bobthefish_start_segment $colors
|
||||
|
||||
# handle work_dir != project dir
|
||||
if [ "$work_dir" ]
|
||||
set -l work_parent (__bobthefish_dirname $work_dir)
|
||||
if [ "$work_parent" ]
|
||||
echo -n "$work_parent/"
|
||||
end
|
||||
|
||||
set_color normal
|
||||
set_color -b $color_repo_work_tree
|
||||
echo -n (__bobthefish_basename $work_dir)
|
||||
|
||||
set_color normal
|
||||
set_color -b $colors
|
||||
[ "$project_pwd" ]
|
||||
and echo -n /
|
||||
end
|
||||
|
||||
echo -ns $project_pwd ' '
|
||||
function __bobthefish_prompt_git -S -a git_root_dir -a real_pwd -a repaint -d 'Display the actual git state'
|
||||
if __bobthefish_git_async_enabled
|
||||
__bobthefish_prompt_git_async $git_root_dir $real_pwd $repaint
|
||||
else
|
||||
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)
|
||||
|
||||
set project_pwd (string trim --left --chars=/ -- $project_pwd)
|
||||
|
||||
if [ "$project_pwd" ]
|
||||
set -l colors $color_path
|
||||
if not [ -w "$real_pwd" ]
|
||||
set colors $color_path_nowrite
|
||||
end
|
||||
|
||||
__bobthefish_start_segment $colors
|
||||
|
||||
echo -ns $project_pwd ' '
|
||||
end
|
||||
__bobthefish_prompt_git_sync $git_root_dir $real_pwd
|
||||
end
|
||||
end
|
||||
|
||||
@@ -1328,6 +1098,9 @@ end
|
||||
function fish_prompt -d 'bobthefish, a fish theme optimized for awesome'
|
||||
# Save the last status for later (do this before anything else)
|
||||
set -l last_status $status
|
||||
set -l git_async_repaint
|
||||
set -e __bobthefish_git_async_repaint_pending
|
||||
and set git_async_repaint 1
|
||||
|
||||
# Use a simple prompt on dumb terminals.
|
||||
if [ "$TERM" = dumb ]
|
||||
@@ -1382,7 +1155,7 @@ function fish_prompt -d 'bobthefish, a fish theme optimized for awesome'
|
||||
case ''
|
||||
__bobthefish_prompt_dir $real_pwd
|
||||
case "$git_root_dir"
|
||||
__bobthefish_prompt_git $git_root_dir $real_pwd
|
||||
__bobthefish_prompt_git $git_root_dir $real_pwd $git_async_repaint
|
||||
case "$hg_root_dir"
|
||||
__bobthefish_prompt_hg $hg_root_dir $real_pwd
|
||||
case "$fossil_root_dir"
|
||||
|
||||
Reference in New Issue
Block a user