about summary refs log tree commit diff
path: root/Completion/Unix/Command/_man
blob: 81ac40bc2792606cf602e9534e9acb17c42b51dd (plain) (blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
#compdef man apropos whatis

_man() {
  local dirs expl mrd awk

  if (( $words[(I)-M] == (( $CURRENT - 1 )) )); then
    _directories && return 0
  fi

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

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

  (( $#_manpath )) ||
      _manpath=( /usr/man(-/) /(opt|usr)/(pkg|dt|share|X11R6|local)/(cat|)man(-/) )

  integer index=$words[(I)-M]
  if (( index )); then
    local opt
    opt=$words[index+1]
    _manpath=($opt)
  fi

  # `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))

  local sect
  if [[ $OSTYPE = solaris* ]]; then
    sect=${${words[(R)-s*]#-s}:-$words[$words[(i)-s]+1]}
  elif [[ -n ${sect:=$words[$words[(i)-S]+1]} || -n ${sect:=$MANSECT} ]]; then
    if [[ $sect != ${sect::="${sect//:/|}"} ]]; then
      sect="($sect)"
    fi
  elif (( CURRENT > 2 )); then
    sect=$words[2]
  fi

  if [[ $sect = (<->*|1M|l|n) || $sect = \(*\|*\) ]]; then
    dirs=( $^_manpath/(sman|man|cat)${~sect}/ )
    awk="\$2 == \"$sect\" {print \$1}"
  else
    dirs=( $^_manpath/(sman|man|cat)*/ )
    awk='{print $1}'
  fi
  if [[ $OSTYPE = solaris* && ( $words[CURRENT] = -s* || $words[CURRENT-1] == -s ) ]]; then
    [[ $words[CURRENT] = -s* ]] && compset -P '-s'
    sects=( ${(o)${dirs##*(man|cat)}%/} )
    _wanted sections expl 'section' compadd -a sects
  elif zstyle -t ":completion:${curcontext}:manuals" separate-sections; then
    typeset -U sects
    local ret=1

    sects=( ${(o)${dirs##*(man|cat)}%/} )

    (( $#sects )) || return 1

    _tags manuals.${^sects}
    while _tags; do
      for sect in $sects; do
        _requested manuals.$sect expl "manual page, section $sect" _man_pages &&
            ret=0
      done
      (( ret )) || return 0
    done

    return 1
  else
    sect=
    _wanted manuals expl 'manual page' _man_pages
  fi
}

_man_pages() {
  local matcher pages dummy sopt

  # What files corresponding to manual pages can end in.
  local suf='.((?|<->*)(|.gz|.bz2|.Z|.lzma))'

  if [[ $PREFIX$SUFFIX = */* ]]; 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.
    _path_files -g "*$suf" && return
    _path_files
    return
  fi

  zparseopts -E M+:=matcher

  if (( $#matcher )); then
    matcher=( ${matcher:#-M} )
    matcher="$matcher"
  else
    matcher=
  fi

  pages=( ${(M)dirs:#*$sect/} )
  compfiles -p pages '' '' "$matcher" '' dummy '*'
  pages=( ${^~pages}(N:t) )

  (($#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'.

  [[ $OSTYPE = solaris* ]] && sopt='-s '
  if ((CURRENT > 2)) ||
      ! zstyle -t ":completion:${curcontext}:manuals.$sect" insert-sections
  then
    compadd "$@" - ${pages%$~suf}
  else
    compadd "$@" -P "$sopt$sect " - ${pages%$~suf}
  fi
}

_man "$@"