Add additional args
add predition of directories add ability for prediction union
This commit is contained in:
parent
04d16f6064
commit
c8263230e1
|
@ -7,6 +7,7 @@ type Flags map[string]Predicate
|
|||
type Command struct {
|
||||
Sub Commands
|
||||
Flags Flags
|
||||
Args Predicate
|
||||
}
|
||||
|
||||
// options returns all available complete options for the given command
|
||||
|
@ -38,6 +39,11 @@ func (c *Command) options(args []string) (options []Option, only bool) {
|
|||
options = append(options, Arg(flag))
|
||||
}
|
||||
|
||||
// add additional expected argument of the command
|
||||
if c.Args.Expects {
|
||||
options = append(options, c.Args.predict()...)
|
||||
}
|
||||
|
||||
return
|
||||
}
|
||||
|
||||
|
|
|
@ -27,12 +27,13 @@ func TestCompleter_Complete(t *testing.T) {
|
|||
"-flag2": PredictNothing,
|
||||
"-flag3": PredictNothing,
|
||||
},
|
||||
Args: PredictDirs("./tests/").Or(PredictFiles("./tests/*.md")),
|
||||
},
|
||||
},
|
||||
Flags: map[string]Predicate{
|
||||
"-h": PredictNothing,
|
||||
"-global1": PredictAnything,
|
||||
"-o": PredictFiles("./gocomplete/*.go"),
|
||||
"-o": PredictFiles("./tests/*.txt"),
|
||||
},
|
||||
},
|
||||
}
|
||||
|
@ -45,6 +46,8 @@ func TestCompleter_Complete(t *testing.T) {
|
|||
allGlobals = append(allGlobals, flag)
|
||||
}
|
||||
|
||||
testTXTFiles := []string{"./tests/a.txt", "./tests/b.txt", "./tests/c.txt"}
|
||||
|
||||
tests := []struct {
|
||||
args string
|
||||
want []string
|
||||
|
@ -83,7 +86,19 @@ func TestCompleter_Complete(t *testing.T) {
|
|||
},
|
||||
{
|
||||
args: "sub2 ",
|
||||
want: []string{"-flag2", "-flag3", "-h", "-global1", "-o"},
|
||||
want: []string{"./tests", "-flag2", "-flag3", "-h", "-global1", "-o"},
|
||||
},
|
||||
{
|
||||
args: "sub2 tests",
|
||||
want: []string{"./tests", "./tests/readme.md", "./tests/dir"},
|
||||
},
|
||||
{
|
||||
args: "sub2 tests/re",
|
||||
want: []string{"./tests/readme.md"},
|
||||
},
|
||||
{
|
||||
args: "sub2 -flag2 ",
|
||||
want: []string{"./tests", "-flag2", "-flag3", "-h", "-global1", "-o"},
|
||||
},
|
||||
{
|
||||
args: "sub1 -fl",
|
||||
|
@ -119,15 +134,31 @@ func TestCompleter_Complete(t *testing.T) {
|
|||
},
|
||||
{
|
||||
args: "-o ",
|
||||
want: []string{"./gocomplete/complete.go"},
|
||||
want: []string{},
|
||||
},
|
||||
{
|
||||
args: "-o goco",
|
||||
want: []string{"./gocomplete/complete.go"},
|
||||
args: "-o ./tes",
|
||||
want: []string{},
|
||||
},
|
||||
{
|
||||
args: "-o ./goco",
|
||||
want: []string{"./gocomplete/complete.go"},
|
||||
args: "-o tests/",
|
||||
want: testTXTFiles,
|
||||
},
|
||||
{
|
||||
args: "-o tests",
|
||||
want: testTXTFiles,
|
||||
},
|
||||
{
|
||||
args: "-o ./compl",
|
||||
want: []string{},
|
||||
},
|
||||
{
|
||||
args: "-o ./complete.go",
|
||||
want: []string{},
|
||||
},
|
||||
{
|
||||
args: "-o ./complete.go ",
|
||||
want: allGlobals,
|
||||
},
|
||||
}
|
||||
|
||||
|
|
|
@ -10,6 +10,7 @@ var (
|
|||
"-o": complete.PredictFiles("*"),
|
||||
"-i": complete.PredictNothing,
|
||||
},
|
||||
Args: complete.PredictFiles("**.go").Or(complete.PredictDirs("./")),
|
||||
}
|
||||
|
||||
test = complete.Command{
|
||||
|
|
|
@ -35,5 +35,8 @@ func (a ArgFileName) Matches(prefix string) bool {
|
|||
if err != nil {
|
||||
logger("failed getting abs path of %s: %s", prefix, err)
|
||||
}
|
||||
return strings.HasPrefix(full, prefixFull)
|
||||
|
||||
// if the file has the prefix as prefix,
|
||||
// but we don't want to show too many files, so, if it is in a deeper directory - omit it.
|
||||
return strings.HasPrefix(full, prefixFull) && (full == prefixFull || !strings.Contains(full[len(prefixFull)+1:], "/"))
|
||||
}
|
||||
|
|
51
predicate.go
51
predicate.go
|
@ -16,11 +16,20 @@ type Predicate struct {
|
|||
Predictor func() []Option
|
||||
}
|
||||
|
||||
func (f *Predicate) predict() []Option {
|
||||
if f.Predictor == nil {
|
||||
// Or unions two predicate struct, so that the result predicate
|
||||
// returns the union of their predication
|
||||
func (p Predicate) Or(other Predicate) Predicate {
|
||||
return Predicate{
|
||||
Expects: p.Expects && other.Expects,
|
||||
Predictor: func() []Option { return append(p.predict(), other.predict()...) },
|
||||
}
|
||||
}
|
||||
|
||||
func (p Predicate) predict() []Option {
|
||||
if p.Predictor == nil {
|
||||
return nil
|
||||
}
|
||||
return f.Predictor()
|
||||
return p.Predictor()
|
||||
}
|
||||
|
||||
var (
|
||||
|
@ -35,6 +44,28 @@ func PredictFiles(pattern string) Predicate {
|
|||
}
|
||||
}
|
||||
|
||||
func PredictDirs(path string) Predicate {
|
||||
return Predicate{
|
||||
Expects: true,
|
||||
Predictor: dirs(path),
|
||||
}
|
||||
}
|
||||
func dirs(path string) func() []Option {
|
||||
return func() (options []Option) {
|
||||
dirs := []string{}
|
||||
filepath.Walk(path, func(path string, info os.FileInfo, err error) error {
|
||||
if info.IsDir() {
|
||||
dirs = append(dirs, path)
|
||||
}
|
||||
return nil
|
||||
})
|
||||
if !filepath.IsAbs(path) {
|
||||
filesToRel(dirs)
|
||||
}
|
||||
return filesToOptions(dirs)
|
||||
}
|
||||
}
|
||||
|
||||
func glob(pattern string) func() []Option {
|
||||
return func() []Option {
|
||||
files, err := filepath.Glob(pattern)
|
||||
|
@ -44,11 +75,7 @@ func glob(pattern string) func() []Option {
|
|||
if !filepath.IsAbs(pattern) {
|
||||
filesToRel(files)
|
||||
}
|
||||
options := make([]Option, len(files))
|
||||
for i, f := range files {
|
||||
options[i] = ArgFileName(f)
|
||||
}
|
||||
return options
|
||||
return filesToOptions(files)
|
||||
}
|
||||
}
|
||||
func filesToRel(files []string) {
|
||||
|
@ -69,3 +96,11 @@ func filesToRel(files []string) {
|
|||
}
|
||||
return
|
||||
}
|
||||
|
||||
func filesToOptions(files []string) []Option {
|
||||
options := make([]Option, len(files))
|
||||
for i, f := range files {
|
||||
options[i] = ArgFileName(f)
|
||||
}
|
||||
return options
|
||||
}
|
||||
|
|
|
@ -0,0 +1,3 @@
|
|||
# About this directory
|
||||
|
||||
This directory is for testing file completion purposes
|
Loading…
Reference in New Issue