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

Add go template shell completion for --format #10099

Merged
merged 1 commit into from
Apr 22, 2021

Conversation

Luap99
Copy link
Member

@Luap99 Luap99 commented Apr 21, 2021

The --format flags accepts go template strings. I use this often but I
consistently forget the field names. This commit adds a way to provide
shell completion for the --format flag. It works by automatically
receiving the field names with the reflect package from the given
struct. This requires almost no maintenance since this ensures that we
always use the correct field names. This also works for nested structs.

$ podman ps --format "{{.P"
{{.Pid}}      {{.PIDNS}}    {{.Pod}}      {{.PodName}}  {{.Ports}}

NOTE: This only works when you use quotes otherwise the shell does not
provide completions. Also this does not work for fish at the moment.

@openshift-ci-robot
Copy link
Collaborator

[APPROVALNOTIFIER] This PR is APPROVED

This pull-request has been approved by: Luap99

The full list of commands accepted by this bot can be found here.

The pull request process is described here

Needs approval from an approver in each of these files:

Approvers can indicate their approval by writing /approve in a comment
Approvers can cancel approval by writing /approve cancel in a comment

@openshift-ci-robot openshift-ci-robot added the approved Indicates a PR has been approved by an approver from all required OWNERS files. label Apr 21, 2021
@rhatdan
Copy link
Member

rhatdan commented Apr 21, 2021

Very cool, since I have a hard time remembering these and often have to do an inspect to find the names.

I would love to have a demo of this at a podman monthly meeting.

LGTM

@edsantiago
Copy link
Member

You are my hero.

Is there any way to make it work with -a? (podman images -a, podman ps -a)?

@Luap99
Copy link
Member Author

Luap99 commented Apr 21, 2021

Is there any way to make it work with -a? (podman images -a, podman ps -a)?

Not sure if I understand this question correctly. The --format flag completion should work regardless of what flags are set.

$ bin/podman ps -a --format "{{."
{{.AutoRemove}}  {{.Created}}     {{.Exited}}      {{.Image}}       {{.IsInfra}}     {{.Mounts}}      {{.NET}}         {{.PIDNS}}       {{.Ports}}       {{.State}}       {{.UTS}}
{{.CGROUPNS}}    {{.CreatedAt}}   {{.ExitedAt}}    {{.ImageID}}     {{.Labels}}      {{.Names}}       {{.Networks}}    {{.Pod}}         {{.Size}}        {{.Status}}      
{{.Command}}     {{.ExitCode}}    {{.ID}}          {{.IPC}}         {{.MNT}}         {{.Namespaces}}  {{.Pid}}         {{.PodName}}     {{.StartedAt}}   {{.USERNS}}      
$ bin/podman images -a --format "{{."
{{.ConfigDigest}}  {{.Created}}       {{.Digest}}        {{.ID}}            {{.Names}}         {{.ReadOnly}}      {{.RepoTags}}      {{.Size}}          
{{.Containers}}    {{.Dangling}}      {{.History}}       {{.Labels}}        {{.ParentId}}      {{.RepoDigests}}   {{.SharedSize}}    {{.VirtualSize}}   

@edsantiago
Copy link
Member

Oh, interesting. The -a thing was a red herring. It turns out, at least on my end, that completion works only randomly: sometimes it works, sometimes it doesn't (as in: tab just makes it beep, nothing else). I tried with bash and zsh. There is no difference in the text I'm typing. Very weird.

@edsantiago
Copy link
Member

This is really weird. I keep getting myself into a place where --format completion doesn't work at all, on both zsh and bash. With bash, I need to restart the shell to get things working again. With zsh, I can ^U and re-type.

More weirdnesses:

  • in bash, hitting TAB makes the quotes disappear.
  • in zsh, typing any letter makes completion not work at all. That is: podman images --format '{{.', hit TAB, that gives me a list and moves my cursor one character left, to just after the dot. If I type L (only one completion) and hit TAB, nothing, just beep. If I type R (two completions, both starting with Re), I get the e filled in, and further tabs just beep.
  • In zsh, when completion does work, it tacks on an unwanted space between the final closing brace and closing quote: ...}}<space>'
    This is really promising, though! Thank you!

@Luap99
Copy link
Member Author

Luap99 commented Apr 21, 2021

This is really weird. I keep getting myself into a place where --format completion doesn't work at all, on both zsh and bash. With bash, I need to restart the shell to get things working again. With zsh, I can ^U and re-type.

Only --format does not work but other completions such as subcommands or other flags work? I have no idea what could cause this. You could do a export BASH_COMP_DEBUG_FILE=/tmp/completion-debug. This will write debug information to this file when you press tab, this works for all shells with this env var.

in bash, hitting TAB makes the quotes disappear.

Not for me.

in zsh, typing any letter makes completion not work at all. That is: podman images --format '{{.', hit TAB, that gives me a list and moves my cursor one character left, to just after the dot. If I type L (only one completion) and hit TAB, nothing, just beep. If I type R (two completions, both starting with Re), I get the e filled in, and further tabs just beep.

