diff --git a/README.md b/README.md index 1d81a3a7..903e0528 100644 --- a/README.md +++ b/README.md @@ -104,11 +104,11 @@ sgpt -s "find all json files in current folder" --no-interaction | pbcopy ### Shell integration -This is a **very handy feature**, which allows you to use `sgpt` shell completions directly in your terminal, without the need to type `sgpt` with prompt and arguments. Shell integration enables the use of ShellGPT with hotkeys in your terminal, supported by both Bash and ZSH shells. This feature puts `sgpt` completions directly into terminal buffer (input line), allowing for immediate editing of suggested commands. +This is a **very handy feature**, which allows you to use `sgpt` shell completions directly in your terminal, without the need to type `sgpt` with prompt and arguments. Shell integration enables the use of ShellGPT with hotkeys in your terminal, supported by Bash, ZSH, and Fish shells. This feature puts `sgpt` completions directly into terminal buffer (input line), allowing for immediate editing of suggested commands. https://github.com/TheR1D/shell_gpt/assets/16740832/bead0dab-0dd9-436d-88b7-6abfb2c556c1 -To install shell integration, run `sgpt --install-integration` and restart your terminal to apply changes. This will add few lines to your `.bashrc` or `.zshrc` file. After that, you can use `Ctrl+l` (by default) to invoke ShellGPT. When you press `Ctrl+l` it will replace you current input line (buffer) with suggested command. You can then edit it and just press `Enter` to execute. +To install shell integration, run `sgpt --install-integration` and restart your terminal to apply changes. This will add few lines to your `.bashrc`, `.zshrc`, or `.config/fish/conf.d/sgpt_commandline.fish` file. After that, you can use `Ctrl+l` (Bash/ZSH) or `Ctrl+o` (Fish) to invoke ShellGPT, and it will replace you current input line (buffer) with suggested command. You can then edit it and just press `Enter` to execute. ### Generating code By using the `--code` or `-c` parameter, you can specifically request pure code output, for instance: diff --git a/sgpt/app.py b/sgpt/app.py index 9c711e66..775b2665 100644 --- a/sgpt/app.py +++ b/sgpt/app.py @@ -144,7 +144,7 @@ def main( ), install_integration: bool = typer.Option( False, - help="Install shell integration (ZSH and Bash only)", + help="Install shell integration (ZSH, Bash, and Fish)", callback=install_shell_integration, hidden=True, # Hiding since should be used only once. ), diff --git a/sgpt/integration.py b/sgpt/integration.py index fd19fc6d..d8b5b21c 100644 --- a/sgpt/integration.py +++ b/sgpt/integration.py @@ -25,3 +25,36 @@ bindkey ^l _sgpt_zsh # Shell-GPT integration ZSH v0.2 """ + +fish_integration = """ +status is-interactive || exit + +function _sgpt_commandline + # Get the current command line content + set -l _sgpt_prompt (commandline | string replace -r '^[ #]+' '') + + # Only proceed if there is a prompt + if test -z "$_sgpt_prompt" + return + end + + # Append an hourglass to the current command + commandline -a "⌛" + commandline -f end-of-line # needed to display the icon + + # Get the output of the sgpt command + set -l _sgpt_output (echo "$_sgpt_prompt" | sgpt --shell --no-interaction) + + if test $status -eq 0 + # Replace the command line with the output from sgpt + commandline -r -- (string trim "$_sgpt_output") + commandline -a " # $_sgpt_prompt" + else + # If the sgpt command failed, remove the hourglass + commandline -f backward-delete-char + commandline -a " # ERROR: sgpt command failed" + end +end + +bind ctrl-o _sgpt_commandline +""" diff --git a/sgpt/utils.py b/sgpt/utils.py index d49af9a3..f96a05e7 100644 --- a/sgpt/utils.py +++ b/sgpt/utils.py @@ -8,7 +8,7 @@ from click import BadParameter, UsageError from sgpt.__version__ import __version__ -from sgpt.integration import bash_integration, zsh_integration +from sgpt.integration import bash_integration, fish_integration, zsh_integration def get_edited_prompt() -> str: @@ -66,7 +66,7 @@ def wrapper(cls: Any, value: str) -> None: @option_callback def install_shell_integration(*_args: Any) -> None: """ - Installs shell integration. Currently only supports ZSH and Bash. + Installs shell integration. Currently supports ZSH, Bash, and Fish. Allows user to get shell completions in terminal by using hotkey. Replaces current "buffer" of the shell with the completion. """ @@ -81,8 +81,20 @@ def install_shell_integration(*_args: Any) -> None: typer.echo("Installing Bash integration...") with open(os.path.expanduser("~/.bashrc"), "a", encoding="utf-8") as file: file.write(bash_integration) + elif "fish" in shell: + typer.echo("Installing Fish integration...") + fish_config_dir = os.path.expanduser("~/.config/fish/conf.d") + os.makedirs(fish_config_dir, exist_ok=True) + with open( + os.path.join(fish_config_dir, "sgpt_commandline.fish"), + "w", + encoding="utf-8", + ) as file: + file.write(fish_integration) else: - raise UsageError("ShellGPT integrations only available for ZSH and Bash.") + raise UsageError( + "ShellGPT integrations only available for ZSH, Bash, and Fish." + ) typer.echo("Done! Restart your shell to apply changes.")