As discussed with @JohnSundell in #74 - it's super cool to have autocompletions in shells, so it's way easier to use tool. I've added very basic for of autocompletions for fish shell.
During the development of this feature I was hoping to find a universal solution, but in the end I think what we currently have is simply an overkill π Let me tell you why...
(But there's a place for some nice refactoring, cause what I did is a code duplication. We can standardize it, extract it and make it way nicer)
The most popular shells are (I guess): bash, zsh and fish. In that case making something super generic and fully automatic is just a something we shouldn't spend much time.
Secondly, shells like fish and zsh (AFAIR) are interactive, so you have a lot of nice features available there which we simply can't use, cause we're generating scripts, so we assume they're really repetitive, right?
Example: in fish you can specify behavior of the completion based on passed parameters and also specify the results via different command. In case of Marathon when we call completion on marathon remove it will suggest only installed packages at .marathon/Scripts/Cached - COOL, HUH? π
Last, but not least, when someone will want to contribute to this... Well... It's hard to get easily what's happening, cause we're escaping string and blah, blah, blah...
If you take a look at the file I had to write to generate marathon.fish and on marathon.fish directly...
internal final class FishAutocompleteInstaller {
static func installIfNeeded(in folder: Folder) {
do {
guard !folder.containsSubfolder(named: "fish") else {
return
}
let zshFolder = try folder.createSubfolder(named: "fish")
let autocompleteFile = try zshFolder.createFile(named: "marathon.fish")
var autocompleteCode = generateFishFunctions()
for command in Command.all {
autocompleteCode.append("complete -f -c marathon " +
"-n '__fish_marathon_needs_command' " +
"-a '\(command.rawValue)' " +
"-d '\(command.description)'" +
"\n")
}
try autocompleteFile.write(string: autocompleteCode)
} catch {
// Since this operation isn't critical, we silently fail if an error occur
}
}
fileprivate static func generateFishFunctions() -> String {
let needsCommand = "function __fish_marathon_needs_command\n" +
"\tset cmd (commandline -opc)\n" +
"\tif [ (count $cmd) -eq 1 ]\n" +
"\t\treturn 0\n" +
"\tend\n" +
"\treturn 1\n" +
"end" +
"\n\n"
return needsCommand
}
}
function __fish_marathon_needs_command
set cmd (commandline -opc)
if [ (count $cmd) -eq 1 ]
return 0
end
return 1
end
complete -f -c marathon -n '__fish_marathon_needs_command' -a 'create' -d 'Create new script at a given path and open it'
complete -f -c marathon -n '__fish_marathon_needs_command' -a 'edit' -d 'Edit a script at a given path'
complete -f -c marathon -n '__fish_marathon_needs_command' -a 'remove' -d 'Remove a package or the cache data for a script at a given path'
complete -f -c marathon -n '__fish_marathon_needs_command' -a 'run' -d 'Run a script at a given path'
complete -f -c marathon -n '__fish_marathon_needs_command' -a 'install' -d 'Install a script at a given path or URL as a binary'
complete -f -c marathon -n '__fish_marathon_needs_command' -a 'add' -d 'Add a package from a given URL to be able to use it from your scripts'
complete -f -c marathon -n '__fish_marathon_needs_command' -a 'list' -d 'List all packages and cached script data'
complete -f -c marathon -n '__fish_marathon_needs_command' -a 'update' -d 'Update all added packages to their latest versions'
complete -f -c marathon -n '__fish_marathon_needs_command' -a 'help' -d 'Print these instructions'
Simple math: 38 lines vs 17 lines
I do realize that maintaining bash scripts isn't so cool compared to writing Swift scripts, but you get my point π Also, this will require manual updates to each completions file just to make them work with the latest Marathon version, but still, I thinks it'll be a simpler solution π
This PR closes #74
As discussed with @JohnSundell in #74 - it's super cool to have autocompletions in shells, so it's way easier to use tool. I've added very basic for of autocompletions for
fish
shell.During the development of this feature I was hoping to find a universal solution, but in the end I think what we currently have is simply an overkill π Let me tell you why... (But there's a place for some nice refactoring, cause what I did is a code duplication. We can standardize it, extract it and make it way nicer)
The most popular shells are (I guess):
bash
,zsh
andfish
. In that case making something super generic and fully automatic is just a something we shouldn't spend much time.Secondly, shells like
fish
andzsh
(AFAIR) are interactive, so you have a lot of nice features available there which we simply can't use, cause we're generating scripts, so we assume they're really repetitive, right? Example: infish
you can specify behavior of thecompletion
based on passed parameters and also specify the results via different command. In case of Marathon when we call completion onmarathon remove
it will suggest only installed packages at.marathon/Scripts/Cached
- COOL, HUH? πLast, but not least, when someone will want to contribute to this... Well... It's hard to get easily what's happening, cause we're escaping string and blah, blah, blah...
If you take a look at the file I had to write to generate
marathon.fish
and onmarathon.fish
directly...Simple math: 38 lines vs 17 lines I do realize that maintaining bash scripts isn't so cool compared to writing Swift scripts, but you get my point π Also, this will require manual updates to each completions file just to make them work with the latest Marathon version, but still, I thinks it'll be a simpler solution π
Let me know what do you think... βοΈ