@@ -7,7 +7,6 @@ let s:loaded_man = 1
7
7
8
8
let s:find_arg = '-w'
9
9
let s:localfile_arg = v:true " Always use -l if possible. #6683
10
-
let s:section_arg = '-S'
11
10
12
11
function! man#init() abort
13
12
try
@@ -216,16 +215,38 @@ endfunction
216
215
217
216
function! s:get_path(sect, name) abort
218
217
" Some man implementations (OpenBSD) return all available paths from the
219
-
" search command, so we get() the first one. #8341
220
-
if empty(a:sect)
221
-
return substitute(get(split(s:system(['man', s:find_arg, a:name])), 0, ''), '\n\+$', '', '')
218
+
" search command. Previously, this function would simply select the first one.
219
+
"
220
+
" However, some searches will report matches that are incorrect:
221
+
" man -w strlen may return string.3 followed by strlen.3, and therefore
222
+
" selecting the first would get us the wrong page. Thus, we must find the
223
+
" first matching one.
224
+
"
225
+
" There's yet another special case here. Consider the following:
226
+
" If you run man -w strlen and string.3 comes up first, this is a problem. We
227
+
" should search for a matching named one in the results list.
228
+
" However, if you search for man -w clock_gettime, you will *only* get
229
+
" clock_getres.2, which is the right page. Searching the resuls for
230
+
" clock_gettime will no longer work. In this case, we should just use the
231
+
" first one that was found in the correct section.
232
+
"
233
+
" Finally, we can avoid relying on -S or -s here since they are very
234
+
" inconsistently supported. Instead, call -w with a section and a name.
235
+
let results = split(s:system(['man', s:find_arg, a:sect, a:name]))
236
+
237
+
if empty(results)
238
+
return ''
222
239
endif
223
-
" '-s' flag handles:
224
-
" - tokens like 'printf(echo)'
225
-
" - sections starting with '-'
226
-
" - 3pcap section (found on macOS)
227
-
" - commas between sections (for section priority)
228
-
return substitute(get(split(s:system(['man', s:find_arg, s:section_arg, a:sect, a:name])), 0, ''), '\n\+$', '', '')
240
+
241
+
" find any that match the specified name
242
+
let namematches = filter(copy(results), 'fnamemodify(v:val, ":t") =~ a:name')
243
+
let sectmatches = []
244
+
245
+
if !empty(namematches) && !empty(a:sect)
246
+
let sectmatches = filter(copy(namematches), 'fnamemodify(v:val, ":e") == a:sect')
247
+
endif
248
+
249
+
return substitute(get(sectmatches, 0, get(namematches, 0, results[0])), '\n\+$', '', '')
229
250
endfunction
230
251
231
252
" s:verify_exists attempts to find the path to a manpage
@@ -243,40 +264,72 @@ endfunction
243
264
" then we don't do it again in step 2.
244
265
function! s:verify_exists(sect, name) abort
245
266
let sect = a:sect
246
-
if empty(sect)
247
-
let sect = get(b:, 'man_default_sects', '')
248
-
endif
249
267
250
-
try
251
-
return s:get_path(sect, a:name)
252
-
catch /^command error (/
253
-
endtry
254
-
255
-
if !empty(get(b:, 'man_default_sects', '')) && sect !=# b:man_default_sects
268
+
if empty(sect)
269
+
" no section specified, so search with b:man_default_sects
270
+
if exists('b:man_default_sects')
271
+
let sects = split(b:man_default_sects, ',')
272
+
for sec in sects
273
+
try
274
+
let res = s:get_path(sec, a:name)
275
+
if !empty(res)
276
+
return res
277
+
endif
278
+
catch /^command error (/
279
+
endtry
280
+
endfor
281
+
endif
282
+
else
283
+
" try with specified section
256
284
try
257
-
return s:get_path(b:man_default_sects, a:name)
285
+
let res = s:get_path(sect, a:name)
286
+
if !empty(res)
287
+
return res
288
+
endif
258
289
catch /^command error (/
259
290
endtry
260
-
endif
261
291
262
-
if !empty(sect)
263
-
try
264
-
return s:get_path('', a:name)
265
-
catch /^command error (/
266
-
endtry
292
+
" try again with b:man_default_sects
293
+
if exists('b:man_default_sects')
294
+
let sects = split(b:man_default_sects, ',')
295
+
for sec in sects
296
+
try
297
+
let res = s:get_path(sec, a:name)
298
+
if !empty(res)
299
+
return res
300
+
endif
301
+
catch /^command error (/
302
+
endtry
303
+
endfor
304
+
endif
267
305
endif
268
306
307
+
" if none of the above worked, we will try with no section
308
+
try
309
+
let res = s:get_path('', a:name)
310
+
if !empty(res)
311
+
return res
312
+
endif
313
+
catch /^command error (/
314
+
endtry
315
+
316
+
" if that still didn't work, we will check for $MANSECT and try again with it
317
+
" unset
269
318
if !empty($MANSECT)
270
319
try
271
320
let MANSECT = $MANSECT
272
321
call setenv('MANSECT', v:null)
273
-
return s:get_path('', a:name)
322
+
let res = s:get_path('', a:name)
323
+
if !empty(res)
324
+
return res
325
+
endif
274
326
catch /^command error (/
275
327
finally
276
328
call setenv('MANSECT', MANSECT)
277
329
endtry
278
330
endif
279
331
332
+
" finally, if that didn't work, there is no hope
280
333
throw 'no manual entry for ' . a:name
281
334
endfunction
282
335
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4