Fish completion support #686

Closed
opened 2023-04-23 08:56:26 +00:00 by isaec · 5 comments

What I'm trying to do and why

I'd like to have fish completion support for borgmatic. I went to write my own completions and noticed that the bash completions are generated automatically? It should be possible to output automatic completions in the same way for fish completions.

Other notes / implementation ideas

If there isn't interest in outputting completions automatically, it shouldn't be too hard to put it together by hand, the syntax is a lot nicer than bash completions. I don't understand the python being used to generate the bash completions or I would offer to make a PR.

It's also possible that taking advantage of fish completions nicer features, like specifying when file completions make sense, running code to get the possible options, and tagging flags with explanations would be easier / only possible by hand. I'm not sure what you have access to through this kind of introspection.

Environment

borgmatic version: 1.7.12

Use sudo borgmatic --version or sudo pip show borgmatic | grep ^Version

borgmatic installation method: [arch community package]

Borg version: 1.2.4

Use sudo borg --version

Python version: 3.10.10

Use python3 --version

operating system and version: 6.2.12-arch1-1

#### What I'm trying to do and why I'd like to have fish completion support for borgmatic. I went to write my own completions and noticed that the bash completions are generated automatically? It should be possible to output automatic completions in the same way for [fish completions](https://fishshell.com/docs/current/completions.html). #### Other notes / implementation ideas If there isn't interest in outputting completions automatically, it shouldn't be too hard to put it together by hand, the syntax is a lot nicer than bash completions. I don't understand the python being used to generate the bash completions or I would offer to make a PR. It's also possible that taking advantage of fish completions nicer features, like specifying when file completions make sense, running code to get the possible options, and tagging flags with explanations would be easier / only possible by hand. I'm not sure what you have access to through this kind of introspection. #### Environment **borgmatic version:** 1.7.12 Use `sudo borgmatic --version` or `sudo pip show borgmatic | grep ^Version` **borgmatic installation method:** [arch community package] **Borg version:** 1.2.4 Use `sudo borg --version` **Python version:** 3.10.10 Use `python3 --version` **operating system and version:** 6.2.12-arch1-1
Owner

I'd be fully supportive of automatically generated Fish completions, but the reason I didn't do manual completions for Bash was because I didn't want to maintain them by hand as borgmatic flags change from version to version. And they do change pretty frequently.

In case it helps you do a PR for Fish completions, here's how the existing Bash completions code works—ignoring the actual Bash part:

In borgmatic/commands/completion.py:bash_completion():

  • Get the command-line argument parsers, both global ones and those specific to actions like create, check, prune, etc.
  • From those, get the global flags.
  • Loop through the action-specific parsers. For each one:
    • Get the action-specific flags.
    • Ouput a slew of Bash completion incantations for each flag.
  • Tack on some Bash completions for the global flags as well.

So in theory you could use a similar approach for generating Fish flags: It's basically just a loop over the borgmatic actions and the flags for each.

Let me know your thoughts.

I'd be fully supportive of automatically generated Fish completions, but the reason I didn't do manual completions for Bash was because I didn't want to maintain them by hand as borgmatic flags change from version to version. And they do change pretty frequently. In case it helps you do a PR for Fish completions, here's how the existing Bash completions code works—ignoring the actual Bash part: In `borgmatic/commands/completion.py:bash_completion()`: * Get the command-line argument parsers, both global ones and those specific to actions like `create`, `check`, `prune`, etc. * From those, get the global flags. * Loop through the action-specific parsers. For each one: * Get the action-specific flags. * Ouput a slew of Bash completion incantations for each flag. * Tack on some Bash completions for the global flags as well. So in theory you could use a similar approach for generating Fish flags: It's basically just a loop over the borgmatic actions and the flags for each. Let me know your thoughts.
Author

This sounds great! Some of the "best" fish completions go further and do intellegent things--stuff like automatic completion for archive name when selecting an archive. This would be hard to automate, but I really don't think its needed.

You'd probably want to disable file completions at the top and then list all the commands and their flags automatically.

There is an open issue about how difficult it is to do flags for subcommands...

