Показать имя функции в строке состояния
Я редактирую большой файл C, C++ или Java, скажем, около 15000 строк, с довольно длинными определениями функций, скажем, около 400 строк. Когда курсор находится в середине определения функции, было бы здорово увидеть имя функции в строке состояния Vim.
Когда мы установим :set ls=2
в Vim мы можем получить путь к файлу (относительно текущего каталога), номер строки и т. д. Было бы очень здорово, если бы мы могли видеть и имя функции. Есть идеи как его получить?
В настоящее время я использую [[
чтобы перейти к началу функции и Ctrl-O, чтобы вернуться к строке, которую я редактирую.
8 ответов
Для этого вы можете использовать ctags.vim, он покажет текущее имя функции в заголовке или строке состояния.
Чтобы показать текущее имя функции в программах на 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()
Изучив это и принятое решение, я считаю, что самое простое решение:
Установите 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
Я использую 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