chezmoi init

This commit is contained in:
Cy Pokhrel 2024-10-22 11:11:45 -04:00
commit 530d6d7195
No known key found for this signature in database
GPG key ID: 1200FBE36C2ADE2E
1176 changed files with 111325 additions and 0 deletions

View file

@ -0,0 +1,72 @@
# git-prompt plugin
A `zsh` prompt that displays information about the current git repository. In particular:
the branch name, difference with remote branch, number of files staged or changed, etc.
To use it, add `git-prompt` to the plugins array in your zshrc file:
```zsh
plugins=(... git-prompt)
```
You may also need to [customize your theme](https://github.com/ohmyzsh/ohmyzsh/issues/9395#issuecomment-1027130429)
to change the way the prompt is built. See the
[OMZ wiki on customizing themes](https://github.com/ohmyzsh/ohmyzsh/wiki/Customization#overriding-and-adding-themes).
See the [original repository](https://github.com/olivierverdier/zsh-git-prompt).
## Requirements
This plugin uses `python3`, so your host needs to have it installed.
## Examples
The prompt may look like the following:
- `(master↑3|✚1)`: on branch `master`, ahead of remote by 3 commits, 1 file changed but not staged
- `(status|●2)`: on branch `status`, 2 files staged
- `(master|✚7…)`: on branch `master`, 7 files changed, some files untracked
- `(master|✖2✚3)`: on branch `master`, 2 conflicts, 3 files changed
- `(experimental↓2↑3|✔)`: on branch `experimental`; your branch has diverged by 3 commits, remote by 2 commits; the repository is otherwise clean
- `(:70c2952|✔)`: not on any branch; parent commit has hash `70c2952`; the repository is otherwise clean
- `(master|⚑2)`: on branch `master`, there are 2 stashed changes
## Prompt Structure
By default, the general appearance of the prompt is:
```text
(<branch><branch tracking>|<local status>)
```
The symbols are as follows:
### Local Status Symbols
| Symbol | Meaning |
|--------|--------------------------------|
| ✔ | repository clean |
| ●n | there are `n` staged files |
| ✖n | there are `n` unmerged files |
| ✚n | there are `n` unstaged files |
| -n | there are `n` deleted files |
| ⚑n | there are `n` stashed changes |
| … | there are some untracked files |
### Branch Tracking Symbols
| Symbol | Meaning |
|--------|---------------------------------------------------------------|
| ↑n | ahead of remote by `n` commits |
| ↓n | behind remote by `n` commits |
| ↓m↑n | branches diverged: other by `m` commits, yours by `n` commits |
## Customisation
- Set the variable `ZSH_THEME_GIT_PROMPT_CACHE` to any value in order to enable caching.
- Set the variable `ZSH_THEME_GIT_SHOW_UPSTREAM` to any value to display the upstream branch.
- You may also change a number of variables (whose name start with `ZSH_THEME_GIT_PROMPT_`)
to change the appearance of the prompt. Take a look at the bottom of the [plugin file](git-prompt.plugin.zsh)`
to see what variables are available.
**Enjoy!**

View file

@ -0,0 +1,113 @@
# Handle $0 according to the standard:
# https://zdharma-continuum.github.io/Zsh-100-Commits-Club/Zsh-Plugin-Standard.html
0="${${ZERO:-${0:#$ZSH_ARGZERO}}:-${(%):-%N}}"
0="${${(M)0:#/*}:-$PWD/$0}"
__GIT_PROMPT_DIR="${0:A:h}"
## Hook function definitions
function chpwd_update_git_vars() {
update_current_git_vars
}
function preexec_update_git_vars() {
case "$2" in
git*|hub*|gh*|stg*)
__EXECUTED_GIT_COMMAND=1
;;
esac
}
function precmd_update_git_vars() {
if [ -n "$__EXECUTED_GIT_COMMAND" ] || [ ! -n "$ZSH_THEME_GIT_PROMPT_CACHE" ]; then
update_current_git_vars
unset __EXECUTED_GIT_COMMAND
fi
}
autoload -U add-zsh-hook
add-zsh-hook chpwd chpwd_update_git_vars
add-zsh-hook precmd precmd_update_git_vars
add-zsh-hook preexec preexec_update_git_vars
## Function definitions
function update_current_git_vars() {
unset __CURRENT_GIT_STATUS
local gitstatus="$__GIT_PROMPT_DIR/gitstatus.py"
_GIT_STATUS=$(python3 ${gitstatus} 2>/dev/null)
__CURRENT_GIT_STATUS=("${(@s: :)_GIT_STATUS}")
GIT_BRANCH=$__CURRENT_GIT_STATUS[1]
GIT_AHEAD=$__CURRENT_GIT_STATUS[2]
GIT_BEHIND=$__CURRENT_GIT_STATUS[3]
GIT_STAGED=$__CURRENT_GIT_STATUS[4]
GIT_CONFLICTS=$__CURRENT_GIT_STATUS[5]
GIT_CHANGED=$__CURRENT_GIT_STATUS[6]
GIT_UNTRACKED=$__CURRENT_GIT_STATUS[7]
GIT_STASHED=$__CURRENT_GIT_STATUS[8]
GIT_CLEAN=$__CURRENT_GIT_STATUS[9]
GIT_DELETED=$__CURRENT_GIT_STATUS[10]
if [ -z ${ZSH_THEME_GIT_SHOW_UPSTREAM+x} ]; then
GIT_UPSTREAM=
else
GIT_UPSTREAM=$(git rev-parse --abbrev-ref --symbolic-full-name "@{upstream}" 2>/dev/null) && GIT_UPSTREAM="${ZSH_THEME_GIT_PROMPT_UPSTREAM_SEPARATOR}${GIT_UPSTREAM}"
fi
}
git_super_status() {
precmd_update_git_vars
if [ -n "$__CURRENT_GIT_STATUS" ]; then
STATUS="$ZSH_THEME_GIT_PROMPT_PREFIX$ZSH_THEME_GIT_PROMPT_BRANCH$GIT_BRANCH$GIT_UPSTREAM%{${reset_color}%}"
if [ "$GIT_BEHIND" -ne "0" ]; then
STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_BEHIND$GIT_BEHIND%{${reset_color}%}"
fi
if [ "$GIT_AHEAD" -ne "0" ]; then
STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_AHEAD$GIT_AHEAD%{${reset_color}%}"
fi
STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_SEPARATOR"
if [ "$GIT_STAGED" -ne "0" ]; then
STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_STAGED$GIT_STAGED%{${reset_color}%}"
fi
if [ "$GIT_CONFLICTS" -ne "0" ]; then
STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CONFLICTS$GIT_CONFLICTS%{${reset_color}%}"
fi
if [ "$GIT_CHANGED" -ne "0" ]; then
STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CHANGED$GIT_CHANGED%{${reset_color}%}"
fi
if [ "$GIT_DELETED" -ne "0" ]; then
STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_DELETED$GIT_DELETED%{${reset_color}%}"
fi
if [ "$GIT_UNTRACKED" -ne "0" ]; then
STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED$GIT_UNTRACKED%{${reset_color}%}"
fi
if [ "$GIT_STASHED" -ne "0" ]; then
STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_STASHED$GIT_STASHED%{${reset_color}%}"
fi
if [ "$GIT_CLEAN" -eq "1" ]; then
STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_CLEAN"
fi
STATUS="$STATUS%{${reset_color}%}$ZSH_THEME_GIT_PROMPT_SUFFIX"
echo "$STATUS"
fi
}
# Default values for the appearance of the prompt.
ZSH_THEME_GIT_PROMPT_PREFIX="("
ZSH_THEME_GIT_PROMPT_SUFFIX=")"
ZSH_THEME_GIT_PROMPT_SEPARATOR="|"
ZSH_THEME_GIT_PROMPT_BRANCH="%{$fg_bold[magenta]%}"
ZSH_THEME_GIT_PROMPT_STAGED="%{$fg[red]%}%{●%G%}"
ZSH_THEME_GIT_PROMPT_CONFLICTS="%{$fg[red]%}%{✖%G%}"
ZSH_THEME_GIT_PROMPT_CHANGED="%{$fg[blue]%}%{✚%G%}"
ZSH_THEME_GIT_PROMPT_DELETED="%{$fg[blue]%}%{-%G%}"
ZSH_THEME_GIT_PROMPT_BEHIND="%{↓%G%}"
ZSH_THEME_GIT_PROMPT_AHEAD="%{↑%G%}"
ZSH_THEME_GIT_PROMPT_UNTRACKED="%{$fg[cyan]%}%{…%G%}"
ZSH_THEME_GIT_PROMPT_STASHED="%{$fg_bold[blue]%}%{⚑%G%}"
ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[green]%}%{✔%G%}"
ZSH_THEME_GIT_PROMPT_UPSTREAM_SEPARATOR="->"
# Set the prompt.
RPROMPT='$(git_super_status)'

View file

@ -0,0 +1,103 @@
#!/usr/bin/env python3
from __future__ import print_function
import os
import sys
import re
from subprocess import Popen, PIPE, check_output
def get_tagname_or_hash():
"""return tagname if exists else hash"""
# get hash
hash_cmd = ['git', 'rev-parse', '--short', 'HEAD']
hash_ = check_output(hash_cmd).decode('utf-8').strip()
# get tagname
tags_cmd = ['git', 'for-each-ref', '--points-at=HEAD', '--count=2', '--sort=-version:refname', '--format=%(refname:short)', 'refs/tags']
tags = check_output(tags_cmd).decode('utf-8').split()
if tags:
return tags[0] + ('+' if len(tags) > 1 else '')
elif hash_:
return hash_
return None
# Re-use method from https://github.com/magicmonty/bash-git-prompt to get stashs count
def get_stash():
cmd = Popen(['git', 'rev-parse', '--git-dir'], stdout=PIPE, stderr=PIPE)
so, se = cmd.communicate()
stash_file = '%s%s' % (so.decode('utf-8').rstrip(), '/logs/refs/stash')
try:
with open(stash_file) as f:
return sum(1 for _ in f)
except IOError:
return 0
# `git status --porcelain --branch` can collect all information
# branch, remote_branch, untracked, staged, changed, conflicts, ahead, behind
po = Popen(['git', 'status', '--porcelain', '--branch'], env=dict(os.environ, LANG="C"), stdout=PIPE, stderr=PIPE)
stdout, sterr = po.communicate()
if po.returncode != 0:
sys.exit(0) # Not a git repository
# collect git status information
untracked, staged, changed, deleted, conflicts = [], [], [], [], []
ahead, behind = 0, 0
status = [(line[0], line[1], line[2:]) for line in stdout.decode('utf-8').splitlines()]
for st in status:
if st[0] == '#' and st[1] == '#':
if re.search('Initial commit on', st[2]) or re.search('No commits yet on', st[2]):
branch = st[2].split(' ')[-1]
elif re.search('no branch', st[2]): # detached status
branch = get_tagname_or_hash()
elif len(st[2].strip().split('...')) == 1:
branch = st[2].strip()
else:
# current and remote branch info
branch, rest = st[2].strip().split('...')
if len(rest.split(' ')) == 1:
# remote_branch = rest.split(' ')[0]
pass
else:
# ahead or behind
divergence = ' '.join(rest.split(' ')[1:])
divergence = divergence.lstrip('[').rstrip(']')
for div in divergence.split(', '):
if 'ahead' in div:
ahead = int(div[len('ahead '):].strip())
elif 'behind' in div:
behind = int(div[len('behind '):].strip())
elif st[0] == '?' and st[1] == '?':
untracked.append(st)
else:
if st[1] == 'M':
changed.append(st)
if st[1] == 'D':
deleted.append(st)
if st[0] == 'U':
conflicts.append(st)
elif st[0] != ' ':
staged.append(st)
stashed = get_stash()
if not changed and not deleted and not staged and not conflicts and not untracked:
clean = 1
else:
clean = 0
out = ' '.join([
branch,
str(ahead),
str(behind),
str(len(staged)),
str(len(conflicts)),
str(len(changed)),
str(len(untracked)),
str(stashed),
str(clean),
str(len(deleted))
])
print(out, end='')