From df724b40064c62883c5466eea2dc50683fc823cf Mon Sep 17 00:00:00 2001 From: Norwin Date: Mon, 24 May 2021 04:42:21 +0800 Subject: [PATCH] Add tab completion for fish shell (#364) as title, fixes #361 Handling of fish shell is different in urfave/cli; urfave/cli provides a generator for the shell script needed (probably because the fish `completion` syntax isn't flexible enough to let the application handle the completion at runtime? idk) This means that the fish completion can become out of sync with the tea binary. If we want to account for that, on each application run we need to - check if `~/.config/fish/conf.d/tea_completion.fish` exists; if so - check if the tea version that wrote it is the currently running version - if not, rewrite the file. Not sure this is worth the complexity & cost It generates a completion that also suggests file names, which looks kinda messy: Didn't find a way around this, but [there may be a way](https://github.com/urfave/cli/blob/5bb54ace578d17a134feb806f22163e7064ede87/fish.go#L160-L180) ![grafik](/attachments/b08541c9-0f37-4c70-a2e3-1ec9da15a430) Co-authored-by: Norwin Roosen Co-authored-by: 6543 <6543@obermui.de> Reviewed-on: https://gitea.com/gitea/tea/pulls/364 Reviewed-by: 6543 <6543@obermui.de> Reviewed-by: Lunny Xiao Co-authored-by: Norwin Co-committed-by: Norwin --- cmd/autocomplete.go | 42 +++++++++++++++++++++++++++++++++++++----- 1 file changed, 37 insertions(+), 5 deletions(-) diff --git a/cmd/autocomplete.go b/cmd/autocomplete.go index 64e7289..cb69887 100644 --- a/cmd/autocomplete.go +++ b/cmd/autocomplete.go @@ -22,7 +22,7 @@ var CmdAutocomplete = cli.Command{ Category: catSetup, Usage: "Install shell completion for tea", Description: "Install shell completion for tea", - ArgsUsage: " (bash, zsh, powershell)", + ArgsUsage: " (bash, zsh, powershell, fish)", Flags: []cli.Flag{ &cli.BoolFlag{ Name: "install", @@ -52,8 +52,14 @@ func runAutocompleteAdd(ctx *cli.Context) error { localFile = "tea.ps1" cmds = "\"& %s\" >> $profile" + case "fish": + // fish is different, in that urfave/cli provides a generator for the shell script needed. + // this also means that the fish completion can become out of sync with the tea binary! + // writing to this directory suffices, as fish reads files there on startup, no cmds needed. + return writeFishAutoCompleteFile(ctx) + default: - return fmt.Errorf("Must specify valid shell type") + return fmt.Errorf("Must specify valid %s", ctx.Command.ArgsUsage) } localPath, err := xdg.ConfigFile("tea/" + localFile) @@ -62,8 +68,7 @@ func runAutocompleteAdd(ctx *cli.Context) error { } cmds = fmt.Sprintf(cmds, localPath) - - if err := saveAutoCompleteFile(remoteFile, localPath); err != nil { + if err = writeRemoteAutoCompleteFile(remoteFile, localPath); err != nil { return err } @@ -85,7 +90,7 @@ func runAutocompleteAdd(ctx *cli.Context) error { return nil } -func saveAutoCompleteFile(file, destPath string) error { +func writeRemoteAutoCompleteFile(file, destPath string) error { url := fmt.Sprintf("https://gitea.com/gitea/tea/raw/branch/master/%s", file) fmt.Println("Fetching " + url) @@ -104,3 +109,30 @@ func saveAutoCompleteFile(file, destPath string) error { _, err = io.Copy(writer, res.Body) return err } + +func writeFishAutoCompleteFile(ctx *cli.Context) error { + // NOTE: to make sure this file is in sync with tea commands, we'd need to + // - check if the file exists + // - if it does, check if the tea version that wrote it is the currently running version + // - if not, rewrite the file + // on each application run + // NOTE: this generates a completion that also suggests file names, which looks kinda messy.. + script, err := ctx.App.ToFishCompletion() + if err != nil { + return err + } + + localPath, err := xdg.ConfigFile("fish/conf.d/tea_completion.fish") + if err != nil { + return err + } + writer, err := os.Create(localPath) + if err != nil { + return err + } + if _, err = io.WriteString(writer, script); err != nil { + return err + } + fmt.Printf("Installed tab completion to %s\n", localPath) + return nil +}