-
-
Notifications
You must be signed in to change notification settings - Fork 948
Expand file tree
/
Copy pathutils.py
More file actions
131 lines (108 loc) · 3.84 KB
/
utils.py
File metadata and controls
131 lines (108 loc) · 3.84 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
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
import os
import re
from pathlib import Path
import platform
import shlex
import subprocess
from tempfile import NamedTemporaryFile
from typing import Any, Callable
import typer
from click import BadParameter, UsageError
from sgpt.__version__ import __version__
from sgpt.command import Command
from sgpt.config import cfg
from sgpt.integration import bash_integration, zsh_integration
def get_edited_prompt() -> str:
"""
Opens the user's default editor to let them
input a prompt, and returns the edited text.
:return: String prompt.
"""
with NamedTemporaryFile(suffix=".txt", delete=False) as file:
# Create file and store path.
file_path = file.name
editor = os.environ.get("EDITOR", "vim")
# This will write text to file using $EDITOR.
os.system(f"{editor} {file_path}")
# Read file when editor is closed.
with open(file_path, "r", encoding="utf-8") as file:
output = file.read()
os.remove(file_path)
if not output:
raise BadParameter("Couldn't get valid PROMPT from $EDITOR")
return output
command_helper = Command(command_path=Path(cfg.get("COMMAND_PATH")))
def get_fixed_prompt() -> str:
"""
get the last command and output then return a PROMPT
"""
command, output = command_helper.get_last_command()
return f"The last command `{command}` failed with error:\n{output}\nPlease fix it."
def extract_command_from_completion(completion: str) -> str:
"""
using regex to extract the command from the completion
"""
if match := re.search(r"```(.*sh)?(.*?)```", completion, re.DOTALL):
return match[2].strip()
return completion
def run_command(command: str) -> None:
"""
Runs a command in the user's shell.
It is aware of the current user's $SHELL.
:param command: A shell command to run.
"""
if platform.system() == "Windows":
is_powershell = len(os.getenv("PSModulePath", "").split(os.pathsep)) >= 3
full_command = (
f'powershell.exe -Command "{command}"'
if is_powershell
else f'cmd.exe /c "{command}"'
)
else:
shell = os.environ.get("SHELL", "/bin/sh")
full_command = f"{shell} -c {shlex.quote(command)}"
# os.system(full_command)
process = subprocess.Popen(
args=full_command,
stdout=subprocess.PIPE,
stderr=subprocess.STDOUT,
universal_newlines=True,
shell=True,
)
output, _ = process.communicate()
print(output)
command_helper.set_last_command(command, output)
def option_callback(func: Callable) -> Callable: # type: ignore
def wrapper(cls: Any, value: str) -> None:
if not value:
return
func(cls, value)
raise typer.Exit()
return wrapper
@option_callback
def install_shell_integration(*_args: Any) -> None:
"""
Installs shell integration. Currently only supports ZSH and Bash.
Allows user to get shell completions in terminal by using hotkey.
Replaces current "buffer" of the shell with the completion.
"""
# TODO: Add support for Windows.
# TODO: Implement updates.
shell = os.getenv("SHELL", "")
if "zsh" in shell:
typer.echo("Installing ZSH integration...")
with open(os.path.expanduser("~/.zshrc"), "a", encoding="utf-8") as file:
file.write(zsh_integration)
elif "bash" in shell:
typer.echo("Installing Bash integration...")
with open(os.path.expanduser("~/.bashrc"), "a", encoding="utf-8") as file:
file.write(bash_integration)
else:
raise UsageError("ShellGPT integrations only available for ZSH and Bash.")
typer.echo("Done! Restart your shell to apply changes.")
@option_callback
def get_sgpt_version(*_args: Any) -> None:
"""
Displays the current installed version of ShellGPT
"""
typer.echo(f"ShellGPT {__version__}")