Skip to content

Conversation

@zeroshade
Copy link
Member

closes #86

First pass at creating custom shell tab-completion scripts for bash/zsh/fish via dbc completion <shell>

If you do dbc completion <shell> -h it'll also explain how to use the auto completion script for that shell.

@zeroshade zeroshade changed the title feat(cmd/dbc): Add custom shell completions feat(cmd/dbc): add custom shell completions Oct 10, 2025
@ianmcook
Copy link
Member

Works in zsh on macOS!

Would it be possible to implement something like dbc completion install that automatically detects the shell and performs the steps that you documented to install the completions?

@eitsupi
Copy link
Member

eitsupi commented Oct 11, 2025

Awesome! I've been playing around a bit with Fish on Linux.

As a note, there were some parts that didn't seem to work perfectly.

Maybe the files shouldn't be listed?

$ ./dbc 
add  (Add a driver to the driver list)  docs/                           pixi.toml                                     
ci/                                     drivers.go                      README.md
# snip

Seems lack completion:

$ ./dbc com

Seems lack --help (and --version?):

$ ./dbc add -
-h  (Help)  -p  --path  (Driver list to add to)

@zeroshade
Copy link
Member Author

@eitsupi I've updated the scripts based on your feedback, let me know what you think!

@zeroshade
Copy link
Member Author

Would it be possible to implement something like dbc completion install that automatically detects the shell and performs the steps that you documented to install the completions?

It's a bit hard to detect the shell properly since the SHELL env var is just the user's default shell. For example notice that despite starting a bash session, the SHELL env var is still /usr/bin/zsh because that's my default shell:

image

My personal preference would be to add the steps to the docs rather than add a dbc completion install subcommand. However, one idea is that we could update the built packages (deb/rpm/etc) to have it automatically add the completion files to the appropriate places

@amoeba
Copy link
Member

amoeba commented Oct 13, 2025

Thanks for this @zeroshade.

I'm not totally keen on having a dedicated subcommand for managing completions, I think it competes for space with our other subcommands and it's not in the same category as the others. Are there other tools that use a dedicated subcommand like this?

As for the completions themselves, I'm still seeing files in the current working directory when I tab like @eitsupi did. Is that expected?

@zeroshade
Copy link
Member Author

I'm not totally keen on having a dedicated subcommand for managing completions, I think it competes for space with our other subcommands and it's not in the same category as the others. Are there other tools that use a dedicated subcommand like this?

goreleaser does, along with any CLI tool that uses the https://github.com/spf13/cobra framework as that adds it automatically. uv also does the same (though it calls it generate-shell-completion)

As for the completions themselves, I'm still seeing files in the current working directory when I tab like @eitsupi did. Is that expected?

I'll have to play with fish a bit to figure that out, I'm not seeing that behavior with bash

image

Or in zsh

image

So let me see what I have to change for fish

@zeroshade
Copy link
Member Author

okay, i found the right option and tested it. I got it to stop giving files as suggestions! give it a try

@zeroshade
Copy link
Member Author

I've also updated the config for linux packages to auto include the auto complete scripts so if you install via deb/rpm it will automatically install the tab completion scripts for all three shells

@amoeba
Copy link
Member

amoeba commented Oct 13, 2025

Nice, that fixes the issue for me. What do you think about my comment about whether we should actually have a completion subcommand or just handle this entirely through packaging?

@zeroshade
Copy link
Member Author

