Показать имя функции в строке состояния

Я редактирую большой файл C, C++ или Java, скажем, около 15000 строк, с довольно длинными определениями функций, скажем, около 400 строк. Когда курсор находится в середине определения функции, было бы здорово увидеть имя функции в строке состояния Vim.

Когда мы установим :set ls=2 в Vim мы можем получить путь к файлу (относительно текущего каталога), номер строки и т. д. Было бы очень здорово, если бы мы могли видеть и имя функции. Есть идеи как его получить?

В настоящее время я использую [[ чтобы перейти к началу функции и Ctrl-O, чтобы вернуться к строке, которую я редактирую.

8 ответов

Решение

Для этого вы можете использовать ctags.vim, он покажет текущее имя функции в заголовке или строке состояния.

ИСТОЧНИК: https://superuser.com/questions/279651/how-can-i-make-vim-show-the-current-class-and-method-im-editing

Чтобы показать текущее имя функции в программах на 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", просто сопоставьте функцию с тем, что вам нравится.

Основано на ответе @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()

Изучив это и принятое решение, я считаю, что самое простое решение:

  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

Я использую https://github.com/mgedmin/chelper.vim для этого. Ему не нужен файл тегов, он анализирует исходный код на лету.

Есть несколько плагинов для строки состояния или по запросу с отображением, например:

Мое решение заключается в следующем:

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 на отдельной строке.

Я только сегодня заметил, что он терпит неудачу, если включен в пространство имен {}, даже если он отформатирован в соответствии с ожиданиями.

На основе решения @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
Другие вопросы по тегам