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 {
|
type Command struct {
|
||||||
Sub Commands
|
Sub Commands
|
||||||
Flags Flags
|
Flags Flags
|
||||||
|
Args Predicate
|
||||||
}
|
}
|
||||||
|
|
||||||
// options returns all available complete options for the given command
|
// 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))
|
options = append(options, Arg(flag))
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// add additional expected argument of the command
|
||||||
|
if c.Args.Expects {
|
||||||
|
options = append(options, c.Args.predict()...)
|
||||||
|
}
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,12 +27,13 @@ func TestCompleter_Complete(t *testing.T) {
|
||||||
"-flag2": PredictNothing,
|
"-flag2": PredictNothing,
|
||||||
"-flag3": PredictNothing,
|
"-flag3": PredictNothing,
|
||||||
},
|
},
|
||||||
|
Args: PredictDirs("./tests/").Or(PredictFiles("./tests/*.md")),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
Flags: map[string]Predicate{
|
Flags: map[string]Predicate{
|
||||||
"-h": PredictNothing,
|
"-h": PredictNothing,
|
||||||
"-global1": PredictAnything,
|
"-global1": PredictAnything,
|
||||||
"-o": PredictFiles("./gocomplete/*.go"),
|
"-o": PredictFiles("./tests/*.txt"),
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -45,6 +46,8 @@ func TestCompleter_Complete(t *testing.T) {
|
||||||
allGlobals = append(allGlobals, flag)
|
allGlobals = append(allGlobals, flag)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
testTXTFiles := []string{"./tests/a.txt", "./tests/b.txt", "./tests/c.txt"}
|
||||||
|
|
||||||
tests := []struct {
|
tests := []struct {
|
||||||
args string
|
args string
|
||||||
want []string
|
want []string
|
||||||
|
@ -83,7 +86,19 @@ func TestCompleter_Complete(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
args: "sub2 ",
|
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",
|
args: "sub1 -fl",
|
||||||
|
@ -119,15 +134,31 @@ func TestCompleter_Complete(t *testing.T) {
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
args: "-o ",
|
args: "-o ",
|
||||||
want: []string{"./gocomplete/complete.go"},
|
want: []string{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
args: "-o goco",
|
args: "-o ./tes",
|
||||||
want: []string{"./gocomplete/complete.go"},
|
want: []string{},
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
args: "-o ./goco",
|
args: "-o tests/",
|
||||||
want: []string{"./gocomplete/complete.go"},
|
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("*"),
|
"-o": complete.PredictFiles("*"),
|
||||||
"-i": complete.PredictNothing,
|
"-i": complete.PredictNothing,
|
||||||
},
|
},
|
||||||
|
Args: complete.PredictFiles("**.go").Or(complete.PredictDirs("./")),
|
||||||
}
|
}
|
||||||
|
|
||||||
test = complete.Command{
|
test = complete.Command{
|
||||||
|
|
|
@ -35,5 +35,8 @@ func (a ArgFileName) Matches(prefix string) bool {
|
||||||
if err != nil {
|
if err != nil {
|
||||||
logger("failed getting abs path of %s: %s", prefix, err)
|
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
|
Predictor func() []Option
|
||||||
}
|
}
|
||||||
|
|
||||||
func (f *Predicate) predict() []Option {
|
// Or unions two predicate struct, so that the result predicate
|
||||||
if f.Predictor == nil {
|
// 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 nil
|
||||||
}
|
}
|
||||||
return f.Predictor()
|
return p.Predictor()
|
||||||
}
|
}
|
||||||
|
|
||||||
var (
|
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 {
|
func glob(pattern string) func() []Option {
|
||||||
return func() []Option {
|
return func() []Option {
|
||||||
files, err := filepath.Glob(pattern)
|
files, err := filepath.Glob(pattern)
|
||||||
|
@ -44,11 +75,7 @@ func glob(pattern string) func() []Option {
|
||||||
if !filepath.IsAbs(pattern) {
|
if !filepath.IsAbs(pattern) {
|
||||||
filesToRel(files)
|
filesToRel(files)
|
||||||
}
|
}
|
||||||
options := make([]Option, len(files))
|
return filesToOptions(files)
|
||||||
for i, f := range files {
|
|
||||||
options[i] = ArgFileName(f)
|
|
||||||
}
|
|
||||||
return options
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
func filesToRel(files []string) {
|
func filesToRel(files []string) {
|
||||||
|
@ -69,3 +96,11 @@ func filesToRel(files []string) {
|
||||||
}
|
}
|
||||||
return
|
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