2013-06-18 2 views
22

Предположим, у меня есть папка с большим количеством файлов .h и .cpp. Я часто нужно сделать следующее:В Vim как быстро переключаться между файлами .h и .cpp с тем же именем?

  1. открыть файл prefix_SomeReallyLongFileName.h,
  2. внести некоторые изменения к нему,
  3. , а затем откройте prefix_SomeReallyLongFileName.cpp.

Есть ли быстрый способ открыть файл с тем же именем, что и текущий файл, но другое расширение?

Неужели другие люди тоже сталкиваются с этой ситуацией, и если да, то каков ваш предпочтительный способ навигации по файлам C++ в каталоге? Благодарю.

+1

Я не уверен, что это случается со многими людьми. Обычно у вас есть файлы заголовков в отдельной папке, кроме исходных файлов (например, 'include /' и 'src /'), поэтому то, что вы просите, не происходит (если не искать файл в '../include/ 'или' ../ src/'). Обычно я открываю два терминала, сохраняю файл заголовка открытым в одном и исходный файл в другом, так как обычно я перехожу назад и вперед между файлами. – Shahbaz

+2

Вы можете ввести ': e', а затем нажать ctrl-r%. Это поместит текущее имя файла в строку, затем вы можете заменить расширение. –

+3

Связанные вопросы [Использование a.vim для C++] (http://stackoverflow.com/q/2192152) и [Vim script для переключения между заголовком и файлом реализации с помощью cscope] (http://stackoverflow.com/q/5108484). – glts

ответ

39

Вы можете использовать модификатор :r (корень) имени файла, который удаляет последнее расширение (проверить :h filename-modifiers для получения дополнительной информации)

:e %:r.cpp 

где

  • % является сокращением для текущего файла.
  • :r удаляет расширение
  • .cpp просто добавляет эту строку в конец.

Это эффективно заменяет расширение текущего файла другим, а затем открывает файл с более новым расширением.


Еще более короткий путь (любезность Peter Rincker),

:e %<.cpp 

Соответствующая документация на :h extension-removal

+1

Для меня в файле 'ac',': e%: eh' становится 'ch' вместо ожидаемого 'ah' – Shahbaz

+0

@Shahbaz, извиняюсь, я должен использовать': r'. Я исправлю сообщение. – doubleDown

+0

Нет проблем, просто хотел сообщить вам (я также изучаю) – Shahbaz

19

Согласно вики Vim есть немало suggested ways.

я опишу несколько вариантов из статьи:

  • a.vim или FSwitch.vim плагинов
  • с помощью Ctags
  • :e %<.c или :e %<.h. %< представляет текущий файл без расширения
  • Быстрое картирование nnoremap <F4> :e %:p:s,.h$,.X123X,:s,.cpp$,.h,:s,.X123X$,.cpp,<CR>. Добавьте это в свой ~/.vimrc.
+3

Другим плагином, заслуживающим упоминания, является [* altr *] (http://www.vim.org/scripts/script.php?script_id=4202), лучший * a.vim *. Он поддерживает не только '.h' и' .cpp', но и другие альтернативы и может быть настроен. – glts

+0

Я использую указанную выше команду, но вместо 'e' я использую' tag'. Однако он говорит, что «тег не найден». Это потому, что он вызывается из файла '.vimrc', а не из исходного файла? – Paschalis

+1

@Paschalis ': tag' и': e' - совершенно разные команды. ': e' редактирует данный файл, а': tag' переходит к указанному тегу. Приведенная выше команда (сопоставление) в основном принимает текущее имя файла '%' и применяет некоторые подкачки для изменения '.h' ->' .cpp' и '.cpp' ->' .h'. Это означает, что команда переключается между исходным файлом и файлом заголовка (и обратно). Используя ': tag' с этим сопоставлением, вы в основном ищете имя файла с отключенным расширением, что не имеет никакого смысла. Для получения дополнительной помощи см. ': H: tag',': h: e' и ': h c_%'. –

6

Установить «нетронутый», а затем использовать ]f и [f для перехода на предыдущий и следующий файл. Поскольку источник и заголовок имеют одно и то же имя, кроме суффикса, это следующие и предыдущие файлы.

+1

FYI для googlers: '] f' и' [f' обрабатывать файлы только в текущем каталоге. Таким образом, это отвечает на вопрос OP, но не поможет тем, кто разделяет файлы заголовков и исходных файлов в разные каталоги и т. Д. – Matthew

1

Это только с помощью простого (?!) vimscript, так что вы можете поместить его в свой vimrc, теперь он работает для .c файлов, но может быть изменена довольно легко для .cpp (очевидно), он даже имеет некоторые «ошибки обрабатывая "во внутренних if-утверждениях (это, вероятно, бессмысленно), но если кому-то это нужно, эй, оно есть! Без него это намного короче (просто оставьте, например, :e %<.h), поэтому выбирайте все, что захотите.

function! HeaderToggle() " bang for overwrite when saving vimrc 
let file_path = expand("%") 
let file_name = expand("%<") 
let extension = split(file_path, '\.')[-1] " '\.' is how you really split on dot 
let err_msg = "There is no file " 

if extension == "c" 
    let next_file = join([file_name, ".h"], "") 

    if filereadable(next_file) 
    :e %<.h 
    else 
     echo join([err_msg, next_file], "") 
    endif 
elseif extension == "h" 
    let next_file = join([file_name, ".c"], "") 

    if filereadable(next_file) 
     :e %<.c 
    else 
     echo join([err_msg, next_file], "") 
    endif 
endif 
endfunction 

затем добавить дополнительно к вашему vimrc что-то вдоль этих линий:

let mapleader = "," " <Leader> 
nnoremap <Leader>h :call HeaderToggle()<CR> 

Теперь, когда вы находитесь в нормальном режиме, нажмите запятой , (это наша <Leader> кнопка), то h и функция из вызывается выше, и вы будете переключаться между файлами. Тада!

Смежные вопросы