vim에서 함수 정의로 이동


241

vim을 사용하여 함수 정의로 어떻게 이동할 수 있습니까? 예를 들어 Visual Assist를 사용하면 Alt+ 를 입력 할 수 있습니다.g 를 사용하면 함수 아래에 있으며 정의가있는 파일을 나열하는 상황에 맞는 메뉴를 엽니 다.

vim에서 어떻게 이런 일을 할 수 있습니까?


2
gnu global은 ctags보다 낫습니다.
Jichao

6
@Jichao, 당신의 경험에 대해 좀 더 통찰력을 줄 수 있습니까? gnu global은 어떤 언어로 더 잘 작동 했습니까? 내가 중요하게 여기고 싶은 맥락에 대해 다른 것이 있습니까? 또는 아마도 당신은 많은 다른 시나리오에서 그것을 사용했고 당신은 대부분 / 항상 선호하는 것처럼 보입니까? 당신은 그것에 대해 무엇을 더 좋아합니까? 감사.
still_dreaming_1

@Jichao 귀하의 의견을 커뮤니티 위키 답변으로 바 꾸었습니다. 이 답변에 대한 귀하의 변경과 의견을 환영합니다.
still_dreaming_1

답변:


213

ctags를 사용하십시오. 태그 파일을 생성하고 : tags 명령을 사용하여 vim에 위치를 알려줍니다. 그런 다음 사용하여 함수 정의로 건너 뛸 수 있습니다.Ctrl -를]

이 질문 에는 더 많은 태그 트릭과 팁 있습니다.


2
php는 "유사한 ctags"와 함께 작동 할 정도로 C와 비슷합니다. 파이썬 모드인지 알 수 없습니다.
Paul Tomblin

5
Cscope에 대한 경험이 없습니다. 무엇입니까?
Paul Tomblin

10
C와의 유사성은 CTags 지원 PHP와 아무 관련이 없습니다. Python뿐만 아니라 PHP도 지원합니다. 전체 지원을 보려면 ctags.sourceforge.net/languages.html 을 살펴보십시오 .
데이터

1
ctags를 어떻게 생성합니까?
dwaynemac

4
ctags를 조작하는 방법을 배우는 것이 가장 좋은 위치에 대한 참조를 얻는 것이 좋습니다.
Fzs2

137

모든 것이 하나의 파일에 포함 된 경우, gd'고토 정의'에서와 같이 명령이 있습니다.이 명령 은 커서 아래 단어 파일의 첫 번째 항목으로, 종종 정의입니다.


1
커서 아래에 단어가 없으면 입력해야합니까?
Fuad Saud

@FuadSaud는 다음을 사용하여 검색합니다/
LucasB

6
/모든 사건과 일치하므로 거의 항상 정확하지 않습니다. 실제로 :tag <function_name>ctags를 통해 정의로 이동하기 위해 할 수 있다는 것을 알았습니다 .
Fuad Saud

@Faud Jump To Definition 기능은 모든 IDE에서 커서로 식별자를 가리키는 데 의존합니다. 타이핑 / 검색은 또 다른 기능으로 혼동됩니다.
피의

101

g* ctags를 설정하지 않고 괜찮은 작업을 수행합니다.

즉, 유형 g, *(또는 *- (이 경우, 함수 이름) 커서 아래의 단어를 검색 할 수 아래 참조). 그런 다음 Enter 키를 눌러 n(또는 다음으로 이동합니다 Shift- n발생 이전의 경우).

이 명령은 커서 아래의 단어 만 검색한다는 점을 감안하면 정의로 직접 이동하지는 않지만 현재 ctags 설정을 처리하지 않으려면 최소한 다시 설정하지 않아도됩니다. 정의를 검색하려면 함수 이름을 입력하십시오.

-편집-g *를 오랫동안 사용해 왔지만 최근에 이러한 단축키에 대한 두 가지 단축키를 발견했습니다!

(a) *커서 아래에있는 다음 단어로 이동합니다. ( gvi에서 'goto'명령 을 입력 할 필요가 없습니다 ).

(b) #비슷한 방식으로 이전 사건으로 간다.

N과 n은 여전히 ​​작동하지만 '#'은 커서 아래에서 변수 선언을 찾을 때와 같이 처음에는 역방향으로 검색을 시작하는 데 매우 유용합니다.


10
검색 *g*단어 의 차이점 은 단어 경계입니다. *않는 \<keyword\>검색 (동일 \bkeyword\b하면서, 일반 정규식에서)을 g*위한 검색 keyword단어 경계없이.
Nicolai S

파일에 함수가 백 번 발생하는 *경우 정의를 찾기 전에 평균 50 개의 적중을 가져옵니다.
naught101

49

사용 gd또는 gD프로그램의 모든 변수에 커서를 배치하는 동안.

  1. gd 지역 선언으로 이동합니다.
  2. gD 글로벌 선언으로 이동합니다.

