-
Notifications
You must be signed in to change notification settings - Fork 1
/
gh-shell
executable file
·157 lines (138 loc) · 4.04 KB
/
gh-shell
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
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
#!/usr/bin/env bash
set -eo pipefail
usage () {
echo "AVAILABLE COMMANDS"
echo " list: View your saved shell commands"
echo " add: Add a shell command to your list"
echo " remove: Remove a shell command from your list"
echo " restore: Append all commands from your list so your current shell's history file"
echo ""
echo "EXAMPLES"
echo "$ gh shell list"
echo "$ gh shell add <command>"
echo "$ gh shell remove <command>"
echo "$ gh shell restore"
}
get_gist_id () {
gh api gists -q 'map(select(.files | has("gh-shell")))[0].id'
}
read_gist () {
gh gist view -f gh-shell $1
}
list () {
id=$(get_gist_id)
if [[ -z "$id" ]]; then
echo "You don't have any commands saved. Try adding one with 'gh shell add <command>'."
exit 1
fi
output=$(read_gist $id)
if [[ -z "$output" ]]; then
echo "You don't have any commands saved. Try adding one with 'gh shell add <command>'."
exit 1
fi
echo "$output"
}
create_gist () {
command=$*
echo "$command" | gh gist create -d "Saved commands for gh-shell" -f gh-shell - &>/dev/null
}
delete_gist () {
gh gist delete $1
}
update_gist () {
id=$1
shift
content=$*
jq --arg c "$content" -n '{"files":{"gh-shell":{"content":$c}}}' \
| gh api gists/$id -X PATCH -H 'Accept: application/vnd.github.v3+json' --input - \
&>/dev/null
}
add () {
shift
command="$*"
if [[ -z "$command" ]]; then
echo "No command specified to add."
echo ""
usage
exit 1
fi
id=$(get_gist_id)
if [[ -z "$id" ]]; then
create_gist $command
else
content=$(read_gist $id)
content=$(echo -e "$content\n$command")
update_gist $id "$content"
fi
}
remove () {
shift
command="$*"
if [[ -z "$command" ]]; then
echo "No command specified to remove."
echo ""
usage
exit 1
fi
id=$(get_gist_id)
if [[ -z "$id" ]]; then
# List doesn't exist. Nothing to remove.
exit 0
else
content=$(read_gist $id)
set +e
content=$(echo "$content" | grep -Fxv "$command")
set -e
if [[ -z "$content" ]]; then
# When the last command is removed, delete the whole gist
delete_gist $id
else
update_gist $id "$content"
fi
fi
}
restore () {
# When invoked through `gh` directly in a shell, the process chain should look something like
# (shell) -> gh shell restore -> bash -> gh-shell
# $PPID will point to the process id of `gh shell restore`. We need to find the parent
# of this process to determine which shell the user is invoking this from so that we
# can update the correct history file for that shell.
parent_shell_pid=$(ps -o ppid= -p $PPID | tr -d '[:space:]')
parent_shell=$(ps -p $parent_shell_pid -o comm=)
case $parent_shell in
*zsh)
echo "✅ Detected zsh"
file=${HISTFILE:-$HOME/.zsh_history}
;;
*bash)
echo "✅ Detected bash"
file=${HISTFILE:-$HOME/.bash_history}
;;
*)
echo "⚠️ Could not detect shell ($parent_shell). Assuming bash."
file=${HISTFILE:-$HOME/.bash_history}
esac
echo "$(list)" >> $file
echo "History file $file updated"
case $parent_shell in
*zsh)
if [[ -z "$TERM_SESSION_ID" ]]; then
echo "Open a new shell or refresh history in the current shell by running 'fc -RI'"
else
# Special case for running in an Apple Terminal instance, which by default captures
# terminal session history separately and merges from the shared history on launch
echo "Open a new Terminal instance to refresh history"
fi
;;
*)
echo "Open a new shell or refresh history in the current shell by running 'history -n'"
esac
}
declare -A COMMANDS=(
[usage]=usage
[list]=list
[add]=add
[remove]=remove
[restore]=restore
)
"${COMMANDS[${1:-usage}]:-${COMMANDS[usage]}}" "$@"