aboutsummaryrefslogtreecommitdiff
path: root/shell/zsh
diff options
context:
space:
mode:
authorbozo.kopic <bozo@kopic.xyz>2020-12-16 02:12:41 +0100
committerbozo.kopic <bozo@kopic.xyz>2020-12-16 02:12:41 +0100
commit004162c05e42a2f2645ca06702567967b1d88961 (patch)
tree18319b9654b8ec561524a58fed0fd3af7131647e /shell/zsh
parent2f694c9ab1416de12d6c5da47d384a625662edf1 (diff)
.
Diffstat (limited to 'shell/zsh')
-rw-r--r--shell/zsh/.zshrc12
-rw-r--r--shell/zsh/zsh-git-prompt/LICENSE.md21
-rw-r--r--shell/zsh/zsh-git-prompt/README.md93
-rwxr-xr-xshell/zsh/zsh-git-prompt/gitstatus.py65
-rw-r--r--shell/zsh/zsh-git-prompt/zshrc.sh108
5 files changed, 299 insertions, 0 deletions
diff --git a/shell/zsh/.zshrc b/shell/zsh/.zshrc
new file mode 100644
index 0000000..6d0d4ef
--- /dev/null
+++ b/shell/zsh/.zshrc
@@ -0,0 +1,12 @@
+HISTFILE=~/.zsh_history
+HISTSIZE=1000
+SAVEHIST=1000
+
+bindkey -v
+
+autoload -Uz compinit
+compinit
+
+. ~/.dotfiles/shell/zsh/zsh-git-prompt/zshrc.sh
+
+PROMPT='[%F{green}%n%f@%m %F{green}%~%f $(git_super_status)]$ '
diff --git a/shell/zsh/zsh-git-prompt/LICENSE.md b/shell/zsh/zsh-git-prompt/LICENSE.md
new file mode 100644
index 0000000..cba6fbc
--- /dev/null
+++ b/shell/zsh/zsh-git-prompt/LICENSE.md
@@ -0,0 +1,21 @@
+The MIT License (MIT)
+
+Copyright (c) 2014 Olivier Verdier
+
+Permission is hereby granted, free of charge, to any person obtaining a copy
+of this software and associated documentation files (the "Software"), to deal
+in the Software without restriction, including without limitation the rights
+to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
+copies of the Software, and to permit persons to whom the Software is
+furnished to do so, subject to the following conditions:
+
+The above copyright notice and this permission notice shall be included in all
+copies or substantial portions of the Software.
+
+THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
+AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
+OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
+SOFTWARE.
diff --git a/shell/zsh/zsh-git-prompt/README.md b/shell/zsh/zsh-git-prompt/README.md
new file mode 100644
index 0000000..668726c
--- /dev/null
+++ b/shell/zsh/zsh-git-prompt/README.md
@@ -0,0 +1,93 @@
+# Informative git prompt for zsh
+
+[![Build Status](https://travis-ci.org/olivierverdier/zsh-git-prompt.svg)](https://travis-ci.org/olivierverdier/zsh-git-prompt)
+
+A `zsh` prompt that displays information about the current git repository. In particular the branch name, difference with remote branch, number of files staged, changed, etc.
+
+(an original idea from this [blog post][]).
+
+## 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
+
+Here is how it could look like when you are ahead by 4 commits, behind by 5 commits, and have 1 staged files, 1 changed but unstaged file, and some untracked files, on branch `dev`:
+
+
+<img src="https://github.com/olivierverdier/zsh-git-prompt/raw/master/screenshot.png" width=300/>
+
+
+## Prompt Structure
+
+By default, the general appearance of the prompt is:
+
+```
+(<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` changed but *unstaged* files
+|… | 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
+
+### Branch Symbol
+
+When the branch name starts with a colon `:`, it means it’s actually a hash, not a branch (although it should be pretty clear, unless you name your branches like hashes :-)
+
+## Install
+
+1. Clone this repository somewhere on your hard drive.
+2. Source the file `zshrc.sh` from your `~/.zshrc` config file, and
+ configure your prompt. So, somewhere in `~/.zshrc`, you should have:
+
+ ```sh
+ source path/to/zshrc.sh
+ # an example prompt
+ PROMPT='%B%m%~%b$(git_super_status) %# '
+ ```
+3. Go in a git repository and test it!
+
+### Haskell (optional)
+
+There is now a Haskell implementation as well, which can be four to six times faster than the Python one. The reason is not that Haskell is faster in itself (although it is), but that this implementation calls `git` only once. To install, do the following:
+
+1. Make sure [Haskell's stack](http://docs.haskellstack.org/en/stable/README.html#how-to-install) is installed on your system
+2. `cd` to this folder
+2. Run `stack setup` to install the Haskell compiler, if it is not already there
+3. Run `stack build && stack install` (don't worry, the executable is only “installed” in this folder, not on your system)
+4. Define the variable `GIT_PROMPT_EXECUTABLE="haskell"` somewhere in
+ your `.zshrc`
+
+## Customisation
+
+- You may redefine the function `git_super_status` (after the `source` statement) to adapt it to your needs (to change the order in which the information is displayed).
+- Define the variable `ZSH_THEME_GIT_PROMPT_CACHE` in order to enable caching.
+- You may also change a number of variables (which name start with `ZSH_THEME_GIT_PROMPT_`) to change the appearance of the prompt. Take a look in the file `zshrc.sh` to see how the function `git_super_status` is defined, and what variables are available.
+
+**Enjoy!**
+
+ [blog post]: http://sebastiancelis.com/2009/nov/16/zsh-prompt-git-users/
+
diff --git a/shell/zsh/zsh-git-prompt/gitstatus.py b/shell/zsh/zsh-git-prompt/gitstatus.py
new file mode 100755
index 0000000..d944fd4
--- /dev/null
+++ b/shell/zsh/zsh-git-prompt/gitstatus.py
@@ -0,0 +1,65 @@
+#!/usr/bin/env python
+from __future__ import print_function
+
+# change this symbol to whatever you prefer
+prehash = ':'
+
+from subprocess import Popen, PIPE
+
+import sys
+gitsym = Popen(['git', 'symbolic-ref', 'HEAD'], stdout=PIPE, stderr=PIPE)
+branch, error = gitsym.communicate()
+
+error_string = error.decode('utf-8')
+
+if 'fatal: Not a git repository' in error_string:
+ sys.exit(0)
+
+branch = branch.decode("utf-8").strip()[11:]
+
+res, err = Popen(['git','diff','--name-status'], stdout=PIPE, stderr=PIPE).communicate()
+err_string = err.decode('utf-8')
+if 'fatal' in err_string:
+ sys.exit(0)
+changed_files = [namestat[0] for namestat in res.decode("utf-8").splitlines()]
+staged_files = [namestat[0] for namestat in Popen(['git','diff', '--staged','--name-status'], stdout=PIPE).communicate()[0].splitlines()]
+nb_changed = len(changed_files) - changed_files.count('U')
+nb_U = staged_files.count('U')
+nb_staged = len(staged_files) - nb_U
+staged = str(nb_staged)
+conflicts = str(nb_U)
+changed = str(nb_changed)
+nb_untracked = len([0 for status in Popen(['git','status','--porcelain',],stdout=PIPE).communicate()[0].decode("utf-8").splitlines() if status.startswith('??')])
+untracked = str(nb_untracked)
+
+ahead, behind = 0,0
+
+if not branch: # not on any branch
+ branch = prehash + Popen(['git','rev-parse','--short','HEAD'], stdout=PIPE).communicate()[0].decode("utf-8")[:-1]
+else:
+ remote_name = Popen(['git','config','branch.%s.remote' % branch], stdout=PIPE).communicate()[0].decode("utf-8").strip()
+ if remote_name:
+ merge_name = Popen(['git','config','branch.%s.merge' % branch], stdout=PIPE).communicate()[0].decode("utf-8").strip()
+ if remote_name == '.': # local
+ remote_ref = merge_name
+ else:
+ remote_ref = 'refs/remotes/%s/%s' % (remote_name, merge_name[11:])
+ revgit = Popen(['git', 'rev-list', '--left-right', '%s...HEAD' % remote_ref],stdout=PIPE, stderr=PIPE)
+ revlist = revgit.communicate()[0]
+ if revgit.poll(): # fallback to local
+ revlist = Popen(['git', 'rev-list', '--left-right', '%s...HEAD' % merge_name],stdout=PIPE, stderr=PIPE).communicate()[0]
+ behead = revlist.decode("utf-8").splitlines()
+ ahead = len([x for x in behead if x[0]=='>'])
+ behind = len(behead) - ahead
+
+out = ' '.join([
+ branch,
+ str(ahead),
+ str(behind),
+ staged,
+ conflicts,
+ changed,
+ untracked,
+ ])
+print(out, end='')
+
diff --git a/shell/zsh/zsh-git-prompt/zshrc.sh b/shell/zsh/zsh-git-prompt/zshrc.sh
new file mode 100644
index 0000000..d4010c1
--- /dev/null
+++ b/shell/zsh/zsh-git-prompt/zshrc.sh
@@ -0,0 +1,108 @@
+# To install source this file from your .zshrc file
+
+# see documentation at http://linux.die.net/man/1/zshexpn
+# A: finds the absolute path, even if this is symlinked
+# h: equivalent to dirname
+export __GIT_PROMPT_DIR=${0:A:h}
+
+export GIT_PROMPT_EXECUTABLE=${GIT_PROMPT_EXECUTABLE:-"python"}
+
+# Initialize colors.
+autoload -U colors
+colors
+
+# Allow for functions in the prompt.
+setopt PROMPT_SUBST
+
+autoload -U add-zsh-hook
+
+add-zsh-hook chpwd chpwd_update_git_vars
+add-zsh-hook preexec preexec_update_git_vars
+add-zsh-hook precmd precmd_update_git_vars
+
+## Function definitions
+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
+}
+
+function chpwd_update_git_vars() {
+ update_current_git_vars
+}
+
+function update_current_git_vars() {
+ unset __CURRENT_GIT_STATUS
+
+ if [[ "$GIT_PROMPT_EXECUTABLE" == "python" ]]; then
+ local gitstatus="$__GIT_PROMPT_DIR/gitstatus.py"
+ _GIT_STATUS=`python ${gitstatus} 2>/dev/null`
+ fi
+ if [[ "$GIT_PROMPT_EXECUTABLE" == "haskell" ]]; then
+ _GIT_STATUS=`git status --porcelain --branch &> /dev/null | $__GIT_PROMPT_DIR/src/.bin/gitstatus`
+ fi
+ __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_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%{${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_UNTRACKED" -ne "0" ]; then
+ STATUS="$STATUS$ZSH_THEME_GIT_PROMPT_UNTRACKED%{${reset_color}%}"
+ fi
+ if [ "$GIT_CHANGED" -eq "0" ] && [ "$GIT_CONFLICTS" -eq "0" ] && [ "$GIT_STAGED" -eq "0" ] && [ "$GIT_UNTRACKED" -eq "0" ]; 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. Configure at will.
+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_BEHIND="%{↓%G%}"
+ZSH_THEME_GIT_PROMPT_AHEAD="%{↑%G%}"
+ZSH_THEME_GIT_PROMPT_UNTRACKED="%{…%G%}"
+ZSH_THEME_GIT_PROMPT_CLEAN="%{$fg_bold[green]%}%{✔%G%}"
+
+