From e8b008c08b494ac0187066f52f58defb85a8aa0d Mon Sep 17 00:00:00 2001 From: Christopher Apple Date: Sat, 2 Nov 2019 20:51:25 -0600 Subject: [PATCH 1/6] starting getting fish added to forgit --- forgit.plugin.fish | 225 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 225 insertions(+) create mode 100755 forgit.plugin.fish diff --git a/forgit.plugin.fish b/forgit.plugin.fish new file mode 100755 index 0000000..9938b0c --- /dev/null +++ b/forgit.plugin.fish @@ -0,0 +1,225 @@ +#!/usr/local/bin/fish +# MIT (c) Wenxuan Zhang + +function forgit::warn + printf "%b[Warn]%b %s\n" '\e[0;33m' '\e[0m' "$argv" >&2; +end + +function forgit::info + printf "%b[Info]%b %s\n" '\e[0;32m' '\e[0m' "$argv" >&2; +end + +function forgit::inside_work_tree + git rev-parse --is-inside-work-tree >/dev/null; +end + +# https://github.com/so-fancy/diff-so-fancy +hash diff-so-fancy >/dev/null 2>&1 && set forgit_fancy '|diff-so-fancy' +# https://github.com/wfxr/emoji-cli +hash emojify >/dev/null 2>&1 && set forgit_emojify '|emojify' + + +# git commit viewer +function forgit::log + forgit::inside_work_tree || return 1 + set cmd "echo {} |grep -Eo '[a-f0-9]+' |head -1 |xargs -I% git show --color=always % $argv $forgit_fancy" + set opts " + $FORGIT_FZF_DEFAULT_OPTS + +s +m --tiebreak=index --preview=\"$cmd\" + --bind=\"enter:execute($cmd |LESS='-R' less)\" + --bind=\"ctrl-y:execute-silent(echo {} |grep -Eo '[a-f0-9]+' | head -1 | tr -d '\n' | pbcopy)\" + $FORGIT_LOG_FZF_OPTS + " + #TODO: removed option for another pbcopy above + eval "git log --graph --color=always --format='%C(auto)%h%d %s %C(black)%C(bold)%cr' $argv $forgit_emojify" | + env FZF_DEFAULT_OPTS "$opts" fzf +end + +## git diff viewer +function forgit::diff + forgit::inside_work_tree || return 1 + if not count $argv > /dev/null + if git rev-parse "$1" > /dev/null 2>&1 + #set commit "$1" && set files ("${@:2}") + set commit "$1" && set files "$2" + else + set files "$argv" + end + end + + set cmd "git diff --color=always $commit -- {} $forgit_fancy" + set opts " + $FORGIT_FZF_DEFAULT_OPTS + +m -0 --preview=\"$cmd\" --bind=\"enter:execute($cmd |env LESS='-R' less)\" + $FORGIT_DIFF_FZF_OPTS + " + set cmd "echo" && hash realpath > /dev/null 2>&1 && set cmd "realpath --relative-to=." + #eval "git diff --name-only $commit -- ${files[*]}| xargs -I% $cmd '$(git rev-parse --show-toplevel)/%'"| + set git_rev_parse (git rev-parse --show-toplevel) + eval "git diff --name-only $commit -- $files*| xargs -I% $cmd '$git_rev_parse/%'"| + env FZF_DEFAULT_OPTS="$opts" fzf +end + +# git add selector +function forgit::add + forgit::inside_work_tree || return 1 + set changed (git config --get-color color.status.changed red) + set unmerged (git config --get-color color.status.unmerged red) + set untracked (git config --get-color color.status.untracked red) + + set opts " + $FORGIT_FZF_DEFAULT_OPTS + -0 -m --nth 2..,.. + --preview=\"git diff --color=always -- {-1} $forgit_fancy\" + $FORGIT_ADD_FZF_OPTS + " + set files (git -c color.status=always -c status.relativePaths=true status --short | + grep -F -e "$changed" -e "$unmerged" -e "$untracked" | + awk '{printf "[%10s] ", $1; $1=""; print $0}' | + env FZF_DEFAULT_OPTS="$opts" fzf | cut -d] -f2 | + sed 's/.* -> //') # for rename case + if test -n $files + echo "$files" |xargs -I{} git add {} && git status --short && return + end + echo 'Nothing to add.' +end + +## git reset HEAD (unstage) selector +function forgit::reset::head + forgit::inside_work_tree || return 1 + set cmd "git diff --cached --color=always -- {} $forgit_fancy" + set opts " + $FORGIT_FZF_DEFAULT_OPTS + -m -0 --preview=\"$cmd\" + $FORGIT_RESET_HEAD_FZF_OPTS + " + set files "(git diff --cached --name-only --relative | env FZF_DEFAULT_OPTS="$opts" fzf)" + if test -n $files + echo "$files" |xargs -I{} git reset -q HEAD {} && git status --short && return + end + echo 'Nothing to unstage.' +end + +## git checkout-restore selector +#forgit::restore() { +# forgit::inside_work_tree || return 1 +# local cmd files opts +# cmd="git diff --color=always -- {} $forgit_fancy" +# opts=" +# $FORGIT_FZF_DEFAULT_OPTS +# -m -0 --preview=\"$cmd\" +# $FORGIT_CHECKOUT_FZF_OPTS +# " +# files="$(git ls-files --modified "$(git rev-parse --show-toplevel)"| FZF_DEFAULT_OPTS="$opts" fzf)" +# [[ -n "$files" ]] && echo "$files" |xargs -I{} git checkout {} && git status --short && return +# echo 'Nothing to restore.' +#} +# +## git stash viewer +#forgit::stash::show() { +# forgit::inside_work_tree || return 1 +# local cmd opts +# cmd="git stash show \$(echo {}| cut -d: -f1) --color=always --ext-diff $forgit_fancy" +# opts=" +# $FORGIT_FZF_DEFAULT_OPTS +# +s +m -0 --tiebreak=index --preview=\"$cmd\" --bind=\"enter:execute($cmd |LESS='-R' less)\" +# $FORGIT_STASH_FZF_OPTS +# " +# git stash list | FZF_DEFAULT_OPTS="$opts" fzf +#} +# +## git clean selector +#forgit::clean() { +# forgit::inside_work_tree || return 1 +# local files opts +# opts=" +# $FORGIT_FZF_DEFAULT_OPTS +# -m -0 +# $FORGIT_CLEAN_FZF_OPTS +# " +# # Note: Postfix '/' in directory path should be removed. Otherwise the directory itself will not be removed. +# files=$(git clean -xdfn "$argv"| awk '{print $3}'| FZF_DEFAULT_OPTS="$opts" fzf |sed 's#/$##') +# [[ -n "$files" ]] && echo "$files" |xargs -I% git clean -xdf % && return +# echo 'Nothing to clean.' +#} +# +## git ignore generator +#export FORGIT_GI_REPO_REMOTE=${FORGIT_GI_REPO_REMOTE:-https://github.com/dvcs/gitignore} +#export FORGIT_GI_REPO_LOCAL=${FORGIT_GI_REPO_LOCAL:-~/.forgit/gi/repos/dvcs/gitignore} +#export FORGIT_GI_TEMPLATES=${FORGIT_GI_TEMPLATES:-$FORGIT_GI_REPO_LOCAL/templates} +# +#forgit::ignore() { +# [ -d "$FORGIT_GI_REPO_LOCAL" ] || forgit::ignore::update +# local IFS cmd args cat opts +# # https://github.com/sharkdp/bat.git +# hash bat > /dev/null 2>&1 && cat='bat -l gitignore --color=always' || cat="cat" +# cmd="$cat $FORGIT_GI_TEMPLATES/{2}{,.gitignore} 2>/dev/null" +# opts=" +# $FORGIT_FZF_DEFAULT_OPTS +# -m --preview=\"$cmd\" --preview-window='right:70%' +# $FORGIT_IGNORE_FZF_OPTS +# " +# # shellcheck disable=SC2206,2207 +# IFS=$'\n' args=($argv) && [[ $# -eq 0 ]] && args=($(forgit::ignore::list | nl -nrn -w4 -s' ' | +# FZF_DEFAULT_OPTS="$opts" fzf |awk '{print $2}')) +# [ ${#args[@]} -eq 0 ] && return 1 +# # shellcheck disable=SC2068 +# if hash bat > /dev/null 2>&1; then +# forgit::ignore::get ${args[@]} | bat -l gitignore +# else +# forgit::ignore::get ${args[@]} +# fi +#} +#forgit::ignore::update() { +# if [[ -d "$FORGIT_GI_REPO_LOCAL" ]]; then +# forgit::info 'Updating gitignore repo...' +# (cd "$FORGIT_GI_REPO_LOCAL" && git pull --no-rebase --ff) || return 1 +# else +# forgit::info 'Initializing gitignore repo...' +# git clone --depth=1 "$FORGIT_GI_REPO_REMOTE" "$FORGIT_GI_REPO_LOCAL" +# fi +#} +#forgit::ignore::get() { +# local item filename header +# for item in "$argv"; do +# if filename=$(find -L "$FORGIT_GI_TEMPLATES" -type f \( -iname "${item}.gitignore" -o -iname "${item}" \) -print -quit); then +# [[ -z "$filename" ]] && forgit::warn "No gitignore template found for '$item'." && continue +# header="${filename##*/}" && header="${header%.gitignore}" +# echo "### $header" && cat "$filename" && echo +# fi +# done +#} +#forgit::ignore::list() { +# find "$FORGIT_GI_TEMPLATES" -print |sed -e 's#.gitignore$##' -e 's#.*/##' | sort -fu +#} +#forgit::ignore::clean() { +# setopt localoptions rmstarsilent +# [[ -d "$FORGIT_GI_REPO_LOCAL" ]] && rm -rf "$FORGIT_GI_REPO_LOCAL" +#} +# +#FORGIT_FZF_DEFAULT_OPTS=" +#$FZF_DEFAULT_OPTS +#--ansi +#--height='80%' +#--bind='alt-k:preview-up,alt-p:preview-up' +#--bind='alt-j:preview-down,alt-n:preview-down' +#--bind='ctrl-r:toggle-all' +#--bind='ctrl-s:toggle-sort' +#--bind='?:toggle-preview' +#--bind='alt-w:toggle-preview-wrap' +#--preview-window='right:60%' +#$FORGIT_FZF_DEFAULT_OPTS +#" +# +## register aliases +## shellcheck disable=SC2139 +#if test -z "$FORGIT_NO_ALIASES" +# alias "${forgit_add:-ga}"='forgit::add' +# alias "${forgit_reset_head:-grh}"='forgit::reset::head' +# alias "${forgit_log:-glo}"='forgit::log' +# alias "${forgit_diff:-gd}"='forgit::diff' +# alias "${forgit_ignore:-gi}"='forgit::ignore' +# alias "${forgit_restore:-gcf}"='forgit::restore' +# alias "${forgit_clean:-gclean}"='forgit::clean' +# alias "${forgit_stash_show:-gss}"='forgit::stash::show' +#end From 35cbef1d591f506ae32bb794b755081d9c6d3a24 Mon Sep 17 00:00:00 2001 From: Christopher Apple Date: Sat, 2 Nov 2019 21:03:34 -0600 Subject: [PATCH 2/6] restore now working --- forgit.plugin.fish | 54 +++++++++++++++++++++++----------------------- 1 file changed, 27 insertions(+), 27 deletions(-) diff --git a/forgit.plugin.fish b/forgit.plugin.fish index 9938b0c..b4815e6 100755 --- a/forgit.plugin.fish +++ b/forgit.plugin.fish @@ -78,6 +78,7 @@ function forgit::add awk '{printf "[%10s] ", $1; $1=""; print $0}' | env FZF_DEFAULT_OPTS="$opts" fzf | cut -d] -f2 | sed 's/.* -> //') # for rename case + if test -n $files echo "$files" |xargs -I{} git add {} && git status --short && return end @@ -100,45 +101,46 @@ function forgit::reset::head echo 'Nothing to unstage.' end -## git checkout-restore selector -#forgit::restore() { -# forgit::inside_work_tree || return 1 -# local cmd files opts -# cmd="git diff --color=always -- {} $forgit_fancy" -# opts=" -# $FORGIT_FZF_DEFAULT_OPTS -# -m -0 --preview=\"$cmd\" -# $FORGIT_CHECKOUT_FZF_OPTS -# " -# files="$(git ls-files --modified "$(git rev-parse --show-toplevel)"| FZF_DEFAULT_OPTS="$opts" fzf)" -# [[ -n "$files" ]] && echo "$files" |xargs -I{} git checkout {} && git status --short && return -# echo 'Nothing to restore.' -#} -# +# git checkout-restore selector +function forgit::restore + forgit::inside_work_tree || return 1 + + set cmd "git diff --color=always -- {} $forgit_fancy" + set opts " + $FORGIT_FZF_DEFAULT_OPTS + -m -0 --preview=\"$cmd\" + $FORGIT_CHECKOUT_FZF_OPTS + " + set git_rev_parse (git rev-parse --show-toplevel) + set files (git ls-files --modified "$git_rev_parse" | env FZF_DEFAULT_OPTS="$opts" fzf) + if test -n $files + echo "$files" |xargs -I{} git checkout {} && git status --short && return + end + echo 'Nothing to restore.' +end + ## git stash viewer #forgit::stash::show() { # forgit::inside_work_tree || return 1 -# local cmd opts -# cmd="git stash show \$(echo {}| cut -d: -f1) --color=always --ext-diff $forgit_fancy" -# opts=" +# set cmd "git stash show \$(echo {}| cut -d: -f1) --color=always --ext-diff $forgit_fancy" +# set opts" # $FORGIT_FZF_DEFAULT_OPTS # +s +m -0 --tiebreak=index --preview=\"$cmd\" --bind=\"enter:execute($cmd |LESS='-R' less)\" # $FORGIT_STASH_FZF_OPTS # " -# git stash list | FZF_DEFAULT_OPTS="$opts" fzf +# git stash list | env FZF_DEFAULT_OPTS="$opts" fzf #} # ## git clean selector #forgit::clean() { # forgit::inside_work_tree || return 1 -# local files opts -# opts=" +# set opts" # $FORGIT_FZF_DEFAULT_OPTS # -m -0 # $FORGIT_CLEAN_FZF_OPTS # " # # Note: Postfix '/' in directory path should be removed. Otherwise the directory itself will not be removed. -# files=$(git clean -xdfn "$argv"| awk '{print $3}'| FZF_DEFAULT_OPTS="$opts" fzf |sed 's#/$##') +# set files $(git clean -xdfn "$argv"| awk '{print $3}'| env FZF_DEFAULT_OPTS="$opts" fzf |sed 's#/$##') # [[ -n "$files" ]] && echo "$files" |xargs -I% git clean -xdf % && return # echo 'Nothing to clean.' #} @@ -150,18 +152,17 @@ end # #forgit::ignore() { # [ -d "$FORGIT_GI_REPO_LOCAL" ] || forgit::ignore::update -# local IFS cmd args cat opts # # https://github.com/sharkdp/bat.git # hash bat > /dev/null 2>&1 && cat='bat -l gitignore --color=always' || cat="cat" -# cmd="$cat $FORGIT_GI_TEMPLATES/{2}{,.gitignore} 2>/dev/null" -# opts=" +# set cmd "$cat $FORGIT_GI_TEMPLATES/{2}{,.gitignore} 2>/dev/null" +# set opts" # $FORGIT_FZF_DEFAULT_OPTS # -m --preview=\"$cmd\" --preview-window='right:70%' # $FORGIT_IGNORE_FZF_OPTS # " # # shellcheck disable=SC2206,2207 # IFS=$'\n' args=($argv) && [[ $# -eq 0 ]] && args=($(forgit::ignore::list | nl -nrn -w4 -s' ' | -# FZF_DEFAULT_OPTS="$opts" fzf |awk '{print $2}')) +# env FZF_DEFAULT_OPTS="$opts" fzf |awk '{print $2}')) # [ ${#args[@]} -eq 0 ] && return 1 # # shellcheck disable=SC2068 # if hash bat > /dev/null 2>&1; then @@ -180,7 +181,6 @@ end # fi #} #forgit::ignore::get() { -# local item filename header # for item in "$argv"; do # if filename=$(find -L "$FORGIT_GI_TEMPLATES" -type f \( -iname "${item}.gitignore" -o -iname "${item}" \) -print -quit); then # [[ -z "$filename" ]] && forgit::warn "No gitignore template found for '$item'." && continue From e0dadacdfea374993feb8426bddd942bba0f6e50 Mon Sep 17 00:00:00 2001 From: Christopher Apple Date: Sat, 2 Nov 2019 21:08:34 -0600 Subject: [PATCH 3/6] stash working --- forgit.plugin.fish | 29 +++++++++++++++-------------- forgit.plugin.zsh | 2 ++ 2 files changed, 17 insertions(+), 14 deletions(-) diff --git a/forgit.plugin.fish b/forgit.plugin.fish index b4815e6..5e871b3 100755 --- a/forgit.plugin.fish +++ b/forgit.plugin.fish @@ -26,7 +26,7 @@ function forgit::log set opts " $FORGIT_FZF_DEFAULT_OPTS +s +m --tiebreak=index --preview=\"$cmd\" - --bind=\"enter:execute($cmd |LESS='-R' less)\" + --bind=\"enter:execute($cmd |env LESS='-R' less)\" --bind=\"ctrl-y:execute-silent(echo {} |grep -Eo '[a-f0-9]+' | head -1 | tr -d '\n' | pbcopy)\" $FORGIT_LOG_FZF_OPTS " @@ -119,22 +119,23 @@ function forgit::restore echo 'Nothing to restore.' end -## git stash viewer -#forgit::stash::show() { -# forgit::inside_work_tree || return 1 -# set cmd "git stash show \$(echo {}| cut -d: -f1) --color=always --ext-diff $forgit_fancy" -# set opts" -# $FORGIT_FZF_DEFAULT_OPTS -# +s +m -0 --tiebreak=index --preview=\"$cmd\" --bind=\"enter:execute($cmd |LESS='-R' less)\" -# $FORGIT_STASH_FZF_OPTS -# " -# git stash list | env FZF_DEFAULT_OPTS="$opts" fzf -#} +# git stash viewer +function forgit::stash::show + forgit::inside_work_tree || return 1 + set cmd "git stash show \$(echo {}| cut -d: -f1) --color=always --ext-diff $forgit_fancy" + set opts " + $FORGIT_FZF_DEFAULT_OPTS + +s +m -0 --tiebreak=index --preview=\"$cmd\" --bind=\"enter:execute($cmd |env LESS='-R' less)\" + $FORGIT_STASH_FZF_OPTS + " + git stash list | env FZF_DEFAULT_OPTS="$opts" fzf +end + # ## git clean selector #forgit::clean() { # forgit::inside_work_tree || return 1 -# set opts" +# set opts " # $FORGIT_FZF_DEFAULT_OPTS # -m -0 # $FORGIT_CLEAN_FZF_OPTS @@ -155,7 +156,7 @@ end # # https://github.com/sharkdp/bat.git # hash bat > /dev/null 2>&1 && cat='bat -l gitignore --color=always' || cat="cat" # set cmd "$cat $FORGIT_GI_TEMPLATES/{2}{,.gitignore} 2>/dev/null" -# set opts" +# set opts " # $FORGIT_FZF_DEFAULT_OPTS # -m --preview=\"$cmd\" --preview-window='right:70%' # $FORGIT_IGNORE_FZF_OPTS diff --git a/forgit.plugin.zsh b/forgit.plugin.zsh index 40ae1eb..877f872 100755 --- a/forgit.plugin.zsh +++ b/forgit.plugin.zsh @@ -4,6 +4,8 @@ forgit::warn() { printf "%b[Warn]%b %s\n" '\e[0;33m' '\e[0m' "$@" >&2; } forgit::info() { printf "%b[Info]%b %s\n" '\e[0;32m' '\e[0m' "$@" >&2; } forgit::inside_work_tree() { git rev-parse --is-inside-work-tree >/dev/null; } +dumb dumb dumb test + # https://github.com/so-fancy/diff-so-fancy hash diff-so-fancy &>/dev/null && forgit_fancy='|diff-so-fancy' # https://github.com/wfxr/emoji-cli From 46bfc0b6c6a93cd6964b9dfb63b3e57052165bfe Mon Sep 17 00:00:00 2001 From: Christopher Apple Date: Sat, 2 Nov 2019 21:23:39 -0600 Subject: [PATCH 4/6] stopping for the night --- forgit.plugin.fish | 110 ++++++++++++++++++++++++--------------------- 1 file changed, 58 insertions(+), 52 deletions(-) diff --git a/forgit.plugin.fish b/forgit.plugin.fish index 5e871b3..b1e2db7 100755 --- a/forgit.plugin.fish +++ b/forgit.plugin.fish @@ -54,7 +54,7 @@ function forgit::diff $FORGIT_DIFF_FZF_OPTS " set cmd "echo" && hash realpath > /dev/null 2>&1 && set cmd "realpath --relative-to=." - #eval "git diff --name-only $commit -- ${files[*]}| xargs -I% $cmd '$(git rev-parse --show-toplevel)/%'"| + #eval "git diff --name-only $commit -- ${files[*]}| xargs -I% $cmd '(git rev-parse --show-toplevel)/%'"| set git_rev_parse (git rev-parse --show-toplevel) eval "git diff --name-only $commit -- $files*| xargs -I% $cmd '$git_rev_parse/%'"| env FZF_DEFAULT_OPTS="$opts" fzf @@ -122,7 +122,7 @@ end # git stash viewer function forgit::stash::show forgit::inside_work_tree || return 1 - set cmd "git stash show \$(echo {}| cut -d: -f1) --color=always --ext-diff $forgit_fancy" + set cmd "git stash show \(echo {}| cut -d: -f1) --color=always --ext-diff $forgit_fancy" set opts " $FORGIT_FZF_DEFAULT_OPTS +s +m -0 --tiebreak=index --preview=\"$cmd\" --bind=\"enter:execute($cmd |env LESS='-R' less)\" @@ -131,48 +131,54 @@ function forgit::stash::show git stash list | env FZF_DEFAULT_OPTS="$opts" fzf end -# -## git clean selector -#forgit::clean() { -# forgit::inside_work_tree || return 1 -# set opts " -# $FORGIT_FZF_DEFAULT_OPTS -# -m -0 -# $FORGIT_CLEAN_FZF_OPTS -# " -# # Note: Postfix '/' in directory path should be removed. Otherwise the directory itself will not be removed. -# set files $(git clean -xdfn "$argv"| awk '{print $3}'| env FZF_DEFAULT_OPTS="$opts" fzf |sed 's#/$##') -# [[ -n "$files" ]] && echo "$files" |xargs -I% git clean -xdf % && return -# echo 'Nothing to clean.' -#} -# -## git ignore generator -#export FORGIT_GI_REPO_REMOTE=${FORGIT_GI_REPO_REMOTE:-https://github.com/dvcs/gitignore} -#export FORGIT_GI_REPO_LOCAL=${FORGIT_GI_REPO_LOCAL:-~/.forgit/gi/repos/dvcs/gitignore} -#export FORGIT_GI_TEMPLATES=${FORGIT_GI_TEMPLATES:-$FORGIT_GI_REPO_LOCAL/templates} -# -#forgit::ignore() { -# [ -d "$FORGIT_GI_REPO_LOCAL" ] || forgit::ignore::update -# # https://github.com/sharkdp/bat.git -# hash bat > /dev/null 2>&1 && cat='bat -l gitignore --color=always' || cat="cat" -# set cmd "$cat $FORGIT_GI_TEMPLATES/{2}{,.gitignore} 2>/dev/null" -# set opts " -# $FORGIT_FZF_DEFAULT_OPTS -# -m --preview=\"$cmd\" --preview-window='right:70%' -# $FORGIT_IGNORE_FZF_OPTS -# " -# # shellcheck disable=SC2206,2207 -# IFS=$'\n' args=($argv) && [[ $# -eq 0 ]] && args=($(forgit::ignore::list | nl -nrn -w4 -s' ' | -# env FZF_DEFAULT_OPTS="$opts" fzf |awk '{print $2}')) -# [ ${#args[@]} -eq 0 ] && return 1 -# # shellcheck disable=SC2068 -# if hash bat > /dev/null 2>&1; then -# forgit::ignore::get ${args[@]} | bat -l gitignore -# else -# forgit::ignore::get ${args[@]} -# fi -#} -#forgit::ignore::update() { + +# git clean selector +function forgit::clean + forgit::inside_work_tree || return 1 + + set opts " + $FORGIT_FZF_DEFAULT_OPTS + -m -0 + $FORGIT_CLEAN_FZF_OPTS + " + # Note: Postfix '/' in directory path should be removed. Otherwise the directory itself will not be removed. + # TODO removed $argv here + set files (git clean -xdfn | awk '{print $3}' | env FZF_DEFAULT_OPTS="$opts" fzf | sed 's#/$##') + + if test -n $files + echo "$files" |xargs -I% git clean -xdf % && return + end + echo 'Nothing to clean.' +end + +# git ignore generator +set -x FORGIT_GI_REPO_REMOTE ${FORGIT_GI_REPO_REMOTE:-https://github.com/dvcs/gitignore} +set -x FORGIT_GI_REPO_LOCAL ${FORGIT_GI_REPO_LOCAL:-~/.forgit/gi/repos/dvcs/gitignore} +set -x FORGIT_GI_TEMPLATES ${FORGIT_GI_TEMPLATES:-$FORGIT_GI_REPO_LOCAL/templates} + +function forgit::ignore + [ -d "$FORGIT_GI_REPO_LOCAL" ] || forgit::ignore::update + # https://github.com/sharkdp/bat.git + hash bat > /dev/null 2>&1 && cat='bat -l gitignore --color=always' || cat="cat" + set cmd "$cat $FORGIT_GI_TEMPLATES/{2}{,.gitignore} 2>/dev/null" + set opts " + $FORGIT_FZF_DEFAULT_OPTS + -m --preview=\"$cmd\" --preview-window='right:70%' + $FORGIT_IGNORE_FZF_OPTS + " + # shellcheck disable=SC2206,2207 + IFS=$'\n' args=($argv) && [[ $# -eq 0 ]] && args=((forgit::ignore::list | nl -nrn -w4 -s' ' | + env FZF_DEFAULT_OPTS="$opts" fzf |awk '{print $2}')) + [ ${#args[@]} -eq 0 ] && return 1 + # shellcheck disable=SC2068 + if hash bat > /dev/null 2>&1; then + forgit::ignore::get ${args[@]} | bat -l gitignore + else + forgit::ignore::get ${args[@]} + fi +end + +#function forgit::ignore::update # if [[ -d "$FORGIT_GI_REPO_LOCAL" ]]; then # forgit::info 'Updating gitignore repo...' # (cd "$FORGIT_GI_REPO_LOCAL" && git pull --no-rebase --ff) || return 1 @@ -180,23 +186,23 @@ end # forgit::info 'Initializing gitignore repo...' # git clone --depth=1 "$FORGIT_GI_REPO_REMOTE" "$FORGIT_GI_REPO_LOCAL" # fi -#} -#forgit::ignore::get() { +#end +#function forgit::ignore::get # for item in "$argv"; do -# if filename=$(find -L "$FORGIT_GI_TEMPLATES" -type f \( -iname "${item}.gitignore" -o -iname "${item}" \) -print -quit); then +# if filename=(find -L "$FORGIT_GI_TEMPLATES" -type f \( -iname "${item}.gitignore" -o -iname "${item}" \) -print -quit); then # [[ -z "$filename" ]] && forgit::warn "No gitignore template found for '$item'." && continue # header="${filename##*/}" && header="${header%.gitignore}" # echo "### $header" && cat "$filename" && echo # fi # done -#} -#forgit::ignore::list() { +#end +#function forgit::ignore::list # find "$FORGIT_GI_TEMPLATES" -print |sed -e 's#.gitignore$##' -e 's#.*/##' | sort -fu -#} -#forgit::ignore::clean() { +#end +#function forgit::ignore::clean # setopt localoptions rmstarsilent # [[ -d "$FORGIT_GI_REPO_LOCAL" ]] && rm -rf "$FORGIT_GI_REPO_LOCAL" -#} +#end # #FORGIT_FZF_DEFAULT_OPTS=" #$FZF_DEFAULT_OPTS From 10f0af9bb866dfe4ecdf953ffd6f0ce01ccee904 Mon Sep 17 00:00:00 2001 From: Christopher Apple Date: Sun, 3 Nov 2019 12:32:11 -0700 Subject: [PATCH 5/6] First draft of fish forgit completed :) --- forgit.plugin.fish | 230 +++++++++++++++++++++++++++++---------------- 1 file changed, 151 insertions(+), 79 deletions(-) diff --git a/forgit.plugin.fish b/forgit.plugin.fish index b1e2db7..db36a0f 100755 --- a/forgit.plugin.fish +++ b/forgit.plugin.fish @@ -1,5 +1,10 @@ #!/usr/local/bin/fish -# MIT (c) Wenxuan Zhang +# MIT (c) Chris Apple + +if not hash fzf > /dev/null 2>&1 + echo "FZF not found and is requried for forgit" + exit 1 +end function forgit::warn printf "%b[Warn]%b %s\n" '\e[0;33m' '\e[0m' "$argv" >&2; @@ -23,16 +28,22 @@ hash emojify >/dev/null 2>&1 && set forgit_emojify '|emojify' function forgit::log forgit::inside_work_tree || return 1 set cmd "echo {} |grep -Eo '[a-f0-9]+' |head -1 |xargs -I% git show --color=always % $argv $forgit_fancy" + + if test -n "$FORGIT_COPY_CMD" + set copy_cmd $FORGIT_COPY_CMD + else + set copy_cmd pbcopy + end + set opts " $FORGIT_FZF_DEFAULT_OPTS +s +m --tiebreak=index --preview=\"$cmd\" --bind=\"enter:execute($cmd |env LESS='-R' less)\" - --bind=\"ctrl-y:execute-silent(echo {} |grep -Eo '[a-f0-9]+' | head -1 | tr -d '\n' | pbcopy)\" + --bind=\"ctrl-y:execute-silent(echo {} |grep -Eo '[a-f0-9]+' | head -1 | tr -d '\n' | $copy_cmd)\" $FORGIT_LOG_FZF_OPTS " - #TODO: removed option for another pbcopy above eval "git log --graph --color=always --format='%C(auto)%h%d %s %C(black)%C(bold)%cr' $argv $forgit_emojify" | - env FZF_DEFAULT_OPTS "$opts" fzf + env FZF_DEFAULT_OPTS="$opts" fzf end ## git diff viewer @@ -79,7 +90,7 @@ function forgit::add env FZF_DEFAULT_OPTS="$opts" fzf | cut -d] -f2 | sed 's/.* -> //') # for rename case - if test -n $files + if test -n "$files" echo "$files" |xargs -I{} git add {} && git status --short && return end echo 'Nothing to add.' @@ -94,8 +105,9 @@ function forgit::reset::head -m -0 --preview=\"$cmd\" $FORGIT_RESET_HEAD_FZF_OPTS " - set files "(git diff --cached --name-only --relative | env FZF_DEFAULT_OPTS="$opts" fzf)" - if test -n $files + set files (git diff --cached --name-only --relative | env FZF_DEFAULT_OPTS="$opts" fzf) + if test -n "$files" + echo herer echo "$files" |xargs -I{} git reset -q HEAD {} && git status --short && return end echo 'Nothing to unstage.' @@ -113,7 +125,7 @@ function forgit::restore " set git_rev_parse (git rev-parse --show-toplevel) set files (git ls-files --modified "$git_rev_parse" | env FZF_DEFAULT_OPTS="$opts" fzf) - if test -n $files + if test -n "$files" echo "$files" |xargs -I{} git checkout {} && git status --short && return end echo 'Nothing to restore.' @@ -131,7 +143,6 @@ function forgit::stash::show git stash list | env FZF_DEFAULT_OPTS="$opts" fzf end - # git clean selector function forgit::clean forgit::inside_work_tree || return 1 @@ -141,92 +152,153 @@ function forgit::clean -m -0 $FORGIT_CLEAN_FZF_OPTS " - # Note: Postfix '/' in directory path should be removed. Otherwise the directory itself will not be removed. - # TODO removed $argv here - set files (git clean -xdfn | awk '{print $3}' | env FZF_DEFAULT_OPTS="$opts" fzf | sed 's#/$##') - if test -n $files + set files (git clean -xdfn $argv| awk '{print $3}'| env FZF_DEFAULT_OPTS="$opts" fzf |sed 's#/$##') + + if test -n "$files" echo "$files" |xargs -I% git clean -xdf % && return end echo 'Nothing to clean.' end # git ignore generator -set -x FORGIT_GI_REPO_REMOTE ${FORGIT_GI_REPO_REMOTE:-https://github.com/dvcs/gitignore} -set -x FORGIT_GI_REPO_LOCAL ${FORGIT_GI_REPO_LOCAL:-~/.forgit/gi/repos/dvcs/gitignore} -set -x FORGIT_GI_TEMPLATES ${FORGIT_GI_TEMPLATES:-$FORGIT_GI_REPO_LOCAL/templates} +if test -z "$FORGIT_GI_REPO_REMOTE" + set -x FORGIT_GI_REPO_REMOTE https://github.com/dvcs/gitignore +end + +if test -z "$FORGIT_GI_REPO_LOCAL" + set -x FORGIT_GI_REPO_LOCAL ~/.forgit/gi/repos/dvcs/gitignore +end + +if test -z "$FORGIT_GI_TEMPLATES" + set -x FORGIT_GI_TEMPLATES $FORGIT_GI_REPO_LOCAL/templates +end function forgit::ignore - [ -d "$FORGIT_GI_REPO_LOCAL" ] || forgit::ignore::update + if test -d "$FORGIT_GI_REPO_LOCAL" + forgit::ignore::update + end + # https://github.com/sharkdp/bat.git - hash bat > /dev/null 2>&1 && cat='bat -l gitignore --color=always' || cat="cat" + hash bat > /dev/null 2>&1 && set cat 'bat -l gitignore --color=always' || set cat "cat" set cmd "$cat $FORGIT_GI_TEMPLATES/{2}{,.gitignore} 2>/dev/null" set opts " $FORGIT_FZF_DEFAULT_OPTS -m --preview=\"$cmd\" --preview-window='right:70%' $FORGIT_IGNORE_FZF_OPTS " - # shellcheck disable=SC2206,2207 - IFS=$'\n' args=($argv) && [[ $# -eq 0 ]] && args=((forgit::ignore::list | nl -nrn -w4 -s' ' | - env FZF_DEFAULT_OPTS="$opts" fzf |awk '{print $2}')) - [ ${#args[@]} -eq 0 ] && return 1 - # shellcheck disable=SC2068 - if hash bat > /dev/null 2>&1; then - forgit::ignore::get ${args[@]} | bat -l gitignore + set IFS '\n' + + set args $argv + if not count $argv > /dev/null + set args (forgit::ignore::list | nl -nrn -w4 -s' ' | + env FZF_DEFAULT_OPTS="$opts" fzf |awk '{print $2}') + end + + if not count $args > /dev/null + return 1 + end + + if hash bat > /dev/null 2>&1 + forgit::ignore::get $args | bat -l gitignore else - forgit::ignore::get ${args[@]} - fi + forgit::ignore::get $args + end end -#function forgit::ignore::update -# if [[ -d "$FORGIT_GI_REPO_LOCAL" ]]; then -# forgit::info 'Updating gitignore repo...' -# (cd "$FORGIT_GI_REPO_LOCAL" && git pull --no-rebase --ff) || return 1 -# else -# forgit::info 'Initializing gitignore repo...' -# git clone --depth=1 "$FORGIT_GI_REPO_REMOTE" "$FORGIT_GI_REPO_LOCAL" -# fi -#end -#function forgit::ignore::get -# for item in "$argv"; do -# if filename=(find -L "$FORGIT_GI_TEMPLATES" -type f \( -iname "${item}.gitignore" -o -iname "${item}" \) -print -quit); then -# [[ -z "$filename" ]] && forgit::warn "No gitignore template found for '$item'." && continue -# header="${filename##*/}" && header="${header%.gitignore}" -# echo "### $header" && cat "$filename" && echo -# fi -# done -#end -#function forgit::ignore::list -# find "$FORGIT_GI_TEMPLATES" -print |sed -e 's#.gitignore$##' -e 's#.*/##' | sort -fu -#end -#function forgit::ignore::clean -# setopt localoptions rmstarsilent -# [[ -d "$FORGIT_GI_REPO_LOCAL" ]] && rm -rf "$FORGIT_GI_REPO_LOCAL" -#end -# -#FORGIT_FZF_DEFAULT_OPTS=" -#$FZF_DEFAULT_OPTS -#--ansi -#--height='80%' -#--bind='alt-k:preview-up,alt-p:preview-up' -#--bind='alt-j:preview-down,alt-n:preview-down' -#--bind='ctrl-r:toggle-all' -#--bind='ctrl-s:toggle-sort' -#--bind='?:toggle-preview' -#--bind='alt-w:toggle-preview-wrap' -#--preview-window='right:60%' -#$FORGIT_FZF_DEFAULT_OPTS -#" -# -## register aliases -## shellcheck disable=SC2139 -#if test -z "$FORGIT_NO_ALIASES" -# alias "${forgit_add:-ga}"='forgit::add' -# alias "${forgit_reset_head:-grh}"='forgit::reset::head' -# alias "${forgit_log:-glo}"='forgit::log' -# alias "${forgit_diff:-gd}"='forgit::diff' -# alias "${forgit_ignore:-gi}"='forgit::ignore' -# alias "${forgit_restore:-gcf}"='forgit::restore' -# alias "${forgit_clean:-gclean}"='forgit::clean' -# alias "${forgit_stash_show:-gss}"='forgit::stash::show' -#end +function forgit::ignore::update + if test -d "$FORGIT_GI_REPO_LOCAL" + forgit::info 'Updating gitignore repo...' + set pull_result (git -C "$FORGIT_GI_REPO_LOCAL" pull --no-rebase --ff) + test -n "$pull_result" || return 1 + else + forgit::info 'Initializing gitignore repo...' + git clone --depth=1 "$FORGIT_GI_REPO_REMOTE" "$FORGIT_GI_REPO_LOCAL" + end +end + +function forgit::ignore::get + for item in $argv + set filename (find -L "$FORGIT_GI_TEMPLATES" -type f \( -iname "$item.gitignore" -o -iname "$item}" \) -print -quit) + if test -n "$filename" + set header $filename && set header (echo $filename | sed 's/.*\.//') + echo "### $header" && cat "$filename" && echo + else + forgit::warn "No gitignore template found for '$item'." && continue + end + end +end + +function forgit::ignore::list + find "$FORGIT_GI_TEMPLATES" -print |sed -e 's#.gitignore$##' -e 's#.*/##' | sort -fu +end + +function forgit::ignore::clean + setopt localoptions rmstarsilent + [[ -d "$FORGIT_GI_REPO_LOCAL" ]] && rm -rf "$FORGIT_GI_REPO_LOCAL" +end + +set FORGIT_FZF_DEFAULT_OPTS " +$FZF_DEFAULT_OPTS +--ansi +--height='80%' +--bind='alt-k:preview-up,alt-p:preview-up' +--bind='alt-j:preview-down,alt-n:preview-down' +--bind='ctrl-r:toggle-all' +--bind='ctrl-s:toggle-sort' +--bind='?:toggle-preview' +--bind='alt-w:toggle-preview-wrap' +--preview-window='right:60%' +$FORGIT_FZF_DEFAULT_OPTS +" + +# register aliases +if test -z "$FORGIT_NO_ALIASES" + if test -n "$forgit_add" + alias $forgit_add 'forgit::add' + else + alias ga 'forgit::add' + end + + if test -n "$forgit_reset_head" + alias $forgit_reset_head 'forgit::reset::head' + else + alias grh 'forgit::reset::head' + end + + if test -n "$forgit_log" + alias $forgit_log 'forgit::log' + else + alias glo 'forgit::log' + end + + if test -n "$forgit_diff" + alias $forgit_diff 'forgit::diff' + else + alias gd 'forgit::diff' + end + + if test -n "$forgit_ignore" + alias $forgit_ignore 'forgit::ignore' + else + alias gi 'forgit::ignore' + end + + if test -n "$forgit_restore" + alias $forgit_restore 'forgit::restore' + else + alias gcf 'forgit::restore' + end + + if test -n "$forgit_clean" + alias $forgit_clean 'forgit::clean' + else + alias gclean 'forgit::clean' + end + + if test -n "$forgit_stash_show" + alias $forgit_stash_show 'forgit::stash::show' + else + alias gss 'forgit::stash::show' + end +end From 2382cb55b62dfaa9fd8bb28b4d9f35e231720aff Mon Sep 17 00:00:00 2001 From: Christopher Apple Date: Sun, 3 Nov 2019 12:33:34 -0700 Subject: [PATCH 6/6] oops, left some test code in there --- forgit.plugin.zsh | 2 -- 1 file changed, 2 deletions(-) diff --git a/forgit.plugin.zsh b/forgit.plugin.zsh index 877f872..40ae1eb 100755 --- a/forgit.plugin.zsh +++ b/forgit.plugin.zsh @@ -4,8 +4,6 @@ forgit::warn() { printf "%b[Warn]%b %s\n" '\e[0;33m' '\e[0m' "$@" >&2; } forgit::info() { printf "%b[Info]%b %s\n" '\e[0;32m' '\e[0m' "$@" >&2; } forgit::inside_work_tree() { git rev-parse --is-inside-work-tree >/dev/null; } -dumb dumb dumb test - # https://github.com/so-fancy/diff-so-fancy hash diff-so-fancy &>/dev/null && forgit_fancy='|diff-so-fancy' # https://github.com/wfxr/emoji-cli