forked from not-poma/lazyshell
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlazyshell.zsh
More file actions
executable file
·87 lines (73 loc) · 2.6 KB
/
lazyshell.zsh
File metadata and controls
executable file
·87 lines (73 loc) · 2.6 KB
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
#!/usr/bin/env zsh
__lazyshell_complete() {
if [ -z "$OPENAI_API_KEY" ]; then
echo ""
echo "Error: OPENAI_API_KEY is not set"
echo "Get your API key from https://beta.openai.com/account/api-keys and then run:"
echo "export OPENAI_API_KEY=<your API key>"
zle reset-prompt
return 1
fi
local buffer_context="$BUFFER"
# Read user input
# Todo: use zle to read input
local REPLY
autoload -Uz read-from-minibuffer
read-from-minibuffer '> GPT query: '
BUFFER="$buffer_context"
CURSOR=$#BUFFER
if [[ -z "$buffer_context" ]]; then
local prompt="Write a bash command for query: \`$REPLY\`. Answer with the command only."
else
local prompt="Alter bash command \`$buffer_context\` to comply with query \`$REPLY\`. Answer with the command only."
fi
# todo: better escaping
local escaped_prompt=$(echo "$prompt" | sed 's/"/\\"/g' | sed 's/\n/\\n/g')
local data='{"prompt":"'"$escaped_prompt"'","model":"text-davinci-003","max_tokens":256,"temperature":0}'
# Display a spinner while the API request is running in the background
local spinner=("⠋" "⠙" "⠹" "⠸" "⠼" "⠴" "⠦" "⠧" "⠇" "⠏")
set +m
local response_file=$(mktemp)
{ curl -s -X POST -H "Content-Type: application/json" -H "Authorization: Bearer $OPENAI_API_KEY" --data "$data" https://api.openai.com/v1/completions > "$response_file" } &>/dev/null &
local pid=$!
while true; do
for i in "${spinner[@]}"; do
if ! kill -0 $pid 2> /dev/null; then
break 2
fi
zle -R "$i GPT query: $REPLY"
sleep 0.1
done
done
wait $pid
if [ $? -ne 0 ]; then
# todo displayed error is erased immediately, find a better way to display it
zle -R "Error: API request failed"
return 1
fi
# Read the response from file
# Todo: avoid using temp files
local response=$(cat "$response_file")
rm "$response_file"
local generated_text=$(echo -E $response | jq -r '.choices[0].text' | xargs)
local error=$(echo -E $response | jq -r '.error.message')
if [ $? -ne 0 ]; then
zle -R "Error: Invalid response from API"
return 1
fi
if [[ -n "$error" && "$error" != "null" ]]; then
zle -R "Error: $error"
return 1
fi
# Replace the current buffer with the generated text
BUFFER="$generated_text"
CURSOR=$#BUFFER
}
if [ -z "$OPENAI_API_KEY" ]; then
echo "Warning: OPENAI_API_KEY is not set"
echo "Get your API key from https://beta.openai.com/account/api-keys and then run:"
echo "export OPENAI_API_KEY=<your API key>"
fi
# Bind the __lazyshell_complete function to the Alt-g hotkey
zle -N __lazyshell_complete
bindkey '\eg' __lazyshell_complete