1071d4279SBram Moolenaar" Vim filetype plugin file 2071d4279SBram Moolenaar" Language: man 37ceefb35SBram Moolenaar" Maintainer: Jason Franklin <[email protected]> 42cfb4a2aSBram Moolenaar" Maintainer: SungHyun Nam <[email protected]> 5*6e649224SBram Moolenaar" Last Change: 2021 Sep 26 6071d4279SBram Moolenaar 7071d4279SBram Moolenaar" To make the ":Man" command available before editing a manual page, source 8071d4279SBram Moolenaar" this script from your startup vimrc file. 9071d4279SBram Moolenaar 10071d4279SBram Moolenaar" If 'filetype' isn't "man", we must have been called to only define ":Man". 11071d4279SBram Moolenaarif &filetype == "man" 12071d4279SBram Moolenaar 13071d4279SBram Moolenaar " Only do this when not done yet for this buffer 14071d4279SBram Moolenaar if exists("b:did_ftplugin") 15071d4279SBram Moolenaar finish 16071d4279SBram Moolenaar endif 17071d4279SBram Moolenaar let b:did_ftplugin = 1 1891f84f6eSBram Moolenaarendif 19071d4279SBram Moolenaar 2091f84f6eSBram Moolenaarlet s:cpo_save = &cpo 2191f84f6eSBram Moolenaarset cpo-=C 2291f84f6eSBram Moolenaar 2391f84f6eSBram Moolenaarif &filetype == "man" 24071d4279SBram Moolenaar " allow dot and dash in manual page name. 25071d4279SBram Moolenaar setlocal iskeyword+=\.,- 2691f84f6eSBram Moolenaar let b:undo_ftplugin = "setlocal iskeyword<" 27071d4279SBram Moolenaar 28071d4279SBram Moolenaar " Add mappings, unless the user didn't want this. 29071d4279SBram Moolenaar if !exists("no_plugin_maps") && !exists("no_man_maps") 30071d4279SBram Moolenaar if !hasmapto('<Plug>ManBS') 31071d4279SBram Moolenaar nmap <buffer> <LocalLeader>h <Plug>ManBS 3291f84f6eSBram Moolenaar let b:undo_ftplugin = b:undo_ftplugin 3391f84f6eSBram Moolenaar \ . '|silent! nunmap <buffer> <LocalLeader>h' 34071d4279SBram Moolenaar endif 35d2cec5b0SBram Moolenaar nnoremap <buffer> <Plug>ManBS :%s/.\b//g<CR>:setl nomod<CR>'' 36071d4279SBram Moolenaar 37acc22406SBram Moolenaar nnoremap <buffer> <silent> <c-]> :call <SID>PreGetPage(v:count)<CR> 38acc22406SBram Moolenaar nnoremap <buffer> <silent> <c-t> :call <SID>PopPage()<CR> 39d042dc82SBram Moolenaar nnoremap <buffer> <silent> q :q<CR> 4091f84f6eSBram Moolenaar 4191f84f6eSBram Moolenaar " Add undo commands for the maps 4291f84f6eSBram Moolenaar let b:undo_ftplugin = b:undo_ftplugin 4391f84f6eSBram Moolenaar \ . '|silent! nunmap <buffer> <Plug>ManBS' 4491f84f6eSBram Moolenaar \ . '|silent! nunmap <buffer> <c-]>' 4591f84f6eSBram Moolenaar \ . '|silent! nunmap <buffer> <c-t>' 4691f84f6eSBram Moolenaar \ . '|silent! nunmap <buffer> q' 47d042dc82SBram Moolenaar endif 48d042dc82SBram Moolenaar 49d042dc82SBram Moolenaar if exists('g:ft_man_folding_enable') && (g:ft_man_folding_enable == 1) 50d042dc82SBram Moolenaar setlocal foldmethod=indent foldnestmax=1 foldenable 5191f84f6eSBram Moolenaar let b:undo_ftplugin = b:undo_ftplugin 5291f84f6eSBram Moolenaar \ . '|silent! setl fdm< fdn< fen<' 53071d4279SBram Moolenaar endif 54071d4279SBram Moolenaar 55071d4279SBram Moolenaarendif 56071d4279SBram Moolenaar 57071d4279SBram Moolenaarif exists(":Man") != 2 5891f84f6eSBram Moolenaar com -nargs=+ -complete=shellcmd Man call s:GetPage(<q-mods>, <f-args>) 59071d4279SBram Moolenaar nmap <Leader>K :call <SID>PreGetPage(0)<CR> 6068563937SBram Moolenaar nmap <Plug>ManPreGetPage :call <SID>PreGetPage(0)<CR> 61071d4279SBram Moolenaarendif 62071d4279SBram Moolenaar 63071d4279SBram Moolenaar" Define functions only once. 64071d4279SBram Moolenaarif !exists("s:man_tag_depth") 65071d4279SBram Moolenaar 66071d4279SBram Moolenaarlet s:man_tag_depth = 0 67071d4279SBram Moolenaar 68864207deSBram Moolenaarlet s:man_sect_arg = "" 69864207deSBram Moolenaarlet s:man_find_arg = "-w" 70864207deSBram Moolenaartry 71071d4279SBram Moolenaar if !has("win32") && $OSTYPE !~ 'cygwin\|linux' && system('uname -s') =~ "SunOS" && system('uname -r') =~ "^5" 72071d4279SBram Moolenaar let s:man_sect_arg = "-s" 73071d4279SBram Moolenaar let s:man_find_arg = "-l" 74071d4279SBram Moolenaar endif 75864207deSBram Moolenaarcatch /E145:/ 76864207deSBram Moolenaar " Ignore the error in restricted mode 77864207deSBram Moolenaarendtry 78071d4279SBram Moolenaar 79cb80aa2dSBram Moolenaarfunc s:PreGetPage(cnt) 80071d4279SBram Moolenaar if a:cnt == 0 81071d4279SBram Moolenaar let old_isk = &iskeyword 82c229967cSBram Moolenaar if &ft == 'man' 83071d4279SBram Moolenaar setl iskeyword+=(,) 84c229967cSBram Moolenaar endif 85071d4279SBram Moolenaar let str = expand("<cword>") 86071d4279SBram Moolenaar let &l:iskeyword = old_isk 87071d4279SBram Moolenaar let page = substitute(str, '(*\(\k\+\).*', '\1', '') 88071d4279SBram Moolenaar let sect = substitute(str, '\(\k\+\)(\([^()]*\)).*', '\2', '') 89071d4279SBram Moolenaar if match(sect, '^[0-9 ]\+$') == -1 90071d4279SBram Moolenaar let sect = "" 91071d4279SBram Moolenaar endif 92071d4279SBram Moolenaar if sect == page 93071d4279SBram Moolenaar let sect = "" 94071d4279SBram Moolenaar endif 95071d4279SBram Moolenaar else 96071d4279SBram Moolenaar let sect = a:cnt 97071d4279SBram Moolenaar let page = expand("<cword>") 98071d4279SBram Moolenaar endif 99191acfdeSBram Moolenaar call s:GetPage('', sect, page) 100071d4279SBram Moolenaarendfunc 101071d4279SBram Moolenaar 102cb80aa2dSBram Moolenaarfunc s:GetCmdArg(sect, page) 103cb80aa2dSBram Moolenaar 104cb80aa2dSBram Moolenaar if empty(a:sect) 105cb80aa2dSBram Moolenaar return shellescape(a:page) 106071d4279SBram Moolenaar endif 107cb80aa2dSBram Moolenaar 108cb80aa2dSBram Moolenaar return s:man_sect_arg . ' ' . shellescape(a:sect) . ' ' . shellescape(a:page) 109071d4279SBram Moolenaarendfunc 110071d4279SBram Moolenaar 111cb80aa2dSBram Moolenaarfunc s:FindPage(sect, page) 112cb80aa2dSBram Moolenaar let l:cmd = printf('man %s %s', s:man_find_arg, s:GetCmdArg(a:sect, a:page)) 113cb80aa2dSBram Moolenaar call system(l:cmd) 114cb80aa2dSBram Moolenaar 115cb80aa2dSBram Moolenaar if v:shell_error 116071d4279SBram Moolenaar return 0 117071d4279SBram Moolenaar endif 118cb80aa2dSBram Moolenaar 119071d4279SBram Moolenaar return 1 120071d4279SBram Moolenaarendfunc 121071d4279SBram Moolenaar 122cb80aa2dSBram Moolenaarfunc s:GetPage(cmdmods, ...) 123071d4279SBram Moolenaar if a:0 >= 2 124071d4279SBram Moolenaar let sect = a:1 125071d4279SBram Moolenaar let page = a:2 126071d4279SBram Moolenaar elseif a:0 >= 1 127071d4279SBram Moolenaar let sect = "" 128071d4279SBram Moolenaar let page = a:1 129071d4279SBram Moolenaar else 130071d4279SBram Moolenaar return 131071d4279SBram Moolenaar endif 132071d4279SBram Moolenaar 133071d4279SBram Moolenaar " To support: nmap K :Man <cword> 134071d4279SBram Moolenaar if page == '<cword>' 135071d4279SBram Moolenaar let page = expand('<cword>') 136071d4279SBram Moolenaar endif 137071d4279SBram Moolenaar 1385be4ceecSBram Moolenaar if !exists('g:ft_man_no_sect_fallback') || (g:ft_man_no_sect_fallback == 0) 139071d4279SBram Moolenaar if sect != "" && s:FindPage(sect, page) == 0 140071d4279SBram Moolenaar let sect = "" 141071d4279SBram Moolenaar endif 1425be4ceecSBram Moolenaar endif 143071d4279SBram Moolenaar if s:FindPage(sect, page) == 0 144acc22406SBram Moolenaar let msg = 'man.vim: no manual entry for "' . page . '"' 145acc22406SBram Moolenaar if !empty(sect) 146acc22406SBram Moolenaar let msg .= ' in section ' . sect 1475be4ceecSBram Moolenaar endif 148acc22406SBram Moolenaar echomsg msg 149071d4279SBram Moolenaar return 150071d4279SBram Moolenaar endif 151071d4279SBram Moolenaar exec "let s:man_tag_buf_".s:man_tag_depth." = ".bufnr("%") 152071d4279SBram Moolenaar exec "let s:man_tag_lin_".s:man_tag_depth." = ".line(".") 153071d4279SBram Moolenaar exec "let s:man_tag_col_".s:man_tag_depth." = ".col(".") 154071d4279SBram Moolenaar let s:man_tag_depth = s:man_tag_depth + 1 155071d4279SBram Moolenaar 156e5e69501SBram Moolenaar let open_cmd = 'edit' 157e5e69501SBram Moolenaar 158071d4279SBram Moolenaar " Use an existing "man" window if it exists, otherwise open a new one. 159071d4279SBram Moolenaar if &filetype != "man" 160071d4279SBram Moolenaar let thiswin = winnr() 161071d4279SBram Moolenaar exe "norm! \<C-W>b" 162c81e5e79SBram Moolenaar if winnr() > 1 163071d4279SBram Moolenaar exe "norm! " . thiswin . "\<C-W>w" 164071d4279SBram Moolenaar while 1 165071d4279SBram Moolenaar if &filetype == "man" 166071d4279SBram Moolenaar break 167071d4279SBram Moolenaar endif 168071d4279SBram Moolenaar exe "norm! \<C-W>w" 169071d4279SBram Moolenaar if thiswin == winnr() 170071d4279SBram Moolenaar break 171071d4279SBram Moolenaar endif 172071d4279SBram Moolenaar endwhile 173071d4279SBram Moolenaar endif 174c81e5e79SBram Moolenaar if &filetype != "man" 175ddf8d1c7SBram Moolenaar if exists("g:ft_man_open_mode") 176e5e69501SBram Moolenaar if g:ft_man_open_mode == 'vert' 177e5e69501SBram Moolenaar let open_cmd = 'vsplit' 178e5e69501SBram Moolenaar elseif g:ft_man_open_mode == 'tab' 179e5e69501SBram Moolenaar let open_cmd = 'tabedit' 180ddf8d1c7SBram Moolenaar else 181e5e69501SBram Moolenaar let open_cmd = 'split' 182ddf8d1c7SBram Moolenaar endif 183ddf8d1c7SBram Moolenaar else 184e5e69501SBram Moolenaar let open_cmd = a:cmdmods . ' split' 18591f84f6eSBram Moolenaar endif 186c81e5e79SBram Moolenaar endif 187071d4279SBram Moolenaar endif 188e5e69501SBram Moolenaar 189e5e69501SBram Moolenaar silent execute open_cmd . " $HOME/" . page . '.' . sect . '~' 190e5e69501SBram Moolenaar 191071d4279SBram Moolenaar " Avoid warning for editing the dummy file twice 192d2cec5b0SBram Moolenaar setl buftype=nofile noswapfile 193071d4279SBram Moolenaar 194bca9c301SBram Moolenaar setl fdc=0 ma nofen nonu nornu 19555b0fb70SBram Moolenaar %delete _ 196ddf8d1c7SBram Moolenaar let unsetwidth = 0 197cbebd487SBram Moolenaar if empty($MANWIDTH) 198071d4279SBram Moolenaar let $MANWIDTH = winwidth(0) 199ddf8d1c7SBram Moolenaar let unsetwidth = 1 200cbebd487SBram Moolenaar endif 2017f2e9d7cSBram Moolenaar 2027f2e9d7cSBram Moolenaar " Ensure Vim is not recursively invoked (man-db does this) when doing ctrl-[ 2037f2e9d7cSBram Moolenaar " on a man page reference by unsetting MANPAGER. 20440962ec9SBram Moolenaar " Some versions of env(1) do not support the '-u' option, and in such case 20540962ec9SBram Moolenaar " we set MANPAGER=cat. 20640962ec9SBram Moolenaar if !exists('s:env_has_u') 20740962ec9SBram Moolenaar call system('env -u x true') 20840962ec9SBram Moolenaar let s:env_has_u = (v:shell_error == 0) 20940962ec9SBram Moolenaar endif 21040962ec9SBram Moolenaar let env_cmd = s:env_has_u ? 'env -u MANPAGER' : 'env MANPAGER=cat' 211d1caa941SBram Moolenaar let env_cmd .= ' GROFF_NO_SGR=1' 2122cfb4a2aSBram Moolenaar let man_cmd = env_cmd . ' man ' . s:GetCmdArg(sect, page) . ' | col -b' 21340962ec9SBram Moolenaar silent exec "r !" . man_cmd 2147f2e9d7cSBram Moolenaar 215ddf8d1c7SBram Moolenaar if unsetwidth 216ddf8d1c7SBram Moolenaar let $MANWIDTH = '' 217ddf8d1c7SBram Moolenaar endif 218071d4279SBram Moolenaar " Remove blank lines from top and bottom. 2192a953fcfSBram Moolenaar while line('$') > 1 && getline(1) =~ '^\s*$' 22055b0fb70SBram Moolenaar 1delete _ 221071d4279SBram Moolenaar endwhile 2222a953fcfSBram Moolenaar while line('$') > 1 && getline('$') =~ '^\s*$' 22355b0fb70SBram Moolenaar $delete _ 224071d4279SBram Moolenaar endwhile 225071d4279SBram Moolenaar 1 226071d4279SBram Moolenaar setl ft=man nomod 227071d4279SBram Moolenaar setl bufhidden=hide 228071d4279SBram Moolenaar setl nobuflisted 229ddf8d1c7SBram Moolenaar setl noma 230071d4279SBram Moolenaarendfunc 231071d4279SBram Moolenaar 232cb80aa2dSBram Moolenaarfunc s:PopPage() 233071d4279SBram Moolenaar if s:man_tag_depth > 0 234071d4279SBram Moolenaar let s:man_tag_depth = s:man_tag_depth - 1 235071d4279SBram Moolenaar exec "let s:man_tag_buf=s:man_tag_buf_".s:man_tag_depth 236071d4279SBram Moolenaar exec "let s:man_tag_lin=s:man_tag_lin_".s:man_tag_depth 237071d4279SBram Moolenaar exec "let s:man_tag_col=s:man_tag_col_".s:man_tag_depth 238071d4279SBram Moolenaar exec s:man_tag_buf."b" 239071d4279SBram Moolenaar exec s:man_tag_lin 24085eee130SBram Moolenaar exec "norm! ".s:man_tag_col."|" 241071d4279SBram Moolenaar exec "unlet s:man_tag_buf_".s:man_tag_depth 242071d4279SBram Moolenaar exec "unlet s:man_tag_lin_".s:man_tag_depth 243071d4279SBram Moolenaar exec "unlet s:man_tag_col_".s:man_tag_depth 244071d4279SBram Moolenaar unlet s:man_tag_buf s:man_tag_lin s:man_tag_col 245071d4279SBram Moolenaar endif 246071d4279SBram Moolenaarendfunc 247071d4279SBram Moolenaar 248071d4279SBram Moolenaarendif 249071d4279SBram Moolenaar 25091f84f6eSBram Moolenaarlet &cpo = s:cpo_save 25191f84f6eSBram Moolenaarunlet s:cpo_save 25291f84f6eSBram Moolenaar 253ddf8d1c7SBram Moolenaar" vim: set sw=2 ts=8 noet: 254