Skip to content

Commit e0b0e33

Browse files
gitprompt
0 parents  commit e0b0e33

14 files changed

+378
-0
lines changed

.github/ISSUE_TEMPLATE/bug_report.md

+40
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,40 @@
1+
---
2+
name: "Bug report"
3+
about: Report a reproducible bug or regression.
4+
labels: 'bug'
5+
6+
---
7+
8+
# Bug Report
9+
10+
gitprompt version:
11+
12+
<!--
13+
Please provide a clear and concise description of what the bug is. Include
14+
screenshots if needed. Please test using the latest version of gitprompt to
15+
make sure your issue has not already been fixed.
16+
-->
17+
18+
## Steps To Reproduce
19+
20+
1.
21+
2.
22+
23+
<!--
24+
Your bug will get fixed much faster if we can run your code and it doesn't
25+
have dependencies other than gitprompt. Issues without reproduction steps or
26+
code examples may be immediately closed as not actionable.
27+
-->
28+
29+
Link to code example:
30+
31+
<!--
32+
Please provide a link to a repository on GitHub or provide a minimal code
33+
example that reproduces the problem. You may provide a screenshot of some
34+
application if you think it is relevant to your bug report. Here are some
35+
tips for providing a minimal example: https://stackoverflow.com/help/mcve.
36+
-->
37+
38+
## The current behavior
39+
40+
## The expected behavior

.github/ISSUE_TEMPLATE/config.yml

+5
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
blank_issues_enabled: false
2+
contact_links:
3+
- name: Question
4+
url: https://github.com/danieldietrich/gitprompt/discussions
5+
about: Please ask questions here.
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
---
2+
name: Feature request
3+
about: Suggest an idea for this project
4+
labels: 'feature-request'
5+
6+
---
7+
<!-- Please search existing issues to avoid creating duplicates. -->
8+
<!-- Describe the feature you'd like. -->

.github/ISSUE_TEMPLATE/improvement.md

+7
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,7 @@
1+
---
2+
name: General improvement
3+
about: Suggest an improvement for this project
4+
5+
---
6+
<!-- Please search existing issues to avoid creating duplicates. -->
7+
<!-- Describe the improvement you'd like to see in the project. -->

.github/workflows/test.yml

+23
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
name: Test
2+
3+
on:
4+
push:
5+
branches:
6+
- main
7+
pull_request:
8+
branches:
9+
- main
10+
11+
jobs:
12+
build:
13+
name: gitprompt.sh
14+
runs-on: ubuntu-latest
15+
timeout-minutes: 5
16+
steps:
17+
- name: Checkout
18+
uses: actions/checkout@v2
19+
- name: Unit tests
20+
shell: bash
21+
run: |
22+
cd tests
23+
bash gitprompt-tests

.gitignore

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
.DS_Store

LICENSE

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
Copyright 2022 Daniel Dietrich
2+
3+
Permission is hereby granted, free of charge, to any person obtaining a copy of this software and
4+
associated documentation files (the "Software"), to deal in the Software without restriction,
5+
including without limitation the rights to use, copy, modify, merge, publish, distribute,
6+
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
7+
furnished to do so, subject to the following conditions:
8+
9+
The above copyright notice and this permission notice shall be included in all copies or
10+
substantial portions of the Software.
11+
12+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING
13+
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
14+
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
15+
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
16+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

README.md

