#138691 zsh: completion for man should find filenames as well as man pages

Package:
zsh
Source:
zsh
Description:
shell with lots of features
Submitter:
Matt Zimmerman
Date:
2021-08-22 23:48:03 UTC
Severity:
wishlist
#138691#5
Date:
2002-03-17 04:15:09 UTC
From:
To:
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.

#138691#10
Date:
2002-03-18 16:06:15 UTC
From:
To:
This doesn't work for me with man-db 2.3.20-15.  What am I doing wrong?
#138691#15
Date:
2002-03-18 16:45:08 UTC
From:
To:
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:[~]

I have gotten in the habit of doing this because it is still shorter than
man -l.

By the way, shouldn't it be possible to do man page completion based on the
output of man -wa, rather than trying to emulate man's own searching?

#138691#20
Date:
2002-03-18 16:53:10 UTC
From:
To:
Ah, I didn't try that.

Not if you can't hit tab, it isn't.  :)

I would think man -f would be more useful, actually.  It's too bad that
man-db doesn't identify itself more clearly with --version, or it would
be a lot easier to determine when such things would be more appropriate.

#138691#25
Date:
2002-03-18 17:13:14 UTC
From:
To:
whatis --regex, which I just discovered, would be even better.
It reports its verson the same as man, though, so if that isn't sufficient,
I guess it's no good.

It would be worth filing a bug against man-db to get this functionality.
What are the details of the issue with --version?

#138691#30
Date:
2002-03-18 17:46:45 UTC
From:
To:
Well, it's just writing an expression to match; since I can't
find a single other man that responds well to --version, it probably
isn't too much of a problem.

So it's just the standard issues with matching too narrowly or broadly.

#138691#35
Date:
2021-08-01 20:27:38 UTC
From:
To:
As this very old bug is still open...

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

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

#138691#40
Date:
2021-08-22 18:53:53 UTC
From:
To:
Vincent Lefevre wrote on Sun, Aug 01, 2021 at 22:27:38 +0200:
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.

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

#138691#45
Date:
2021-08-22 23:46:07 UTC
From:
To:
I've done some tests, and it seems to work as expected. Thanks.