I am also unable to reproduce this one. It tried for some time with all combinations but it worked correct as long as quotes are used. I have not configured anything in zsh, maybe you have some special settings which causes this to fail.

In zsh, when completion does work, it tacks on an unwanted space between the final closing brace and closing quote: ...}}'

OK, I know how to fix this one.

@Luap99 Luap99 force-pushed the format-completion branch from 932b73d to d9d877f Compare April 21, 2021 21:22
@edsantiago
Copy link
Member

I have not configured anything in zsh, maybe you have some special settings which causes this to fail.

That was it:

# when cursor is in middle of word, ignore RHS
# [default: expand-or-complete]
bindkey "^I" expand-or-complete-prefix

git reports that I added this in 2014, and I no longer remember why.

I'm sorry for wasting your time. I should've tried tabula rasa before reporting that.

(As for bash, I don't use it, so I don't really care if it works or not.)

Anyhow, here's one I did try with a plain zsh setup: podman info. Is there any way to get it to stop after a field that has subfields, instead of completing it and requiring a bunch of backspaces?

$ ./bin/podman info --format '{{.H'         <--- hit TAB
actual$ ./bin/podman info --format '{{.Host}} |'           '|' indicates cursor
wanted$ ./bin/podman info --format '{{.Host.|'

@Luap99
Copy link
Member Author

Luap99 commented Apr 21, 2021

Anyhow, here's one I did try with a plain zsh setup: podman info. Is there any way to get it to stop after a field that has subfields, instead of completing it and requiring a bunch of backspaces?

This should be possible.
However in this exact case you mention there is another problem. When the nested structs are referenced as pointer by the parent there is not way for the reflect logic the read the field names since this is just a nil pointer by default. To fix this we would need to initialize not only the root struct but also all child structs. In this case it would look like this: common.AutocompleteFormat(define.Info{Host: &define.HostInfo{}, Store: &define.StoreInfo{}})

I think it is worth to do for some structs with many fields but not for everything since this would defeat my nice simple solution.

@edsantiago
Copy link
Member

Simple is good. Thank you for your quick response.

@Luap99 Luap99 force-pushed the format-completion branch from d9d877f to 1d7b75f Compare April 21, 2021 22:14
@Luap99
Copy link
Member Author

Luap99 commented Apr 21, 2021

Updated I add a dot instead of the braces when the field is a struct.

$ bin/podman info --format "{{."
{{.Host.         {{.Registries}}  {{.Store.        {{.Version.
$ bin/podman info --format "{{.Host."
{{.Host.Arch}}            {{.Host.Conmon.           {{.Host.Hostname}}        {{.Host.MemFree}}         {{.Host.RemoteSocket.     {{.Host.SwapFree}}        
{{.Host.BuildahVersion}}  {{.Host.CPUs}}            {{.Host.IDMappings.       {{.Host.MemTotal}}        {{.Host.RuntimeInfo}}     {{.Host.SwapTotal}}       
{{.Host.CgroupManager}}   {{.Host.Distribution.     {{.Host.Kernel}}          {{.Host.OCIRuntime.       {{.Host.Security.         {{.Host.Uptime}}          
{{.Host.CGroupsVersion}}  {{.Host.EventLogger}}     {{.Host.Linkmode}}        {{.Host.OS}}

The --format flags accepts go template strings. I use this often but I
consistently forget the field names. This commit adds a way to provide
shell completion for the --format flag. It works by automatically
receiving the field names with the reflect package from the given
struct. This requires almost no maintenance since this ensures that we
always use the correct field names. This also works for nested structs.

```
$ podman ps --format "{{.P"
{{.Pid}}      {{.PIDNS}}    {{.Pod}}      {{.PodName}}  {{.Ports}}
```

NOTE: This only works when you use quotes otherwise the shell does not
provide completions. Also this does not work for fish at the moment.

Signed-off-by: Paul Holzinger <[email protected]>
@Luap99 Luap99 force-pushed the format-completion branch from 1d7b75f to d81021e Compare April 21, 2021 22:31
@edsantiago
Copy link
Member

Updated I add a dot instead of the braces when the field is a struct.

And it works beautifully. I appreciate this SO MUCH!

@rhatdan
Copy link
Member

rhatdan commented Apr 22, 2021

/lgtm

@openshift-ci-robot openshift-ci-robot added the lgtm Indicates that a PR is ready to be merged. label Apr 22, 2021
@openshift-merge-robot openshift-merge-robot merged commit 8465626 into containers:master Apr 22, 2021
@Luap99 Luap99 deleted the format-completion branch April 22, 2021 13:57
@github-actions github-actions bot added the locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments. label Sep 23, 2023
@github-actions github-actions bot locked as resolved and limited conversation to collaborators Sep 23, 2023
Sign up for free to subscribe to this conversation on GitHub. Already have an account? Sign in.
Labels
approved Indicates a PR has been approved by an approver from all required OWNERS files. lgtm Indicates that a PR is ready to be merged. locked - please file new issue/PR Assist humans wanting to comment on an old issue or PR with locked comments.
Projects
None yet
Development

Successfully merging this pull request may close these issues.

5 participants