posener / complete Goto Github PK
View Code? Open in Web Editor NEWbash completion written in go + bash completion for go command
License: MIT License
bash completion written in go + bash completion for go command
License: MIT License
go get
gocomplete -install
cd ..example/self && go run main.go -complete
$ self [Tab]
❌
compgen:96: no such file or directory: /var/folders/80/gh9snl2d35bcgh166p7jqs940000gn/T/go-build209898158/command-line-arguments/_obj/exe/main
goroutine 1 [running]:
.../vendor/github.com/posener/complete.(*Complete).Complete(0xc00038c690, 0x0)
.../vendor/github.com/posener/complete/complete.go:67 +0x634
...
panic: runtime error: slice bounds out of range```
on tabbing for completion right after the name of the command. I haven't investigated closer but reverting to `1.1.2` fixes the issue.
var force = flag.String("f", "", "force")
...
// Auto completion
cmd := &complete.Command{
Sub: map[string]*complete.Command{
"update": {
Sub: offPred,
Flags: map[string]complete.Predictor{
"f": predict.Nothing,
},
},
},
}
cmd.Complete("<cmd>")
On the latest version, when I execute this code, only Sub:
will get suggested. However, if I remove the Sub:
entirely, then Flags:
show up. I have the feeling I'm doing it wrong, but I've boiled it down to this, at least.
PS: I'm using Kong as well, and the -h
flag always shows up automatically (not sure if that's Kong or this package), but that flag shows up fine.
gocomplete
installation procedure as detailed in the documentation.go test /bi
and press Tab once to trigger shell autocompletion.The line is completed as go test /bin/
. There is no additional output.
The prompt is filled with diagnostic messages. On my system it looks like this:
$ go test /bi2021/04/06 12:56:04 failed importing directory /bin: no buildable Go source files in /bin
2021/04/06 12:56:04 failed importing directory /boot: no buildable Go source files in /boot
2021/04/06 12:56:04 failed importing directory /cdrom: no buildable Go source files in /cdrom
2021/04/06 12:56:04 failed importing directory /dev: no buildable Go source files in /dev
2021/04/06 12:56:04 failed importing directory /etc: no buildable Go source files in /etc
2021/04/06 12:56:04 failed importing directory /home: no buildable Go source files in /home
2021/04/06 12:56:04 failed importing directory /lib: no buildable Go source files in /lib
2021/04/06 12:56:04 failed importing directory /lib32: no buildable Go source files in /lib32
2021/04/06 12:56:04 failed importing directory /lib64: no buildable Go source files in /lib64
2021/04/06 12:56:04 failed importing directory /lost+found: open /lost+found: permission denied
2021/04/06 12:56:04 failed importing directory /media: no buildable Go source files in /media
2021/04/06 12:56:04 failed importing directory /mnt: no buildable Go source files in /mnt
2021/04/06 12:56:04 failed importing directory /opt: no buildable Go source files in /opt
2021/04/06 12:56:04 failed importing directory /proc: no buildable Go source files in /proc
2021/04/06 12:56:04 failed importing directory /root: open /root: permission denied
2021/04/06 12:56:04 failed importing directory /run: no buildable Go source files in /run
2021/04/06 12:56:04 failed importing directory /sbin: no buildable Go source files in /sbin
2021/04/06 12:56:04 failed importing directory /snap: no buildable Go source files in /snap
2021/04/06 12:56:04 failed importing directory /srv: no buildable Go source files in /srv
2021/04/06 12:56:04 failed importing directory /sys: no buildable Go source files in /sys
2021/04/06 12:56:04 failed importing directory /tmp: no buildable Go source files in /tmp
2021/04/06 12:56:04 failed importing directory /usr: no buildable Go source files in /usr
2021/04/06 12:56:04 failed importing directory /var: no buildable Go source files in /var
2021/04/06 12:56:04 failed importing directory /: no buildable Go source files in /
n/
It's not that difficult to find your bearings and work from the assumption that the command was completed as expected (as described earlier) in this trivial case, but it becomes particularly annoying when you are in the middle of a more complex invocation, such as a build or a tool command with multiple flags, options and other parameters.
A false assumption is made that all errors are always relevant to the end user and therefore everything should be dumped to stderr
without distinction.
I would like to predict not hardcoded options but pull them from daemon every time.
For example I input command app user remove
, click TAB, and cli would offer me list of users which pulled by calling exec.Command("cli-get-users')
type ppred struct{}
func (y ppred) Predict(prefix string) []string {
dateCmd := exec.Command("app", "user", "list")
dateOut, err := dateCmd.Output()
if err != nil {
// handle error
}
s := strings.Split(strings.TrimSpace(string(dateOut)), "\n")
return predict.Set(s).Predict(prefix)
}
Output is always empty, but when I run this code inside unit test, output is present and we're all good.
If this is expected behaviour please someone explain or point me to explanation why it's not working.
If command complete
does not exists, fail the installation with appropriate error.
Global flags should not be valid/recommended after a subcommand, should they? Currently in s5cmd/develop I'm reading COMP_LINE
and checking if any subcommands (well, "non-flags") are specified, if they are, I reset Command.Flags
to nil
(before the complete.New()
call) to remedy this. Also, some flags can be mutually exclusive. So, a way to turn off a specific flag might be handy and help with these cases. Flags are also recommended after arguments, which doesn't seem like a common/intuitive use to me.
To help with these issues, maybe support a flag "callback" to dynamically disable a particular flag? Where one might check for Args.Last
and if there's an argument (non-flag) there (or a mutually-exclusive option is already specified) disable the flag essentially making the completion smarter. (I might make a PR for this if you like, if you don't have something better in mind that is...)
Hi there!
First, thank you for the great library! I'm encountering a weird issue that only seems present on zsh. Here's a quick program to reproduce:
package main
import (
"github.com/posener/complete"
)
func main() {
run := complete.Command{
Args: complete.PredictFiles("*"),
}
complete.New("playground", run).Run()
}
Compile this and install the shell completions. On my shell (zsh), when I run this command and press <tab>
, I correctly get a list of files. However, when I select a folder and press <enter>
, a space is inserted and prediction stops.
Here's the same binary, same terminal, using /bin/bash instead of /bin/zsh:
As you can see, selecting an item in zsh appears to move to the next argument where bash continues to wait for the next filepath.
Do you have any ideas here? I've done a complete uninstall of zsh and disabled all plugins and still see the same behavior. Have you seen this before?
As an alternative to inferring the completion command from the binary, allow the command to be specified.
This is necessary for using a subcommand as a the completion command.
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
I followed the install command, go get -u github.com/posener/complete/v2/gocomplete
but got this error
package github.com/posener/complete/v2/gocomplete: cannot find package "github.com/posener/complete/v2/gocomplete" in any of
When writing completion function in bash you can use compopt -o nospace
to omit the trailing space from completed arguments.
How could something like this be achieved using this library? Calling out to compopt
from the predict function doesn't work.
Golang 1.16 introduced a change that makes the test fail:
Testing in: /builddir/build/BUILD/complete-2.0.1-alpha.13/_build/src
PATH: /builddir/build/BUILD/complete-2.0.1-alpha.13/_build/bin:/usr/bin:/bin:/usr/sbin:/sbin:/usr/local/sbin
GOPATH: /builddir/build/BUILD/complete-2.0.1-alpha.13/_build:/usr/share/gocode
GO111MODULE: off
command: go test -buildmode pie -compiler gc -ldflags " -X github.com/posener/complete/v2/version=2.0.1~alpha.13 -extldflags '-Wl,-z,relro -Wl,--as-needed -Wl,-z,now -specs=/usr/lib/rpm/redhat/redhat-hardened-ld '"
testing: github.com/posener/complete/v2
github.com/posener/complete/v2
PASS
ok github.com/posener/complete/v2 0.007s
github.com/posener/complete/v2/compflag
invalid value "3" for flag -a: not in allowed values: 1,2
Usage:
-a value
invalid value "3" for flag -a: not in allowed values: 1,2
Usage:
-a value
(default 0)
invalid value "1h" for flag -a: not in allowed values: 1s,1m
Usage:
invalid value "x" for flag -a: bad value for Int flag
-a value
(default 0s)
invalid value "1" for flag -a: bad value for Duration flag
Usage:
-a value
(default 0s)
Usage:
-a value
(default 0)
PASS
ok github.com/posener/complete/v2/compflag 0.006s
github.com/posener/complete/v2/gocomplete
run
--- FAIL: Example (0.00s)
panic: unexpected call to os.Exit(0) during test [recovered]
panic: unexpected call to os.Exit(0) during test
It is maybe related to https://tip.golang.org/doc/go1.16#go-test
golang/go#29062
https://go-review.googlesource.com/c/go/+/250977/
Now, the way of installation of Golang's pacage is as follow.
go install github.com/posener/complete/v2/gocomplete@latest
Can I modify a README of this repository?
Consider tagging a new patch release as v1.1.2 so that people still using the dep tool will clearly know that they can pull in a new version that includes the minor changes that have been made since 1.1.1.
I ran into troubles when implementing autocompletion for multiple positional arguments if flags are present.
In order to implement autocompletion for both position arguments, you need to check how many args have already been completed (via args.Completed
). Here's an example from terraform (and the implementation).
And here's another example from my own CLI package.
These work fine when no flags are present, but it breaks down if there's flags because those flags will be included in args.Completed
which means you can't naively just check the length of the array.
trellis deploy prod<tab>
# autocompletes to production
trellis deploy production exam<tab>
# autocompletes to example.com
trellis deploy --bran<tab>
# autocompletes to branch
trellis deploy --branch=foo prod<tab>
# does not autocomplete properly
I think I've been able to fix this by passing in the flag.FlagSet
and parsing the args on every prediction. Then instead of checking the length of args.Completed
, you use the length of parsed positional args. However, this adds a lot of complexity and seemed non-intuitive. Here's my solution so far: https://github.com/roots/trellis-cli/blob/dd2156bf2c923978ef3866c2b00517d903553cc8/trellis/complete.go#L38-L55
Since args and flags are handled separately in complete.Command
, I'd kind of expect that the predict function just for args wouldn't include the flags. Or if it did (because that might be useful in case positional args depend on flags?), complete.Args
would at least handle this automatically and provide both separately?
This would be a breaking change, but could this package move completed flags out of args.Completed
and into args.FlagsCompleted
? Or maybe Predict
could be called like this for arguments:
c.Predict(args, flags)
Though that seems much more breaking. I'm probably missing other solutions as well though 😅
$ go tool com<tab>
$ go tool pp<tab>
This should autocomplete to go tool compile
and go tool pprof
. And ideally also understand the subcommands' flags (of which there are admittedly many). But just completing the subcommands themselves would be a nice start.
Hello,
The Travis pipeline uses the CodeCov.io bash uploader on successful builds. The bash uploader was recently involved in a security incident. This is both a heads up as well as a request to consider removing the CodeCov dependency. If CodeCov is still needed would it be feasible to instead use a static known-good copy of the uploader instead of grabbing latest and executing it?
Thanks!
I use this package's go completion daily and I really appreciate it. However the completion suggestions for packages is both limited and now outdated as it relies on GOPATH, which is effectively deprecated.
I would like the go completion to take advantage of go list
to obtain a module aware list of suggestions. This can even be used to greatly improve the use of go doc
and complete not just package name but also symbols from the package. The suggestions can even take into account the -u
flag and offer unexported completion suggestions as well.
This can fall back to searching the module cache if no matching name is in the local projects go.mod file, and finally it could fall back to searching $GOPATH/src/ for package name completions.
I did a little research and discovered that there is no package that exposes the same functionality as go list
however it has well defined JSON output option so parsing the output is trivial.
I am interested in submitting a PR for this but wanted to discuss it in an issue first.
Shells like zsh
and fish
support specifying descriptions of suggestions. Would be amazing if you could implement support for this, e.g.
zsh
fish
-d
/--description
)\t
separator)Currently the completion assumes that the cursor is on the end of the completion line.
There is an environment variable COMP_POINT which indicates the cursor location, which this library should use.
Hey,
I want from my tool which is using posener/complete to automatically show a yes/no prompt to request user's consent to install bash completion (or others).
However it seems there is no way to avoid to show that prompt when completion is already installed. It seems the only way to do that is to to add IsInstalled() API.
I can send a PR for that if my proposal is accepted.
I did:
$ go get -u github.com/posener/complete/gocomplete
$ gocomplete -install
# restart shell
$ go bui<tab>
Result: No completion.
From a cursory scan of the source, gocomplete -install
should have prompted me, but it did not. Is it possible that the completer for go install
is somehow interfering with the request for installation?
Thanks, and looking forward to using this.
Is there any way for a subcommands' prediction to get its parents flags?
For example
adb -s FA81Y1A02186 uninstall com.blabla
-s flag correctly predicts FA81Y1A02186.
However, if i in the handler want to predict what packages to uninstall, i need the predicted flag value from before. Because i want to query the specific device for packages that are installed.
Currently i can't. Maybe i've missed something.
I discovered this while using Hashicorp's Vault. Please see hashicorp/vault#4094 (hashicorp/vault#4094 (comment)) for more info.
Basically, I suspect the logic should first do a MkdirAll before creating a file. Otherwise, if the path contains a directory which is missing it would fail.
Is there a standard way of caching results (eg api call response) between completion calls.
The seemingly standard way of doing it in bash based completions is to used a global variable eg [1].
I understand this isn't technically an issue with this library. However it seems the appropriate place to ask the question.
Hi, I just started getting this error:
❯ go version
go version go1.7.6 linux/amd64
❯ go get -u github.com/posener/complete/gocomplete
# github.com/posener/complete/cmd/install
go/src/github.com/posener/complete/cmd/install/install.go:75: undefined: os.Executable
❯ echo $?
2
tv@dark ~$ mkdir z
tv@dark ~$ cd z
tv@dark ~/z$ go mod init m
go: creating new go.mod: module m
tv@dark ~/z$ go get github.com/posener/complete/gocomplete
go: finding github.com/posener/complete/gocomplete latest
package github.com/posener/complete/gocomplete: unknown import path "github.com/posener/complete/gocomplete": ambiguous import: found github.com/posener/complete/gocomplete in multiple modules:
github.com/posener/complete v1.1.2 (/home/tv/go/pkg/mod/github.com/posener/[email protected]/gocomplete)
github.com/posener/complete/gocomplete v0.0.0-20190609060259-60e9d0a23799 (/home/tv/go/pkg/mod/github.com/posener/complete/[email protected])
[EXIT:1] tv@dark ~/z$
At this point, you'd be better off removing gocomplete/go.* completely. It can be part of the parent module.
Thanks for making this lib it's quite useful. Please see the error and potential problem outlined below.
10:21:07 chrome@Beast src → bit complete
install completion for bit? y
installing...
regexp: Compile(`^complete -C C:\Users\chrome\go\bin\bit.exe bit$`): error parsing regexp: invalid escape sequence: `\U`
goroutine 1 [running]:
runtime/debug.Stack(0xf51840, 0xc000006018, 0xc00011cc78)
C:/Dev/Go/src/runtime/debug/stack.go:24 +0xa5
github.com/chriswalz/bit/cmd.HandleExit()
C:/Users/chrome/go/pkg/mod/github.com/chriswalz/[email protected]/cmd/util.go:320 +0xea
panic(0xe0cfe0, 0xc0000533f0)
C:/Dev/Go/src/runtime/panic.go:965 +0x1c7
regexp.MustCompile(0xc000376510, 0x30, 0x1)
C:/Dev/Go/src/regexp/regexp.go:311 +0x15f
github.com/chriswalz/complete/v3/install.lineInFile(0xc00001cd38, 0x17, 0xc0003764b0, 0x2e, 0x2)
C:/Users/chrome/go/pkg/mod/github.com/chriswalz/complete/[email protected]/install/utils.go:12 +0x12c
github.com/chriswalz/complete/v3/install.bash.IsInstalled(0xc00001cd38, 0x17, 0xea613a, 0x3, 0xc000376450, 0x1e, 0x2)
C:/Users/chrome/go/pkg/mod/github.com/chriswalz/complete/[email protected]/install/bash.go:15 +0xfc
github.com/chriswalz/complete/v3/install.bash.Install(0xc00001cd38, 0x17, 0xea613a, 0x3, 0xc000376450, 0x1e, 0x0, 0x0)
C:/Users/chrome/go/pkg/mod/github.com/chriswalz/complete/[email protected]/install/bash.go:19 +0x77
github.com/chriswalz/complete/v3/install.Install(0xea613a, 0x3, 0xc00011d350, 0xe)
C:/Users/chrome/go/pkg/mod/github.com/chriswalz/complete/[email protected]/install/install.go:66 +0xf6
According to this comment the problem is due to:
https://github.com/posener/complete/blob/master/install/bash.go#L36
https://github.com/posener/complete/blob/master/install/bash.go#L15
https://github.com/posener/complete/blob/master/install/utils.go#L12
The code seems to assume that cmd or bin doesn't contain any regexp characters. The 3. probably should escape all those characters. It's weird that it's using regexps for that in the first place.
Feel free to close this immediately for being pedantic, however the comments in this package are not line wrapped at a sensible length. This is extremely annoying to work with in a terminal editor. This is totally a style choice, but I hate having to read comments in vim that go beyond 80 chars in length on a single line.
Test the gocomplete
package with the following applied:
diff --git a/gocomplete/tests_test.go b/gocomplete/tests_test.go
index 750147a..c7521ef 100644
--- a/gocomplete/tests_test.go
+++ b/gocomplete/tests_test.go
@@ -21,7 +21,7 @@ func TestPredictions(t *testing.T) {
{
name: "predict tests ok",
predictor: predictTest,
- want: []string{"TestPredictions", "Example"},
+ want: []string{"bork", "bork"},
},
{
name: "predict benchmark ok",
$ go test ./gocomplete/
ok github.com/posener/complete/v2/gocomplete 0.003s
$ go test -v ./gocomplete/
=== RUN TestPredictions
=== PAUSE TestPredictions
=== CONT TestPredictions
=== RUN TestPredictions/predict_tests_ok
tests_test.go:37: Failed TestPredictions/predict_tests_ok: got: ["Example" "TestPredictions"], want: ["bork" "bork"]
=== RUN TestPredictions/predict_benchmark_ok
--- FAIL: TestPredictions (0.00s)
--- FAIL: TestPredictions/predict_tests_ok (0.00s)
--- PASS: TestPredictions/predict_benchmark_ok (0.00s)
=== RUN Example
run
--- FAIL: Example (0.00s)
got:
want:
run
FAIL
ok github.com/posener/complete/v2/gocomplete 0.004s
The package testing
uses os.Exit
all over the place, and, as of 5d9f7f1, all those uses, including test failure reporting, are effectively broken once the gocomplete.Example
test runs.
I would prefer to use a completely different approach to exposing the install/uninstall than with the flags
package. I'm using a completely different package for building CLI apps, and would like to integrate the output of this framework with that other package by simply Printing/Sprinting the output to wherever the user wants.
The instruction is quite confusing for me. Here is what I did. I wrote a piece of code very similar to the example code on the doc page, which generated a binary let's call "autocomplete", then I run "./autocomplete -install" and install it. Then I run my command as usual, and nothing was different. There has been an added line to my bashrc. Is there anything I am doing wrong?
I am a newbie. How can I integrate the completion into my go script?Can you describe the specific steps?
After v2 was merged directly into master (contrary to recommendations here https://blog.golang.org/v2-go-modules, section "Major version strategies"), some tools that (indirectly) rely on posener/complete and do no require module support broke.
Trying to build gocomplete gives an error:
go: finding github.com/posener/complete/gocomplete latest
go: github.com/posener/complete/[email protected]: parsing go.mod: unexpected module path "gocomplete"
go: error loading module requirements
gocomplete
package. The Example
test fails.$ go test ./gocomplete/
run
--- FAIL: Example (0.00s)
got:
want:
run
FAIL
FAIL github.com/posener/complete/v2/gocomplete 0.004s
FAIL
complete
package confirms this as a problem in the latter.diff --git a/complete_test.go b/complete_test.go
index 3a0809f..e26522e 100644
--- a/complete_test.go
+++ b/complete_test.go
@@ -3,6 +3,7 @@ package complete
import (
"io/ioutil"
"os"
+ "strconv"
"testing"
"github.com/posener/complete/v2/internal/arg"
@@ -214,6 +215,42 @@ func TestComplete(t *testing.T) {
}
}
+// ExampleComplete_outputCapturing demonstrates the ability to capture
+// the output of Complete() invocations, crucial for integration tests.
+func ExampleComplete_outputCapturing() {
+ // a stringLookup function maps one string to another.
+ // os.GetEnv is an instance of such a function.
+ type stringLookup = func(string) string
+
+ // promptEnv returns stringLookup func that emulates the environment
+ // variables a shell would set when its prompt has the given contents.
+ var promptEnv = func(contents string) stringLookup {
+ return func(key string) string {
+ switch key {
+ case "COMP_LINE":
+ return contents
+ case "COMP_POINT":
+ return strconv.Itoa(len(contents))
+ }
+ return ""
+ }
+ }
+
+ defer func(f func(int)) { exit = f }(exit)
+ defer func(f stringLookup) { getEnv = f }(getEnv)
+ exit = func(int) {}
+
+ // This is where the actual example starts:
+
+ cmd := &Command{Sub: map[string]*Command{"bar": {}}}
+ getEnv = promptEnv("foo b")
+
+ Complete("foo", cmd)
+
+ // Output:
+ // bar
+}
+
type set []string
func (s set) Predict(_ string) []string {
$ go test -run=^Example -v
=== RUN ExampleComplete_outputCapturing
bar
--- FAIL: ExampleComplete_outputCapturing (0.00s)
got:
want:
bar
FAIL
FAIL github.com/posener/complete/v2 0.003s
FAIL
^
realityThat's an easy one: everyone would like their tests to never fail, but these ones do. 😞
The root cause lies in the line 54 here:
Lines 52 to 56 in 002575c
It defines a global var out io.Writer
, assigned to at the package initialization (this article seems a bit more explicit on the sequence).
This means that by the time tests (in this case, testing.runExample()
, to be precise) finally get around to capturing stdout
, it has already been effectively hard-coded to the initial value throughout the complete
package. Which in turn means that nothing outside of complete
can ever change where the output goes to, therefore no tests in the world (apart from the complete
package itself) can ever see what's really going on with the output.
I recently switched to the current master branch of complete. Previously I was able to define global flags and have them suggested before I input any sub commands. Now they are skipped even though they are defined as Flags in the main command definition. I also define a Sub in the main command and noticed that the complete() function only seems to suggest leaf command options if there are no sub commands defined. I would like to be able to define global flags such as --verbose and have them suggested.
case len(c.SubCmdList()) == 0:
// No sub commands, parse flags and positional arguments.
return c.suggestLeafCommandOptions(), nil
It would be awesome with support for http://fish.sh/
Hey,
I noticed this bug when helping out with the other PRs. The autocomplete library can autocomplete a subcommand even if the given arguments wouldn't result in a valid command.
The issue stems from here: https://github.com/posener/complete/blob/master/command.go#L75-L76
For example nomad job
has these subcommands:
$ nomad job
This command is accessed by using one of the subcommands below.
Subcommands:
deployments List deployments for a job
dispatch Dispatch an instance of a parameterized job
history Display all tracked versions of a job
promote Promote a job's canaries
revert Revert to a prior version of the job
status Display status information about a job
If I write: $ nomad job nonexistent stat<tab>
it will autocomplete which is incorrect.
It is because the loop iterates till it finds a match, but really should give up if the argument leads to an incorrect subcommand.
Add tests for different shells (maybe in a container) that install a demo app and verify that completion work.
Consider this structure
run := complete.Command{
Sub: complete.Commands{
"build": complete.Command{
Sub: complete.Commands{
"next": complete.Command{},
"forward": complete.Command{},
"build": complete.Command{},
},
},
},
}
complete.New("app", run).Run()
When you try app build it should suggests three sub commands next, forward and build but it suggests nothing.
I am getting started with this project so I apologize for such a basic question.
For example the following is a zsh completion function for command foo
:
#compdef _foo foo
compadd first second third fourth
So, if we type foo <tab>
in the zsh terminal, it suggests first second third fourth.
How can I do this using complete?
I build the below command, run ./<cmd> -complete
.
Then I type (in bash) ./<cmd> -na
and expect it to auto fill 'me'.
Should that work?
int main(){
var name string
flag.StringVar(&name, "name", "", "Give your name")
cmp := complete.New(
flag.Arg(0),
complete.Command{
Sub: complete.Commands{
"sadface": complete.Command{
},
},
Flags: complete.Flags{
"name": complete.PredictAnything,
},
},
)
cmp.AddFlags(nil, "complete", "uncomplete")
flag.Parse()
fmt.Printf("%s %s %s", flag.Args()...)
if cmp.Run() {
return
}
if name == "" {
fmt.Println("Your name is missing")
os.Exit(1)
}
fmt.Println("Hi,", name)
}
The title isn't great. I'll explain. First, thanks for a great library. 🎉
I have a diff at the bottom of this issue with a fix, but I'm not sure how you want to unit test it so I didn't open a PR. Its a one-line fix.
We have a CLI with the following two commands:
nomad job status
nomad status
They each implement their own arg autocompletion func. However, we noticed that only the outer one was ever being called. i.e. when you did nomad job status <tab>
, it was returning the same output for nomad status <tab>
. Further confusing: it seemed to call both autocomplete funcs, but only outputted the outer one.
We expected the behavior to only call the inner one.
A failing structure is shown below (where each Args PredictFucn outputs a different thing):
complete.Command{
Sub: {
"job": {
Sub: {
"status": {
Sub: {},
Flags: {},
GlobalFlags: {},
Args: complete.PredictFunc {...},
},
},
Flags: {},
GlobalFlags: {},
Args: nil,
},
"status": {
Sub: {},
Flags: {},
GlobalFlags: {},
Args: complete.PredictFunc {...},
},
},
Flags: {},
GlobalFlags: {},
Args: nil,
}
I found the solution is to set only = true
in c.predict
when there is a subcommand found. This properly short-circuits the search. Otherwise, a parent matching command is found and overwrites any results. We also don't want the results merged, since the parent command does something totally different.
Here is the diff:
diff --git a/command.go b/command.go
index eeeb9e0..42b7f43 100644
--- a/command.go
+++ b/command.go
@@ -87,6 +87,7 @@ func (c *Command) predict(a Args) (options []string, only bool) {
// if a sub command was entered, we won't add the parent command
// completions and we return here.
if subCommandFound {
+ only = true
return
}
We'd love to see this fixed!
Again, thanks for a great library. We're rolling this out to all HashiCorp tooling and its been great so far. This is the first bug we've ran into.
Hello, I am pretty exicted by the "Complete packages names" feature, which is exactly what I'm looking for.
I assume it should work on any fully qualified package name that resides inside $GOPATH (which would default to ~/go if $GOPATH is not set).
Unfortunately, I couldn't make it work:
go build github.c
🔂
go test github.com/gorilla/mu
🔂
...no results. I have tried with and without GOPATH set, even after starting new bash.
Any idea?
Make the complete script be able to live at the same binary as the executable it completes.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.