aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/autoload/man.vim75
-rw-r--r--runtime/ftplugin/man.vim4
2 files changed, 38 insertions, 41 deletions
diff --git a/runtime/autoload/man.vim b/runtime/autoload/man.vim
index a9256638e1..36f42c0003 100644
--- a/runtime/autoload/man.vim
+++ b/runtime/autoload/man.vim
@@ -64,33 +64,20 @@ function! man#open_page(count, count1, mods, ...) abort
return
endtry
- call s:push_tag()
- let bufname = 'man://'.name.(empty(sect)?'':'('.sect.')')
-
+ let [l:buf, l:save_tfu] = [bufnr(), &tagfunc]
try
- set eventignore+=BufReadCmd
+ set tagfunc=man#goto_tag
+ let l:target = l:name . '(' . l:sect . ')'
if a:mods !~# 'tab' && s:find_man()
- execute 'silent keepalt edit' fnameescape(bufname)
+ execute 'silent keepalt tag' l:target
else
- execute 'silent keepalt' a:mods 'split' fnameescape(bufname)
+ execute 'silent keepalt' a:mods 'stag' l:target
endif
finally
- set eventignore-=BufReadCmd
- endtry
-
- try
- let page = s:get_page(path)
- catch
- if a:mods =~# 'tab' || !s:find_man()
- " a new window was opened
- close
- endif
- call s:error(v:exception)
- return
+ call setbufvar(l:buf, '&tagfunc', l:save_tfu)
endtry
let b:man_sect = sect
- call s:put_page(page)
endfunction
function! man#read_page(ref) abort
@@ -163,6 +150,7 @@ endfunction
function! s:put_page(page) abort
setlocal modifiable
setlocal noreadonly
+ setlocal noswapfile
silent keepjumps %delete _
silent put =a:page
while getline(1) =~# '^\s*$'
@@ -254,24 +242,6 @@ function! s:verify_exists(sect, name) abort
return s:extract_sect_and_name_path(path) + [path]
endfunction
-let s:tag_stack = []
-
-function! s:push_tag() abort
- let s:tag_stack += [{
- \ 'buf': bufnr('%'),
- \ 'lnum': line('.'),
- \ 'col': col('.'),
- \ }]
-endfunction
-
-function! man#pop_tag() abort
- if !empty(s:tag_stack)
- let tag = remove(s:tag_stack, -1)
- execute 'silent' tag['buf'].'buffer'
- call cursor(tag['lnum'], tag['col'])
- endif
-endfunction
-
" extracts the name and sect out of 'path/name.sect'
function! s:extract_sect_and_name_path(path) abort
let tail = fnamemodify(a:path, ':t')
@@ -356,14 +326,18 @@ function! man#complete(arg_lead, cmd_line, cursor_pos) abort
return s:complete(sect, sect, name)
endfunction
-function! s:complete(sect, psect, name) abort
+function! s:get_paths(sect, name) abort
try
let mandirs = join(split(s:system(['man', s:find_arg]), ':\|\n'), ',')
catch
call s:error(v:exception)
return
endtry
- let pages = globpath(mandirs,'man?/'.a:name.'*.'.a:sect.'*', 0, 1)
+ return globpath(mandirs,'man?/'.a:name.'*.'.a:sect.'*', 0, 1)
+endfunction
+
+function! s:complete(sect, psect, name) abort
+ let pages = s:get_paths(a:sect, a:name)
" We remove duplicates in case the same manpage in different languages was found.
return uniq(sort(map(pages, 's:format_candidate(v:val, a:psect)'), 'i'))
endfunction
@@ -402,4 +376,27 @@ function! man#init_pager() abort
endif
endfunction
+function! man#goto_tag(pattern, flags, info) abort
+ let [l:sect, l:name] = man#extract_sect_and_name_ref(a:pattern)
+
+ let l:paths = s:get_paths(l:sect, l:name)
+ let l:structured = []
+
+ for l:path in l:paths
+ let l:n = s:extract_sect_and_name_path(l:path)[1]
+ let l:structured += [{ 'name': l:n, 'path': l:path }]
+ endfor
+
+ " sort by relevance - exact matches first, then the previous order
+ call sort(l:structured, { a, b -> a.name ==? l:name ? -1 : b.name ==? l:name ? 1 : 0 })
+
+ return map(l:structured, {
+ \ _, entry -> {
+ \ 'name': entry.name,
+ \ 'filename': 'man://' . entry.path,
+ \ 'cmd': '1'
+ \ }
+ \ })
+endfunction
+
call s:init()
diff --git a/runtime/ftplugin/man.vim b/runtime/ftplugin/man.vim
index 6c7f095f62..b3b23833ba 100644
--- a/runtime/ftplugin/man.vim
+++ b/runtime/ftplugin/man.vim
@@ -20,13 +20,13 @@ setlocal wrap breakindent linebreak
setlocal nonumber norelativenumber
setlocal foldcolumn=0 colorcolumn=0 nolist nofoldenable
+setlocal tagfunc=man#goto_tag
+
if !exists('g:no_plugin_maps') && !exists('g:no_man_maps')
nnoremap <silent> <buffer> j gj
nnoremap <silent> <buffer> k gk
nnoremap <silent> <buffer> gO :call man#show_toc()<CR>
- nnoremap <silent> <buffer> <C-]> :Man<CR>
nnoremap <silent> <buffer> K :Man<CR>
- nnoremap <silent> <buffer> <C-T> :call man#pop_tag()<CR>
if 1 == bufnr('%') || s:pager
nnoremap <silent> <buffer> <nowait> q :lclose<CR>:q<CR>
else