I went to look at fish completions I wrote before, and this one has conditional flags--flags that only are available if you pass other flags.

# never use file completion, except for specific commands
complete -c optimus-manager --no-files

complete -c optimus-manager -l help -s h            -d 'Show help message and exit.'
complete -c optimus-manager -l version -s v         -d 'Print version and exit.'

complete -c optimus-manager -l status               -d 'Print current status of optimus-manager.'
complete -c optimus-manager -l print-mode           -d 'Print the GPU mode that your current desktop session is running on.'
complete -c optimus-manager -l print-next-mode      -d 'Print the GPU mode that will be used the next time you log into your session.'
complete -c optimus-manager -l print-startup        -d 'Print the GPU mode that will be used on startup.'

complete -c optimus-manager -l switch -x -a 'integrated' -d 'switch to the integrated GPU and power the Nvidia GPU off'
complete -c optimus-manager -l switch -x -a 'nvidia' -d 'switch to the Nvidia GPU'
complete -c optimus-manager -l switch -x -a 'hybrid' -d 'switch to the iGPU but leave the Nvidia GPU available for on-demand offloading'
complete -c optimus-manager -l switch -d 'Set the GPU mode to MODE. You need to log out then log in to apply the change.'

complete -c optimus-manager -l temp-config -F -r    -d 'Set a path to a temporary configuration file to use for the next reboot ONLY. Useful for testing power switching configurations without ending up with an unbootable setup.'

complete -c optimus-manager -l unset-temp-config    -d 'Undo --temp-config (unset temp config path)' --condition '! optimus-manager --status | grep -oP "Temporary config path\s?: \Kno"'
complete -c optimus-manager -l no-confirm           -d 'Do not ask for confirmation and skip all warnings when switching GPUs.' --condition '__fish_contains_opt switch'
complete -c optimus-manager -l cleanup              -d 'Remove auto-generated configuration files left over by the daemon.'


# -h, --help           show this help message and exit
# -v, --version        Print version and exit.
# --status             Print current status of optimus-manager
# --print-mode         Print the GPU mode that your current desktop session is running on.
# --print-next-mode    Print the GPU mode that will be used the next time you log into your session.
# --print-startup      Print the GPU mode that will be used on startup.
# --switch MODE        Set the GPU mode to MODE. You need to log out then log in to apply the change.Possible modes :
# 											integrated, nvidia, hybrid, intel (deprecated, equivalent to integrated)
# --temp-config PATH   Set a path to a temporary configuration file to use for the next reboot ONLY. Useful for testing power
# 											switching configurations without ending up with an unbootable setup.
# --unset-temp-config  Undo --temp-config (unset temp config path)
# --no-confirm         Do not ask for confirmation and skip all warnings when switching GPUs.
# --cleanup            Remove auto-generated configuration files left over by the daemon.

The git completions are referenced as an example of using flags for subcommands, but its horrific to look at... d2f5daf8e8/share/completions/git.fish (L561-L593)

This stackoverflow answer might be a fine implementation and would be ok to embed at the top and use to set flags for only given subcommands.

So I think you'd get the global flags and register them (all in one line because you aren't putting a description), and then iterate each subcommand and register all the flags, and use one of the subcommand filtering functions.

If there was a way to get a description of the given command and flag I think it would be really nice...

I'm a little scared of mucking around with borgmatic on a system I also back up, but I'll take a shot at it when I get a bit more time. Thank you for your help!