+44
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,44 @@
1+
<!-- markdownlint-disable MD034 -->
2+
3+
# _ gitprompt
4+
5+
A beautiful git prompt for zsh and bash.
6+
7+
![terminal](./docs/img/terminal.png)
8+
9+
## Features
10+
11+
* 256 colors support
12+
* Show current directory
13+
* Show git branch, status and push state
14+
* Show current time at the right side (zsh only)
15+
* Automatic PROMPT refresh on git changes and time (every second, zsh only)
16+
17+
## Usage
18+
19+
| Szenario | Command | Description |
20+
| --------- | --------------------------------- | ------------------------------------------------- |
21+
| ad-hoc | `. <(curl gitprompt.sh)` | Use **gitprompt** in the current terminal session |
22+
| permanent | `curl gitprompt.sh/install \| sh` | Install **gitprompt** in your home directory |
23+
| [dotfiles](https://www.gitpod.io/docs/configure/user-settings/dotfiles) | `https://github.com/danieldietrich/dotfiles` | Personalize your Gitpod workspace environments |
24+
25+
## Customization
26+
27+
ENV variables can be set in your `.bashrc` or `.zshrc` file.
28+
29+
| ENV var | Default | Description |
30+
| ----------------------- | -------------- | ------------------------------ |
31+
| `GP_COLOR_PROMPT` | `"38;5;49"` | Prompt color |
32+
| `GP_COLOR_GIT_BRANCH` | `"38;5;8"` | Branch color |
33+
| `GP_COLOR_GIT_STATUS` | `"38;5;9"` | Dirty state color |
34+
| `GP_COLOR_GIT_UNPUSHED` | `"38;5;11"` | Unpushed state color |
35+
| `GP_COLOR_PWD_DARK` | `"1;38;5;24"` | Directory color dark |
36+
| `GP_COLOR_PWD_LIGHT` | `"1;38;5;39"` | Directory color light |
37+
38+
These variables only apply to the zsh version.
39+
40+
| ENV var | Default | Description |
41+
| ----------------------- | -------------- | ------------------------------ |
42+
| `GP_COLOR_CLOCK` | `"38;5;99"` | Clock color |
43+
| `GP_COLORS` | `true` | Enable colors |
44+
| `GP_UPDATE_PROMPT` | `true` | Enables/disables PROMPT update |

docs/CNAME

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
gitprompt.sh

docs/img/terminal.png

350 KB
Loading

docs/index.html

+129
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,129 @@
1+
#!/bin/bash -n
2+
# ------------------------------------------------------------------------------
3+
# (C)opyright 2022 by Daniel Dietrich - MIT license
4+
# ------------------------------------------------------------------------------
5+
6+
# <html hidden><script>location.href="/page.html"</script></html>
7+
8+
# ------------------------------------------------------------------------------
9+
#
10+
# Usage:
11+
#
12+
# | Command | Description |
13+
# | ------------------------------------------ | ----------------------------- |
14+
# | . <(curl gitprompt.sh) | Use gitprompt in Active shell |
15+
# | curl gitprompt.sh/install | sh | Install gitprompt to $HOME |
16+
# | https://github.com/danieldietrich/dotfiles | Gitpod dotfiles |
17+
#
18+
# Customize gitprompt by placing ENV vars in your .bashrc or .zshrc file.
19+
#
20+
# | ENV var | Default | Description |
21+
# | --------------------- | ------------ | ----------------------------------- |
22+
# | GP_COLOR_PROMPT | "38;5;49" | Prompt color |
23+
# | GP_COLOR_GIT_BRANCH | "38;5;8" | Branch color |
24+
# | GP_COLOR_GIT_STATUS | "38;5;9" | Dirty state color |
25+
# | GP_COLOR_GIT_UNPUSHED | "38;5;11" | Unpushed state color |
26+
# | GP_COLOR_PWD_DARK | "1;38;5;24" | Directory color dark |
27+
# | GP_COLOR_PWD_LIGHT | "1;38;5;39" | Directory color light |
28+
#
29+
# These variables only apply to the zsh version.
30+
#
31+
# | ENV var | Default | Description |
32+
# | --------------------- | ------------ | ----------------------------------- |
33+
# | GP_COLOR_CLOCK | "38;5;99" | Clock color |
34+
# | GP_COLORS | true | Enable colors |
35+
# | GP_UPDATE_PROMPT | true | Enables/disables PROMPT update |
36+
#
37+
# ------------------------------------------------------------------------------
38+
39+
# shellcheck disable=SC2154 disable=SC2155 disable=SC2296 disable=SC2301
40+
41+
__gp_color() {
42+
if [ -n "$GP_COLORS" ]; then
43+
[ -n "$ZSH_VERSION" ] && echo -ne "%{\e[$1m%}" || echo -ne "\001\033[$1m\002"
44+
fi
45+
}
46+
47+
# param 1: dir
48+
# param 2 (test only): output of git status -sb
49+
# param 3 (test only): non-empty for dirty state
50+
__gp_status() {
51+
52+
# colors
53+
local COLOR_BRANCH=$(__gp_color "${GP_COLOR_GIT_BRANCH:-38;5;8}")
54+
local COLOR_STATUS=$(__gp_color "${GP_COLOR_GIT_STATUS:-38;5;9}")
55+
local COLOR_UNPUSHED=$(__gp_color "${GP_COLOR_GIT_UNPUSHED:-38;5;11}")
56+
local COLOR_RESET=$(__gp_color 0)
57+
58+
local dir=${1:-.} git_status branch_info branch changes state remote ahead behind unpushed
59+
60+
__parse() (
61+
echo -n "$(set -o pipefail; sed -rn "$1" <<< "$branch_info")"
62+
)
63+
64+
# first line: branch, remote, ahead, behind
65+
# subsequent lines: local changes
66+
if ! git_status=${2:-"$(set -o pipefail; git status -sb 2>/dev/null)"}; then
67+
return 0
68+
fi
69+
branch_info=$(head -n 1 <<< "$git_status")
70+
changes=$(echo "$git_status" | tail -n +2 | wc -l | xargs) # xargs trims spaces
71+
72+
# parse state
73+
[ "$changes" -gt 0 ] && state="$changes"
74+
75+
# parse branch
76+
branch=$(__parse "s/^## (HEAD \(no branch\))$/\1/p")
77+
branch=${branch:-$(__parse "s/^## No commits yet on (.*)$/\1/p")}
78+
branch=${branch:-$(__parse "s/^## ([^ \.]*).*$/\1/p")}
79+
80+
# parse push state
81+
remote=$(__parse "s/^## .*[\.]{3}([^ ]*).*$/\1/p")
82+
ahead=$(__parse "s/^## .* \[.*ahead ([0-9]*).*$/\1/p")
83+
behind=$(__parse "s/^## .* \[.*behind ([0-9]*).*$/\1/p")
84+
unpushed=$(
85+
[ -n "$ahead" ] && echo -n "$ahead";
86+
[ -n "$behind" ] && echo -n "$behind";
87+
)
88+
89+
printf "%s⎇ %s%s%s%s%s%s" "${COLOR_BRANCH}" "${branch}$([ -n "$remote" ] && echo -n "$remote")" "${COLOR_STATUS}" "${state}" "${COLOR_UNPUSHED}" "${unpushed}" "${COLOR_RESET}"
90+
}
91+
92+
__gp_pwd() {
93+
local COLOR_DARK=$(__gp_color "${GP_COLOR_PWD_DARK:-1;38;5;24}")
94+
local COLOR_LIGHT=$(__gp_color "${GP_COLOR_PWD_LIGHT:-1;38;5;39}")
95+
local COLOR_RESET=$(__gp_color 0)
96+
local pwd="${PWD/#$HOME/~}" dir prefix suffix
97+
dir=$(dirname "$pwd" 2>/dev/null)
98+
prefix=$(if [[ "$dir" == "." ]] || [[ -z "$dir" ]]; then echo -n ""; elif [[ "$dir" == "/" ]]; then echo -n "/"; else echo -n "$dir/"; fi)
99+
dir=$(basename "$pwd" 2>/dev/null)
100+
suffix=$(if [[ "$dir" == "/" ]]; then echo -n ""; else echo -n "$dir"; fi)
101+
printf "%s%s%s%s%s" "${COLOR_DARK}" "${prefix/#\~/${COLOR_LIGHT}~${COLOR_DARK}}" "${COLOR_LIGHT}" "${suffix}" "${COLOR_RESET}"
102+
}
103+
104+
__update_prompt() {
105+
emulate -L zsh
106+
zmodload -i zsh/sched
107+
108+
integer i=${"${(@)zsh_scheduled_events#*:*:}"[(I)schedprompt]}
109+
(( i )) && sched -"$i"
110+
111+
if [ -n "$GP_UPDATE_PROMPT" ]; then
112+
zle && zle reset-prompt
113+
fi
114+
115+
sched +1 __update_prompt
116+
}
117+
118+
export TERM=xterm-256color
119+
120+
GP_COLORS=true
121+
122+
if [ -n "$ZSH_VERSION" ]; then
123+
setopt PROMPT_SUBST
124+
export PROMPT="%\$((\$COLUMNS / 2))<…<\$(__gp_pwd)\$(__gp_status)\$(__gp_color \${GP_COLOR_PROMPT:-38;5;49}) ❯$(__gp_color 0) "
125+
export RPROMPT="\$(__gp_color \${GP_COLOR_CLOCK:-38;5;99})%D{%K:%M:%S}$(__gp_color 0)"
126+
GP_UPDATE_PROMPT=true ; __update_prompt
127+
else
128+
export PS1="\$(__gp_pwd)\$(__gp_status)\$(__gp_color \${GP_COLOR_PROMPT:-38;5;49}) ❯$(__gp_color 0) "
129+
fi

docs/install

+25
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
#!/bin/sh
2+
# ------------------------------------------------------------------------------
3+
# (C)opyright 2022 by Daniel Dietrich - MIT license
4+
# ------------------------------------------------------------------------------
5+
6+
# shellcheck disable=SC2059 disable=SC1090 disable=SC2088
7+
8+
echo "Installing gitprompt..."
9+
10+
gitprompt="$HOME/.gitprompt"
11+
12+
if [ -f "$gitprompt" ]; then
13+
echo "$gitprompt found, skipping installation"
14+
else
15+
if curl -sL https://gitprompt.sh > "$gitprompt"; then
16+
SOURCE_GITPROMPT="\n\n. ~/.gitprompt &>/dev/null\n"
17+
printf "$SOURCE_GITPROMPT" >> ~/.zshrc
18+
printf "$SOURCE_GITPROMPT" >> ~/.bashrc
19+
printf "$SOURCE_GITPROMPT" >> ~/.bash_profile
20+
echo "Installed $gitprompt"
21+
else
22+
echo "Failed to install $gitprompt"
23+
exit 1
24+
fi
25+
fi

docs/page.html

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
<!DOCTYPE html>
2+
<html lang="en">
3+
<head>
4+
</head>
5+
<body>
6+
<h1>
7+
<code>❯ . <(curl gitprompt.sh)</code>
8+
</h1>
9+
<body>
10+
</html>

tests/gitprompt-tests

+69
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,69 @@
1+
#!/bin/bash
2+
3+
# shellcheck disable=SC1091 disable=SC2034 disable=SC2155
4+
5+
. ../docs/index.html
6+
7+
GP_COLORS=""
8+
ERROR=""
9+
10+
__test_gp_status() {
11+
local expected=$1
12+
local dir=$2
13+
local git_status_sb=$3
14+
local dirty=$4
15+
local actual=$(__gp_status "$dir" "$git_status_sb" "$dirty")
16+
if [[ "$actual" != "$expected" ]]; then
17+
echo "ERROR: expected '$expected' but was '$actual'"
18+
ERROR=true
19+
fi
20+
}
21+
22+
# detached HEAD (git checkout <commit-hash>)
23+
__test_gp_status "⎇ HEAD (no branch)" "." "## HEAD (no branch)"
24+
__test_gp_status "⎇ HEAD (no branch)✗1" "." "## HEAD (no branch)
25+
?? x"
26+
27+
# fresh repo (git init)
28+
__test_gp_status "⎇ main" "." "## No commits yet on main"
29+
__test_gp_status "⎇ main✗1" "." "## No commits yet on main
30+
?? x"
31+
32+
# first commit, upstream branch (git add . ; git commit -m "first commit")
33+
__test_gp_status "⎇ main" "." "## main"
34+
__test_gp_status "⎇ main✗1" "." "## main
35+
?? x"
36+
37+
# unpushed changes without remote
38+
__test_gp_status "⎇ main↑1" "." "## main [ahead 1]"
39+
__test_gp_status "⎇ main✗1↑1" "." "## main [ahead 1]
40+
?? x"
41+
42+
# TODO(@@dd): incoming changes without remote?
43+
__test_gp_status "⎇ main↓1" "." "## main [behind 1]"
44+
__test_gp_status "⎇ main✗1↓1" "." "## main [behind 1]
45+
?? x"
46+
47+
# TODO(@@dd): merge conflict without remote?
48+
__test_gp_status "⎇ main↑1↓1" "." "## main [ahead 1, behind 1]"
49+
__test_gp_status "⎇ main✗1↑1↓1" "." "## main [ahead 1, behind 1]
50+
?? x"
51+
52+
# unpushed changes to remote
53+
__test_gp_status "⎇ main → origin/main↑1" "." "## main...origin/main [ahead 1]"
54+
__test_gp_status "⎇ main → origin/main✗1↑1" "." "## main...origin/main [ahead 1]
55+
?? x"
56+
57+
# merge conflict with remote
58+
__test_gp_status "⎇ main → origin/main↑1↓1" "." "## main...origin/main [ahead 1, behind 1]"
59+
__test_gp_status "⎇ main → origin/main✗1↑1↓1" "." "## main...origin/main [ahead 1, behind 1]
60+
?? x"
61+
62+
# incoming changes from remote
63+
__test_gp_status "⎇ main → origin/main↓1" "." "## main...origin/main [behind 1]"
64+
__test_gp_status "⎇ main → origin/main✗1↓1" "." "## main...origin/main [behind 1]
65+
?? x"
66+
67+
if [ -n "$ERROR" ]; then
68+
exit 1
69+
fi

0 commit comments

Comments
 (0)