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
137
138
139
140
141
142
143
144
145
146
147
148
|
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
function man#get_page(...)
let invoked_from_man = (&filetype ==# 'man')
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:find_page(sect, page) == 0
let sect = ''
endif
if s:find_page(sect, page) == 0
echo 'No 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 !invoked_from_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 !invoked_from_man
tabnew
call s:set_window_local_options()
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:get_cmd_arg(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 nomodified
setlocal filetype=man
if invoked_from_man
call s:set_window_local_options()
endif
endfunction
function s:set_window_local_options()
setlocal colorcolumn=0 foldcolumn=0 nonumber
setlocal nolist norelativenumber nofoldenable
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
" 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 s:get_cmd_arg(sect, page)
if a:sect == ''
return a:page
endif
return s:man_sect_arg.' '.a:sect.' '.a:page
endfunction
function s:find_page(sect, page)
let where = system('/usr/bin/man '.s:man_find_arg.' '.s:get_cmd_arg(a:sect, a:page))
if where !~ "^/"
if matchstr(where, " [^ ]*$") !~ "^ /"
return 0
endif
endif
return 1
endfunction
|