Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

How to keep default bash filename completion for positional argument? #131

Open
romainreignier opened this issue Dec 29, 2020 · 3 comments

Comments

@romainreignier
Copy link

Hi, I really like how easily complete allows to add completion to CLI tools using flag but since I use it, I have lost the classic bash completion on filenames for positional arguments.

Take this example:

package main

import (
	"flag"
	"fmt"
	"os"

	"github.com/posener/complete/v2"
)

func main() {
	printJSON := flag.Bool("json", false, "prints the filename in JSON")

	complete.CommandLine()
	flag.Parse()

	if flag.NArg() < 1 {
		fmt.Printf("File argument is missing\n\n")
		flag.Usage()
		os.Exit(1)
	}

	if *printJSON {
		fmt.Println("{\"filename\": \"" + flag.Arg(0) + "\"}")
	} else {
		fmt.Println("File: " + flag.Arg(0))
	}
}

Without the complete.CommandLine() line, I do not get completion for the -json flag but my positional argument is well completed by bash.
But with this line, I do not get completion anymore.

Is there anything to get the file completion behavior back?

Thank you

@posener
Copy link
Owner

posener commented Dec 29, 2020

Hi there,

I am not aware for any fall back option. If there is such, it will be nice to have it.
Other than that, I can give you two options:

  1. Try the posener/cmd library, where you can easily define completion for positional arguments.
  2. Use the Command.Args option

@romainreignier
Copy link
Author

Hi @posener

Thank you for your reply.

The solution 1. seems the simpler.

I have then modified my minimal example to:

package main

import (
	"fmt"
	"os"

	"github.com/posener/cmd"
	"github.com/posener/complete/v2/predict"
)

func main() {
	root := cmd.New()
	printJSON := root.Bool("json", false, "prints the filename in JSON")
	args := root.Args("<input_file>", "File to print the name", predict.OptPredictor(predict.Files("*")))
	root.Parse()

	// Could be remplaced with args = make(cmd.ArgsStr, 1) and ArgsVar()
	if len(*args) < 1 {
		fmt.Printf("File argument is missing\n\n")
		root.Usage()
		os.Exit(1)
	}

	if *printJSON {
		fmt.Println("{\"filename\": \"" + (*args)[0] + "\"}")
	} else {
		fmt.Println("File: " + (*args)[0])
	}
}

Without the --json flag, the positional argument is completed but when the boolean flag is used, the file completion does not work.

What would be the correct usage?

Thank you

@posener
Copy link
Owner

posener commented Dec 30, 2020

Hi

Right, it seems to be a bug... 😞

$ ./test <tab>
./       go.mod   go.sum   -h       -json    main.go  test

But ./test -json<tab> adds space, and then ./test -json <tab> adds dash, and then:

$ ./test -json -
-h     -json 

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
Development

No branches or pull requests

2 participants