在状态栏中显示函数名

42

我正在编辑一个大的C、C++或Java文件,大约有15000行,其中包含相当长的函数定义,大约有400行。当光标在函数定义的中间时,在Vim状态栏中看到函数名会很酷。

当我们在Vim中设置:set ls=2时,我们可以得到文件路径(相对于当前目录),行号等。如果我们也能看到函数名,那将会非常棒。你有什么想法吗?

目前,我使用[[转到函数的开头,然后使用Ctrl-O返回到我正在编辑的行。


你当前的方法有什么问题? - romainl
11
他希望有更快更简单的方式...来始终显示那些信息。 - jahroy
如果他不总是看它,那么始终显示和更新它有什么意义呢? - romainl
8
@jahroy,是的,我希望它一直显示,这样每当我想查看它时,我就可以直接看。 - Manikandaraj Srinivasan
21
作为 Vim 用户,这是你的权利! - jahroy
8个回答

20

为了在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"键,只需将该功能映射到任何你喜欢的键位即可。


2
尝试了其他的选择,对于我来说,这是最好和最快的。不需要进行ctags更新,因为我的代码流只有几百个文件,每个文件都有几万行。 - Ayman
2
search() 中的 'n' 标志不会移动光标,因此具有相同功能的较短版本如下:fun! ShowFuncName() echohl ModeMsg echo getline(search("^[^ \t#/]\\{2}.*[^:]\s*$", 'bWn')) echohl None endfun map f :call ShowFuncName() 参考:运行 :help search() - solidak

16

10

基于@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()


2

经过调查和接受的解决方案,我认为最简单的解决方案是:

  1. 安装Universal Ctags https://ctags.io/

  2. 安装Tagbar https://github.com/preservim/tagbar

  3. 在设置状态行时调用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


1
我的解决方案如下:
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

我试图匹配C/C++/Java允许的函数名称。这通常对我有用(包括重载运算符),但假定打开的{在单独一行的列0处。
今天我注意到,即使按预期格式进行,如果包含在命名空间{}中,它也会失败。


0

请注意,这仅适用于C语言。 - Benjamin Carlsson
我已经转而使用https://github.com/mgedmin/taghelper.vim,它支持少量其他语言。 - Marius Gedminas

0

基于@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

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接