mirror of
https://github.com/fish-shell/fish-shell.git
synced 2024-11-26 10:43:47 +08:00
a77bc70def
git on macOS has two hazards: 1. It comes "preinstalled" as a stub which pops a dialog to install command line developer tools. 2. It may populate the xcrun cache when run for the first time, which may take several seconds. We fix these as follows, both fixes limited to Darwin: 1. If git is `/usr/bin/git` and `xcode-select --print-path` fails, then do not run git automatically. 2. Second, if there is no file at `xcrun --show-cache-path`, we take it as an indication that the cache is not yet populated. In this case we run `git` in the background to populate the cache. Credit to @floam for the idea. Fixes #9343. Fixes #6625.
682 lines
28 KiB
Fish
682 lines
28 KiB
Fish
# based off of the git-prompt script that ships with git
|
|
# hence licensed under GPL version 2 (like the rest of fish).
|
|
#
|
|
# Written by Lily Ballard and updated by Brian Gernhardt and fish contributors
|
|
#
|
|
# This is based on git's git-prompt.bash script, Copyright (C) 2006,2007 Shawn O. Pearce <spearce@spearce.org>.
|
|
# The act of porting the code, along with any new code, are Copyright (C) 2012 Lily Ballard.
|
|
|
|
function __fish_git_prompt_show_upstream --description "Helper function for fish_git_prompt"
|
|
set -l show_upstream $__fish_git_prompt_showupstream
|
|
set -l svn_prefix # For better SVN upstream information
|
|
set -l informative
|
|
|
|
set -l svn_url_pattern
|
|
set -l count
|
|
set -l upstream git
|
|
set -l verbose
|
|
set -l name
|
|
|
|
# Default to informative if __fish_git_prompt_show_informative_status is set
|
|
if contains -- "$__fish_git_prompt_show_informative_status" yes true 1
|
|
set informative 1
|
|
end
|
|
|
|
set -l svn_remote
|
|
# get some config options from git-config
|
|
command git config -z --get-regexp '^(svn-remote\..*\.url|bash\.showupstream)$' 2>/dev/null | while read -lz key value
|
|
switch $key
|
|
case bash.showupstream
|
|
set show_upstream $value
|
|
test -n "$show_upstream"
|
|
or return
|
|
case svn-remote.'*'.url
|
|
set svn_remote $svn_remote $value
|
|
# Avoid adding \| to the beginning to avoid needing #?? later
|
|
if test -n "$svn_url_pattern"
|
|
set svn_url_pattern $svn_url_pattern"|$value"
|
|
else
|
|
set svn_url_pattern $value
|
|
end
|
|
set upstream svn+git # default upstream is SVN if available, else git
|
|
|
|
# Save the config key (without .url) for later use
|
|
set -l remote_prefix (string replace -r '\.url$' '' -- $key)
|
|
set svn_prefix $svn_prefix $remote_prefix
|
|
end
|
|
end
|
|
|
|
# parse configuration variables
|
|
# and clear informative default when needed
|
|
for option in $show_upstream
|
|
switch $option
|
|
case git svn
|
|
set upstream $option
|
|
set -e informative
|
|
case verbose
|
|
set verbose 1
|
|
set -e informative
|
|
case informative
|
|
set informative 1
|
|
case name
|
|
set name 1
|
|
case none
|
|
return
|
|
end
|
|
end
|
|
|
|
# Find our upstream
|
|
switch $upstream
|
|
case git
|
|
set upstream '@{upstream}'
|
|
case svn\*
|
|
# get the upstream from the 'git-svn-id: …' in a commit message
|
|
# (git-svn uses essentially the same procedure internally)
|
|
set -l svn_upstream (git log --first-parent -1 --grep="^git-svn-id: \($svn_url_pattern\)" 2>/dev/null)
|
|
if test (count $svn_upstream) -ne 0
|
|
echo $svn_upstream[-1] | read -l __ svn_upstream __
|
|
set svn_upstream (string replace -r '@.*' '' -- $svn_upstream)
|
|
set -l cur_prefix
|
|
|
|
for i in (seq (count $svn_remote))
|
|
set -l remote $svn_remote[$i]
|
|
set -l mod_upstream (string replace "$remote" "" -- $svn_upstream)
|
|
if test "$svn_upstream" != "$mod_upstream"
|
|
# we found a valid remote
|
|
set svn_upstream $mod_upstream
|
|
set cur_prefix $svn_prefix[$i]
|
|
break
|
|
end
|
|
end
|
|
|
|
if test -z "$svn_upstream"
|
|
# default branch name for checkouts with no layout:
|
|
if test -n "$GIT_SVN_ID"
|
|
set upstream $GIT_SVN_ID
|
|
else
|
|
set upstream git-svn
|
|
end
|
|
else
|
|
set upstream (string replace '/branches' '' -- $svn_upstream | string replace -a '/' '')
|
|
|
|
# Use fetch config to fix upstream
|
|
set -l fetch_val (command git config "$cur_prefix".fetch)
|
|
if test -n "$fetch_val"
|
|
string split -m1 : -- "$fetch_val" | read -l trunk pattern
|
|
set upstream (string replace -r -- "/$trunk\$" '' $pattern) /$upstream
|
|
end
|
|
end
|
|
else if test $upstream = svn+git
|
|
set upstream '@{upstream}'
|
|
end
|
|
end
|
|
|
|
# Find how many commits we are ahead/behind our upstream
|
|
set count (command git rev-list --count --left-right $upstream...HEAD 2>/dev/null | string replace \t " ")
|
|
|
|
# calculate the result
|
|
if test -n "$verbose"
|
|
# Verbose has a space by default
|
|
set -l prefix "$___fish_git_prompt_char_upstream_prefix"
|
|
# Using two underscore version to check if user explicitly set to nothing
|
|
if not set -q __fish_git_prompt_char_upstream_prefix
|
|
set prefix " "
|
|
end
|
|
|
|
echo $count | read -l behind ahead
|
|
switch "$count"
|
|
case '' # no upstream
|
|
case "0 0" # equal to upstream
|
|
echo "$prefix$___fish_git_prompt_char_upstream_equal"
|
|
case "0 *" # ahead of upstream
|
|
echo "$prefix$___fish_git_prompt_char_upstream_ahead$ahead"
|
|
case "* 0" # behind upstream
|
|
echo "$prefix$___fish_git_prompt_char_upstream_behind$behind"
|
|
case '*' # diverged from upstream
|
|
echo "$prefix$___fish_git_prompt_char_upstream_diverged$ahead-$behind"
|
|
end
|
|
if test -n "$count" -a -n "$name"
|
|
echo " "(command git rev-parse --abbrev-ref "$upstream" 2>/dev/null)
|
|
end
|
|
else if test -n "$informative"
|
|
echo $count | read -l behind ahead
|
|
switch "$count"
|
|
case '' # no upstream
|
|
case "0 0" # equal to upstream
|
|
case "0 *" # ahead of upstream
|
|
echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_ahead$ahead"
|
|
case "* 0" # behind upstream
|
|
echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_behind$behind"
|
|
case '*' # diverged from upstream
|
|
echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_ahead$ahead$___fish_git_prompt_char_upstream_behind$behind"
|
|
end
|
|
else
|
|
switch "$count"
|
|
case '' # no upstream
|
|
case "0 0" # equal to upstream
|
|
echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_equal"
|
|
case "0 *" # ahead of upstream
|
|
echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_ahead"
|
|
case "* 0" # behind upstream
|
|
echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_behind"
|
|
case '*' # diverged from upstream
|
|
echo "$___fish_git_prompt_char_upstream_prefix$___fish_git_prompt_char_upstream_diverged"
|
|
end
|
|
end
|
|
|
|
# For the return status
|
|
test "$count" = "0 0"
|
|
end
|
|
|
|
# Decide if git is safe to run.
|
|
# On Darwin, git is pre-installed as a stub, which will pop a dialog if you run it.
|
|
if string match -q Darwin -- "$(uname)" && type -q xcode-select && type -q xcrun
|
|
if string match -q /usr/bin/git -- "$(command -s git)" && not xcode-select --print-path &>/dev/null
|
|
# Only the stub git is installed.
|
|
# Do not try to run it.
|
|
function __fish_git_prompt_ready
|
|
return 1
|
|
end
|
|
else
|
|
# git is installed, but on the first run it may be very slow as xcrun needs to populate the cache.
|
|
# Kick it off in the background to populate the cache.
|
|
command git --version &>/dev/null &
|
|
disown
|
|
function __fish_git_prompt_ready
|
|
path is "$(xcrun --show-cache-path)" || return 1
|
|
# git is ready, erase the function.
|
|
functions -e __fish_git_prompt_ready
|
|
return 0
|
|
end
|
|
end
|
|
end
|
|
|
|
function fish_git_prompt --description "Prompt function for Git"
|
|
# If git isn't installed, there's nothing we can do
|
|
# Return 1 so the calling prompt can deal with it
|
|
if not command -sq git
|
|
return 1
|
|
end
|
|
# Fail if __fish_git_prompt_ready is defined and fails.
|
|
if functions -q __fish_git_prompt_ready && not __fish_git_prompt_ready
|
|
return 1
|
|
end
|
|
set -l repo_info (command git rev-parse --git-dir --is-inside-git-dir --is-bare-repository --is-inside-work-tree HEAD 2>/dev/null)
|
|
test -n "$repo_info"
|
|
or return
|
|
|
|
set -l git_dir $repo_info[1]
|
|
set -l inside_gitdir $repo_info[2]
|
|
set -l bare_repo $repo_info[3]
|
|
set -l inside_worktree $repo_info[4]
|
|
set -q repo_info[5]
|
|
and set -l sha $repo_info[5]
|
|
|
|
set -l rbc (__fish_git_prompt_operation_branch_bare $repo_info)
|
|
set -l r $rbc[1] # current operation
|
|
set -l b $rbc[2] # current branch
|
|
set -l detached $rbc[3]
|
|
set -l dirtystate #dirty working directory
|
|
set -l stagedstate #staged changes
|
|
set -l invalidstate #staged changes
|
|
set -l stashstate #stashes
|
|
set -l untrackedfiles #untracked
|
|
set -l c $rbc[4] # bare repository
|
|
set -l p #upstream
|
|
set -l informative_status
|
|
|
|
set -q __fish_git_prompt_status_order
|
|
or set -g __fish_git_prompt_status_order stagedstate invalidstate dirtystate untrackedfiles stashstate
|
|
|
|
if not set -q ___fish_git_prompt_init
|
|
# This takes a while, so it only needs to be done once,
|
|
# and then whenever the configuration changes.
|
|
__fish_git_prompt_validate_chars
|
|
__fish_git_prompt_validate_colors
|
|
set -g ___fish_git_prompt_init
|
|
end
|
|
|
|
set -l space "$___fish_git_prompt_color$___fish_git_prompt_char_stateseparator$___fish_git_prompt_color_done"
|
|
|
|
# Use our variables as defaults, but allow overrides via the local git config.
|
|
# That means if neither is set, this stays empty.
|
|
#
|
|
# So "!= true" or "!= false" are useful tests if you want to do something by default.
|
|
set -l informative
|
|
set -l dirty
|
|
set -l untracked
|
|
command git config -z --get-regexp 'bash\.(showInformativeStatus|showDirtyState|showUntrackedFiles)' 2>/dev/null | while read -lz key value
|
|
switch $key
|
|
case bash.showinformativestatus
|
|
set informative $value
|
|
case bash.showdirtystate
|
|
set dirty $value
|
|
case bash.showuntrackedfiles
|
|
set untracked $value
|
|
end
|
|
end
|
|
|
|
# If we don't print these, there is no need to compute them. Note: For now, staged and dirty are coupled.
|
|
if not set -q dirty[1]
|
|
contains -- "$__fish_git_prompt_showdirtystate" yes true 1
|
|
and set dirty true
|
|
end
|
|
contains dirtystate $__fish_git_prompt_status_order || contains stagedstate $__fish_git_prompt_status_order
|
|
or set dirty false
|
|
|
|
if not set -q untracked[1]
|
|
contains -- "$__fish_git_prompt_showuntrackedfiles" yes true 1
|
|
and set untracked true
|
|
end
|
|
contains untrackedfiles $__fish_git_prompt_status_order
|
|
or set untracked false
|
|
|
|
if test true = $inside_worktree
|
|
# Use informative status if it has been enabled locally, or it has been
|
|
# enabled globally (via the fish variable) and dirty or untracked are not false.
|
|
#
|
|
# This is to allow overrides for the repository.
|
|
if test "$informative" = true
|
|
or begin
|
|
contains -- "$__fish_git_prompt_show_informative_status" yes true 1
|
|
and test "$dirty" != false
|
|
end
|
|
set informative_status (untracked=$untracked __fish_git_prompt_informative_status $git_dir)
|
|
if test -n "$informative_status"
|
|
set informative_status "$space$informative_status"
|
|
end
|
|
else
|
|
if not test "$dirty" = true; and test "$untracked" = true
|
|
# Only untracked, ls-files is faster.
|
|
command git -c core.fsmonitor= ls-files --others --exclude-standard --directory --no-empty-directory --error-unmatch -- :/ >/dev/null 2>&1
|
|
and set untrackedfiles 1
|
|
else if test "$dirty" = true
|
|
# With both dirty and untracked, git status is ~10% faster.
|
|
# With just dirty, it's ~20%.
|
|
set -l opt -uno
|
|
test "$untracked" = true; and set opt -unormal
|
|
# Don't use `--ignored=no`; it was introduced in Git 2.16, from January 2018
|
|
# Ignored files are omitted by default
|
|
set -l stat (command git -c core.fsmonitor= status --porcelain -z $opt | string split0)
|
|
|
|
set dirtystate (string match -qr '^.[ACDMR]' -- $stat; and echo 1)
|
|
if test -n "$sha"
|
|
set stagedstate (string match -qr '^[ACDMR].' -- $stat; and echo 1)
|
|
else
|
|
set invalidstate 1
|
|
end
|
|
|
|
test "$untracked" = true
|
|
and set untrackedfiles (string match -qr '\?\?' -- $stat; and echo 1)
|
|
end
|
|
|
|
if contains -- "$__fish_git_prompt_showstashstate" yes true 1
|
|
and test -r $git_dir/logs/refs/stash
|
|
set stashstate 1
|
|
end
|
|
end
|
|
|
|
# (showupstream has a variety of options, not just bool)
|
|
if set -q __fish_git_prompt_showupstream
|
|
or contains -- "$__fish_git_prompt_show_informative_status" yes true 1
|
|
set p (__fish_git_prompt_show_upstream)
|
|
end
|
|
end
|
|
|
|
set -l branch_color $___fish_git_prompt_color_branch
|
|
set -l branch_done $___fish_git_prompt_color_branch_done
|
|
if contains -- "$__fish_git_prompt_showcolorhints" yes true 1
|
|
if test $detached = yes
|
|
set branch_color $___fish_git_prompt_color_branch_detached
|
|
set branch_done $___fish_git_prompt_color_branch_detached_done
|
|
else if test -n "$dirtystate$untrackedfiles"; and set -q __fish_git_prompt_color_branch_dirty
|
|
set branch_color (set_color $__fish_git_prompt_color_branch_dirty)
|
|
set branch_done (set_color $__fish_git_prompt_color_branch_dirty_done)
|
|
else if test -n "$stagedstate"; and set -q __fish_git_prompt_color_branch_staged
|
|
set branch_color (set_color $__fish_git_prompt_color_branch_staged)
|
|
set branch_done (set_color $__fish_git_prompt_color_branch_staged_done)
|
|
end
|
|
end
|
|
|
|
set -l f ""
|
|
for i in $__fish_git_prompt_status_order
|
|
if test -n "$$i"
|
|
set -l color_var ___fish_git_prompt_color_$i
|
|
set -l color_done_var ___fish_git_prompt_color_{$i}_done
|
|
set -l symbol_var ___fish_git_prompt_char_$i
|
|
|
|
set -l color $$color_var
|
|
set -l color_done $$color_done_var
|
|
set -l symbol $$symbol_var
|
|
|
|
set f "$f$color$symbol$color_done"
|
|
end
|
|
end
|
|
|
|
set b (string replace refs/heads/ '' -- $b)
|
|
if string match -qr '^\d+$' "$__fish_git_prompt_shorten_branch_len"
|
|
set -q __fish_git_prompt_shorten_branch_char_suffix
|
|
and set -l char -c "$__fish_git_prompt_shorten_branch_char_suffix"
|
|
set b (string shorten -m "$__fish_git_prompt_shorten_branch_len" $char -- "$b")
|
|
end
|
|
if test -n "$b"
|
|
set b "$branch_color$b$branch_done"
|
|
if test -z "$dirtystate$untrackedfiles$stagedstate"; and test -n "$___fish_git_prompt_char_cleanstate"
|
|
and not contains -- "$__fish_git_prompt_show_informative_status" yes true 1
|
|
set b "$b$___fish_git_prompt_color_cleanstate$___fish_git_prompt_char_cleanstate$___fish_git_prompt_color_cleanstate_done"
|
|
end
|
|
end
|
|
if test -n "$c"
|
|
set c "$___fish_git_prompt_color_bare$c$___fish_git_prompt_color_bare_done"
|
|
end
|
|
if test -n "$r"
|
|
set r "$___fish_git_prompt_color_merging$r$___fish_git_prompt_color_merging_done"
|
|
end
|
|
if test -n "$p"
|
|
set p "$___fish_git_prompt_color_upstream$p$___fish_git_prompt_color_upstream_done"
|
|
end
|
|
|
|
# Formatting
|
|
if test -n "$f"
|
|
set f "$space$f"
|
|
end
|
|
set -l format $argv[1]
|
|
if test -z "$format"
|
|
set format " (%s)"
|
|
end
|
|
|
|
printf "%s$format%s" "$___fish_git_prompt_color_prefix" "$___fish_git_prompt_color_prefix_done$c$b$f$r$p$informative_status$___fish_git_prompt_color_suffix" "$___fish_git_prompt_color_suffix_done"
|
|
end
|
|
|
|
### helper functions
|
|
|
|
function __fish_git_prompt_informative_status
|
|
set -l stashstate 0
|
|
set -l stashfile "$argv[1]/logs/refs/stash"
|
|
if contains -- "$__fish_git_prompt_showstashstate" yes true 1; and test -e "$stashfile"
|
|
set stashstate (count < $stashfile)
|
|
end
|
|
|
|
# If we're not told to show untracked files, we don't.
|
|
# If we are, we still use the "normal" mode because it's a lot faster,
|
|
# and it's unlikely anyone cares about the number of files if it's *all* of the files
|
|
# in that directory.
|
|
set -l untr -uno
|
|
test "$untracked" = true
|
|
and set untr -unormal
|
|
|
|
# Use git status --porcelain.
|
|
# The v2 format is better, but we don't actually care in this case.
|
|
set -l stats (string sub -l 2 (git -c core.fsmonitor= status --porcelain -z $untr | string split0))
|
|
set -l invalidstate (string match -r '^UU' $stats | count)
|
|
set -l stagedstate (string match -r '^[ACDMR].' $stats | count)
|
|
set -l dirtystate (string match -r '^.[ACDMR]' $stats | count)
|
|
set -l untrackedfiles (string match -r '^\?\?' $stats | count)
|
|
|
|
set -l info
|
|
|
|
# If `math` fails for some reason, assume the state is clean - it's the simpler path
|
|
set -l state (math $dirtystate + $invalidstate + $stagedstate + $untrackedfiles + $stashstate 2>/dev/null)
|
|
if test -z "$state"
|
|
or test "$state" = 0
|
|
if test -n "$___fish_git_prompt_char_cleanstate"
|
|
set info $___fish_git_prompt_color_cleanstate$___fish_git_prompt_char_cleanstate$___fish_git_prompt_color_cleanstate_done
|
|
end
|
|
else
|
|
for i in $__fish_git_prompt_status_order
|
|
if test $$i != 0
|
|
set -l color_var ___fish_git_prompt_color_$i
|
|
set -l color_done_var ___fish_git_prompt_color_{$i}_done
|
|
set -l symbol_var ___fish_git_prompt_char_$i
|
|
|
|
set -l color $$color_var
|
|
set -l color_done $$color_done_var
|
|
set -l symbol $$symbol_var
|
|
|
|
set -l count
|
|
|
|
if not set -q __fish_git_prompt_hide_$i
|
|
set count $$i
|
|
end
|
|
|
|
set info "$info$color$symbol$count$color_done"
|
|
end
|
|
end
|
|
end
|
|
|
|
echo $info
|
|
|
|
end
|
|
|
|
# Keeping these together avoids many duplicated checks
|
|
function __fish_git_prompt_operation_branch_bare --description "fish_git_prompt helper, returns the current Git operation and branch"
|
|
# This function is passed the full repo_info array
|
|
set -l git_dir $argv[1]
|
|
set -l inside_gitdir $argv[2]
|
|
set -l bare_repo $argv[3]
|
|
set -q argv[5]
|
|
and set -l sha $argv[5]
|
|
|
|
set -l branch
|
|
set -l operation
|
|
set -l detached no
|
|
set -l bare
|
|
set -l step
|
|
set -l total
|
|
|
|
if test -d $git_dir/rebase-merge
|
|
set branch (cat $git_dir/rebase-merge/head-name 2>/dev/null)
|
|
set step (cat $git_dir/rebase-merge/msgnum 2>/dev/null)
|
|
set total (cat $git_dir/rebase-merge/end 2>/dev/null)
|
|
if test -f $git_dir/rebase-merge/interactive
|
|
set operation "|REBASE-i"
|
|
else
|
|
set operation "|REBASE-m"
|
|
end
|
|
else
|
|
if test -d $git_dir/rebase-apply
|
|
set step (cat $git_dir/rebase-apply/next 2>/dev/null)
|
|
set total (cat $git_dir/rebase-apply/last 2>/dev/null)
|
|
if test -f $git_dir/rebase-apply/rebasing
|
|
set branch (cat $git_dir/rebase-apply/head-name 2>/dev/null)
|
|
set operation "|REBASE"
|
|
else if test -f $git_dir/rebase-apply/applying
|
|
set operation "|AM"
|
|
else
|
|
set operation "|AM/REBASE"
|
|
end
|
|
else if test -f $git_dir/MERGE_HEAD
|
|
set operation "|MERGING"
|
|
else if test -f $git_dir/CHERRY_PICK_HEAD
|
|
set operation "|CHERRY-PICKING"
|
|
else if test -f $git_dir/REVERT_HEAD
|
|
set operation "|REVERTING"
|
|
else if test -f $git_dir/BISECT_LOG
|
|
set operation "|BISECTING"
|
|
end
|
|
end
|
|
|
|
if test -n "$step" -a -n "$total"
|
|
set operation "$operation $step/$total"
|
|
end
|
|
|
|
if test -z "$branch"
|
|
if not set branch (command git symbolic-ref HEAD 2>/dev/null)
|
|
set detached yes
|
|
set branch (switch "$__fish_git_prompt_describe_style"
|
|
case contains
|
|
command git describe --contains HEAD
|
|
case branch
|
|
command git describe --contains --all HEAD
|
|
case describe
|
|
command git describe HEAD
|
|
case default '*'
|
|
command git describe --tags --exact-match HEAD
|
|
end 2>/dev/null)
|
|
if test $status -ne 0
|
|
# Shorten the sha ourselves to 8 characters - this should be good for most repositories,
|
|
# and even for large ones it should be good for most commits
|
|
# No need for an ellipsis.
|
|
if set -q sha
|
|
set branch (string shorten -m8 -c "" -- $sha)
|
|
else
|
|
set branch unknown
|
|
end
|
|
end
|
|
set branch "($branch)"
|
|
end
|
|
end
|
|
|
|
if test true = $inside_gitdir
|
|
if test true = $bare_repo
|
|
set bare "BARE:"
|
|
else
|
|
# Let user know they're inside the git dir of a non-bare repo
|
|
set branch "GIT_DIR!"
|
|
end
|
|
end
|
|
|
|
echo $operation
|
|
echo $branch
|
|
echo $detached
|
|
echo $bare
|
|
end
|
|
|
|
function __fish_git_prompt_set_char
|
|
set -l user_variable_name "$argv[1]"
|
|
set -l char $argv[2]
|
|
|
|
if set -q argv[3]
|
|
and begin
|
|
contains -- "$__fish_git_prompt_show_informative_status" yes true 1
|
|
or contains -- "$__fish_git_prompt_use_informative_chars" yes true 1
|
|
end
|
|
set char $argv[3]
|
|
end
|
|
|
|
set -l variable _$user_variable_name
|
|
set -l variable_done "$variable"_done
|
|
|
|
if not set -q $variable
|
|
set -g $variable (set -q $user_variable_name; and echo $$user_variable_name; or echo $char)
|
|
end
|
|
end
|
|
|
|
function __fish_git_prompt_validate_chars --description "fish_git_prompt helper, checks char variables"
|
|
# cleanstate is only defined with actual informative status.
|
|
contains -- "$__fish_git_prompt_show_informative_status" yes true 1
|
|
and __fish_git_prompt_set_char __fish_git_prompt_char_cleanstate '✔'
|
|
or __fish_git_prompt_set_char __fish_git_prompt_char_cleanstate ''
|
|
|
|
__fish_git_prompt_set_char __fish_git_prompt_char_dirtystate '*' '✚'
|
|
__fish_git_prompt_set_char __fish_git_prompt_char_invalidstate '#' '✖'
|
|
__fish_git_prompt_set_char __fish_git_prompt_char_stagedstate '+' '●'
|
|
__fish_git_prompt_set_char __fish_git_prompt_char_stashstate '$' '⚑'
|
|
__fish_git_prompt_set_char __fish_git_prompt_char_stateseparator ' ' '|'
|
|
__fish_git_prompt_set_char __fish_git_prompt_char_untrackedfiles '%' '…'
|
|
__fish_git_prompt_set_char __fish_git_prompt_char_upstream_ahead '>' '↑'
|
|
__fish_git_prompt_set_char __fish_git_prompt_char_upstream_behind '<' '↓'
|
|
__fish_git_prompt_set_char __fish_git_prompt_char_upstream_diverged '<>'
|
|
__fish_git_prompt_set_char __fish_git_prompt_char_upstream_equal '='
|
|
__fish_git_prompt_set_char __fish_git_prompt_char_upstream_prefix ''
|
|
|
|
end
|
|
|
|
function __fish_git_prompt_set_color
|
|
set -l user_variable_name "$argv[1]"
|
|
|
|
set -l default default_done
|
|
switch (count $argv)
|
|
case 1 # No defaults given, use prompt color
|
|
set default $___fish_git_prompt_color
|
|
set default_done $___fish_git_prompt_color_done
|
|
case 2 # One default given, use normal for done
|
|
set default "$argv[2]"
|
|
set default_done (set_color normal)
|
|
case 3 # Both defaults given
|
|
set default "$argv[2]"
|
|
set default_done "$argv[3]"
|
|
end
|
|
|
|
set -l variable _$user_variable_name
|
|
set -l variable_done "$variable"_done
|
|
|
|
if not set -q $variable
|
|
if test -n "$$user_variable_name"
|
|
set -g $variable (set_color $$user_variable_name)
|
|
set -g $variable_done (set_color normal)
|
|
else
|
|
set -g $variable $default
|
|
set -g $variable_done $default_done
|
|
end
|
|
end
|
|
end
|
|
|
|
|
|
function __fish_git_prompt_validate_colors --description "fish_git_prompt helper, checks color variables"
|
|
|
|
# Base color defaults to nothing (must be done first)
|
|
__fish_git_prompt_set_color __fish_git_prompt_color '' ''
|
|
|
|
# Normal colors
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_prefix
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_suffix
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_bare
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_merging
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_cleanstate
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_invalidstate
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_upstream
|
|
|
|
# Colors with defaults with showcolorhints
|
|
if contains -- "$__fish_git_prompt_showcolorhints" yes true 1
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_flags (set_color --bold blue)
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_branch (set_color green)
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_dirtystate (set_color red)
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_stagedstate (set_color green)
|
|
else
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_flags
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_branch
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_dirtystate $___fish_git_prompt_color_flags $___fish_git_prompt_color_flags_done
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_stagedstate $___fish_git_prompt_color_flags $___fish_git_prompt_color_flags_done
|
|
end
|
|
|
|
# Branch_detached has a default, but is only used with showcolorhints
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_branch_detached (set_color red)
|
|
|
|
# Colors that depend on flags color
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_stashstate $___fish_git_prompt_color_flags $___fish_git_prompt_color_flags_done
|
|
__fish_git_prompt_set_color __fish_git_prompt_color_untrackedfiles $___fish_git_prompt_color_flags $___fish_git_prompt_color_flags_done
|
|
|
|
end
|
|
|
|
function __fish_git_prompt_reset -a type -a op -a var --description "Event handler, resets prompt when functionality changes" \
|
|
--on-variable=__fish_git_prompt_{show_informative_status,use_informative_chars}
|
|
if status --is-interactive
|
|
# Clear characters that have different defaults with/without informative status
|
|
set -e ___fish_git_prompt_char_{name,cleanstate,dirtystate,invalidstate,stagedstate,stashstate,stateseparator,untrackedfiles,upstream_ahead,upstream_behind}
|
|
# Clear init so we reset the chars next time.
|
|
set -e ___fish_git_prompt_init
|
|
end
|
|
end
|
|
|
|
function __fish_git_prompt_reset_color -a type -a op -a var --description "Event handler, resets prompt when any color changes" \
|
|
--on-variable=__fish_git_prompt_color{'',_prefix,_suffix,_bare,_merging,_cleanstate,_invalidstate,_upstream,_flags,_branch,_dirtystate,_stagedstate,_branch_detached,_stashstate,_untrackedfiles} --on-variable=__fish_git_prompt_showcolorhints
|
|
if status --is-interactive
|
|
set -e _$var
|
|
set -e _{$var}_done
|
|
set -e ___fish_git_prompt_init
|
|
if contains -- $var __fish_git_prompt_color __fish_git_prompt_color_flags __fish_git_prompt_showcolorhints
|
|
# reset all the other colors too
|
|
set -e ___fish_git_prompt_color_{prefix,suffix,bare,merging,branch,dirtystate,stagedstate,invalidstate,stashstate,untrackedfiles,upstream,flags}{,_done}
|
|
end
|
|
end
|
|
end
|
|
|
|
function __fish_git_prompt_reset_char -a type -a op -a var --description "Event handler, resets prompt when any char changes" \
|
|
--on-variable=__fish_git_prompt_char_{cleanstate,dirtystate,invalidstate,stagedstate,stashstate,stateseparator,untrackedfiles,upstream_ahead,upstream_behind,upstream_diverged,upstream_equal,upstream_prefix}
|
|
if status --is-interactive
|
|
set -e ___fish_git_prompt_init
|
|
set -e _$var
|
|
end
|
|
end
|