Skip to content

Commit

Permalink
Basic shell completion
Browse files Browse the repository at this point in the history
This is an initial effort to address
jotaen#177

With this change, klog uses github.com/posener/complete and
github.com/willabides/kongplete to generate completions for klog's own
commands.

There are two coordinated changes that make this feature work:

1. When the `COMP_LINE` environment variable is set, `klog` runs in a
   special command completion mode. It parses the value of `COMP_LINE`
   (the current command line), prints to stdout a list of possible
   completions based on what is on the command line so far, and exits
   early.
2. `klog completion` prints to stdout a code snippet that defines a
   completion specification in the current shell. When this code snippet
   is executed in a shell session, the shell will thereafter invoke the
   same `klog` executable (with the `COMP_LINE` environment variable
   set) to generate possible completions.

For example, in bash, completions can be enabled by running

    source <(log completion)

Once bash completions are enabled, pressing tab after typing "klog "

    klog [Tab]

will present the available klog commands.

In the current implementation, the generated completions are rudimentary
and lack ergonomics.

There is zero test coverage for this new feature. Because it relies on
interaction with the shell, this feature is not easy to test.
  • Loading branch information
chairmank committed Apr 15, 2022
1 parent 7b5503c commit 6091f12
Show file tree
Hide file tree
Showing 4 changed files with 32 additions and 5 deletions.
5 changes: 5 additions & 0 deletions go.mod
Original file line number Diff line number Diff line change
Expand Up @@ -6,11 +6,16 @@ require (
cloud.google.com/go v0.97.0
github.com/alecthomas/kong v0.2.22
github.com/stretchr/testify v1.7.0
github.com/willabides/kongplete v0.3.0
)

require (
github.com/davecgh/go-spew v1.1.1 // indirect
github.com/hashicorp/errwrap v1.0.0 // indirect
github.com/hashicorp/go-multierror v1.0.0 // indirect
github.com/pkg/errors v0.9.1 // indirect
github.com/pmezard/go-difflib v1.0.0 // indirect
github.com/posener/complete v1.2.3 // indirect
github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab // indirect
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b // indirect
)
10 changes: 10 additions & 0 deletions go.sum
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,10 @@ github.com/googleapis/gax-go/v2 v2.0.4/go.mod h1:0Wqv26UfaUD9n4G6kQubkQ+KchISgw+
github.com/googleapis/gax-go/v2 v2.0.5/go.mod h1:DWXyrwAJ9X0FpwwEdw+IPEYBICEFu5mhpdKc/us6bOk=
github.com/googleapis/gax-go/v2 v2.1.0/go.mod h1:Q3nei7sK6ybPYH7twZdmQpAd1MKb7pfu6SK+H1/DsU0=
github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw=
github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA=
github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4=
github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uPribsnS6o=
github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk=
github.com/hashicorp/golang-lru v0.5.0/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/hashicorp/golang-lru v0.5.1/go.mod h1:/m3WP610KZHVQ1SGc6re/UDhFvYD7pJ4Ao+sR/qLZy8=
github.com/ianlancetaylor/demangle v0.0.0-20181102032728-5e5cf60278f6/go.mod h1:aSSvb/t6k1mPoxDqO4vJh6VOCGPwU4O0C2/Eqndh1Sc=
Expand All @@ -163,7 +167,11 @@ github.com/pkg/errors v0.9.1 h1:FEBLx1zS214owpjy7qsBeixbURkuhQAwrK5UwLGTwt4=
github.com/pkg/errors v0.9.1/go.mod h1:bwawxfHBFNV+L2hUp1rHADufV3IMtnDRdf1r5NINEl0=
github.com/pmezard/go-difflib v1.0.0 h1:4DBwDE0NGyQoBHbLQYPwSUPoCMWR5BEzIk/f1lZbAQM=
github.com/pmezard/go-difflib v1.0.0/go.mod h1:iKH77koFhYxTK1pcRnkKkqfTogsbg7gZNVY4sRDYZ/4=
github.com/posener/complete v1.2.3 h1:NP0eAhjcjImqslEwo/1hq7gpajME0fTLTezBKDqfXqo=
github.com/posener/complete v1.2.3/go.mod h1:WZIdtGGp+qx0sLrYKtIRAruyNpv6hFCicSgv7Sy7s/s=
github.com/prometheus/client_model v0.0.0-20190812154241-14fe0d1b01d4/go.mod h1:xMI15A0UPsDsEKsMN9yxemIoYk6Tm2C1GtYGdfGttqA=
github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab h1:ZjX6I48eZSFetPb41dHudEyVr5v953N15TsNZXlkcWY=
github.com/riywo/loginshell v0.0.0-20200815045211-7d26008be1ab/go.mod h1:/PfPXh0EntGc3QAAyUaviy4S9tzy4Zp0e2ilq4voC6E=
github.com/rogpeppe/fastuuid v1.2.0/go.mod h1:jVj6XXZzXRy/MSR5jhDC/2q6DgLz+nrA6LYCDYWNEvQ=
github.com/rogpeppe/go-internal v1.3.0/go.mod h1:M8bDsm7K2OlrFYOpmOWEs/qY81heoFRclV5y23lUDJ4=
github.com/spaolacci/murmur3 v0.0.0-20180118202830-f09979ecbc72/go.mod h1:JwIasOWyU6f++ZhiEuf87xNszmSA2myDM2Kzu9HwQUA=
Expand All @@ -173,6 +181,8 @@ github.com/stretchr/testify v1.5.1/go.mod h1:5W2xD1RspED5o8YsWQXVCued0rvSQ+mT+I5
github.com/stretchr/testify v1.6.1/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/stretchr/testify v1.7.0 h1:nwc3DEeHmmLAfoZucVR881uASk0Mfjw8xYJ99tb5CcY=
github.com/stretchr/testify v1.7.0/go.mod h1:6Fq8oRcR53rry900zMqJjRRixrwX3KX962/h/Wwjteg=
github.com/willabides/kongplete v0.3.0 h1:8dJZ0r2a2YnSdYCQk9TjQDKzLrj1zUvIOPIG3bOV75c=
github.com/willabides/kongplete v0.3.0/go.mod h1:VPdrG6LY+tP0LMkSBuTgIQ8c6+P8wvIDHVJzDdDh9Fw=
github.com/yuin/goldmark v1.1.25/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.27/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
github.com/yuin/goldmark v1.1.32/go.mod h1:3hX8gzYuyVAZsxl0MRgGTJEmQBFcNTphYh9decYSb74=
Expand Down
15 changes: 10 additions & 5 deletions src/app/cli/index.go
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,10 @@ Package cli contains handlers for all available commands.
*/
package cli

