[Pkg-zsh-devel] Bug#138691: zsh: completion for man should find filenames as well as man pages

Daniel Shahaf danielsh at apache.org
Sun Aug 22 19:53:53 BST 2021


Vincent Lefevre wrote on Sun, Aug 01, 2021 at 22:27:38 +0200:
> As this very old bug is still open...
> 
> On 2002-03-18 11:45:08 -0500, Matt Zimmerman wrote:
> > On Mon, Mar 18, 2002 at 11:06:15AM -0500, Clint Adams wrote:
> > 
> > > > When the -l option is given, man will open and display a man page
> > > > specified as a pathname (and not search manpath).  At least with
> > > > Debian's man, this also works if -l is not specified, though manpath is
> > > > searched first.
> > > 
> > > This doesn't work for me with man-db 2.3.20-15.  What am I doing wrong?
> > 
> > The fallback only seems to work if there is a '/' character in the argument:
> > 
> > poseidon:[~] ls man.1
> > man.1
> > poseidon:[~] man man.1
> > No manual entry for man.1
> > zsh: exit 16    man man.1
> > poseidon:[~] man -l man.1
> > Reformatting man.1, please wait...
> > poseidon:[~] man ./man.1
> > Reformatting man.1, please wait...
> > poseidon:[~] 
> 
> With zsh 5.8-6+b2 on my machine, completion works as expected if there
> is a "/" character:
> 
> zira:~> man ./ma[Tab]
> 
> gives
> 
> zira:~> man ./man.1

Looks like this was first fixed in "28468: allow man page completion for
files when / is present" (e5ddd5b62f794e262119053c367ab66eca678475),
first released in zsh-4.3.10-test-3 and debian/4.3.11-4.  There were
later follow-ups, e.g., 45226 from 2020-01-05.

> Completion also works with -l, but also proposes files that are not
> man pages. I don't know whether such a difference is expected.

Shouldn't be hard to fix.  Here's a proof of concept; the $funcstack
check should be replaced by something else to decouple caller and
callee.

[[[
diff --git a/Completion/Unix/Command/_man b/Completion/Unix/Command/_man
index dba1d13dc..5c2d96c52 100644
--- a/Completion/Unix/Command/_man
+++ b/Completion/Unix/Command/_man
@@ -93,7 +93,7 @@ _man() {
       '(-i -I --ignore-case --match-case)'{-i,--ignore-case}'[search case-insensitively]'
       '(-i -I --ignore-case --match-case)'{-I,--match-case}'[search case-sensitively]'
       '(-L --locale)'{-L+,--locale=}'[specify locale]:locale:_locales'
-      "(${(j< >)modes})"{-l+,--local-file=}'[format and display specified file]:*:::manual file:_files'
+      "(${(j< >)modes})"{-l+,--local-file=}'[format and display specified file]:*:::manual file:_man_pages'
       "!(${(j< >)modes})"{--location,--location-cat}
       '--names-only[match only page names (with --regex or --wildcard)]'
       '(--nh --no-hyphenation)'{--nh,--no-hyphenation}'[disable hyphenation]'
@@ -139,7 +139,7 @@ _man() {
       '-S+[display only man pages with file names matching specified string]:search string'
     )
     [[ $variant == openbsd* ]] && args+=(
-      "(${(j< >)modes})-l+[format and display specified file]:*:::manual file:_files"
+      "(${(j< >)modes})-l+[format and display specified file]:*:::manual file:_man_pages"
       # @todo Could enumerate these
       '-S[search manual of specified architecture]:architecture'
     )
@@ -419,7 +419,7 @@ _man_pages() {
   # What files corresponding to manual pages can end in.
   local suf='.((?|<->*|ntcl)(|.gz|.bz2|.z|.Z|.lzma))'
 
-  if [[ $PREFIX$SUFFIX = */* ]]; then
+  if [[ $PREFIX$SUFFIX = */* || ${funcstack[2]} = '_arguments' ]]; then
     # Easy way to test for versions of man that allow file names.
     # This can't be a normal man page reference.
     # Try to complete by glob first.
]]]

Does it work as intended?

I don't intend to take this further; feel free to finish this yourself,
or to poke upstream in case someone there has time to finish this.

Cheers,

Daniel



More information about the Pkg-zsh-devel mailing list