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
131
132
133
134
135
136
|
let s:man_tag_depth = 0
let s:man_sect_arg = ''
let s:man_find_arg = '-w'
try
if !has('win32') && $OSTYPE !~? 'cygwin\|linux' && system('uname -s') =~? 'SunOS' && system('uname -r') =~? '^5'
let s:man_sect_arg = '-s'
let s:man_find_arg = '-l'
endif
catch /E145:/
" Ignore the error in restricted mode
endtry
" Expects a string like 'access' or 'access(2)'.
function s:parse_page_and_section(str)
try
let save_isk = &iskeyword
setlocal iskeyword-=(,)
let page = substitute(a:str, '(*\(\k\+\).*', '\1', '')
let sect = substitute(a:str, '\(\k\+\)(\([^()]*\)).*', '\2', '')
if sect == page || -1 == match(sect, '^[0-9 ]\+$')
let sect = ''
endif
catch
let &l:iskeyword = save_isk
echoerr 'man.vim: failed to parse: "'.a:str.'"'
endtry
return [page, sect]
endfunction
function man#get_page(...)
if a:0 == 0
echoerr 'argument required'
return
elseif a:0 > 2
echoerr 'too many arguments'
return
elseif a:0 == 2
let [sect, page] = [a:1, a:2]
elseif type(1) == type(a:1)
let [page, sect] = ['<cword>', a:1]
else
let [page, sect] = [a:1, '']
endif
if page == '<cword>'
let page = expand('<cword>')
endif
let [page, sect] = s:parse_page_and_section(page)
if sect !=# '' && s:FindPage(sect, page) == 0
let sect = ''
endif
if s:FindPage(sect, page) == 0
echo "\nNo manual entry for '".page."'"
return
endif
exec 'let s:man_tag_buf_'.s:man_tag_depth.' = '.bufnr('%')
exec 'let s:man_tag_lin_'.s:man_tag_depth.' = '.line('.')
exec 'let s:man_tag_col_'.s:man_tag_depth.' = '.col('.')
let s:man_tag_depth = s:man_tag_depth + 1
" Use an existing "man" window if it exists, otherwise open a new one.
if &filetype != 'man'
let thiswin = winnr()
wincmd b
if winnr() > 1
exe "norm! " . thiswin . "\<C-W>w"
while 1
if &filetype == 'man'
break
endif
wincmd w
if thiswin == winnr()
break
endif
endwhile
endif
if &filetype != 'man'
tabnew
" window-local options
setlocal foldcolumn=0 nonumber nolist norelativenumber nofoldenable
endif
endif
silent exec 'edit man://'.page.(empty(sect)?'':'('.sect.')')
setlocal modifiable
silent keepjumps norm! 1G"_dG
let $MANWIDTH = winwidth(0)
silent exec 'r!/usr/bin/man '.s:GetCmdArg(sect, page).' | col -b'
" Remove blank lines from top and bottom.
while getline(1) =~ '^\s*$'
silent keepjumps norm! gg"_dd
endwhile
while getline('$') =~ '^\s*$'
silent keepjumps norm! G"_dd
endwhile
setlocal filetype=man
endfunction
function man#pop_page()
if s:man_tag_depth > 0
let s:man_tag_depth = s:man_tag_depth - 1
exec "let s:man_tag_buf=s:man_tag_buf_".s:man_tag_depth
exec "let s:man_tag_lin=s:man_tag_lin_".s:man_tag_depth
exec "let s:man_tag_col=s:man_tag_col_".s:man_tag_depth
exec s:man_tag_buf."b"
exec s:man_tag_lin
exec "norm! ".s:man_tag_col."|"
exec "unlet s:man_tag_buf_".s:man_tag_depth
exec "unlet s:man_tag_lin_".s:man_tag_depth
exec "unlet s:man_tag_col_".s:man_tag_depth
unlet s:man_tag_buf s:man_tag_lin s:man_tag_col
endif
endfunction
function s:GetCmdArg(sect, page)
if a:sect == ''
return a:page
endif
return s:man_sect_arg.' '.a:sect.' '.a:page
endfunction
function s:FindPage(sect, page)
let where = system('/usr/bin/man '.s:man_find_arg.' '.s:GetCmdArg(a:sect, a:page))
if where !~ "^/"
if matchstr(where, " [^ ]*$") !~ "^ /"
return 0
endif
endif
return 1
endfunction
|