This sounds great! Some of the "best" fish completions go further and do intellegent things--stuff like automatic completion for archive name when selecting an archive. This would be hard to automate, but I really don't think its needed. You'd probably want to disable file completions at the top and then list all the commands and their flags automatically. There is an [open issue](https://github.com/fish-shell/fish-shell/issues/7107) about how difficult it is to do flags for subcommands... I went to look at fish completions I wrote before, and this one has conditional flags--flags that only are available if you pass other flags. ``` # never use file completion, except for specific commands complete -c optimus-manager --no-files complete -c optimus-manager -l help -s h -d 'Show help message and exit.' complete -c optimus-manager -l version -s v -d 'Print version and exit.' complete -c optimus-manager -l status -d 'Print current status of optimus-manager.' complete -c optimus-manager -l print-mode -d 'Print the GPU mode that your current desktop session is running on.' complete -c optimus-manager -l print-next-mode -d 'Print the GPU mode that will be used the next time you log into your session.' complete -c optimus-manager -l print-startup -d 'Print the GPU mode that will be used on startup.' complete -c optimus-manager -l switch -x -a 'integrated' -d 'switch to the integrated GPU and power the Nvidia GPU off' complete -c optimus-manager -l switch -x -a 'nvidia' -d 'switch to the Nvidia GPU' complete -c optimus-manager -l switch -x -a 'hybrid' -d 'switch to the iGPU but leave the Nvidia GPU available for on-demand offloading' complete -c optimus-manager -l switch -d 'Set the GPU mode to MODE. You need to log out then log in to apply the change.' complete -c optimus-manager -l temp-config -F -r -d 'Set a path to a temporary configuration file to use for the next reboot ONLY. Useful for testing power switching configurations without ending up with an unbootable setup.' complete -c optimus-manager -l unset-temp-config -d 'Undo --temp-config (unset temp config path)' --condition '! optimus-manager --status | grep -oP "Temporary config path\s?: \Kno"' complete -c optimus-manager -l no-confirm -d 'Do not ask for confirmation and skip all warnings when switching GPUs.' --condition '__fish_contains_opt switch' complete -c optimus-manager -l cleanup -d 'Remove auto-generated configuration files left over by the daemon.' # -h, --help show this help message and exit # -v, --version Print version and exit. # --status Print current status of optimus-manager # --print-mode Print the GPU mode that your current desktop session is running on. # --print-next-mode Print the GPU mode that will be used the next time you log into your session. # --print-startup Print the GPU mode that will be used on startup. # --switch MODE Set the GPU mode to MODE. You need to log out then log in to apply the change.Possible modes : # integrated, nvidia, hybrid, intel (deprecated, equivalent to integrated) # --temp-config PATH Set a path to a temporary configuration file to use for the next reboot ONLY. Useful for testing power # switching configurations without ending up with an unbootable setup. # --unset-temp-config Undo --temp-config (unset temp config path) # --no-confirm Do not ask for confirmation and skip all warnings when switching GPUs. # --cleanup Remove auto-generated configuration files left over by the daemon. ``` The git completions are referenced as an example of using flags for *subcommands*, but its horrific to look at... https://github.com/fish-shell/fish-shell/blob/d2f5daf8e8985209ae34577c137b6077e1a57624/share/completions/git.fish#L561-L593 [This stackoverflow answer](https://stackoverflow.com/a/16673041/11938425) might be a fine implementation and would be ok to embed at the top and use to set flags for only given subcommands. So I think you'd get the global flags and register them (all in one line because you aren't putting a description), and then iterate each subcommand and register all the flags, and use one of the subcommand filtering functions. If there was a way to get a description of the given command and flag I think it would be really nice... I'm a little scared of mucking around with borgmatic on a system I also back up, but I'll take a shot at it when I get a bit more time. Thank you for your help!
Author

Thanks again for your help understanding the python, I opened a pull request to add this feature--I don't write python, so I'm sorry if its not pythonic.

Thanks again for your help understanding the python, I opened [a pull request](https://github.com/borgmatic-collective/borgmatic/pull/70) to add this feature--I don't write python, so I'm sorry if its not pythonic.
Owner

Implemented by @isaec in this PR: https://github.com/borgmatic-collective/borgmatic/pull/70

This will be part of the next release.

Implemented by @isaec in this PR: https://github.com/borgmatic-collective/borgmatic/pull/70 This will be part of the next release.
Owner

This was just released in borgmatic 1.7.13!

This was just released in borgmatic 1.7.13!
Sign in to join this conversation.
No Milestone
No Assignees
2 Participants
Notifications
Due Date
The due date is invalid or out of range. Please use the format 'yyyy-mm-dd'.

No due date set.

Dependencies

No dependencies set.

Reference: borgmatic-collective/borgmatic#686
No description provided.