.c / .h 버퍼 전환


8

나는 일반적으로 세로로 분할 된 2 개의 창으로 작업합니다.

내가 해결하고 싶은 문제 는 헤더 <-> 구현 파일에서 쉽게 앞뒤로 점프하는 것 입니다.

나는 운이없이 이것을하는 두 가지 방법을 조사하고 있습니다.

  1. 현재 창 에서 대체 파일 열기 :이 작업을 수행하는 방법에는 여러 가지가 있지만 이전 파일의 위치를 ​​기억하는 방법을 찾을 수 없습니다 (예 : 헤더로 이동, 뒤로 이동하지만 이전과 같은 위치로 이동하지는 않음) ).
  2. 다른 창 에서 대체 파일 열기 : 2 개의 창에서만 작업하기 때문에 잘 정의되어 있지만 vim 지식이 부족합니다.

1
첫 번째 문제에 대한 힌트를 보려면 :h line()(일반 솔루션)의 끝을 참조하십시오 . "이 자동 명령은 '"마크가 설정된 경우 파일을 연 직후 파일에서 마지막으로 알려진 위치로 이동합니다. : au BufReadPost * if line ( "' \ "")> 1 && line ( " '\" ") <= line ("$ ") | exe "normal! g` \" "| endif
VanLaser

점프리스트 및 / 또는 크로스 파일 마크를 사용할 수 없습니까?
fruglemonkey


2
아마 당신이 찾고있는 A.vim
기독교 Brabandt

답변:


5

원하는 것을 달성하기위한 3 가지 주요 단계가 있습니다.

  • 대체 파일 이름 얻기
  • 원하는대로 현재 창 또는 다른 창에서 해당 파일 열기
  • 해당 파일 내에서 커서 위치 복원

대체 파일 이름을 찾으려면 현재 파일 이름을 "루트"및 "확장명"으로 분리하십시오. 이를 수행하는 간단한 방법은 다음과 같습니다.

let parts = split(expand("%:p"), "[.]");
let root = parts[0]
let extension = parts[1]

파일 .h.cpp파일 만 전환 한다는 것을 알고 있다면 확장명을 쉽게 바꿀 수 있습니다.

if extension == "h"
  let extension = "cpp"
else
  let extension = "h"
endif

또는 알려진 확장을 잠재적으로 유효한 대체 확장에 매핑 하는 사전을 만듭니다 . 또는 현재 파일에 가능한 모든 대체 파일 globpath()을 얻는 데 사용 하십시오.

let alternates = globpath(expand("%:h"), root . ".*")

첫 번째 또는 다른 것을 선택하십시오. 나는 globpath나중에 설명 할 몇 가지 추가 스마트와 함께 접근 방식을 선호합니다 . 대상 확장을 선택했으면 전체 대상 경로를 형성하십시오.

let target = root . "." . alternates[whicheverAlternateExtensionYouWant]

이제 현재 창에서 대체 파일을 열 수 있습니다.

execute "edit " . target

또는 winnr()"다른 창"번호를 가져 오려면 사용 하십시오 ( winnr("#")이 창 <C-W>p으로 이동하거나 설정과 항상 동일하다는 것을 알면 하드 코딩 할 수 있습니다).

let window = winnr("#")
execute window . "wincmd w"
execute "edit " . target

이것은 대체 파일을 여는 데 가장 기본적인 솔루션입니다. 위의 접근 방식에는 약간의 결함이 있습니다. 왜냐하면 내가 직접 작성했기 때문에 약간의 커프입니다. "원하는 방식으로"대체 파일 전환 (사용 가능한 모든 결과를 순환) 하는 플러그인 을 작성했습니다 globpath(). 위의 단순성과 관련된 몇 가지 문제를 해결하기 위해 더 많은 것을 탐구하고 싶다면 구현을 확인할 수 있습니다.

마지막으로 "커서 위치 복원"지점입니다. 대체 전환과 직교이므로 마지막으로 저장했지만 (예를 들어 플러그인은 처리하지 않음) 직접 롤링하려는 경우 함수에 넣을 수 있습니다. :help line()커서 위치를 파일을 마지막으로 열었던 위치로 복원하는 데 유용한 자동 명령이 있습니다.

:au BufReadPost * if line("'\"") > 1 && line("'\"") <= line("$") | exe "normal! g`\"" | endif

나는 .vimrc그 행동을 항상 선호하기 때문에 그냥 저것이나 비슷한 것을 넣었 습니다. 그래도 코드를 다른 곳에 쉽게 넣을 수 있습니다.


2

파일 에서 vim-fswitch 플러그인을 다음 구성과 함께 사용할 수 있습니다 .vimrc.

au! BufEnter *.cpp,*.cc,*.c let b:fswitchdst = 'h,hpp'    | let b:fswitchlocs = 'reg:/src/include/,../include,./'
au! BufEnter *.h,*.hpp      let b:fswitchdst = 'cpp,cc,c' | let b:fswitchlocs = 'reg:/include/src/,../src,./'

nmap <silent> <Leader>s :FSHere<cr>

당신이 입력 한 경우 <Leader>(이이 \다음에 기본적으로) sA의 .hpp또는 .h파일, 일치하는 경우 플러그인 확인합니다 .cpp, .cc또는 .c파일이 존재 :

  • 교체하여 include의해 src현재 파일의 경로에
  • src현재 파일 위의 폴더 를 보면
  • 현재 파일의 폴더를 보면

문서 에서 프로젝트를 더 잘 맞추기 위해 사용할 수있는 옵션이 더 있습니다 . 몇 분이 걸리지 만 일단 제대로 이해하면 좋아해야합니다. 나는 개인적으로 매우 유연하고 확장 가능하며 많은 종류의 파일 (.m, .h, .inl 등)에서도 잘 작동합니다.


1

당신의 .vimrc

" =====[ Remap to change windows quickly ]=============================
:nnoremap <silent> <C-H> :wincmd h<CR>
:nnoremap <silent> <C-J> :wincmd j<CR>
:nnoremap <silent> <C-K> :wincmd k<CR>
:nnoremap <silent> <C-L> :wincmd l<CR>

이렇게하면 홈 행에서 Ctrl 및 VIM 방향 키를 사용하여 창 사이를 빠르게 이동할 수 있습니다. 이것의 가장 큰 장점은 quickfix 창을 포함하여 모든 창으로 이동하는 일반적인 방법이 있다는 것입니다.

빨리 헤더와 소스 I 사용 전환하려면 vim-scripts/a.vim여기 : https://github.com/vim-scripts/a.vim , 사용 :A명령을 전환합니다.

참고 => tmux를 사용하는 경우 https://github.com/christoomey/vim-tmux-navigator 를 사용 하여 vim 또는 nvim 창과 터미널 사이를 원활하게 이동할 수 있습니다 .


1

난 그냥 내 슈퍼 빠른 & 더러운 버전을 공유합니다 ...

내 매핑을 설정하십시오. alt-o는 같은 창에서 관련 파일을 열고 alt-shift-o는 분할로 열립니다 ...

nnoremap <A-o> :call EditRelatedFile()<CR>
nnoremap <A-O> :call SplitRelatedFile()<CR>

그런 다음 관련 파일 목록을 가져 오는 기능이 있습니다. 필자는 파일 이름을 마지막 점이 아닌 첫 번째 점에서 자르도록 조정하려고했지만 여전히 독자에게는 연습입니다.

function! GetRelatedFileList()
    " This function may be overloaded in a site-specific vimrc.
    let l:thisPath = expand("%:p:r") . '.*'
    let l:files = glob(l:thisPath)

    return split(l:files, '[\r\n]\+')
endfunction

내 .vimrc 설정은 때때로 클라이언트마다 특화되어 있습니다. 일부에는 소스가 있고 별도의 폴더 계층 구조에 포함되며 일부는 함께 있습니다. 기본적으로 나는 그들이 모두 근처에 있다고 가정하지만 사냥해야 할 경우 이와 같은 대체 기능을 제공 할 것입니다.

" Override the basic GetRelatedFileList coming from vimrc.
function! GetRelatedFileList()
    let l:thisDir = expand("%:p:h:t")
    if (l:thisDir ==? "src") || (l:thisDir ==? "include")
        let l:thisPath = expand("%:p:h:h")
        let l:searchPaths = l:thisPath.'/include,' . l:thisPath.'/src'
        let l:thisBase = expand("%:t:r") . '.*'
        let l:files = globpath(l:searchPaths, l:thisBase)
    else
        let l:thisPath = expand("%:p:r") . '.*'
        let l:files = glob(l:thisPath)
    endif

    return split(l:files, '[\r\n]\+')
endfunction

그런 다음 해당 파일 목록을 살펴보고 현재 버퍼의 파일을 찾고 목록의 다음 파일로 이동합니다. 그것은 종종 .cpp / .h 쌍만큼 단순하지는 않지만 종종 고려해야 할 다른 것들이 있습니다.

function! GetNextRelatedFile()
    let l:fileList = GetRelatedFileList()

    let l:thisFile = expand("%:p")
    let l:index = index(l:fileList, l:thisFile) + 1

    if l:index >= len(l:fileList)
        let l:index = 0
    endif

    return l:fileList[l:index]
endfunction

그리고 마지막으로 현재 창에서 열리거나 분할하는 두 가지 기능 ...

function! EditRelatedFile()
    let l:file = GetNextRelatedFile()
    execute "edit" l:file
endfunction

내 분할 버전은 항상 .cpp 및 .c 파일을 아래 분할에 넣습니다. 그렇지 않으면 기본 분할 (내 경우에는 위)입니다.

function! SplitRelatedFile()
    let l:file = GetNextRelatedFile()
    let l:ext = fnamemodify(l:file, ":e")
    if (l:ext ==? "cpp") || (l:ext ==? "c")
        execute "below split" l:file
    else
        execute "split" l:file
    endif
endfunction
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.