fzf-git.bash (8062B)
1 # Copyright (c) 2016, 2022 Junegunn Choi 2 # ble/contrib/integration/fzf-git.bash (C) 2020, 2023, akinomyoga 3 # 4 # 2020-04-16 https://gist.github.com/junegunn/8b572b8d4b5eddd8b85e5f4d40f17236 (Revision 2019-03-14) 5 # 2023-06-30 https://gist.github.com/junegunn/8b572b8d4b5eddd8b85e5f4d40f17236 (Revision 2022-08-16) 6 # 2023-06-30 https://github.com/junegunn/fzf-git.sh/commit/4bc0323b4822b3426989863996cc266c52c7f25a 7 # 2023-06-30 https://github.com/junegunn/fzf-git.sh/commit/b6192ec86609afea761c7d3954f9b539a512dc80 8 9 ble-import contrib/integration/fzf-initialize 10 11 [[ $- == *i* ]] || return 0 12 13 # GIT heart FZF 14 # ------------- 15 16 #------------------------------------------------------------------------------ 17 # Redefine this function to change the options 18 _fzf_git_fzf() { 19 fzf-tmux -p80%,60% -- \ 20 --layout=reverse --multi --height=50% --min-height=20 --border \ 21 --border-label-pos=2 \ 22 --color='header:italic:underline,label:blue' \ 23 --preview-window='right,50%,border-left' \ 24 --bind='ctrl-/:change-preview-window(down,50%,border-top|hidden|)' "$@" 25 } 26 27 _fzf_git_check() { 28 git rev-parse HEAD > /dev/null 2>&1 && return 0 29 30 [[ -n $TMUX ]] && tmux display-message "Not in a git repository" 31 return 1 32 } 33 34 __fzf_git=${BASH_SOURCE[0]:-${(%):-%x}} 35 __fzf_git=$(readlink -f "$__fzf_git" 2> /dev/null || /usr/bin/ruby --disable-gems -e 'puts File.expand_path(ARGV.first)' "$__fzf_git" 2> /dev/null) 36 37 if [[ -z $_fzf_git_cat ]]; then 38 # Sometimes bat is installed as batcat 39 export _fzf_git_cat="cat" 40 _fzf_git_bat_options="--style='${BAT_STYLE:-full}' --color=always --pager=never" 41 if command -v batcat > /dev/null; then 42 _fzf_git_cat="batcat $_fzf_git_bat_options" 43 elif command -v bat > /dev/null; then 44 _fzf_git_cat="bat $_fzf_git_bat_options" 45 fi 46 fi 47 48 _fzf_git_files() { 49 _fzf_git_check || return "$?" 50 (git -c color.status=always status --short --no-branch 51 git ls-files | grep -vxFf <(git status -s | grep '^[^?]' | cut -c4-; echo :) | sed 's/^/ /') | 52 _fzf_git_fzf -m --ansi --nth 2..,.. \ 53 --border-label '📁 Files' \ 54 --header $'CTRL-O (open in browser) ╱ ALT-E (open in editor)\n\n' \ 55 --bind "ctrl-o:execute-silent:bash $__fzf_git file {-1}" \ 56 --bind "alt-e:execute:${EDITOR:-vim} {-1} > /dev/tty" \ 57 --preview "git diff --no-ext-diff --color=always -- {-1} | sed 1,4d; $_fzf_git_cat {-1}" "$@" | 58 cut -c4- | sed 's/.* -> //' 59 } 60 61 _fzf_git_branches() { 62 _fzf_git_check || return "$?" 63 bash "$__fzf_git" branches | 64 _fzf_git_fzf --ansi \ 65 --border-label '🌲 Branches' \ 66 --header-lines 2 \ 67 --tiebreak begin \ 68 --preview-window down,border-top,40% \ 69 --color hl:underline,hl+:underline \ 70 --no-hscroll \ 71 --bind 'ctrl-/:change-preview-window(down,70%|hidden|)' \ 72 --bind "ctrl-o:execute-silent:bash $__fzf_git branch {}" \ 73 --bind "alt-a:change-prompt(🌳 All branches> )+reload:bash \"$__fzf_git\" all-branches" \ 74 --preview 'git log --oneline --graph --date=short --color=always --pretty="format:%C(auto)%cd %h%d %s" $(sed s/^..// <<< {} | cut -d" " -f1)' "$@" | 75 sed 's/^..//' | cut -d' ' -f1 76 } 77 78 _fzf_git_tags() { 79 _fzf_git_check || return "$?" 80 git tag --sort -version:refname | 81 _fzf_git_fzf --preview-window right,70% \ 82 --border-label '📛 Tags' \ 83 --header $'CTRL-O (open in browser)\n\n' \ 84 --bind "ctrl-o:execute-silent:bash $__fzf_git tag {}" \ 85 --preview 'git show --color=always {}' "$@" 86 } 87 88 _fzf_git_hashes() { 89 _fzf_git_check || return "$?" 90 git log --date=short --format="%C(green)%C(bold)%cd %C(auto)%h%d %s (%an)" --graph --color=always | 91 _fzf_git_fzf --ansi --no-sort --bind 'ctrl-s:toggle-sort' \ 92 --border-label '🍡 Hashes' \ 93 --header $'CTRL-O (open in browser) ╱ CTRL-D (diff) ╱ CTRL-S (toggle sort)\n\n' \ 94 --bind "ctrl-o:execute-silent:bash $__fzf_git commit {}" \ 95 --bind 'ctrl-d:execute:grep -o "[a-f0-9]\{7,\}" <<< {} | head -n 1 | xargs git diff > /dev/tty' \ 96 --color hl:underline,hl+:underline \ 97 --preview 'grep -o "[a-f0-9]\{7,\}" <<< {} | head -n 1 | xargs git show --color=always' "$@" | 98 awk 'match($0, /[a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9][a-f0-9]*/) { print substr($0, RSTART, RLENGTH) }' 99 } 100 101 _fzf_git_remotes() { 102 _fzf_git_check || return "$?" 103 git remote -v | awk '{print $1 "\t" $2}' | uniq | 104 _fzf_git_fzf --tac \ 105 --border-label '📡 Remotes' \ 106 --header $'CTRL-O (open in browser)\n\n' \ 107 --bind "ctrl-o:execute-silent:bash $__fzf_git remote {1}" \ 108 --preview-window right,70% \ 109 --preview 'git log --oneline --graph --date=short --color=always --pretty="format:%C(auto)%cd %h%d %s" {1}/"$(git rev-parse --abbrev-ref HEAD)"' "$@" | 110 cut -d$'\t' -f1 111 } 112 113 _fzf_git_stashes() { 114 _fzf_git_check || return "$?" 115 git stash list | _fzf_git_fzf \ 116 --border-label '🥡 Stashes' \ 117 --header $'CTRL-X (drop stash)\n\n' \ 118 --bind 'ctrl-x:execute-silent(git stash drop {1})+reload(git stash list)' \ 119 -d: --preview 'git show --color=always {1}' "$@" | 120 cut -d: -f1 121 } 122 123 _fzf_git_each_ref() { 124 _fzf_git_check || return "$?" 125 bash "$__fzf_git" refs | _fzf_git_fzf --ansi \ 126 --nth 2,2.. \ 127 --tiebreak begin \ 128 --border-label '☘️ Each ref' \ 129 --header-lines 2 \ 130 --preview-window down,border-top,40% \ 131 --color hl:underline,hl+:underline \ 132 --no-hscroll \ 133 --bind 'ctrl-/:change-preview-window(down,70%|hidden|)' \ 134 --bind "ctrl-o:execute-silent:bash $__fzf_git {1} {2}" \ 135 --bind "alt-e:execute:${EDITOR:-vim} <(git show {2}) > /dev/tty" \ 136 --bind "alt-a:change-prompt(🍀 Every ref> )+reload:bash \"$__fzf_git\" all-refs" \ 137 --preview 'git log --oneline --graph --date=short --color=always --pretty="format:%C(auto)%cd %h%d %s" {2}' "$@" | 138 awk '{print $2}' 139 } 140 #------------------------------------------------------------------------------ 141 142 # export FZF_DEFAULT_OPTS=--no-unicode 143 144 : "${_ble_contrib_fzf_git_config=key-binding}" 145 146 # original 147 function ble/contrib:integration/fzf-git/type:original/init { 148 bind '"\er": redraw-current-line' 149 } 150 function ble/contrib:integration/fzf-git/type:original { 151 local binding='"\C-g\C-'$1'": "$(_fzf_git_'$2')\e\C-e\er"' 152 bind "$binding" 153 } 154 # function ble/contrib:integration/fzf-git/type:original { 155 # local binding='"\C-g\C-'$1'": "$(_fzf_git_'$2')\M-\C-e\M-\C-l"' 156 # bind "$binding" 157 # } 158 159 function ble/widget/fzf-git { 160 ble/widget/insert-string "$(_fzf_git_$1)" 161 ble/textarea#invalidate 162 } 163 164 # key-binding 165 function ble/contrib:integration/fzf-git/type:key-binding { 166 ble-bind -f "C-g C-$1" "fzf-git $2" 167 } 168 169 # sabbrev 170 function ble/contrib:integration/fzf-git/type:sabbrev/init { 171 function fzf-git.sabbrev { 172 COMPREPLY=$(_fzf_git_$1) 173 ble/textarea#invalidate 174 } 175 } 176 function ble/contrib:integration/fzf-git/type:sabbrev { 177 ble-sabbrev -m "g$1"="fzf-git.sabbrev $2" 178 } 179 180 # arpeggio 181 function ble/contrib:integration/fzf-git/type:arpeggio/init { 182 ble-import 'lib/vim-arpeggio.sh' 183 } 184 function ble/contrib:integration/fzf-git/type:arpeggio { 185 ble/lib/vim-arpeggio.sh/bind -f "g$1" "fzf-git $2" 186 } 187 188 # old-functions 189 function ble/contrib:integration/fzf-git/type:old-functions/init { 190 function is_in_git_repo { _fzf_git_fzf "$@"; } 191 function fzf-down { _fzf_git_check "$@"; } 192 } 193 function ble/contrib:integration/fzf-git/type:old-functions { 194 builtin eval "function g$1 { _fzf_git_$2 \"\$@\"; }" 195 } 196 197 function ble/contrib:integration/fzf-git/initialize { 198 local type 199 for type in original key-binding sabbrev arpeggio old-functions; do 200 [[ :$_ble_contrib_fzf_git_config: == *:"$type":* ]] || continue 201 202 ble/function#try ble/contrib:integration/fzf-git/type:"$type"/init 203 ble/contrib:integration/fzf-git/type:"$type" f files 204 ble/contrib:integration/fzf-git/type:"$type" b branches 205 ble/contrib:integration/fzf-git/type:"$type" t tags 206 ble/contrib:integration/fzf-git/type:"$type" h hashes 207 ble/contrib:integration/fzf-git/type:"$type" r remotes 208 ble/contrib:integration/fzf-git/type:"$type" s stashes 209 ble/contrib:integration/fzf-git/type:"$type" s each_ref 210 done 211 builtin unset -f "$FUNCNAME" 212 } 213 ble/contrib:integration/fzf-git/initialize