40

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

当我们:set ls=2在 Vim 中设置时,我们可以获得文件路径(相对于当前目录)、行号等。如果我们也能看到函数名,那就太好了。任何想法如何得到它?

目前我[[用来开始函数并Ctrl-O回到我正在编辑的行。

4

8 回答 8

21

要在C 程序 中显示当前函数名,请在 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”键,只需将功能映射到您喜欢的任何内容。

于 2014-04-24T04:23:40.317 回答
15

您可以为此使用ctags.vim,它会在标题或状态栏中显示当前函数名称。

来源:https ://superuser.com/questions/279651/how-can-i-make-vim-show-the-current-class-and-method-im-editing

于 2012-11-29T22:28:03.400 回答
10

基于@manav mn 的回答

'n' 标志search()不会移动光标,因此具有相同功能的较短版本将是:

fun! ShowFuncName()
  echohl ModeMsg
  echo getline(search("^[^ \t#/]\\{2}.*[^:]\s*$", 'bWn'))
  echohl None
endfun
map f :call ShowFuncName() <CR>

参考:运行:help search()

于 2017-01-19T16:40:50.180 回答
1

有几个用于状态行或按需映射的插件,例如:

于 2012-11-30T08:17:20.657 回答
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 列。

我今天刚刚注意到,如果包含在命名空间 {} 中,它会失败,即使按预期格式化也是如此。

于 2013-04-11T18:06:34.880 回答
1

我为此使用https://github.com/mgedmin/chelper.vim 。它不需要标签文件,而是动态解析源代码。

于 2015-01-12T10:33:23.643 回答
1

在研究了这个和公认的解决方案后,我相信最简单的解决方案是:

  1. 安装通用 Ctags https://ctags.io/

  2. 安装标签栏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

于 2021-06-02T00:14:30.947 回答
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
于 2020-05-29T14:37:38.320 回答