Vim에서 리팩토링


99

물론 IDE에서 리팩토링 할 수 있다는 사실은 많은 사람들에게 귀중한 일입니다. 코딩 할 때는 거의하지 않지만 다른 소스를 편집 할 때는 시도해 볼 수 있습니다. Vim의 여러 파일에서 이러한 사소한 작업을 어떻게 수행합니까?

Ruby 리팩토링을위한 이 플러그인 을 찾았 지만 "모든"언어는 어떻습니까?


2
리팩토링은 언어별로 매우 다릅니다. 관심있는 각 언어에 대한 특정 부가 기능을 찾아야합니다. 아마도 일부 부가 기능은 찾을 수 있고 다른 언어는 찾을 수 없을 것입니다. 원하는 것이 있고 찾을 수없는 경우, 야심이 있다면 다른 유사한 언어에 대한 기존 추가 기능을 시작점으로 사용하여 하나를 작성해 볼 수 있습니다.
Steve Jorgensen 2012 년

2
VIM은 단일 파일 편집을 중심으로 설계되었으며 프로젝트가 아닌 디렉토리 아래의 파일 일 수도 있습니다 . IDE에서 지원하는 많은 리팩토링은 전체 프로젝트의 파일에 영향을줍니다 (예 : 클래스 이름 변경). (g) VI (m)과 같은 편집자에게 "올바르게"만드는 것이 까다로울 것이라고 생각합니다. 회사 나 큰 프로젝트가 그것을 받아 들여야한다고 생각합니다. 기본적으로 간단한 문자열 대체를 피하기 위해 각 언어를 구문 분석해야하고 오류 (ctags 가이 중 일부 를 제공함 )와 해당 프로젝트 유형 (편집 할 파일을 알기 위해) 이 발생하기 쉽습니다 .
Merlyn Morgan-Graham

1
의견을 보내 주셔서 감사합니다. 이것이 까다로워지기 시작하는 곳이며 VIM을 IDE로 구부리는 것은 하나의 프로그램을 사용하여 여러 언어를 편집하는 우아한 해결책이 아닙니다. IDE에서 사용할 수있는 "고급"기능 중 일부로 인해 VIM을 포기하고 싶지 않습니다.
Helmut Granda

@ MerlynMorgan-Graham-어떤 사람들은 코드를 몇 개의 파일에 보관합니다. 이 문제를 완전히 방지합니다.
Rook

7
@ldigas : 문제를 해결할 수 있습니다. 그러나 일부 언어 (예 : Java)에 대한 권장 관행에 위배됩니다. 기본적으로 코드는 도구의 요구 사항에 맞게 구부러지며 실제로는 다른 방향이어야합니다.
Merlyn Morgan-Graham

답변:


78

나는 'Vim은 IDE가 아니다'패러다임에 동의합니다. 그러나 IDE가없는 경우가 있습니다. 이러한 상황에서 내가 사용하는 것은 다음과 같습니다.

: grep, : vimgrep, : Ag, : Ggrep

정기적 인 교체와 더 많은 관련이있는 리팩토링 저는 보통 프로젝트 트리에서 : grep 을 사용한 다음 리팩터링을 수행하기 위해 매크로기록합니다 .-: g 및 : s는 생각할 필요가 없습니다. 일반적으로 적은 노력으로 많은 수의 파일을 빠르게 수정할 수 있습니다. 솔직히 다른 것보다이 방법을 더 많이 사용합니다.

워크 플로에 따라 기본 제공 명령이 느리거나 불편할 수 있습니다. git을 사용하는 경우 우수한 Fugitive 플러그인과 해당 :Ggrep명령을 사용하여 git에 체크인 된 파일 만 검색 하고 싶을 것 입니다. 나는 또한 그것의 속도 때문에 Silver Searcher 를 좋아한다 .

: argdo, : cdo 및 : bufdo

: cdo: argdo 는 파일 세트에 대해 vim 명령을 실행하는 데 편리합니다.

명령 줄

변경이 필요한 파일 목록을 결정하는 것이 더 어려울 때는 :vimgrep명령 줄 grep / find 명령을 사용하여 리팩터링해야하는 파일 목록을보다 면밀하게 관리합니다. 목록을 텍스트 파일에 저장하고 :e매크로 기록의 매시업을 사용하여 필요한 사항을 변경합니다.