import (
"github.com/willabides/kongplete"
)

type Cli struct {
// Evaluate
Print Print `cmd:"" group:"Evaluate" help:"Pretty-prints records"`
Expand All @@ -25,9 +29,10 @@ type Cli struct {
Bk Bookmarks `cmd:"" group:"Bookmarks" hidden:"" help:"Alias"`

// Misc
Edit Edit `cmd:"" group:"Misc" help:"Opens a file or bookmark in your editor"`
Goto Goto `cmd:"" group:"Misc" help:"Opens the file explorer at the given location"`
Json Json `cmd:"" group:"Misc" help:"Converts records to JSON"`
Info Info `cmd:"" group:"Misc" default:"withargs" help:"Displays meta info about klog"`
Version Version `cmd:"" group:"Misc" help:"Prints version info and check for updates"`
Completion kongplete.InstallCompletions `cmd:"" group:"Misc" help:"Output code to define a completion specification for klog in the current shell"`
Edit Edit `cmd:"" group:"Misc" help:"Opens a file or bookmark in your editor"`
Goto Goto `cmd:"" group:"Misc" help:"Opens the file explorer at the given location"`
Json Json `cmd:"" group:"Misc" help:"Converts records to JSON"`
Info Info `cmd:"" group:"Misc" default:"withargs" help:"Displays meta info about klog"`
Version Version `cmd:"" group:"Misc" help:"Prints version info and check for updates"`
}
7 changes: 7 additions & 0 deletions src/app/cli/main/cli.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@ import (
"github.com/jotaen/klog/src/app/cli/lib"
"github.com/jotaen/klog/src/service"
"github.com/jotaen/klog/src/service/period"
"github.com/willabides/kongplete"
"reflect"
)

Expand Down Expand Up @@ -54,6 +55,12 @@ func Run(homeDir string, meta app.Meta, isDebug bool, args []string) (int, error
return -1, nErr
}

// When klog is invoked by shell completion (specifically, when the
// bash-specific COMP_LINE environment variable is set), the
// kongplete.Complete function generates a list of possible completions,
// prints them one per line to stdout, and then exits the program early.
kongplete.Complete(kongApp)

kongCtx, cErr := kongApp.Parse(args)
if cErr != nil {
return -1, cErr
Expand Down

0 comments on commit 6091f12

Please sign in to comment.