더 많은 탐색 옵션은 여기 에서 찾을 수 있습니다 .

Linux 커널과 같은 대규모 프로젝트를 상호 참조 하려면 cscope 를 사용하십시오 .


14

Paul Tomblin이 언급했듯이 ctags 를 사용해야 합니다. 플러그인 사용을 고려할 수도 있습니다. 을 적절한 을 선택하거나 커서 아래에서 함수의 정의를 미리 볼 수도 있습니다. 플러그인이 없으면 ctags 지원에 내장 된 수백 개의 과부하 된 'doAction'메소드 중 하나를 선택하려고하면 두통이 발생합니다.

또한 cscope 와 'find global symbol'기능을 사용할 수 있습니다 . 그러나 vim은 빌드의 기본 옵션이 아닌 + cscope 지원으로 컴파일해야합니다.

함수가 현재 파일에 정의되어 있다는 것을 알고 있다면 일반 모드에서 'gD'키 스트로크를 사용하여 커서 아래의 심볼 정의로 이동할 수 있습니다.

탐색을 위해 가장 많이 다운로드 된 플러그인은 다음과 같습니다.
http://www.vim.org/scripts/script.php?script_id=273

여기에 http://www.vim.org/scripts/script.php?script_id=2507 태그로 이동하면서 컨텍스트를 선택하기 위해 작성한 것입니다
.


안녕하세요 @ mykola-golubyev, 스크립트 Detailed description섹션 에서 제공 한 링크 #2507가 손상되었습니다. 다른 것을 제공해 줄 수 있습니까?
FelikZ

12

또 다른 일반적인 기술은 함수 이름을 첫 번째 열에 배치하는 것입니다. 이를 통해 간단한 검색으로 정의를 찾을 수 있습니다.

int
main(int argc, char *argv[])
{
    ...
}

위의 기능은 /^main파일 내부 또는:grep -r '^main' *.c 디렉토리에서 . 코드가 올바르게 들여 쓰기되는 한 줄의 시작 부분에서 식별자가 발생하는 유일한 시간은 함수 정의에 있습니다.

물론, 이 시점부터 ctags 를 사용하지 않는다면 스스로 부끄러워해야합니다! 그러나이 코딩 표준도 유용한 추가 사항이라고 생각합니다.


13
나는 왜 일부 코더들이 왜 그런 식으로 서명을 작성하는지 궁금해했습니다!
Tarrasch