녹슬지 않을수록 매크로 기록 기술을 유지할수록 Vim이 리팩토링에 더 유용하다는 것을 알았습니다. 레지스터에서 편안한 저장 ​​/ 복원, 레지스터 카운터 변수 증가 / 감소, 나중에 사용하기 위해 매크로 기록을 파일로 정리 / 저장하는 등.


최신 정보

내가 설명하는 방법에 대한이 비디오 캐스트를 더 많이 작성한 이후 vimcasts.org에 게시되었습니다 ( 모든 Vimcast 를 시청 하는 것이 좋습니다! ). 리팩토링의 경우 다음 항목을 확인하십시오.

Vimgolf 는 또한 연습하기 좋은 방법입니다.

이 답변을 작성한 이후 언어 서버 프로토콜 서버의 편재성은 Vim (및 다른 편집자)에게 리팩토링 기능을 제공했습니다. IMO는 용도에 맞게 구축 된 IDE에서 볼 수있는 리팩토링 기능과 동일한 기능을 제공하지 않습니다 (저는이를 사용하고 coc 및 ALE를 선호합니다). 자세한 내용은이 질문에 대한 다른 답변을 참조하십시오!


12
리팩토링은 패턴 매칭 그 이상입니다. 그렇기 때문에이를 안전하게 자동화하려면 IDE가 필요합니다. 분명히 수동으로 할 수 있지만 사용 가능한 옵션과 대부분의 경우 수동으로 수행하는 것이 더 안전하다는 점을 고려할 때 다른 옵션을 고려하는 이유는 무엇입니까?
Cutberto Ocampo 2015

1
@CutbertoOcampo 어느 정도 동의합니다 : 프로젝트의 무수한 측면 (구조, 언어, 직원 기술 및 리소스)에 따라 문제에 적용 할 수있는 훌륭한 리팩토링 도구가있을 수 있습니다. 제 대답은 사실이 아닌 상황에 적용되며 Vim에서 문제를 해결하고 싶습니다.
dsummersl

2
괜찮습니다. 사람들이 오랫동안 선호하는 도구를 사용하여 작업하는 것이 더 편하다고 느낄 수 있으며, 어떤 IDE보다 더 나은 성능을 발휘할 수있는 해킹이 있다는 것을 알고 있습니다. -box 솔루션 나는 실제 IDE가 대부분의 사용자에게 더 잘 수행 될 것이라고 말하고 싶습니다. 나는 80-20 % 종류의 상황을 생각하고있을 것이다 (더욱, 균형은 IDE에 유리함).
Cutberto Ocampo 2015

1
거의 모든 언어에 대한 ide가 있습니다. vim 또는 regex로 리팩토링을 시도하는 것은 정말 미친 소리입니다. 왜 시도하겠습니까?
롤백

1
@rolls는 동료가 필요로하는 컴퓨터를 잡을 수있을만큼 강력해야합니다 ( "단순한 인상"이 아니라 평판과 미래의 위치를 ​​위해).
피 묻은

24

LSP ( Language Server Protocol )

언어 서버 프로토콜에는 프로젝트 전체에서 기호의 스마트 이름 바꾸기 기능이 포함되어 있습니다 .

https://microsoft.github.io//language-server-protocol/specifications/specification-3-14/#textDocument_rename

예를 들어 다음 언어 서버는 이것을 지원합니다.

https://langserver.org/ 에서 더 많은 언어 서버를 찾을 수 있습니다 .

정력

vim 내에서 사용하려면 vim 편집기 클라이언트가 필요합니다. 다음과 같은 옵션이 있습니다.

  1. LanguageClient-neovim ( 녹스 필요)은 매핑을 제안합니다.

    nnoremap <silent> <F2> :call LanguageClient_textDocument_rename()<CR>
    
  2. coc.nvim (node.js 필요)은 매핑을 제안합니다.

    " Remap for rename current word
    nmap <leader>rn <Plug>(coc-rename)
    
  3. 에일

    nnoremap <silent> <Plug>(ale_rename) :ALERename<Return>
    

    Ale은 키 바인딩을 정의하지 않습니다. 이것은 사용자가 수행해야합니다.

  4. vim-lsp 는 다음 명령을 제공합니다.

    :LspRename
    

    Ale과 유사하게 매핑이 제안되지 않습니다. 그러나 물론 다음과 같이 정의 할 수 있습니다.

    nmap <leader>r <plug>(lsp-rename)
    

    ( <leader>r은 귀하의 선택으로 대체됩니다. 대부분의 플러그인이 동의하는 플러그인을 모르겠습니다)

  5. vim-lsc 에는 기본 매핑이 있습니다.

    'Rename': 'gR'
    

