Zsh Mailing List Archive
Messages sorted by: Reverse Date, Date, Thread, Author

Re: man page completion / regexp

On Sun, 6 Jun 2004, Jarkko Maja wrote:

> I'm have in my zsh-4.0.7 ~/.zshrc the following for man page completion:

The misplaced line-breaks caused by cut-and-paste combined with your email
client (?) is so bad that I really can't tell what's supposed to be going
on in that function.

However, based on what you say here:

> This works perfect in Linux/*BSD/Solaris. E.g., man locale[TAB] gives:
> locale.1 locale.5 locale.7 etc and man locale.7 becomes man 7 locale.
> [...] However, with newer versions of Linux's man-pages package there
> are also sections like 0p, 1p, 3p and, e.g., man man.1p becomes man 1
> man. So, to overcome this, I got man 1p man by this:
> command man
> ${(M)${${(M)@%.[0-9Xmnlpo]*}#.}%%[0-9Xmnlpo](|p)} 
> ${@%.[0-9Xmnlpo]*}
> But then I have problem because man X509_NAME_ENTRY_create_by_NID.3ssl
> becomes to man l

Your troubles are with ${(M)${${(M)@%.[0-9Xmnlpo]*}#.}%%[0-9Xmnlpo](|p)}
which breaks down as follows:

${(M)@%.[0-9Xmnlpo]*}	extracts the extension, including the dot, but 
only if it begins with one of the man page section letters.

${${...}#.}	removes the leading dot.  You might be able to replace
all of this with ${@:e} if you're willing to sacrifice a little accuracy.

${(M)${...}%%[0-9Xmnlpo](|p)}	extracts the longest tail of the extension 
that matches the man page sectioning scheme.

It should be pretty clear that what you want is not the longest tail of
the extension that matches, which in the case of "3ssl" is "l", but the
longest head, which is "3".  So the first thing to try is replacing %%
with ##.

However, this leads to another gotcha, which is that alternatives given
with (|) are tried in left-to-right order until _any_ _one_ matches, NOT
until the _longest_ one matches, even when used with %% or ##.  In the
case of (|p), that means that the empty alternative always matches and
hence man.1p becomes 1.  If you change it to (p|), you'll get 1p which
is what you want.

(Interestingly, though, when asking for the shortest match with # or %,
the empty alternative in (p|) is correctly chosen regardless of the order,
which suggests there may be a bug in ## and %%.)

So ${(M)${${(M)@%.[0-9Xmnlpo]*}#.}##[0-9Xmnlpo](p|)} is your answer, or
${(M)${@:e}##[0-9Xmnlpo](p|)} if you shorten it as I suggested.

> Also there man pages in dir man/man3 like LWP.3pm.

Which should reduce to 3 rather than 3p, I guess.  The only way to deal
with that without resorting to extendedglob patterns is to chop off the
"pm" with ${${...}%pm} before attempting to match "3p".  That leaves you
with ${(M)%{(@)${@:e}%pm}##[0-9Xmnlpo](p|)} or similar.

Messages sorted by: Reverse Date, Date, Thread, Author