또한 첫 번째 열에 '{'를 포함하여 함수 시그니처를 작성할 때]]를 눌러 파일에서 앞으로 이동하고 [[뒤로 이동하면 각 기능으로 빠르게 이동할 수 있습니다.
BentChainRing

12

TL; DR :

현대적인 방법은 인텔리전스와 같은 완성 을 위해 COC 를 사용 하고 정의로 이동하기 위해 하나 이상의 언어 서버 (LS)를 사용하는 것입니다. 더 많은 기능을 제공하기 위해 (단, Jump-to-definition에는 필요하지 않음) 하나 이상의 디버거를 설치 하고 완전한 IDE 경험을 얻을 수 있습니다. 빠른 시작:

  1. vim-plug 를 설치 하여 VIM 플러그인 관리
  2. COC 및 (선택적) Vimspector 를 맨 위에 추가하십시오 ~/.vimrc.
    call plug#begin()
    Plug 'neoclide/coc.nvim', {'branch': 'release'}
    Plug 'puremourning/vimspector'
    call plug#end()
    
  3. :source $MYVIMRC | PlugInstallVIM 플러그인 다운로드 요청
  4. COC 확장에 쉽게 액세스 할 수 있도록 다시 시작 vim하고 전화:CocInstall coc-marketplace
  5. :CocList marketplace언어 서버를 호출 하고 검색하십시오. 예 :
    • 입력 python찾기 위해 coc-jedi,
    • php찾을 유형 coc-phpls
  6. (선택 사항) install_gadget.py --help사용 가능한 디버거를 참조하십시오 ( 예 :
    • ./install_gadget.py --enable-python,
    • ./install_gadget.py --force-enable-php

전체 답변 :

언어 서버 (LS)는 백그라운드에서 실행되는 별도의 독립 실행 형 응용 프로그램 (각 프로그래밍 언어마다 하나씩)이며 전체 프로젝트를 실시간으로 분석하여 편집기 (추가 기능뿐만 아니라 모든 편집기)에 추가 기능을 제공합니다 vim. 당신은 다음과 같은 것들을 얻습니다.

  • 네임 스페이스 인식 태그 완성
  • 정의로 이동
  • 다음 / 이전 오류로 이동
  • 객체에 대한 모든 참조를 찾습니다
  • 모든 인터페이스 구현 찾기
  • 전체 프로젝트에서 이름 바꾸기
  • 호버에 관한 문서
  • 스 니펫, 코드 작업, 서식, 보푸라기 등 ...

언어 서버와의 통신은 LSP ( Language Server Protocol) 를 통해 이루어 집니다. 모두 nvimvim8플러그 - 인을 통해 (또는 그 이상) 지원 LSP, 가장 인기있는 존재 완료의 정복 (COC).

적극적으로 개발 된 언어 서버 및 해당 기능의 목록은 Lang Server 웹 사이트에서 제공됩니다. 이들 모두가 COC 확장으로 제공되는 것은 아닙니다. 그중 하나를 사용하려면 직접 COC 확장을 작성하거나 LS를 수동으로 설치하고 다음 VIM 플러그인의 콤보를 COC 대신 사용할 수 있습니다.

디버거와의 통신은 DAP ( 디버그 어댑터 프로토콜) 를 통해 이루어 집니다. VIM에 가장 많이 사용되는 DAP 플러그인은 Vimspector 입니다.

LSP ( Language Server Protocol )는 Microsoft 의 Visual Studio Code 용 으로 만들어졌으며 허용 가능한 MIT 라이센스 (Red Hat 및 Codenvy와의 공동 작업으로 표준화 됨)가 있는 오픈 소스 프로젝트 로 릴리스되었습니다 . 나중에 Microsoft는 DAP ( 디버그 어댑터 프로토콜 )도 출시했습니다 . VSCode가 지원하는 모든 언어는 VIM에서 지원됩니다.

필자는 개인적 으로 추가 보푸라기 (COC와의 충돌을 피하기 위해 LSP 지원이 비활성화 됨) + Vimspector + Vimspector에서 제공하는 디버거 ( "가제트") + VIM 플러그인에 따라 COC 확장 + ALE 에서 제공하는 COC + 언어 서버를 사용하는 것이 좋습니다 .

call plug#begin()
Plug 'neoclide/coc.nvim'
Plug 'dense-analysis/ale'
Plug 'puremourning/vimspector'
Plug 'scrooloose/nerdtree'
Plug 'scrooloose/nerdcommenter'
Plug 'sheerun/vim-polyglot'
Plug 'yggdroot/indentline'
Plug 'tpope/vim-surround'
Plug 'kana/vim-textobj-user'
  \| Plug 'glts/vim-textobj-comment'
Plug 'janko/vim-test'
Plug 'vim-scripts/vcscommand.vim'
Plug 'mhinz/vim-signify'
call plug#end()

당신은 그들이 무엇을 볼 수 각각을 구글 수 있습니다.


11

1- 무성한 ctag를 설치하십시오. osx를 사용하는 경우이 기사는 약간의 트릭을 보여줍니다. http://www.runtime-era.com/2012/05/exuberant-ctags-in-osx-107.html

2- 디렉토리에만 파일에 대한 ctag 만 포함 시키려면 디렉토리에서 다음 명령을 실행하십시오.

ctags -R

그러면 "태그"파일이 생성됩니다.

3- Ruby를 사용하고 있고 보석에 ctag를 포함 시키려면 (이것이 RubyMotion과 내가 개발 한 로컬 보석에 정말 도움이되었습니다), 다음을 수행하십시오.

ctags --exclude=.git --exclude='*.log' -R * `bundle show --paths`

크레딧 : https://coderwall.com/p/lv1qww (vim 대신 emacs에 대한 태그를 생성하는 -e 옵션을 생략했습니다)

4- ~ / .vimrc에 다음 줄을 추가하십시오

set autochdir 
set tags+=./tags;

(반 콜론 인 이유 : http://vim.wikia.com/wiki/Single_tags_file_for_a_source_tree )

5- 당신이 따르고 싶은 단어로 이동하고 ctrl + ]; 되돌아 가려면 ctrl+o(출처 : https://stackoverflow.com/a/53929/226255 )를 사용하십시오.


언급 된 Mac 기사에 대한 링크가 손상되었습니다. 여기에 업데이트 된 링크는 다음과 같습니다 runtime-era.blogspot.com/2012/05/... 가장 좋은 방법은 브루 같은 도구로 ctags를 설치하는 것입니다
ZaydH

6

두 번째 Paul의 답변 : 그렇습니다. ctags (특히 무성한 ctags ( http://ctags.sourceforge.net/ ))는 훌륭합니다. 나는 이것을 vimrc에 추가 했으므로 전체 프로젝트에 대해 하나의 태그 파일을 사용할 수 있습니다.

set tags=tags;/

2

설치하십시오 cscope. 그것은 매우 ctags강력하지만 더 강력하게 작동합니다 . 대신, 정의로 이동하려면 Ctrl+ ]수행 Ctrl+ \+ g. 물론 둘 다 동시에 사용할 수 있습니다. 그러나 큰 프로젝트 (리눅스 커널)에서는 cscope가 훨씬 앞서 있습니다.


1

ctags를 생성 한 후 vim에서 다음을 사용할 수도 있습니다.

:tag <f_name>

위의 기능 정의로 이동합니다.

당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.