1" Vim filetype plugin file 2" Language: man 3" Maintainer: SungHyun Nam <[email protected]> 4" Last Change: 2018 Jul 25 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 sect != "" && s:FindPage(sect, page) == 0 135 let sect = "" 136 endif 137 if s:FindPage(sect, page) == 0 138 echo "\nCannot find a '".page."'." 139 return 140 endif 141 exec "let s:man_tag_buf_".s:man_tag_depth." = ".bufnr("%") 142 exec "let s:man_tag_lin_".s:man_tag_depth." = ".line(".") 143 exec "let s:man_tag_col_".s:man_tag_depth." = ".col(".") 144 let s:man_tag_depth = s:man_tag_depth + 1 145 146 " Use an existing "man" window if it exists, otherwise open a new one. 147 if &filetype != "man" 148 let thiswin = winnr() 149 exe "norm! \<C-W>b" 150 if winnr() > 1 151 exe "norm! " . thiswin . "\<C-W>w" 152 while 1 153 if &filetype == "man" 154 break 155 endif 156 exe "norm! \<C-W>w" 157 if thiswin == winnr() 158 break 159 endif 160 endwhile 161 endif 162 if &filetype != "man" 163 if exists("g:ft_man_open_mode") 164 if g:ft_man_open_mode == "vert" 165 vnew 166 elseif g:ft_man_open_mode == "tab" 167 tabnew 168 else 169 new 170 endif 171 else 172 if a:cmdmods != '' 173 exe a:cmdmods . ' new' 174 else 175 new 176 endif 177 endif 178 setl nonu fdc=0 179 endif 180 endif 181 silent exec "edit $HOME/".page.".".sect."~" 182 " Avoid warning for editing the dummy file twice 183 setl buftype=nofile noswapfile 184 185 setl ma nonu nornu nofen 186 silent exec "norm! 1GdG" 187 let unsetwidth = 0 188 if empty($MANWIDTH) 189 let $MANWIDTH = winwidth(0) 190 let unsetwidth = 1 191 endif 192 193 " Ensure Vim is not recursively invoked (man-db does this) when doing ctrl-[ 194 " on a man page reference by unsetting MANPAGER. 195 " Some versions of env(1) do not support the '-u' option, and in such case 196 " we set MANPAGER=cat. 197 if !exists('s:env_has_u') 198 call system('env -u x true') 199 let s:env_has_u = (v:shell_error == 0) 200 endif 201 let env_cmd = s:env_has_u ? 'env -u MANPAGER' : 'env MANPAGER=cat' 202 let man_cmd = env_cmd . ' man ' . s:GetCmdArg(sect, page) . ' | col -b' 203 silent exec "r !" . man_cmd 204 205 if unsetwidth 206 let $MANWIDTH = '' 207 endif 208 " Remove blank lines from top and bottom. 209 while getline(1) =~ '^\s*$' 210 silent keepj norm! ggdd 211 endwhile 212 while getline('$') =~ '^\s*$' 213 silent keepj norm! Gdd 214 endwhile 215 1 216 setl ft=man nomod 217 setl bufhidden=hide 218 setl nobuflisted 219 setl noma 220endfunc 221 222func <SID>PopPage() 223 if s:man_tag_depth > 0 224 let s:man_tag_depth = s:man_tag_depth - 1 225 exec "let s:man_tag_buf=s:man_tag_buf_".s:man_tag_depth 226 exec "let s:man_tag_lin=s:man_tag_lin_".s:man_tag_depth 227 exec "let s:man_tag_col=s:man_tag_col_".s:man_tag_depth 228 exec s:man_tag_buf."b" 229 exec s:man_tag_lin 230 exec "norm! ".s:man_tag_col."|" 231 exec "unlet s:man_tag_buf_".s:man_tag_depth 232 exec "unlet s:man_tag_lin_".s:man_tag_depth 233 exec "unlet s:man_tag_col_".s:man_tag_depth 234 unlet s:man_tag_buf s:man_tag_lin s:man_tag_col 235 endif 236endfunc 237 238endif 239 240let &cpo = s:cpo_save 241unlet s:cpo_save 242 243" vim: set sw=2 ts=8 noet: 244