In Vim how to switch quickly between .h and .cpp files with the same name?

后端 未结 6 2007
太阳男子
太阳男子 2020-12-23 16:55

Suppose I have a folder with lots of .h and .cpp files. I frequently need to do the following:

  1. open a file prefix_SomeReallyLongFileName.h,
相关标签:
6条回答
  • 2020-12-23 17:10

    Install “unimpaired” and then use ]f and [f to go the previous and next file. Since source and header have they same name except for the suffix, they are next and previous files.

    0 讨论(0)
  • 2020-12-23 17:12

    You can use the :r (root) filename modifier which removes the last extension (check out :h filename-modifiers for more information)

    :e %:r.cpp
    

    where

    • % is shorthand for current filename.
    • :r removes the extension
    • .cpp simply appends that string at the end.

    This effectively substitutes the current file's extension with another, then open the file with the newer extension.


    An even shorter way (courtesy of Peter Rincker),

    :e %<.cpp
    

    Relevant documentation at :h extension-removal

    0 讨论(0)
  • 2020-12-23 17:12

    According to the Vim wiki there are quite a few suggested ways.

    I will outline a few options from the article:

    • a.vim or FSwitch.vim plugins
    • using ctags
    • :e %<.c or :e %<.h. %< represents the current file w/o the extension
    • A quick mapping nnoremap <F4> :e %:p:s,.h$,.X123X,:s,.cpp$,.h,:s,.X123X$,.cpp,<CR>. Add this to your ~/.vimrc.
    0 讨论(0)
  • 2020-12-23 17:17

    https://github.com/ericcurtin/CurtineIncSw.vim is an option.

    Once configured searches the current directory recursively and the directory your source file is in recursively for the file you want to switch to.

    0 讨论(0)
  • 2020-12-23 17:23

    Adding my two cents ;) to the above great answers:

    1. Install Exuberant Ctags
    2. Put the following code into your .vimrc
    " Jump to a file whose extension corresponds to the extension of the current
    " file. The `tags' file, created with:
    " $ ctags --extra=+f -R .
    " has to be present in the current directory.
    function! JumpToCorrespondingFile()
        let l:extensions = { 'c': 'h', 'h': 'c', 'cpp': 'hpp', 'hpp': 'cpp' }
        let l:fe = expand('%:e')
        if has_key(l:extensions, l:fe)
            execute ':tag ' . expand('%:t:r') . '.' . l:extensions[l:fe]
        else
            call PrintError(">>> Corresponding extension for '" . l:fe . "' is not specified") 
        endif
    endfunct
    
    " jump to a file with the corresponding extension (<C-F2> aka <S-F14>)
    nnoremap <S-F14> :call JumpToCorrespondingFile()<CR>
    inoremap <S-F14> <C-o>:call JumpToCorrespondingFile()<CR>
    
    " Print error message.
    function! PrintError(msg) abort
        execute 'normal! \<Esc>'
        echohl ErrorMsg
        echomsg a:msg
        echohl None
    endfunction
    
    0 讨论(0)
  • 2020-12-23 17:28

    This is just using simple(?!) vimscript, so you can put it into your vimrc, now it works for .c files, but can be modified pretty easily for .cpp (obviously), it even has some "error handling" in the inner if-statements (that is probably pointless), but if anyone needs it, hey, it's there! Without it it's way much shorter (just leave the :e %<.h, for example), so choose whatever you want.

    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
    

    then add further to your vimrc something along these lines:

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

    Now whenever you're in normal mode, you press comma , (this is our <Leader> button) then h and function from the above gets called, and you will toggle between files. Tada!

    0 讨论(0)
提交回复
热议问题