AI command generation in the fish shell
Avg. 2 minute(s) of readingI want to share a cool little fish function that I started using to suggest/improve the commands I'm writting.
Why not just use github copilot cli
So, I tried using Github's copilot cli, but it just felt slow/cumbersome. Even when using aliases, it just broke my workflow.
1alias cop="gh copilot suggest -t shell" 2alias copg="gh copilot suggest -t git" 3alias cope="gh copilot explain"
What I came up with
A friend at work complained that VSCode started annoying him with copilot stuff in the terminal, so I went to check it out. Basically, Microsoft started showing a prompt to open copilot in Code's terminal with a ctrl+i keybind. This gave me the idea to do something similar.
In fish we have access to a commandline
built-in that allows manipulating the content of the prompt. I already used, for example, to prepend sudo
to a command when I forget it:
1# pipe bindings 2# append | less and execute 3bind \el -M insert 'commandline -a "| less" && commandline -f execute' 4# prefix yes | and execute 5bind \ey -M insert 'commandline -C 0 && commandline -i "yes | " && commandline -f execute' 6# prefix sudo 7bind \es -M insert 'commandline -C 0 && commandline -i "sudo "'
So I wrote this function. This gets the current content of the command line, generates an AI based suggestion, and replaces it with the result:
1function ai_cmd_suggest 2 set -l base_prompt 3 if test (count $argv) -ge 1 4 set base_prompt "$argv[1]" 5 else 6 return 1 7 end 8 9 set -l current_content (commandline) 10 11 set -l prompt "Only provide a single fish shell command as your response. Do not include any explanations, markdown formatting (like ```), or extra text. $base_prompt\n```fish\n$current_content\n```" 12 set -l new_cmd (echo "$prompt" | ask | string trim) 13 14 # Replace the current commandline content with the AI's suggestion 15 set -l cmd_line "# $current_content 16$new_cmd" 17 commandline "$cmd_line" 18 commandline --cursor (string length "$cmd_line") # Move cursor to end 19end
The ask
command is just an alias/script that I use to wrap-around simonw's llm tool. I use it to interact with Google's Gemini models:
1#!/bin/sh 2 3cat | llm -m 'gemini-2.0-flash' "$@"
How to use it
I set 2 keybindings for the script. These keybindings contain the actual prompt.
1bind \ei -M insert 'ai_cmd_suggest "Suggest a command for the following description:"' 2bind \eI -M insert 'ai_cmd_suggest "Improve and/or fix the following command:"'
With this, I can:
- Write the description for a command and then press
alt+i
to replace it with a command. - Write a command and then press
alt+I
to replace it with a fixed/improved version of the original.
Conclusion
This has been working pretty well and seems to be faster than Github's copilot tool. Although the processing is pretty fast, a loading spinner would be cool, but for now this is good enough. Stay safe :P