mirror of
https://github.com/kazhala/dotbare
synced 2024-11-13 13:10:35 +00:00
217 lines
7.5 KiB
Bash
217 lines
7.5 KiB
Bash
#!/usr/bin/env bash
|
|
#
|
|
# helper functions to obtain git related information
|
|
|
|
#######################################
|
|
# let user select a commit interactively
|
|
# credit to forgit for the git log format
|
|
# Arguments:
|
|
# $1: the helper message to display in the fzf header
|
|
# $2: files to show diff against HEAD
|
|
# Outputs:
|
|
# the selected commit 6 char code
|
|
# e.g. b60b330
|
|
#######################################
|
|
# TODO: line33 "${files[*]}" cannot handle space in file names, but "${files[@]}" won't get properly
|
|
# processed by git for whatever reason just in this preview situation but works every where else, HELP needed.
|
|
# although this won't affect any real functionality or break the code, it will just print a error message in preview.
|
|
function get_commit() {
|
|
local header="${1:-select a commit}"
|
|
local files=("${@:2}")
|
|
if [[ "${#files[@]}" -eq 0 ]]; then
|
|
git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" \
|
|
log --color=always --format='%C(auto)%h%d %s %C(black)%C(bold)%cr' \
|
|
| fzf --header="${header}" --no-multi \
|
|
--preview "echo {} \
|
|
| awk '{print \$1}' \
|
|
| xargs -I __ git --git-dir=${DOTBARE_DIR} --work-tree=${DOTBARE_TREE} \
|
|
show --color=always __ \
|
|
| ${DOTBARE_DIFF_PAGER}" \
|
|
| awk '{print $1}'
|
|
else
|
|
git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" \
|
|
log --oneline --color=always --decorate=short \
|
|
| fzf --header="${header}" --no-multi --preview "echo {} \
|
|
| awk '{print \$1}' \
|
|
| xargs -I __ git --git-dir=${DOTBARE_DIR} --work-tree=${DOTBARE_TREE} \
|
|
diff --color=always __ ${files[*]} \
|
|
| ${DOTBARE_DIFF_PAGER}" \
|
|
| awk '{print $1}'
|
|
fi
|
|
}
|
|
|
|
#######################################
|
|
# let user select a branch interactively
|
|
# Arguments:
|
|
# $1: the helper message to display in the fzf header
|
|
# Outputs:
|
|
# the selected branch name
|
|
# e.g. master
|
|
#######################################
|
|
function get_branch() {
|
|
local header="${1:-select a branch}"
|
|
git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" branch -a \
|
|
| awk '{
|
|
if ($0 ~ /\*.*\(HEAD.*/) {
|
|
gsub(/\* /, "", $0)
|
|
print "\033[32m" $0 "\033[0m"
|
|
} else if (match($1, "\\*") != 0) {
|
|
print "\033[32m" $2 "\033[0m"
|
|
} else if ($0 ~ /^[ \t]+remotes\/.*/) {
|
|
gsub(/[ \t]+/, "", $0)
|
|
print "\033[31m" $0 "\033[0m"
|
|
} else {
|
|
gsub(/^[ \t]+/, "", $0)
|
|
print $0
|
|
}
|
|
}' \
|
|
| fzf --no-multi --header="${header}" \
|
|
--preview="echo {} \
|
|
| awk '{
|
|
if (\$0 ~ /.*HEAD.*/) {
|
|
print \"HEAD\"
|
|
} else {
|
|
print \$0
|
|
}
|
|
}' \
|
|
| xargs -I __ git --git-dir=${DOTBARE_DIR} --work-tree=${DOTBARE_TREE} \
|
|
log --color=always --color=always --format='%C(auto)%h%d %s %C(black)%C(bold)%cr' __"
|
|
}
|
|
|
|
#######################################
|
|
# let user select a dotbare tracked file interactively
|
|
# Arguments:
|
|
# $1: the helper message to display in the fzf header
|
|
# $2: print option, values (full|raw)
|
|
# $3: if exist, don't do multi selection, do single
|
|
# Outputs:
|
|
# the selected file path
|
|
# e.g.$HOME/.config/nvim/init.vim
|
|
#######################################
|
|
function get_git_file() {
|
|
local mydir
|
|
local header="${1:-select tracked file}"
|
|
local print_opt="${2:-full}"
|
|
mydir="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
|
|
set_fzf_multi "$3"
|
|
git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" \
|
|
ls-files --full-name --directory "${DOTBARE_TREE}" \
|
|
| fzf --header="${header}" \
|
|
--preview "${mydir}/../helper/preview.sh ${DOTBARE_TREE}/{}" \
|
|
| awk -v home="${DOTBARE_TREE}" -v print_opt="${print_opt}" '{
|
|
if (print_opt == "full") {
|
|
print home "/" $0
|
|
} else {
|
|
print $0
|
|
}
|
|
}'
|
|
}
|
|
|
|
#######################################
|
|
# let user select a modified file interactively
|
|
# Arguments:
|
|
# $1: the helper message to display in the fzf header
|
|
# $2: display mode of modified files.
|
|
# default: true
|
|
# all: display all modified, include staged and unstaged
|
|
# staged: display only staged files
|
|
# unstaged: display only unstaged files
|
|
# $3: output_format
|
|
# default: name
|
|
# name: formatted name of the file
|
|
# raw: raw file name with status
|
|
# $4: if exists, don't do multi selection, do single
|
|
# Outputs:
|
|
# the selected file path
|
|
# e.g.$HOME/.config/nvim/init.vim
|
|
#######################################
|
|
function get_modified_file() {
|
|
local header="${1:-select a modified file}"
|
|
local display_mode="${2:-all}"
|
|
local output_format="${3:-name}"
|
|
set_fzf_multi "$4"
|
|
git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" \
|
|
status --porcelain \
|
|
| awk -v display_mode="${display_mode}" '{
|
|
if ($0 ~ /^[A-Za-z][A-Za-z].*$/) {
|
|
print "\033[32m" substr($0, 1, 1) "\033[31m" substr($0, 2) "\033[0m"
|
|
} else if ($0 ~ /^[A-Za-z][ \t].*$/) {
|
|
if (display_mode == "all" || display_mode == "staged") {
|
|
print "\033[32m" $0 "\033[0m"
|
|
}
|
|
} else {
|
|
if (display_mode == "all" || display_mode == "unstaged") {
|
|
print "\033[31m" $0 "\033[0m"
|
|
}
|
|
}
|
|
}' \
|
|
| fzf --header="${header}" --preview "echo {} \
|
|
| awk '{sub(\$1 FS,\"\");print \$0}' \
|
|
| xargs -I __ git --git-dir=${DOTBARE_DIR} --work-tree=${DOTBARE_TREE} \
|
|
diff HEAD --color=always -- ${DOTBARE_TREE}/__ \
|
|
| ${DOTBARE_DIFF_PAGER}" \
|
|
| awk -v home="${DOTBARE_TREE}" -v format="${output_format}" '{
|
|
if (format == "name") {
|
|
$1=""
|
|
gsub(/^[ \t]/, "", $0)
|
|
gsub(/"/, "", $0)
|
|
print home "/" $0
|
|
} else {
|
|
print $0
|
|
}
|
|
}'
|
|
}
|
|
|
|
#######################################
|
|
# let user select a stash interactively
|
|
# Arguments:
|
|
# $1: the helpe message to display in header
|
|
# $2: if exists, don't do multi select, only allow single selection
|
|
# Outputs:
|
|
# the selected stash identifier
|
|
# e.g. stash@{0}
|
|
#######################################
|
|
function get_stash() {
|
|
local header="${1:-select a stash}"
|
|
set_fzf_multi "$2"
|
|
git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" \
|
|
stash list \
|
|
| fzf --header="${header}" --preview "echo {} \
|
|
| awk '{
|
|
gsub(/:/, \"\", \$1)
|
|
print \$1
|
|
}' \
|
|
| xargs -I __ git --git-dir=${DOTBARE_DIR} --work-tree=${DOTBARE_TREE} \
|
|
stash show -p __ --color=always \
|
|
| ${DOTBARE_DIFF_PAGER}" \
|
|
| awk '{
|
|
gsub(/:/, "", $1)
|
|
print $1
|
|
}'
|
|
}
|
|
|
|
#######################################
|
|
# Using git grep to find word within
|
|
# all tracked files in the bare repo.
|
|
# Arguments:
|
|
# $1: the help message to display in header
|
|
# $2: the fzf delimiter to start searching, default is 3
|
|
# $3: if exists, don't do multi select, only allow single selection
|
|
# Outputs:
|
|
# the selected file name with it's line number and line, seperated by ":"
|
|
# e.g. .bash_profile:1:echo hello
|
|
#######################################
|
|
function grep_words() {
|
|
local header="${1:-select matches to edit}"
|
|
local delimiter="${2:-3}"
|
|
set_fzf_multi "$2"
|
|
cd "${DOTBARE_TREE}" || exit
|
|
git --git-dir="${DOTBARE_DIR}" --work-tree="${DOTBARE_TREE}" \
|
|
grep --line-number -- . \
|
|
| fzf --delimiter : --nth "${delimiter}".. --header="${header}" \
|
|
--preview "${mydir}/../helper/preview.sh ${DOTBARE_TREE}/{}" \
|
|
| awk -F ":" -v home="${DOTBARE_TREE}" '{
|
|
print home "/" $1 ":" $2
|
|
}'
|
|
}
|