scop / bash-completion

Programmable completion functions for bash
GNU General Public License v2.0
2.92k stars 380 forks source link

completion for man fails to identify manpages for subcommands ("man git bis<TAB>" should complete to "man git bisect ") #495

Open dkg opened 3 years ago

dkg commented 3 years ago

bash-completion ships tab completion for man that identifies specific manpages.

However, modern versions of man (2.5.6 and later, released back in 2009) are clever enough to know that a request for a subcommand like man 1 git bisect is not a request for two manpages (git.1 and bisect.1) but rather a request for the manpage for the subcommand git-bisect.1.

When I try to tab-complete the string man git bis<TAB> it would be better if the tab completion would prduce man git bisect, rather than what it currently does (on my system, it offers completions to bison, bison.yacc, or bisque).

man does this cleverness when the command name and subcommand name are joined together in the manpage title by either a hyphen (-) (e.g., git-revert.1 from git) or underscore (_) (e.g., ipsec_show.8 from libreswan).

There is some level of ambiguity here, of course: when the user runs man git commit, it produces git-commit.1, but when the user runs man commit git it produces commit.7 (from postgresql) followed by git.1.

So when completing from man XXX Y<TAB>, bash could include the following candidates:

  1. all manpage names that begin with XXX[-_]Y, with the XXX[-_] prefix trimmed
  2. all manpage names that begin with Y

From a usability perspective, most people are trying to read a single manpage at a time. So i would argue that if (1) is non-empty, nothing from (2) should be offered.

Similarly, if someone tries to complete man XXX <TAB>, and subcommand manpages exist, it would make more sense to offer the user only the available subcommand manpages, not all possible manpages.

scop commented 3 years ago

Agreed that this would be good, but implementation somewhat additionally complicated by that the previous argument possibly being a section (or not, if a section was already given earlier), or an option argument (we may not have complete knowledge of options that take an arg), etc.