While I added some stuff for the linux package packaging, my preference is still to include the completion subcommand in some capacity as even uv does it (https://docs.astral.sh/uv/getting-started/installation/#__tabbed_3_1)

@amoeba
Copy link
Member

amoeba commented Oct 13, 2025

That's interesting. Their CLI utility somehow lets them have hidden subcommands. Can we do that without too much hackery?

@amoeba
Copy link
Member

amoeba commented Oct 13, 2025

I suppose our mainprog can just handle it as a special case outside the main handling.

@zeroshade
Copy link
Member Author

There are other CLI option libraries, I went with go-arg because it's small and simple.

So if it's important, we can add the feature to go-arg (I don't think it'd be too hard) or we can switch over to using a different CLI library like cobra or something else which does have that feature

@zeroshade
Copy link
Member Author

I don't see a similar option for bubbletea so I think we'd have to just process argv ourselves to catch dbc generate-shell-completions before we run the bubbletea parts.

We use go-arg for the argument handling, bubbletea is just for the output and flow control

@amoeba
Copy link
Member

amoeba commented Oct 13, 2025

Ah, gotcha. If it's not too much trouble to swap out go-arg for cobra, I'd really like us not to have a visible shell completions subcommand in our help output.

@zeroshade
Copy link
Member Author

swapping out go-arg for cobra (which I believe still shows the completion in the help text) or urfav/cli (which hides it) is a significant refactor as both of them use a full object of cli.Command{Action: func(....... style of defining the framework rather than just leveraging struct tags like we're using for go-arg.

@amoeba
Copy link
Member

amoeba commented Oct 13, 2025

Okay, that's not ideal then. How gross is this?

diff --git a/cmd/dbc/main.go b/cmd/dbc/main.go
index e9c9b89..0b971a5 100644
--- a/cmd/dbc/main.go
+++ b/cmd/dbc/main.go
@@ -142,6 +142,12 @@ var prog *tea.Program
 func main() {
 	var args cmds
 
+	// Handle generate-shell-completion
+	if len(os.Args) >= 2 && os.Args[1] == "generate-shell-completion" {
+		fmt.Println("TODO: Implement me")
+		return
+	}
+
 	p := arg.MustParse(&args)
 	if p.Subcommand() == nil {
 		p.WriteHelp(os.Stdout)

@zeroshade
Copy link
Member Author

pretty gross...

I can take a look at what it would take to add "hidden" command abilities to go-arg and file a PR there? he seems responsive

@amoeba
Copy link
Member

amoeba commented Oct 13, 2025

that would be really great, thanks @zeroshade

@zeroshade
Copy link
Member Author

@amoeba I filed a PR (alexflint/go-arg#292) on go-arg, but for now I've pointed this to use my forked branch with the change so you can test it out and let me know what you think.

@eitsupi
Copy link
Member

eitsupi commented Oct 13, 2025

I'm not totally keen on having a dedicated subcommand for managing completions, I think it competes for space with our other subcommands and it's not in the same category as the others. Are there other tools that use a dedicated subcommand like this?

clap has the ability to add subcommands like this, which I think is very common among Rust CLI tools.
https://docs.rs/clap_complete/4.5.59/clap_complete/index.html

For example, rustup completions

@eitsupi
Copy link
Member

eitsupi commented Oct 13, 2025

I've played around a bit with the latest version and it looks pretty good. Awesome!

I'm not sure if the completion subcommand should be visible in the top-level help.
I was surprised that uv hides it, but I'm sure there are other tools out there that don't, like rustup.

@zeroshade
Copy link
Member Author

@eitsupi my latest change removed it from the top-level help. Any other comments here?

@amoeba
Copy link
Member

amoeba commented Oct 20, 2025

I missed this when I first looked at this but I'm not liking that the current approach installs completions system-wide for bash and zsh. fish looks fine. Do bash and zsh not have user completions.d dirs?

Alternatively, we could document simpler install instructions, I'll push up an example of what I think will work.

@zeroshade
Copy link
Member Author

As far as I could tell there's no automatic place where local user completions will be picked up for bash/zsh without explicitly adding the path to that location to your .bashrc or .zshrc directly etc.

Copy link
Member

@eitsupi eitsupi left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Looks good, thank you.

@amoeba
Copy link
Member

amoeba commented Oct 20, 2025

As far as I could tell there's no automatic place where local user completions will be picked up for bash/zsh without explicitly adding the path to that location to your .bashrc or .zshrc directly etc.

Well, aside from how I documented it in c7324fc. Do you like that at all? I personally don't like anything dynamic in my shell config but there are too many tools that mandate it (like conda).

@zeroshade
Copy link
Member Author

I'm good with the additions to the docs you added. that looks good to me

@amoeba
Copy link
Member

amoeba commented Oct 20, 2025

Okay, I updated the completion help output to show that method too and added a note in the installation page about accessing the help output in case users want more help than what the docs give.

@zeroshade zeroshade merged commit 4b1d591 into main Oct 21, 2025
10 checks passed
@zeroshade zeroshade deleted the shell-completions branch October 21, 2025 15:02
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Add shell completion (bash, zsh, fish)

5 participants