LSP를 용이하게하는 YouCompleteMe 도 참조하십시오 .

Neovim

Neovim은 2019 년 11 월 13 일 부터 lsp에 대한 초기 내장 지원을 제공합니다.

LSP의 일반적인 구성은 https://github.com/neovim/nvim-lsp를 참조하십시오.

그러나 스마트 이름 바꾸기가 어떻게 작동하는지 알 수 없었습니다. 누군가가 이것을 알고 있다면이 섹션을 업데이트하십시오.

기타 리팩토링

LSP 프로토콜이 클래스 구조 변경, 메서드 / 함수에 매개 변수 추가 또는 메서드를 다른 클래스로 이동과 같은 더 복잡한 리팩토링을 지원할 계획이 있는지 모르겠습니다. 리팩토링 목록은 https://refactoring.com/catalog/를 참조 하세요 .


불행히도 LSP의 리팩토링에 대한 지원은 현재 최첨단에 비해 상당히 약합니다. github.com/Microsoft/language-server-protocol/issues/61
Mickael

이름을 바꾸는 AFAIK coc-rename는 현재 버퍼에서만 작동합니다. 프로젝트에서 전체적으로 내 보낸 이름의 사용을 업데이트하지 않았습니다 (파일 간).
oligofren

15

파이썬

를 들어 파이썬 플러그인이 제공 정력을위한 '스마트'이름 바꾸기 기능을 다음 언어 :

  • jedi-vim( github )<leader>r
  • ropevim( github )CTRL-c r r
  • python-mode( github ):h pymode-rope-refactoring

13

C- 패밀리

  1. c-family의 이름 변경 리팩토링을 위해 플러그인 Clighter 를 사용해보십시오 . clang을 기반으로하지만 제한 사항이 있으며 플러그인이 더 이상 사용되지 않는 것으로 표시됩니다.

    Clighter제안한 매핑은 다음과 같습니다.

     nmap <silent> <Leader>r :call clighter#Rename()<CR>
    

    후속 플러그인 clighter8커밋 24927db42 에서 이름 바꾸기 기능을 제거했습니다 .

  2. neovim을 사용하는 경우 플러그인 클램프를 살펴볼 수 있습니다 . 그것은 제안

     nmap <silent> <Leader>r :call ClampRename()<CR>
    


4

아마도 가장 우아한 솔루션은 아니지만 매우 편리하다는 것을 알았습니다. ECLIM 을 사용하여 VIM과 Eclipse를 연결합니다. 물론 모든 소스 코드 편집은 VIM에서 이루어 지지만 리팩토링 할 때이 문제에서 Eclipse의 우수한 기능을 활용할 수 있습니다.

시도 해봐.


3

플러그인 Factorus

github에서 사용할 수있는 factorus 라는 리팩토링 전용 vim 플러그인 이 있습니다 .

현재 (2017-12), 언어 지원

  • 씨,
  • 자바 및
  • 파이썬.

3

플러그인 YouCompleteMe (YCM) (github의 별 2 만 개)

http://ycm-core.github.io/YouCompleteMe/#the-refactorrename-new-name-subcommand

:h RefactorRename-new-name

지원되는 파일 유형에서이 명령은 커서 아래에있는 식별자의 의미 론적 이름 변경을 수행합니다. 여기에는 이름 변경 선언, 식별자의 정의 및 사용 또는 기타 언어에 적합한 작업이 포함됩니다. 특정 동작은 사용중인 시맨틱 엔진에 의해 정의됩니다.

과 유사하게이 FixIt명령은 소스 파일에 자동 수정을 적용합니다. 이름 변경 작업에는 여러 파일에 대한 변경이 포함될 수 있으며, 해당 파일은 당시 Vim 버퍼에서 열리거나 열리지 않을 수 있습니다. YouCompleteMe가이 모든 것을 처리합니다. 동작은 다음 섹션에 설명되어 있습니다.

