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

Re: _man igores global matchers



Bart Schaefer wrote:

> I wrote:
> }
> } This patch drops the filtering on man page name and instead slurps up all
> } the file basenames into the `rep' array, then passes that and the global
> } matcher spec to compadd to let it sort out the mess.  If you have several
> } matchers this can get pretty slow, so it ought at least to cache `rep'
> } somewhere during the loop over the matchers; as it stands this is mostly
> } a proof of concept.
> 
> Here's a better variation, which actually does cache the results for one
> pass around the matcher loop.  It's quite a bit faster than with the
> patch from 14621, but still slower than the existing _man.

I have one, too...

This uses _path_files' builtin compfiles to try to get smarter glob
patterns with respect to the matchers in use.

It gives me acceptable speed but could still be improved, e.g. by
caching the man dirs to use (using a hash with $words[2] as the key if
it gives the section).  These won't take up too much space and don't
change that often (and we could compare $MANPATH to the one that was
used when the dirs were cached, making it really safe).

So, ... should we?  How fast is it for you?


Bye
  Sven

#compdef man apropos whatis

_man() {
  local dirs expl mrd awk

  if [[ $service == man ]] && (( $words[(I)-l] + $words[(I)--local-file] )); then
    _files || return 0
  fi

  if (( ! $#manpath )); then
    local mp
    mp=($(manpath 2>/dev/null))
    [[ "$mp" == *:* ]] && mp=( ${(s.:.)mp} )
    manpath=( $mp )
  fi

  (( $#manpath )) || manpath=( ${(s.:.)$(manpath 2>/dev/null)} ) ||
      manpath=( /usr/man(-/) /(opt|usr)/(dt|share|X11R6|local)/(cat|)man(-/) )

  # `sman' is the SGML manual directory for Solaris 7.
  # 1M is system administrator commands on SVR4

  mrd=(${^manpath/\%L/${LANG:-En_US.ASCII}}/mandb(N))

  if [[ $words[2] = (<->*|1M|l|n) ]]; then
    dirs=( $^manpath/(sman|man|cat)${words[2]}/ )
    awk="\$2 == \"$words[2]\" {print \$1}"
  else
    dirs=( $^manpath/(sman|man|cat)*/ )
    awk='{print $1}'
  fi

  _wanted manuals expl 'manual page' _man_pages
}

_man_pages() {
  local matcher pages dummy

  zparseopts -E M:=matcher

  if (( $#matcher )); then
    matcher="$matcher[2]"
  else
    matcher=
  fi

  pages=( $dirs )
  compfiles -p pages '' '' "$matcher" '' dummy '*'

  pages=( $~pages(:t:r) )

  (($#mrd)) && pages[$#pages+1]=($(awk $awk $mrd))

  # Remove any compression suffix, then remove the minimum possible string
  # beginning with .<->: that handles problem cases like files called
  # `POSIX.1.5'.

  compadd "$@" - ${pages%.<->*}
}

_man "$@"

-- 
Sven Wischnowsky                         wischnow@xxxxxxxxxxxxxxxxxxxxxxx



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