1" Vim filetype plugin file 2" Language: man 3" Maintainer: SungHyun Nam <[email protected]> 4" Last Change: 2020 Apr 13 5 6" To make the ":Man" command available before editing a manual page, source 7" this script from your startup vimrc file. 8 9" If 'filetype' isn't "man", we must have been called to only define ":Man". 10if &filetype == "man" 11 12 " Only do this when not done yet for this buffer 13 if exists("b:did_ftplugin") 14 finish 15 endif 16 let b:did_ftplugin = 1 17endif 18 19let s:cpo_save = &cpo 20set cpo-=C 21 22if &filetype == "man" 23 " allow dot and dash in manual page name. 24 setlocal iskeyword+=\.,- 25 let b:undo_ftplugin = "setlocal iskeyword<" 26 27 " Add mappings, unless the user didn't want this. 28 if !exists("no_plugin_maps") && !exists("no_man_maps") 29 if !hasmapto('<Plug>ManBS') 30 nmap <buffer> <LocalLeader>h <Plug>ManBS 31 let b:undo_ftplugin = b:undo_ftplugin 32 \ . '|silent! nunmap <buffer> <LocalLeader>h' 33 endif 34 nnoremap <buffer> <Plug>ManBS :%s/.\b//g<CR>:setl nomod<CR>'' 35 36 nnoremap <buffer> <c-]> :call <SID>PreGetPage(v:count)<CR> 37 nnoremap <buffer> <c-t> :call <SID>PopPage()<CR> 38 nnoremap <buffer> <silent> q :q<CR> 39 40 " Add undo commands for the maps 41 let b:undo_ftplugin = b:undo_ftplugin 42 \ . '|silent! nunmap <buffer> <Plug>ManBS' 43 \ . '|silent! nunmap <buffer> <c-]>' 44 \ . '|silent! nunmap <buffer> <c-t>' 45 \ . '|silent! nunmap <buffer> q' 46 endif 47 48 if exists('g:ft_man_folding_enable') && (g:ft_man_folding_enable == 1) 49 setlocal foldmethod=indent foldnestmax=1 foldenable 50 let b:undo_ftplugin = b:undo_ftplugin 51 \ . '|silent! setl fdm< fdn< fen<' 52 endif 53 54endif 55 56if exists(":Man") != 2 57 com -nargs=+ -complete=shellcmd Man call s:GetPage(<q-mods>, <f-args>) 58 nmap <Leader>K :call <SID>PreGetPage(0)<CR> 59 nmap <Plug>ManPreGetPage :call <SID>PreGetPage(0)<CR> 60endif 61 62" Define functions only once. 63if !exists("s:man_tag_depth") 64 65let s:man_tag_depth = 0 66 67let s:man_sect_arg = "" 68let s:man_find_arg = "-w" 69try 70 if !has("win32") && $OSTYPE !~ 'cygwin\|linux' && system('uname -s') =~ "SunOS" && system('uname -r') =~ "^5" 71 let s:man_sect_arg = "-s" 72 let s:man_find_arg = "-l" 73 endif 74catch /E145:/ 75 " Ignore the error in restricted mode 76endtry 77 78func <SID>PreGetPage(cnt) 79 if a:cnt == 0 80 let old_isk = &iskeyword 81 if &ft == 'man' 82 setl iskeyword+=(,) 83 endif 84 let str = expand("<cword>") 85 let &l:iskeyword = old_isk 86 let page = substitute(str, '(*\(\k\+\).*', '\1', '') 87 let sect = substitute(str, '\(\k\+\)(\([^()]*\)).*', '\2', '') 88 if match(sect, '^[0-9 ]\+$') == -1 89 let sect = "" 90 endif 91 if sect == page 92 let sect = "" 93 endif 94 else 95 let sect = a:cnt 96 let page = expand("<cword>") 97 endif 98 call s:GetPage('', sect, page) 99endfunc 100 101func <SID>GetCmdArg(sect, page) 102 if a:sect == '' 103 return a:page 104 endif 105 return s:man_sect_arg.' '.a:sect.' '.a:page 106endfunc 107 108func <SID>FindPage(sect, page) 109 let where = system("man ".s:man_find_arg.' '.s:GetCmdArg(a:sect, a:page)) 110 if where !~ "^/" 111 if matchstr(where, " [^ ]*$") !~ "^ /" 112 return 0 113 endif 114 endif 115 return 1 116endfunc 117 118func <SID>GetPage(cmdmods, ...) 119 if a:0 >= 2 120 let sect = a:1 121 let page = a:2 122 elseif a:0 >= 1 123 let sect = "" 124 let page = a:1 125 else 126 return 127 endif 128 129 " To support: nmap K :Man <cword> 130 if page == '<cword>' 131 let page = expand('<cword>') 132 endif 133 134 if !exists('g:ft_man_no_sect_fallback') || (g:ft_man_no_sect_fallback == 0) 135 if sect != "" && s:FindPage(sect, page) == 0 136 let sect = "" 137 endif 138 endif 139 if s:FindPage(sect, page) == 0 140 let msg = "\nNo manual entry for ".page 141 if sect != "" 142 let msg .= " in section ".sect 143 endif 144 echo msg 145 return 146 endif 147 exec "let s:man_tag_buf_".s:man_tag_depth." = ".bufnr("%") 148 exec "let s:man_tag_lin_".s:man_tag_depth." = ".line(".") 149 exec "let s:man_tag_col_".s:man_tag_depth." = ".col(".") 150 let s:man_tag_depth = s:man_tag_depth + 1 151 152 let open_cmd = 'edit' 153 154 " Use an existing "man" window if it exists, otherwise open a new one. 155 if &filetype != "man" 156 let thiswin = winnr() 157 exe "norm! \<C-W>b" 158 if winnr() > 1 159 exe "norm! " . thiswin . "\<C-W>w" 160 while 1 161 if &filetype == "man" 162 break 163 endif 164 exe "norm! \<C-W>w" 165 if thiswin == winnr() 166 break 167 endif 168 endwhile 169 endif 170 if &filetype != "man" 171 if exists("g:ft_man_open_mode") 172 if g:ft_man_open_mode == 'vert' 173 let open_cmd = 'vsplit' 174 elseif g:ft_man_open_mode == 'tab' 175 let open_cmd = 'tabedit' 176 else 177 let open_cmd = 'split' 178 endif 179 else 180 let open_cmd = a:cmdmods . ' split' 181 endif 182 endif 183 endif 184 185 silent execute open_cmd . " $HOME/" . page . '.' . sect . '~' 186 187 " Avoid warning for editing the dummy file twice 188 setl buftype=nofile noswapfile 189 190 setl fdc=0 ma nofen nonu nornu 191 %delete _ 192 let unsetwidth = 0 193 if empty($MANWIDTH) 194 let $MANWIDTH = winwidth(0) 195 let unsetwidth = 1 196 endif 197 198 " Ensure Vim is not recursively invoked (man-db does this) when doing ctrl-[ 199 " on a man page reference by unsetting MANPAGER. 200 " Some versions of env(1) do not support the '-u' option, and in such case 201 " we set MANPAGER=cat. 202 if !exists('s:env_has_u') 203 call system('env -u x true') 204 let s:env_has_u = (v:shell_error == 0) 205 endif 206 let env_cmd = s:env_has_u ? 'env -u MANPAGER' : 'env MANPAGER=cat' 207 let env_cmd .= ' GROFF_NO_SGR=1' 208 let man_cmd = env_cmd . ' man ' . s:GetCmdArg(sect, page) . ' | col -b' 209 silent exec "r !" . man_cmd 210 211 if unsetwidth 212 let $MANWIDTH = '' 213 endif 214 " Remove blank lines from top and bottom. 215 while line('$') > 1 && getline(1) =~ '^\s*$' 216 1delete _ 217 endwhile 218 while line('$') > 1 && getline('$') =~ '^\s*$' 219 $delete _ 220 endwhile 221 1 222 setl ft=man nomod 223 setl bufhidden=hide 224 setl nobuflisted 225 setl noma 226endfunc 227 228func <SID>PopPage() 229 if s:man_tag_depth > 0 230 let s:man_tag_depth = s:man_tag_depth - 1 231 exec "let s:man_tag_buf=s:man_tag_buf_".s:man_tag_depth 232 exec "let s:man_tag_lin=s:man_tag_lin_".s:man_tag_depth 233 exec "let s:man_tag_col=s:man_tag_col_".s:man_tag_depth 234 exec s:man_tag_buf."b" 235 exec s:man_tag_lin 236 exec "norm! ".s:man_tag_col."|" 237 exec "unlet s:man_tag_buf_".s:man_tag_depth 238 exec "unlet s:man_tag_lin_".s:man_tag_depth 239 exec "unlet s:man_tag_col_".s:man_tag_depth 240 unlet s:man_tag_buf s:man_tag_lin s:man_tag_col 241 endif 242endfunc 243 244endif 245 246let &cpo = s:cpo_save 247unlet s:cpo_save 248 249" vim: set sw=2 ts=8 noet: 250