我正在编辑一个大的C、C++或Java文件,大约有15000行,其中包含相当长的函数定义,大约有400行。当光标在函数定义的中间时,在Vim状态栏中看到函数名会很酷。
当我们在Vim中设置:set ls=2
时,我们可以得到文件路径(相对于当前目录),行号等。如果我们也能看到函数名,那将会非常棒。你有什么想法吗?
目前,我使用[[
转到函数的开头,然后使用Ctrl-O返回到我正在编辑的行。
我正在编辑一个大的C、C++或Java文件,大约有15000行,其中包含相当长的函数定义,大约有400行。当光标在函数定义的中间时,在Vim状态栏中看到函数名会很酷。
当我们在Vim中设置:set ls=2
时,我们可以得到文件路径(相对于当前目录),行号等。如果我们也能看到函数名,那将会非常棒。你有什么想法吗?
目前,我使用[[
转到函数的开头,然后使用Ctrl-O返回到我正在编辑的行。
为了在C程序中显示当前的函数名,请在您的vimrc文件中添加以下内容:
To show current function name in C programs, add following in your vimrc:fun! ShowFuncName()
let lnum = line(".")
let col = col(".")
echohl ModeMsg
echo getline(search("^[^ \t#/]\\{2}.*[^:]\s*$", 'bW'))
echohl None
call search("\\%" . lnum . "l" . "\\%" . col . "c")
endfun
map f :call ShowFuncName() <CR>
或者,如果你需要"f"键,只需将该功能映射到任何你喜欢的键位即可。
search()
中的 'n' 标志不会移动光标,因此具有相同功能的较短版本如下:fun! ShowFuncName()
echohl ModeMsg
echo getline(search("^[^ \t#/]\\{2}.*[^:]\s*$", 'bWn'))
echohl None
endfun
map f :call ShowFuncName()
参考:运行 :help search()
。 - solidak基于@manav m-n的答案
search()
中的'n'标志不会移动光标,因此具有相同功能的较短版本如下:
fun! ShowFuncName()
echohl ModeMsg
echo getline(search("^[^ \t#/]\\{2}.*[^:]\s*$", 'bWn'))
echohl None
endfun
map f :call ShowFuncName() <CR>
参考:运行:help search()
经过调查和接受的解决方案,我认为最简单的解决方案是:
安装Universal Ctags https://ctags.io/
安装Tagbar https://github.com/preservim/tagbar
在设置状态行时调用tagbar#currenttag()
,例如在.vimrc中:
:set statusline=%<%f\ %h%m%r%=%{tagbar#currenttag('%s\ ','','f')}%-.(%l,%c%V%)\ %P
请注意:
您传递给currenttag()
的字符串中必须使用斜杠转义空格......而且在vim内运行命令和将其放入.vimrc中甚至不同?无论如何,空格可能很奇怪,但在输出函数名时它们可能是您想要的。
我花了一些时间研究,但默认状态行是
:set statusline=%<%f\ %h%m%r%=%-14.(%l,%c%V%)\ %P
set stl=%f%h%m%r\ %{Options()}%=%l,%c-%v\ %{line('$')}
fu! PlusOpt(opt)
let option = a:opt
if option
return "+"
else
return "-"
endif
endf
fu! Options()
let opt="ic".PlusOpt(&ic)
let opt=opt." ".&ff
let opt=opt." ".&ft
if &ft==?"cpp" || &ft==?"perl"
let text = " {" . FindCurrentFunction() . "}"
let opt= opt.text
endif
return opt
fu! FindCurrentFunction()
let text =''
let save_cursor = getpos(".")
let opening_brace = searchpair('{','','}','bWr', '', '', 100)
if opening_brace > 0
let oldmagic = &magic
let &magic = 1
let operators='operator\s*\%((\s*)\|\[]\|[+*/%^&|~!=<>-]=\?\|[<>&|+-]\{2}\|>>=\|<<=\|->\*\|,\|->\|(\s*)\)\s*'
let class_func_string = '\(\([[:alpha:]_]\w*\)\s*::\s*\)*\s*\%(\~\2\|'.operators
let class_func_string = class_func_string . '\|[[:alpha:]_]\w*\)\ze\s*('
let searchstring = '\_^\S.\{-}\%('.operators
let searchstring = searchstring.'\|[[:alpha:]_]\w*\)\s*(.*\n\%(\_^\s.*\n\)*\_^{'
let l = search(searchstring, 'bW', line(".")-20 )
if l != 0
let line_text = getline(l)
let matched_text = matchstr(line_text, class_func_string)
let matched_text = substitute(matched_text, '\s', '', 'g')
let text = matched_text
endif
call setpos('.', save_cursor)
let &magic = oldmagic
endif
return text
endfunction
我使用https://github.com/mgedmin/chelper.vim来实现这个功能。它不需要标签文件,而是动态解析源代码。
基于@solidak的解决方案(该解决方案已经基于另一个解决方案:)
我想始终在终端底部显示函数名称。 但是,我遇到了一些非常大的函数问题,我通过以下方式解决了这个问题:
fun! ShowFuncName()
echohl ModeMsg
echo getline(search("^[^ \t#/]\\{2}.*[^:]\s*$", 'bWn'))[:winwidth('%')-3]
echohl None
endfun
augroup show_funcname
autocmd CursorMoved * :call ShowFuncName()
augroup end