Add support for fish

This commit is contained in:
Yuki Ito 2018-01-08 17:51:45 +09:00
parent 6bee943216
commit fbb0b60454
3 changed files with 87 additions and 0 deletions

50
cmd/install/fish.go Normal file
View File

@ -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())
}

View File

@ -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 {

View File

@ -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 {