-
-
Notifications
You must be signed in to change notification settings - Fork 1
/
gcd.sh
116 lines (107 loc) · 2.84 KB
/
gcd.sh
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
# This script is intended to be sourced into your ~/.zshrc or ~/.bashrc.
# Search for worktrees and change directories.
gcd () {
__gcd_initialize
__gcd_dir=$(__gcd_worktrees | __gcd_fzf "$@")
__gcd_finalize
if test -n "${__gcd_dir}"
then
cd "${__gcd_dir}" || return 0
fi
}
# search for directories inside the current repository and change directories.
# "cdg /" goes to the root of the current repository.
cdg () {
if test "$(git rev-parse --is-inside-work-tree 2>/dev/null)" != "true"
then
return 0
fi
__gcd_initialize
__gcd_curdir="${PWD}"
__gcd_gitdir=$(git rev-parse --show-cdup 2>/dev/null) || return 0
if test -n "${__gcd_gitdir}"
then
if ! cd "${__gcd_gitdir}"
then
__gcd_finalize
return 0
fi
fi
__gcd_dir=$(
(echo . && git ls-tree -r -d --name-only HEAD 2>/dev/null) | __gcd_fzf "$@"
)
__gcd_finalize
if test -n "${__gcd_dir}"
then
cd "${__gcd_dir}" || return 0
else
cd "${__gcd_curdir}" || return 0
fi
}
# Initialize the zsh shell environment.
__gcd_initialize () {
__gcd_restore_zsh_wordsplit=
if test -n "${ZSH_VERSION}" && test -z "$(setopt | grep shwordsplit)"
then
__gcd_restore_zsh_wordsplit=true
set -o shwordsplit
fi
}
# Restore the zsh shell environment.
__gcd_finalize () {
if test -n "${__gcd_restore_zsh_wordsplit}"
then
set +o shwordsplit
fi
}
# Custom fzf used by gcd / gcdi
__gcd_fzf () {
fzf \
--ansi \
--border=none \
--cycle \
--filepath-word \
--info=inline-right \
--keep-right \
--preview='eza --all --color=always --git-ignore --group-directories-first --icons {}' \
--preview-window=down,33%,border-none \
--query="$*" \
--scheme=path \
--tiebreak=end,chunk,length
}
# Find worktrees and print their paths to stdout.
__gcd_worktrees () {
gcd_paths=$(git config --get-all gcd.paths | envsubst)
if test -z "${gcd_paths}"
then
gcd_paths="${HOME}"
fi
OIFS="${IFS}"
IFS='
'
set --
for gcd_path in ${gcd_paths}
do
set -- "$@" "${gcd_path}"
done
IFS="${OIFS}"
gcd_depth=$(git config gcd.depth || echo 2)
# Add + 1 to account for .git.
gcd_depth=$((gcd_depth + 1))
fdfind_cmd=
fdfind_args="--color=never --case-sensitive --hidden --no-ignore --max-depth=${gcd_depth}"
if type fd >/dev/null 2>&1
then
fdfind_cmd=fd
elif type fdfind >/dev/null 2>&1
then
fdfind_cmd=fdfind
fi
if test -n "${fdfind_cmd}"
then
# shellcheck disable=SC2086
"${fdfind_cmd}" ${fdfind_args} '^\.git$' "$@" | xargs -P 4 -n 1 dirname 2>/dev/null
else
find -L "$@" -maxdepth ${gcd_depth} -name .git -printf '%h\n' 2>/dev/null
fi
}