Skip to content

Instantly share code, notes, and snippets.

@eu81273
Last active July 26, 2018 04:02
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save eu81273/f816ab71cd8dd6fc794c62c36cc44a0f to your computer and use it in GitHub Desktop.
Save eu81273/f816ab71cd8dd6fc794c62c36cc44a0f to your computer and use it in GitHub Desktop.
bash shell에서 powerline 과 같은 효과
#!/usr/bin/env bash
# Powerline
# https://github.com/powerline/powerline
# JS 버전
# https://github.com/ceejbot/powerline-js
# Python 버전
# https://github.com/banga/powerline-shell
# for c in {0..255}; do tput setaf $c; tput setaf $c | cat -v; echo =$c; done
powerline() {
# Unicode symbols
readonly PS_SYMBOL_DARWIN='$'
readonly PS_SYMBOL_LINUX='$'
readonly PS_SYMBOL_OTHER='%'
readonly GIT_BRANCH_SYMBOL=''
readonly GIT_BRANCH_CHANGED_SYMBOL='✔'
readonly GIT_BRANCH_UNCHANGED_SYMBOL='✎'
readonly GIT_NO_REMOTE_SYMBOL='✕'
readonly GIT_REMOTE_FETCH_SYMBOL='↻'
readonly GIT_REMOTE_CHECK_INTERVAL=300
readonly GIT_NEED_PUSH_SYMBOL='⇡'
readonly GIT_NEED_PULL_SYMBOL='⇣'
readonly SYMBOL_ARROW=''
readonly SYMBOL_ARROW_HEAD=''
readonly FG_WHITE="\[$(tput setaf 15)\]"
readonly FG_BLACK="\[$(tput setaf 0)\]"
readonly FG_YELLOW="\[$(tput setaf 3)\]"
readonly FG_ORANGE="\[$(tput setaf 9)\]"
readonly FG_RED="\[$(tput setaf 1)\]"
readonly FG_MAGENTA="\[$(tput setaf 5)\]"
readonly FG_VIOLET="\[$(tput setaf 13)\]"
readonly FG_BLUE="\[$(tput setaf 4)\]"
readonly FG_CYAN="\[$(tput setaf 6)\]"
readonly FG_GREEN="\[$(tput setaf 2)\]"
readonly FG_GRAY="\[$(tput setaf 235)\]"
readonly BG_YELLOW="\[$(tput setab 3)\]"
readonly BG_ORANGE="\[$(tput setab 9)\]"
readonly BG_RED="\[$(tput setab 1)\]"
readonly BG_MAGENTA="\[$(tput setab 5)\]"
readonly BG_VIOLET="\[$(tput setab 13)\]"
readonly BG_BLUE="\[$(tput setab 4)\]"
readonly BG_CYAN="\[$(tput setab 6)\]"
readonly BG_GREEN="\[$(tput setab 2)\]"
readonly BG_GRAY="\[$(tput setab 241)\]"
readonly DIM="\[$(tput dim)\]"
readonly REVERSE="\[$(tput rev)\]"
readonly RESET="\[$(tput sgr0)\]"
readonly BOLD="\[$(tput bold)\]"
# what OS?
case "$(uname)" in
Darwin)
readonly PS_SYMBOL=$PS_SYMBOL_DARWIN
;;
Linux)
readonly PS_SYMBOL=$PS_SYMBOL_LINUX
;;
*)
readonly PS_SYMBOL=$PS_SYMBOL_OTHER
esac
git_status() {
# git not found
[ -x "$(which git)" ] || return
# force git output in English to make our work easier
local GIT_ENGLISH="env LANG=C git"
# get current CURRENT_BRANCH name or short SHA1 hash for detached head
# name-rev --name-only HEAD
# rev-parse --abbrev-ref HEAD
# symbolic-ref --short HEAD
# || $GIT_ENGLISH describe --tags --always 2>/dev/null
# TODO 정확한 브랜치명 가져오도록 변경 필요
local CURRENT_BRANCH="$($GIT_ENGLISH rev-parse --abbrev-ref HEAD 2>/dev/null)"
[ -n "$CURRENT_BRANCH" ] || return # git branch not found
# branch is modified?
local STATUS_MARKS
if [ -n "$($GIT_ENGLISH status --porcelain)" ]
then
STATUS_MARKS+="$GIT_BRANCH_UNCHANGED_SYMBOL "
else
STATUS_MARKS+="$GIT_BRANCH_CHANGED_SYMBOL "
fi
# remote check
if [[ -n $($GIT_ENGLISH remote show) ]]
then
# 현재 REPO_PATH
local REPO_PATH=$($GIT_ENGLISH rev-parse --show-toplevel 2>/dev/null)
# 현재 repo 의 FETCH_HEAD
local FETCH_HEAD="$REPO_PATH/.git/FETCH_HEAD"
# 현재 시각
local TIME_NOW=`date '+%s' 2>/dev/null`
# 마지막 fetch 시각
if [[ "$(uname)" == 'Darwin' ]]
then
local TIME_FETCH=`stat -f '%m' $FETCH_HEAD 2>/dev/null`
else
local TIME_FETCH=`stat -c %Y $FETCH_HEAD 2>/dev/null`
fi
if (( $TIME_NOW - $TIME_FETCH - $GIT_REMOTE_CHECK_INTERVAL > 0 ))
then
# echo "업데이트한지 5분 지남"
# 생각해보니 또 enter 쳐도 반복되면 안되니 바로 touch 한번 해주고
touch $FETCH_HEAD
STATUS_MARKS+="$GIT_REMOTE_FETCH_SYMBOL "
# 현재 repo 의 remote
local REMOTE_URL=$($GIT_ENGLISH config --get remote.origin.url 2>/dev/null)
# git ls-remote --get-url
if [[ $REMOTE_URL =~ git@.* ]]
then
local REMOTE_HOST=`expr "$REMOTE_URL" : '.*@\([^/:]*\)'`
else
local REMOTE_HOST=`expr "$REMOTE_URL" : '.*//\([^/]*\)'`
fi
{
if wget --quiet -T 1 -t 1 --spider ${REMOTE_HOST} >/dev/null
then
$GIT_ENGLISH fetch --quiet --prune >/dev/null
fi
} > /dev/null 2>&1 & disown
else
# echo "5분 이내 업데이트한 상황.."
# how many commits local branch is ahead/behind of remote?
local STATUS="$($GIT_ENGLISH status --porcelain --branch | grep '^##' | grep -o '\[.\+\]$')"
local AHEAD_N="$(echo $STATUS | grep -o 'ahead [[:digit:]]\+' | grep -o '[[:digit:]]\+')"
local BEHIND_N="$(echo $STATUS | grep -o 'behind [[:digit:]]\+' | grep -o '[[:digit:]]\+')"
[ -n "$AHEAD_N" ] && STATUS_MARKS+="$GIT_NEED_PUSH_SYMBOL $AHEAD_N "
[ -n "$BEHIND_N" ] && STATUS_MARKS+="$GIT_NEED_PULL_SYMBOL $BEHIND_N "
fi
else
# echo "리모트 없는 로컬 프로젝트"
STATUS_MARKS+="$GIT_NO_REMOTE_SYMBOL "
fi
# print the git branch segment without a trailing newline
printf "$GIT_BRANCH_SYMBOL $CURRENT_BRANCH $STATUS_MARKS"
}
# PS1 환경변수에 쉘 형태를 정의 가능
# http://webdir.tistory.com/105
ps1() {
# Check the exit code of the previous command and display different
# colors in the prompt accordingly.
if [ $? -eq 0 ]; then
local FG_EXIT="$FG_BLACK"
else
local FG_EXIT="$FG_RED"
fi
local GIT_STATUS="$(git_status)"
local CURRENT_PATH="$BG_YELLOW$FG_WHITE \w "
local CURRENT_EXIT="$FG_EXIT$PS_SYMBOL "
local EDGE="$RESET$FG_GRAY$SYMBOL_ARROW $RESET"
if [[ -n $GIT_STATUS ]]; then
local PATH_GIT_BRIDGE="$RESET$FG_YELLOW$BG_BLUE$SYMBOL_ARROW "
local CURRENT_GIT_STATUS="$FG_BLACK$GIT_STATUS "
local GIT_EXIT_BRIDGE="$RESET$FG_BLUE$BG_GRAY$SYMBOL_ARROW "
PS1="\n$CURRENT_PATH$PATH_GIT_BRIDGE$CURRENT_GIT_STATUS$GIT_EXIT_BRIDGE$CURRENT_EXIT$EDGE"
else
local PATH_EDGE_BRIDGE="$RESET$FG_YELLOW$BG_GRAY$SYMBOL_ARROW "
PS1="$CURRENT_PATH$PATH_EDGE_BRIDGE$CURRENT_EXIT$EDGE"
fi
}
# 프롬프트마다 실행할 함수를 지정
PROMPT_COMMAND=ps1
}
powerline
unset powerline
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment