summaryrefslogtreecommitdiff
path: root/bash.go
blob: 933281d50c8bf2dba9b898fa970ef4c360f98a2e (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
package prep

// initializes logging and command line options

import (
	"fmt"
	"os"
	"path/filepath"

	"go.wit.com/dev/alexflint/arg"
	"go.wit.com/lib/gui/shell"
	"go.wit.com/log"
)

var argBash ArgsBash

/*
This struct can be used with the go-arg package. These
are the generic default command line arguments for the 'GUI' package
*/
type ArgsBash struct {
	Bash bool `arg:"--bash"                               help:"generate bash completion"`
}

var myBash *BashAuto

type BashAuto struct {
	id      int  // should be unique
	hidden  bool // don't update the toolkits when it's hidden
	Auto    func([]string)
	appName string // a good way to track the name of the binary ?
}

func dumpjunk() {
	fmt.Fprintln(os.Stderr, "")
	fmt.Fprintln(os.Stderr, os.Args)
	os.Exit(0)
}

// argname is the name of the executable
func Bash(argname string, autocomplete func([]string)) *BashAuto {
	if len(os.Args) > 1 && os.Args[1] == "--bash" {
		doBash(argname)
		os.Exit(0)
	}

	if len(os.Args) > 1 && os.Args[1] == "--auto-complete" {
		autocomplete(os.Args[2:])
		os.Exit(0)
	}

	arg.Register(&argBash)

	myBash = new(BashAuto)
	myBash.appName = argname

	// parse go.Arg here?
	return myBash
}

// returns the name of the executable registered for shell autocomplete
func AppName() string {
	return myBash.appName
}

// makes a bash autocomplete file for your command
func doBash(argname string) {
	fmt.Println(makeBashCompletionText(argname))

	homeDir, err := os.UserHomeDir()
	if err != nil {
		log.Printf("%v\n", err)
		os.Exit(0)
	}
	filename := filepath.Join(homeDir, ".local/share/bash-completion/completions", argname)
	if shell.Exists(filename) {
		log.Println(filename, "file already exists")
		os.Exit(0)
	}
	basedir, _ := filepath.Split(filename)
	if !shell.IsDir(basedir) {
		os.MkdirAll(basedir, os.ModePerm)
	}

	if f, err := os.OpenFile(filename, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644); err == nil {
		f.Write([]byte(makeBashCompletionText(argname)))
		f.Close()
		log.Println("bash file created:", filename)
		log.Println("restart bash")
	} else {
		log.Info(filename, err)
	}
	os.Exit(0)
}

func makeBashCompletionText(argname string) string {
	var out string

	out += fmt.Sprintf("# add this in your bashrc:\n")
	out += fmt.Sprintf("\n")
	out += fmt.Sprintf("# todo: add this to go-arg as a 'hidden' go-arg option --bash\n")
	out += fmt.Sprintf("#\n")
	out += fmt.Sprintf("# Put the below in the file: ~/.local/share/bash-completion/completions/%s\n", argname)
	out += fmt.Sprintf("#\n")
	out += fmt.Sprintf("# todo: make this output work/parse with:\n")
	out += fmt.Sprintf("# complete -C %s --bash go\n", argname)
	out += fmt.Sprintf("\n")
	out += fmt.Sprintf("_%s_complete()\n", argname)
	out += fmt.Sprintf("{\n")
	out += fmt.Sprintf("	# sets local to this func vars\n")
	out += fmt.Sprintf("	local cur prev all\n")
	out += fmt.Sprintf("	cur=${COMP_WORDS[COMP_CWORD]}\n")
	out += fmt.Sprintf("	prev=${COMP_WORDS[COMP_CWORD-1]}\n")
	out += fmt.Sprintf("	all=${COMP_WORDS[@]}\n")
	out += fmt.Sprintf("\n")
	out += fmt.Sprintf("	# this is where we generate the go-arg output\n")
	out += fmt.Sprintf("        GOARGS=$(%s --auto-complete $prev \\'$cur\\' $all)\n", argname)
	out += fmt.Sprintf("\n")
	out += fmt.Sprintf("	# this compares the command line input from the user\n")
	out += fmt.Sprintf("	# to whatever strings we output\n")
	out += fmt.Sprintf("        COMPREPLY=( $(compgen -W \"$GOARGS\" -- $cur) )  # THIS WORKS\n")
	out += fmt.Sprintf("	return 0\n")
	out += fmt.Sprintf("}\n")
	out += fmt.Sprintf("complete -F _%s_complete %s\n", argname, argname)
	out += fmt.Sprintf("\n")
	out += fmt.Sprintf("# copy and paste the above into your bash shell should work\n")
	return out
}

/*
// prints help to STDERR // TODO: move everything below this to go-args
func (args) doBashHelp() {
	if argv.BashAuto[1] != "''" {
		// if this is not blank, then the user has typed something
		return
	}
	if argv.BashAuto[0] != ARGNAME {
		// if this is not the name of the command, the user already started doing something
		return
	}
	if argv.BashAuto[0] == ARGNAME {
		me.pp.WriteHelp(os.Stderr)
		return
	}
	fmt.Fprintln(os.Stderr, "")
	fmt.Fprintln(os.Stderr, "hello world")
	fmt.Fprintln(os.Stderr, "")
}
*/