summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--cmd/install/fish.go50
-rw-r--r--cmd/install/install.go27
-rw-r--r--cmd/install/utils.go10
3 files changed, 87 insertions, 0 deletions
diff --git a/cmd/install/fish.go b/cmd/install/fish.go
new file mode 100644
index 0000000..f04e7c3
--- /dev/null
+++ b/cmd/install/fish.go
@@ -0,0 +1,50 @@
+package install
+
+import (
+ "bytes"
+ "fmt"
+ "os"
+ "path/filepath"
+ "text/template"
+)
+
+// (un)install in fish
+
+type fish struct {
+ configDir string
+}
+
+func (f fish) Install(cmd, bin string) error {
+ completionFile := filepath.Join(f.configDir, "completions", fmt.Sprintf("%s.fish", cmd))
+ completeCmd := f.cmd(cmd, bin)
+ if _, err := os.Stat(completionFile); err == nil {
+ return fmt.Errorf("already installed at %s", completionFile)
+ }
+
+ return createFile(completionFile, completeCmd)
+}
+
+func (f fish) Uninstall(cmd, bin string) error {
+ completionFile := filepath.Join(f.configDir, "completions", fmt.Sprintf("%s.fish", cmd))
+ if _, err := os.Stat(completionFile); err != nil {
+ return fmt.Errorf("does not installed in %s", f.configDir)
+ }
+
+ return os.Remove(completionFile)
+}
+
+func (f fish) cmd(cmd, bin string) string {
+ var buf bytes.Buffer
+ params := struct{ Cmd, Bin string }{cmd, bin}
+ template.Must(template.New("cmd").Parse(`
+function __complete_{{.Cmd}}
+ set -lx COMP_LINE (string join ' ' (commandline -o))
+ test (commandline -ct) = ""
+ and set COMP_LINE "$COMP_LINE "
+ {{.Bin}}
+end
+complete -c {{.Cmd}} -a "(__complete_{{.Cmd}})"
+`)).Execute(&buf, params)
+
+ return string(buf.Bytes())
+}
diff --git a/cmd/install/install.go b/cmd/install/install.go
index 082a226..4a70624 100644
--- a/cmd/install/install.go
+++ b/cmd/install/install.go
@@ -68,9 +68,36 @@ func installers() (i []installer) {
if f := rcFile(".zshrc"); f != "" {
i = append(i, zsh{f})
}
+ if d := fishConfigDir(); d != "" {
+ i = append(i, fish{d})
+ }
return
}
+func fishConfigDir() string {
+ configDir := filepath.Join(getConfigHomePath(), "fish")
+ if configDir == "" {
+ return ""
+ }
+ if info, err := os.Stat(configDir); err != nil || !info.IsDir() {
+ return ""
+ }
+ return configDir
+}
+
+func getConfigHomePath() string {
+ u, err := user.Current()
+ if err != nil {
+ return ""
+ }
+
+ configHome := os.Getenv("XDG_CONFIG_HOME")
+ if configHome == "" {
+ return filepath.Join(u.HomeDir, ".config")
+ }
+ return configHome
+}
+
func getBinaryPath() (string, error) {
bin, err := os.Executable()
if err != nil {
diff --git a/cmd/install/utils.go b/cmd/install/utils.go
index 2c8b44c..8bcf4e1 100644
--- a/cmd/install/utils.go
+++ b/cmd/install/utils.go
@@ -36,6 +36,16 @@ func lineInFile(name string, lookFor string) bool {
}
}
+func createFile(name string, content string) error {
+ f, err := os.Create(name)
+ if err != nil {
+ return err
+ }
+ defer f.Close()
+ _, err = f.WriteString(fmt.Sprintf("%s\n", content))
+ return err
+}
+
func appendToFile(name string, content string) error {
f, err := os.OpenFile(name, os.O_RDWR|os.O_APPEND, 0)
if err != nil {