mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #1878 from justinmk/man.vim
use :Man instead of `man` for K
This commit is contained in:
commit
ba6c7a6f5b
@ -53,7 +53,6 @@
|
|||||||
#cmakedefine HAVE_WORKING_LIBINTL
|
#cmakedefine HAVE_WORKING_LIBINTL
|
||||||
#cmakedefine UNIX
|
#cmakedefine UNIX
|
||||||
#cmakedefine USE_FNAME_CASE
|
#cmakedefine USE_FNAME_CASE
|
||||||
#define USEMAN_S 1
|
|
||||||
|
|
||||||
#define FEAT_BROWSE
|
#define FEAT_BROWSE
|
||||||
#define FEAT_CSCOPE
|
#define FEAT_CSCOPE
|
||||||
|
148
runtime/autoload/man.vim
Normal file
148
runtime/autoload/man.vim
Normal file
@ -0,0 +1,148 @@
|
|||||||
|
let s:man_tag_depth = 0
|
||||||
|
let s:man_sect_arg = ''
|
||||||
|
let s:man_find_arg = '-w'
|
||||||
|
|
||||||
|
try
|
||||||
|
if !has('win32') && $OSTYPE !~? 'cygwin\|linux' && system('uname -s') =~? 'SunOS' && system('uname -r') =~? '^5'
|
||||||
|
let s:man_sect_arg = '-s'
|
||||||
|
let s:man_find_arg = '-l'
|
||||||
|
endif
|
||||||
|
catch /E145:/
|
||||||
|
" Ignore the error in restricted mode
|
||||||
|
endtry
|
||||||
|
|
||||||
|
function man#get_page(...) abort
|
||||||
|
let invoked_from_man = (&filetype ==# 'man')
|
||||||
|
|
||||||
|
if a:0 == 0
|
||||||
|
echoerr 'argument required'
|
||||||
|
return
|
||||||
|
elseif a:0 > 2
|
||||||
|
echoerr 'too many arguments'
|
||||||
|
return
|
||||||
|
elseif a:0 == 2
|
||||||
|
let [page, sect] = [a:2, 0 + a:1]
|
||||||
|
elseif type(1) == type(a:1)
|
||||||
|
let [page, sect] = ['<cword>', a:1]
|
||||||
|
else
|
||||||
|
let [page, sect] = [a:1, '']
|
||||||
|
endif
|
||||||
|
|
||||||
|
if page == '<cword>'
|
||||||
|
let page = expand('<cword>')
|
||||||
|
endif
|
||||||
|
|
||||||
|
let [page, sect] = s:parse_page_and_section(sect, page)
|
||||||
|
|
||||||
|
if 0 + sect > 0 && s:find_page(sect, page) == 0
|
||||||
|
let sect = ''
|
||||||
|
endif
|
||||||
|
|
||||||
|
if s:find_page(sect, page) == 0
|
||||||
|
echo 'No manual entry for '.page
|
||||||
|
return
|
||||||
|
endif
|
||||||
|
|
||||||
|
exec 'let s:man_tag_buf_'.s:man_tag_depth.' = '.bufnr('%')
|
||||||
|
exec 'let s:man_tag_lin_'.s:man_tag_depth.' = '.line('.')
|
||||||
|
exec 'let s:man_tag_col_'.s:man_tag_depth.' = '.col('.')
|
||||||
|
let s:man_tag_depth = s:man_tag_depth + 1
|
||||||
|
|
||||||
|
" Use an existing "man" window if it exists, otherwise open a new one.
|
||||||
|
if !invoked_from_man
|
||||||
|
let thiswin = winnr()
|
||||||
|
wincmd b
|
||||||
|
if winnr() > 1
|
||||||
|
exe "norm! " . thiswin . "\<C-W>w"
|
||||||
|
while 1
|
||||||
|
if &filetype == 'man'
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
wincmd w
|
||||||
|
if thiswin == winnr()
|
||||||
|
break
|
||||||
|
endif
|
||||||
|
endwhile
|
||||||
|
endif
|
||||||
|
if !invoked_from_man
|
||||||
|
tabnew
|
||||||
|
let invoked_from_man = 1
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
|
||||||
|
silent exec 'edit man://'.page.(empty(sect)?'':'('.sect.')')
|
||||||
|
|
||||||
|
setlocal modifiable
|
||||||
|
silent keepjumps norm! 1G"_dG
|
||||||
|
let $MANWIDTH = winwidth(0)
|
||||||
|
silent exec 'r!/usr/bin/man '.s:cmd(sect, page).' | col -b'
|
||||||
|
" Remove blank lines from top and bottom.
|
||||||
|
while getline(1) =~ '^\s*$'
|
||||||
|
silent keepjumps norm! gg"_dd
|
||||||
|
endwhile
|
||||||
|
while getline('$') =~ '^\s*$'
|
||||||
|
silent keepjumps norm! G"_dd
|
||||||
|
endwhile
|
||||||
|
setlocal nomodified
|
||||||
|
setlocal filetype=man
|
||||||
|
|
||||||
|
if invoked_from_man
|
||||||
|
call s:set_window_local_options()
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function s:set_window_local_options() abort
|
||||||
|
setlocal colorcolumn=0 foldcolumn=0 nonumber
|
||||||
|
setlocal nolist norelativenumber nofoldenable
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function man#pop_page() abort
|
||||||
|
if s:man_tag_depth > 0
|
||||||
|
let s:man_tag_depth = s:man_tag_depth - 1
|
||||||
|
exec "let s:man_tag_buf=s:man_tag_buf_".s:man_tag_depth
|
||||||
|
exec "let s:man_tag_lin=s:man_tag_lin_".s:man_tag_depth
|
||||||
|
exec "let s:man_tag_col=s:man_tag_col_".s:man_tag_depth
|
||||||
|
exec s:man_tag_buf."b"
|
||||||
|
exec s:man_tag_lin
|
||||||
|
exec "norm! ".s:man_tag_col."|"
|
||||||
|
exec "unlet s:man_tag_buf_".s:man_tag_depth
|
||||||
|
exec "unlet s:man_tag_lin_".s:man_tag_depth
|
||||||
|
exec "unlet s:man_tag_col_".s:man_tag_depth
|
||||||
|
unlet s:man_tag_buf s:man_tag_lin s:man_tag_col
|
||||||
|
endif
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
" Expects a string like 'access' or 'access(2)'.
|
||||||
|
function s:parse_page_and_section(sect, str) abort
|
||||||
|
try
|
||||||
|
let save_isk = &iskeyword
|
||||||
|
setlocal iskeyword-=(,)
|
||||||
|
let page = substitute(a:str, '(*\(\k\+\).*', '\1', '')
|
||||||
|
let sect = substitute(a:str, '\(\k\+\)(\([^()]*\)).*', '\2', '')
|
||||||
|
if sect == page || -1 == match(sect, '^[0-9 ]\+$')
|
||||||
|
let sect = a:sect
|
||||||
|
endif
|
||||||
|
catch
|
||||||
|
let &l:iskeyword = save_isk
|
||||||
|
echoerr 'man.vim: failed to parse: "'.a:str.'"'
|
||||||
|
endtry
|
||||||
|
|
||||||
|
return [page, sect]
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function s:cmd(sect, page) abort
|
||||||
|
if 0 + a:sect > 0
|
||||||
|
return s:man_sect_arg.' '.a:sect.' '.a:page
|
||||||
|
endif
|
||||||
|
return a:page
|
||||||
|
endfunction
|
||||||
|
|
||||||
|
function s:find_page(sect, page) abort
|
||||||
|
let where = system('/usr/bin/man '.s:man_find_arg.' '.s:cmd(a:sect, a:page))
|
||||||
|
if where !~ "^/"
|
||||||
|
if matchstr(where, " [^ ]*$") !~ "^ /"
|
||||||
|
return 0
|
||||||
|
endif
|
||||||
|
endif
|
||||||
|
return 1
|
||||||
|
endfunction
|
@ -3877,18 +3877,20 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
The 'keymodel' option is set by the |:behave| command.
|
The 'keymodel' option is set by the |:behave| command.
|
||||||
|
|
||||||
*'keywordprg'* *'kp'*
|
*'keywordprg'* *'kp'*
|
||||||
'keywordprg' 'kp' string (default "man" or "man -s", DOS: ":help")
|
'keywordprg' 'kp' string (default ":Man", Windows: ":help")
|
||||||
global or local to buffer |global-local|
|
global or local to buffer |global-local|
|
||||||
Program to use for the |K| command. Environment variables are
|
Program to use for the |K| command. Environment variables are
|
||||||
expanded |:set_env|. ":help" may be used to access the Vim internal
|
expanded |:set_env|. ":help" may be used to access the Vim internal
|
||||||
help. (Note that previously setting the global option to the empty
|
help. (Note that previously setting the global option to the empty
|
||||||
value did this, which is now deprecated.)
|
value did this, which is now deprecated.)
|
||||||
When "man" is used, Vim will automatically translate a count for the
|
When the first character is ":", the command is invoked as a Vim
|
||||||
"K" command to a section number. Also for "man -s", in which case the
|
command prefixed with [count]. {Nvim}
|
||||||
"-s" is removed when there is no count.
|
When "man" or "man -s" is used, Vim will automatically translate
|
||||||
|
a [count] for the "K" command to a section number.
|
||||||
See |option-backslash| about including spaces and backslashes.
|
See |option-backslash| about including spaces and backslashes.
|
||||||
Example: >
|
Example: >
|
||||||
:set keywordprg=man\ -s
|
:set keywordprg=man\ -s
|
||||||
|
:set keywordprg=:Man
|
||||||
< This option cannot be set from a |modeline| or in the |sandbox|, for
|
< This option cannot be set from a |modeline| or in the |sandbox|, for
|
||||||
security reasons.
|
security reasons.
|
||||||
|
|
||||||
|
@ -542,7 +542,7 @@ which it was defined is reported.
|
|||||||
{not available when compiled without the |+eval| feature}
|
{not available when compiled without the |+eval| feature}
|
||||||
|
|
||||||
*K*
|
*K*
|
||||||
K Run a program to lookup the keyword under the
|
[count]K Run a program to lookup the keyword under the
|
||||||
cursor. The name of the program is given with the
|
cursor. The name of the program is given with the
|
||||||
'keywordprg' (kp) option (default is "man"). The
|
'keywordprg' (kp) option (default is "man"). The
|
||||||
keyword is formed of letters, numbers and the
|
keyword is formed of letters, numbers and the
|
||||||
@ -550,19 +550,18 @@ K Run a program to lookup the keyword under the
|
|||||||
right of the cursor is used. The same can be done
|
right of the cursor is used. The same can be done
|
||||||
with the command >
|
with the command >
|
||||||
:!{program} {keyword}
|
:!{program} {keyword}
|
||||||
< There is an example of a program to use in the tools
|
< Special cases:
|
||||||
directory of Vim. It is called 'ref' and does a
|
- If 'keywordprg' begins with ":" it is invoked as
|
||||||
simple spelling check.
|
a Vim command with [count].
|
||||||
Special cases:
|
|
||||||
- If 'keywordprg' is empty, the ":help" command is
|
- If 'keywordprg' is empty, the ":help" command is
|
||||||
used. It's a good idea to include more characters
|
used. It's a good idea to include more characters
|
||||||
in 'iskeyword' then, to be able to find more help.
|
in 'iskeyword' then, to be able to find more help.
|
||||||
- When 'keywordprg' is equal to "man", a count before
|
- When 'keywordprg' is equal to "man", a [count]
|
||||||
"K" is inserted after the "man" command and before
|
before "K" is inserted after the "man" command and
|
||||||
the keyword. For example, using "2K" while the
|
before the keyword. For example, using "2K" while
|
||||||
cursor is on "mkdir", results in: >
|
the cursor is on "mkdir", results in: >
|
||||||
!man 2 mkdir
|
!man 2 mkdir
|
||||||
< - When 'keywordprg' is equal to "man -s", a count
|
< - When 'keywordprg' is equal to "man -s", a [count]
|
||||||
before "K" is inserted after the "-s". If there is
|
before "K" is inserted after the "-s". If there is
|
||||||
no count, the "-s" is removed.
|
no count, the "-s" is removed.
|
||||||
|
|
||||||
|
@ -1,191 +1,33 @@
|
|||||||
" Vim filetype plugin file
|
" Vim filetype plugin file
|
||||||
" Language: man
|
" Language: man
|
||||||
" Maintainer: SungHyun Nam <goweol@gmail.com>
|
" Maintainer: SungHyun Nam <goweol@gmail.com>
|
||||||
" Last Change: 2014 Nov 12
|
|
||||||
|
|
||||||
" To make the ":Man" command available before editing a manual page, source
|
" Only do this when not done yet for this buffer
|
||||||
" this script from your startup vimrc file.
|
if exists('b:did_ftplugin')
|
||||||
|
finish
|
||||||
" If 'filetype' isn't "man", we must have been called to only define ":Man".
|
endif
|
||||||
if &filetype == "man"
|
let b:did_ftplugin = 1
|
||||||
|
|
||||||
" Only do this when not done yet for this buffer
|
|
||||||
if exists("b:did_ftplugin")
|
|
||||||
finish
|
|
||||||
endif
|
|
||||||
let b:did_ftplugin = 1
|
|
||||||
|
|
||||||
" Ensure Vim is not recursively invoked (man-db does this)
|
|
||||||
" when doing ctrl-[ on a man page reference.
|
|
||||||
if exists("$MANPAGER")
|
|
||||||
let $MANPAGER = ""
|
|
||||||
endif
|
|
||||||
|
|
||||||
" allow dot and dash in manual page name.
|
|
||||||
setlocal iskeyword+=\.,-
|
|
||||||
|
|
||||||
" Add mappings, unless the user didn't want this.
|
|
||||||
if !exists("no_plugin_maps") && !exists("no_man_maps")
|
|
||||||
if !hasmapto('<Plug>ManBS')
|
|
||||||
nmap <buffer> <LocalLeader>h <Plug>ManBS
|
|
||||||
endif
|
|
||||||
nnoremap <buffer> <Plug>ManBS :%s/.\b//g<CR>:setl nomod<CR>''
|
|
||||||
|
|
||||||
nnoremap <buffer> <c-]> :call <SID>PreGetPage(v:count)<CR>
|
|
||||||
nnoremap <buffer> <c-t> :call <SID>PopPage()<CR>
|
|
||||||
endif
|
|
||||||
|
|
||||||
let b:undo_ftplugin = "setlocal iskeyword<"
|
|
||||||
|
|
||||||
|
" Ensure Vim is not recursively invoked (man-db does this)
|
||||||
|
" when doing ctrl-[ on a man page reference.
|
||||||
|
if exists('$MANPAGER')
|
||||||
|
let $MANPAGER = ''
|
||||||
endif
|
endif
|
||||||
|
|
||||||
if exists(":Man") != 2
|
setlocal iskeyword+=\.,-,(,)
|
||||||
com -nargs=+ Man call s:GetPage(<f-args>)
|
|
||||||
nmap <Leader>K :call <SID>PreGetPage(0)<CR>
|
setlocal buftype=nofile noswapfile
|
||||||
|
setlocal nomodifiable readonly bufhidden=hide nobuflisted tabstop=8
|
||||||
|
|
||||||
|
if !exists("g:no_plugin_maps") && !exists("g:no_man_maps")
|
||||||
|
nnoremap <silent> <buffer> <C-]> :call man#get_page(v:count)<CR>
|
||||||
|
nnoremap <silent> <buffer> <C-T> :call man#pop_page()<CR>
|
||||||
|
nnoremap <silent> <nowait><buffer> q <C-W>c
|
||||||
|
if &keywordprg !=# ':Man'
|
||||||
|
nnoremap <silent> <buffer> K :call man#get_page(v:count)<CR>
|
||||||
|
endif
|
||||||
endif
|
endif
|
||||||
|
|
||||||
" Define functions only once.
|
let b:undo_ftplugin = 'setlocal iskeyword<'
|
||||||
if !exists("s:man_tag_depth")
|
|
||||||
|
|
||||||
let s:man_tag_depth = 0
|
|
||||||
|
|
||||||
let s:man_sect_arg = ""
|
|
||||||
let s:man_find_arg = "-w"
|
|
||||||
try
|
|
||||||
if !has("win32") && $OSTYPE !~ 'cygwin\|linux' && system('uname -s') =~ "SunOS" && system('uname -r') =~ "^5"
|
|
||||||
let s:man_sect_arg = "-s"
|
|
||||||
let s:man_find_arg = "-l"
|
|
||||||
endif
|
|
||||||
catch /E145:/
|
|
||||||
" Ignore the error in restricted mode
|
|
||||||
endtry
|
|
||||||
|
|
||||||
func <SID>PreGetPage(cnt)
|
|
||||||
if a:cnt == 0
|
|
||||||
let old_isk = &iskeyword
|
|
||||||
if &ft == 'man'
|
|
||||||
setl iskeyword+=(,)
|
|
||||||
endif
|
|
||||||
let str = expand("<cword>")
|
|
||||||
let &l:iskeyword = old_isk
|
|
||||||
let page = substitute(str, '(*\(\k\+\).*', '\1', '')
|
|
||||||
let sect = substitute(str, '\(\k\+\)(\([^()]*\)).*', '\2', '')
|
|
||||||
if match(sect, '^[0-9 ]\+$') == -1
|
|
||||||
let sect = ""
|
|
||||||
endif
|
|
||||||
if sect == page
|
|
||||||
let sect = ""
|
|
||||||
endif
|
|
||||||
else
|
|
||||||
let sect = a:cnt
|
|
||||||
let page = expand("<cword>")
|
|
||||||
endif
|
|
||||||
call s:GetPage(sect, page)
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
func <SID>GetCmdArg(sect, page)
|
|
||||||
if a:sect == ''
|
|
||||||
return a:page
|
|
||||||
endif
|
|
||||||
return s:man_sect_arg.' '.a:sect.' '.a:page
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
func <SID>FindPage(sect, page)
|
|
||||||
let where = system("/usr/bin/man ".s:man_find_arg.' '.s:GetCmdArg(a:sect, a:page))
|
|
||||||
if where !~ "^/"
|
|
||||||
if matchstr(where, " [^ ]*$") !~ "^ /"
|
|
||||||
return 0
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
return 1
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
func <SID>GetPage(...)
|
|
||||||
if a:0 >= 2
|
|
||||||
let sect = a:1
|
|
||||||
let page = a:2
|
|
||||||
elseif a:0 >= 1
|
|
||||||
let sect = ""
|
|
||||||
let page = a:1
|
|
||||||
else
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
|
|
||||||
" To support: nmap K :Man <cword>
|
|
||||||
if page == '<cword>'
|
|
||||||
let page = expand('<cword>')
|
|
||||||
endif
|
|
||||||
|
|
||||||
if sect != "" && s:FindPage(sect, page) == 0
|
|
||||||
let sect = ""
|
|
||||||
endif
|
|
||||||
if s:FindPage(sect, page) == 0
|
|
||||||
echo "\nCannot find a '".page."'."
|
|
||||||
return
|
|
||||||
endif
|
|
||||||
exec "let s:man_tag_buf_".s:man_tag_depth." = ".bufnr("%")
|
|
||||||
exec "let s:man_tag_lin_".s:man_tag_depth." = ".line(".")
|
|
||||||
exec "let s:man_tag_col_".s:man_tag_depth." = ".col(".")
|
|
||||||
let s:man_tag_depth = s:man_tag_depth + 1
|
|
||||||
|
|
||||||
" Use an existing "man" window if it exists, otherwise open a new one.
|
|
||||||
if &filetype != "man"
|
|
||||||
let thiswin = winnr()
|
|
||||||
exe "norm! \<C-W>b"
|
|
||||||
if winnr() > 1
|
|
||||||
exe "norm! " . thiswin . "\<C-W>w"
|
|
||||||
while 1
|
|
||||||
if &filetype == "man"
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
exe "norm! \<C-W>w"
|
|
||||||
if thiswin == winnr()
|
|
||||||
break
|
|
||||||
endif
|
|
||||||
endwhile
|
|
||||||
endif
|
|
||||||
if &filetype != "man"
|
|
||||||
new
|
|
||||||
setl nonu fdc=0
|
|
||||||
endif
|
|
||||||
endif
|
|
||||||
silent exec "edit $HOME/".page.".".sect."~"
|
|
||||||
" Avoid warning for editing the dummy file twice
|
|
||||||
setl buftype=nofile noswapfile
|
|
||||||
|
|
||||||
setl ma nonu nornu nofen
|
|
||||||
silent exec "norm 1GdG"
|
|
||||||
let $MANWIDTH = winwidth(0)
|
|
||||||
silent exec "r!/usr/bin/man ".s:GetCmdArg(sect, page)." | col -b"
|
|
||||||
" Remove blank lines from top and bottom.
|
|
||||||
while getline(1) =~ '^\s*$'
|
|
||||||
silent norm ggdd
|
|
||||||
endwhile
|
|
||||||
while getline('$') =~ '^\s*$'
|
|
||||||
silent norm Gdd
|
|
||||||
endwhile
|
|
||||||
1
|
|
||||||
setl ft=man nomod
|
|
||||||
setl bufhidden=hide
|
|
||||||
setl nobuflisted
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
func <SID>PopPage()
|
|
||||||
if s:man_tag_depth > 0
|
|
||||||
let s:man_tag_depth = s:man_tag_depth - 1
|
|
||||||
exec "let s:man_tag_buf=s:man_tag_buf_".s:man_tag_depth
|
|
||||||
exec "let s:man_tag_lin=s:man_tag_lin_".s:man_tag_depth
|
|
||||||
exec "let s:man_tag_col=s:man_tag_col_".s:man_tag_depth
|
|
||||||
exec s:man_tag_buf."b"
|
|
||||||
exec s:man_tag_lin
|
|
||||||
exec "norm ".s:man_tag_col."|"
|
|
||||||
exec "unlet s:man_tag_buf_".s:man_tag_depth
|
|
||||||
exec "unlet s:man_tag_lin_".s:man_tag_depth
|
|
||||||
exec "unlet s:man_tag_col_".s:man_tag_depth
|
|
||||||
unlet s:man_tag_buf s:man_tag_lin s:man_tag_col
|
|
||||||
endif
|
|
||||||
endfunc
|
|
||||||
|
|
||||||
endif
|
|
||||||
|
|
||||||
" vim: set sw=2:
|
" vim: set sw=2:
|
||||||
|
6
runtime/plugin/man.vim
Normal file
6
runtime/plugin/man.vim
Normal file
@ -0,0 +1,6 @@
|
|||||||
|
if get(g:, 'loaded_man', 0)
|
||||||
|
finish
|
||||||
|
endif
|
||||||
|
let g:loaded_man = 1
|
||||||
|
|
||||||
|
command! -count=0 -nargs=+ Man call man#get_page(<count>, <f-args>)
|
@ -4213,18 +4213,12 @@ void do_nv_ident(int c1, int c2)
|
|||||||
static void nv_ident(cmdarg_T *cap)
|
static void nv_ident(cmdarg_T *cap)
|
||||||
{
|
{
|
||||||
char_u *ptr = NULL;
|
char_u *ptr = NULL;
|
||||||
char_u *buf;
|
|
||||||
char_u *newbuf;
|
|
||||||
char_u *p;
|
char_u *p;
|
||||||
char_u *kp; /* value of 'keywordprg' */
|
|
||||||
bool kp_help; /* 'keywordprg' is ":help" */
|
|
||||||
size_t n = 0; /* init for GCC */
|
size_t n = 0; /* init for GCC */
|
||||||
int cmdchar;
|
int cmdchar;
|
||||||
bool g_cmd; /* "g" command */
|
bool g_cmd; /* "g" command */
|
||||||
bool tag_cmd = false;
|
bool tag_cmd = false;
|
||||||
char_u *aux_ptr;
|
char_u *aux_ptr;
|
||||||
bool isman;
|
|
||||||
bool isman_s;
|
|
||||||
|
|
||||||
if (cap->cmdchar == 'g') { /* "g*", "g#", "g]" and "gCTRL-]" */
|
if (cap->cmdchar == 'g') { /* "g*", "g#", "g]" and "gCTRL-]" */
|
||||||
cmdchar = cap->nchar;
|
cmdchar = cap->nchar;
|
||||||
@ -4259,10 +4253,11 @@ static void nv_ident(cmdarg_T *cap)
|
|||||||
/* Allocate buffer to put the command in. Inserting backslashes can
|
/* Allocate buffer to put the command in. Inserting backslashes can
|
||||||
* double the length of the word. p_kp / curbuf->b_p_kp could be added
|
* double the length of the word. p_kp / curbuf->b_p_kp could be added
|
||||||
* and some numbers. */
|
* and some numbers. */
|
||||||
kp = (*curbuf->b_p_kp == NUL ? p_kp : curbuf->b_p_kp);
|
char_u *kp = *curbuf->b_p_kp == NUL ? p_kp : curbuf->b_p_kp; // 'keywordprg'
|
||||||
kp_help = (*kp == NUL || STRCMP(kp, ":he") == 0
|
assert(*kp != NUL); // option.c:do_set() should default to ":help" if empty.
|
||||||
|| STRCMP(kp, ":help") == 0);
|
bool kp_ex = (*kp == ':'); // 'keywordprg' is an ex command
|
||||||
buf = xmalloc(n * 2 + 30 + STRLEN(kp));
|
size_t buf_size = n * 2 + 30 + STRLEN(kp);
|
||||||
|
char *buf = xmalloc(buf_size);
|
||||||
buf[0] = NUL;
|
buf[0] = NUL;
|
||||||
|
|
||||||
switch (cmdchar) {
|
switch (cmdchar) {
|
||||||
@ -4283,9 +4278,13 @@ static void nv_ident(cmdarg_T *cap)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case 'K':
|
case 'K':
|
||||||
if (kp_help)
|
if (kp_ex) {
|
||||||
STRCPY(buf, "he! ");
|
if (cap->count0 != 0) { // Send the count to the ex command.
|
||||||
else {
|
snprintf(buf, buf_size, "%" PRId64, (int64_t)(cap->count0));
|
||||||
|
}
|
||||||
|
STRCAT(buf, kp);
|
||||||
|
STRCAT(buf, " ");
|
||||||
|
} else {
|
||||||
/* An external command will probably use an argument starting
|
/* An external command will probably use an argument starting
|
||||||
* with "-" as an option. To avoid trouble we skip the "-". */
|
* with "-" as an option. To avoid trouble we skip the "-". */
|
||||||
while (*ptr == '-' && n > 0) {
|
while (*ptr == '-' && n > 0) {
|
||||||
@ -4300,19 +4299,22 @@ static void nv_ident(cmdarg_T *cap)
|
|||||||
|
|
||||||
/* When a count is given, turn it into a range. Is this
|
/* When a count is given, turn it into a range. Is this
|
||||||
* really what we want? */
|
* really what we want? */
|
||||||
isman = (STRCMP(kp, "man") == 0);
|
bool isman = (STRCMP(kp, "man") == 0);
|
||||||
isman_s = (STRCMP(kp, "man -s") == 0);
|
bool isman_s = (STRCMP(kp, "man -s") == 0);
|
||||||
if (cap->count0 != 0 && !(isman || isman_s))
|
if (cap->count0 != 0 && !(isman || isman_s)) {
|
||||||
sprintf((char *)buf, ".,.+%" PRId64, (int64_t)(cap->count0 - 1));
|
snprintf(buf, buf_size, ".,.+%" PRId64, (int64_t)(cap->count0 - 1));
|
||||||
|
}
|
||||||
|
|
||||||
STRCAT(buf, "! ");
|
STRCAT(buf, "! ");
|
||||||
if (cap->count0 == 0 && isman_s)
|
if (cap->count0 == 0 && isman_s) {
|
||||||
STRCAT(buf, "man");
|
STRCAT(buf, "man");
|
||||||
else
|
} else {
|
||||||
STRCAT(buf, kp);
|
STRCAT(buf, kp);
|
||||||
|
}
|
||||||
STRCAT(buf, " ");
|
STRCAT(buf, " ");
|
||||||
if (cap->count0 != 0 && (isman || isman_s)) {
|
if (cap->count0 != 0 && (isman || isman_s)) {
|
||||||
sprintf((char *)buf + STRLEN(buf), "%" PRId64, (int64_t)cap->count0);
|
snprintf(buf + STRLEN(buf), buf_size - STRLEN(buf), "%" PRId64,
|
||||||
|
(int64_t)cap->count0);
|
||||||
STRCAT(buf, " ");
|
STRCAT(buf, " ");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -4334,19 +4336,19 @@ static void nv_ident(cmdarg_T *cap)
|
|||||||
if (g_cmd)
|
if (g_cmd)
|
||||||
STRCPY(buf, "tj ");
|
STRCPY(buf, "tj ");
|
||||||
else
|
else
|
||||||
sprintf((char *)buf, "%" PRId64 "ta ", (int64_t)cap->count0);
|
snprintf(buf, buf_size, "%" PRId64 "ta ", (int64_t)cap->count0);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Now grab the chars in the identifier
|
* Now grab the chars in the identifier
|
||||||
*/
|
*/
|
||||||
if (cmdchar == 'K' && !kp_help) {
|
if (cmdchar == 'K' && !kp_ex) {
|
||||||
/* Escape the argument properly for a shell command */
|
/* Escape the argument properly for a shell command */
|
||||||
ptr = vim_strnsave(ptr, n);
|
ptr = vim_strnsave(ptr, n);
|
||||||
p = vim_strsave_shellescape(ptr, true, true);
|
p = vim_strsave_shellescape(ptr, true, true);
|
||||||
xfree(ptr);
|
xfree(ptr);
|
||||||
newbuf = (char_u *)xrealloc(buf, STRLEN(buf) + STRLEN(p) + 1);
|
char *newbuf = xrealloc(buf, STRLEN(buf) + STRLEN(p) + 1);
|
||||||
buf = newbuf;
|
buf = newbuf;
|
||||||
STRCAT(buf, p);
|
STRCAT(buf, p);
|
||||||
xfree(p);
|
xfree(p);
|
||||||
@ -4364,7 +4366,7 @@ static void nv_ident(cmdarg_T *cap)
|
|||||||
} else
|
} else
|
||||||
aux_ptr = (char_u *)"\\|\"\n*?[";
|
aux_ptr = (char_u *)"\\|\"\n*?[";
|
||||||
|
|
||||||
p = buf + STRLEN(buf);
|
p = (char_u *)buf + STRLEN(buf);
|
||||||
while (n-- > 0) {
|
while (n-- > 0) {
|
||||||
/* put a backslash before \ and some others */
|
/* put a backslash before \ and some others */
|
||||||
if (vim_strchr(aux_ptr, *ptr) != NULL)
|
if (vim_strchr(aux_ptr, *ptr) != NULL)
|
||||||
@ -4391,10 +4393,11 @@ static void nv_ident(cmdarg_T *cap)
|
|||||||
STRCAT(buf, "\\>");
|
STRCAT(buf, "\\>");
|
||||||
/* put pattern in search history */
|
/* put pattern in search history */
|
||||||
init_history();
|
init_history();
|
||||||
add_to_history(HIST_SEARCH, buf, true, NUL);
|
add_to_history(HIST_SEARCH, (char_u *)buf, true, NUL);
|
||||||
(void)normal_search(cap, cmdchar == '*' ? '/' : '?', buf, 0);
|
(void)normal_search(cap, cmdchar == '*' ? '/' : '?', (char_u *)buf, 0);
|
||||||
} else
|
} else {
|
||||||
do_cmdline_cmd((char *)buf);
|
do_cmdline_cmd(buf);
|
||||||
|
}
|
||||||
|
|
||||||
xfree(buf);
|
xfree(buf);
|
||||||
}
|
}
|
||||||
|
@ -1329,9 +1329,7 @@ return {
|
|||||||
expand=true,
|
expand=true,
|
||||||
varname='p_kp',
|
varname='p_kp',
|
||||||
defaults={
|
defaults={
|
||||||
condition='USEMAN_S',
|
if_true={vi=":Man"},
|
||||||
if_true={vi="man -s"},
|
|
||||||
if_false={vi="man"},
|
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
39
test/functional/normal/K_spec.lua
Normal file
39
test/functional/normal/K_spec.lua
Normal file
@ -0,0 +1,39 @@
|
|||||||
|
local helpers = require('test.functional.helpers')
|
||||||
|
local execute, eq, clear, eval, feed, ok =
|
||||||
|
helpers.execute, helpers.eq, helpers.clear, helpers.eval,
|
||||||
|
helpers.feed, helpers.ok
|
||||||
|
|
||||||
|
describe('K', function()
|
||||||
|
local test_file = 'K_spec_out'
|
||||||
|
before_each(function()
|
||||||
|
clear()
|
||||||
|
os.remove(test_file)
|
||||||
|
end)
|
||||||
|
after_each(function()
|
||||||
|
os.remove(test_file)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("invokes colon-prefixed 'keywordprg' as Vim command", function()
|
||||||
|
helpers.source([[
|
||||||
|
let @a='fnord'
|
||||||
|
set keywordprg=:put]])
|
||||||
|
|
||||||
|
-- K on the text "a" resolves to `:put a`.
|
||||||
|
feed('ia<ESC>K')
|
||||||
|
helpers.expect([[
|
||||||
|
a
|
||||||
|
fnord]])
|
||||||
|
end)
|
||||||
|
|
||||||
|
it("invokes non-prefixed 'keywordprg' as shell command", function()
|
||||||
|
helpers.source([[
|
||||||
|
let @a='fnord'
|
||||||
|
set keywordprg=echo\ fnord\ >>]])
|
||||||
|
|
||||||
|
-- K on the text "K_spec_out" resolves to `!echo fnord >> K_spec_out`.
|
||||||
|
feed('i'..test_file..'<ESC>K')
|
||||||
|
feed('<CR>') -- Press ENTER
|
||||||
|
eq({'fnord'}, eval("readfile('"..test_file.."')"))
|
||||||
|
end)
|
||||||
|
|
||||||
|
end)
|
Loading…
Reference in New Issue
Block a user