파일 형식에서 지원 : c, cpp, objc, objcpp, cuda, java, javascript, typescript, rust, cs

기본적으로 매핑이 없습니다.


그래서 지금은 자바 스크립트, 타이프 스크립트 및 자바에서만 작동합니까?
SR

2

리팩터링 및 입력 할 이름에 커서를 놓습니다.

gd (또는 gD 전역 변수를 리팩토링하는 경우).

그때

cgn new_name esc

. 다음 항목을 리팩토링하기 위해 한 번 이상

또는

:%norm . 버퍼의 모든 발생을 한 번에 리팩터링합니다.


1

저는 vim에서 많은 C / C ++ 코드를 작성합니다. 내가하는 가장 일반적인 리팩토링은 변수, 클래스 이름 등의 이름을 바꾸는 것입니다. 일반적으로 :bufdo :%s/source/dest/g파일에서 검색 / 바꾸기를 수행하는데, 이는 큰 IDE에서 제공하는 이름 바꾸기와 거의 동일합니다.
그러나 제 경우에는 일반적으로 유사한 엔티티의 이름을 바꾸고 다른 경우 (예 : CamelCase, snake_case 등)로 철자를 변경 했으므로 이러한 종류의 "스마트 케이스"검색에 도움이되는 작은 유틸리티를 작성하기로 결정했습니다. 여기에서 호스팅 됩니다 . vim 용 플러그인이 아니라 명령 줄 유틸리티입니다. 유용하게 사용하시기 바랍니다.


0

리팩토링을 위해 Unite를 사용하고 있다면 (그리고 그래야한다면) vim-qfreplace 를 사용하여 매우 쉽게 만들 수 있습니다. 작동 방식을 보여주는 이 비디오 를 확인하십시오 . 워크 플로가 설정되면 비디오에서와 같은 대부분의 항목을 입력하는 대신 몇 가지 매핑을 만들어 최적화 할 수 있습니다.


0

두 개의 플러그인 조합 : vim-ripgrep 은 파일을 찾아 결과를 quickfix 창에 넣고, quickfix-reflector 는 변경 사항을 quickfix 창에 바로 저장하고 각 변경 사항을 파일 전체에 자동으로 저장합니다.


0

나는 emacs의 spacemacs 버전을 사용하는 것을 고려할 것입니다. Vim과 동일한 모드와 대부분의 키 입력을 사용하지만 lisp 특성 때문에 더 많은 추가 기능이 있습니다. C ++로 프로그래밍하려면 C ++ 레이어를 추가하기 만하면 대부분의 IDE가 이미 설정되어 있습니다. python 또는 bash와 같은 다른 해석 언어의 경우 스페이스 맥을 남겨 둘 필요가 없습니다. 그들은 텍스트 내에서 직접 코드 블록을 실행하는 방법을 가지고 있습니다. 이는 코드와 데이터가 동일한 파일에있는 문학적 프로그래밍 또는 재현 가능한 프로그래밍에 환상적으로 작동합니다. 둘 다 텍스트로 완료됩니다.

Spacemacs는 초기로드에서 훨씬 더 무겁지만이를 사용하여 수행 할 수있는 추가 작업은 몇 초의 시작 비용으로 가치가 있습니다. 하나의 계층 조직 모드는 확인해 볼 가치가 있습니다. 내가 사용 해본 최고의 아웃 라이너, 프로그래머, 주간 타이머 / 할 일 목록입니다.


0

가다

  1. 도구 godoctor ( github )는 여러 리팩토링 기능을 지원합니다.
  • 이름 바꾸기
  • 추출 기능
  • 지역 변수 추출
  • var ⇔ : = 전환
  • Godoc 스텁 추가

vim 플러그인 https://github.com/godoctor/godoctor.vim 이 있습니다.

이름을 바꿀 항목에 커서가있는 경우 :

:Rename <newname>

추출 할 하이라이트 블록 :

:Refactor extract newfunc
  1. vim-go

    • 와 식별자의 정확한 형태 보증 된 이름 변경 :GoRename.
  2. 언어 서버 gopls

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