Vim에서 변수 이름 변경


95

많은 단일 문자 변수 이름을 포함하는 Vim을 통해 많은 C / Perl 코드를 읽으려고합니다.

코드를 읽는 동안 변수의 이름을 좀 더 의미있는 것으로 변경하여 나머지 부분을 더 빨리 읽을 수 있도록 도와주는 명령이 있으면 좋을 것입니다.

Vim에이 작업을 신속하게 수행 할 수있는 명령이 있습니까?

나는 정규식이 작동하지 않을 것이라고 생각합니다.

  1. 동일한 단일 문자 이름은 다른 범위 지정 블록에서 다른 목적을 가질 수 있습니다.

  2. 동일한 문자 조합이 다른 큰 변수 이름의 일부이거나 문자열 또는 주석 일 수 있습니다.

알려진 솔루션이 있습니까?

답변:


197

다음은 현재 범위에 정의 된 변수의 이름을 변경하는 방법 {}입니다.

변수 사용법으로 커서를 이동하십시오. 를 누릅니다 gd. 즉, 커서를 정의로 이동합니다. Now Press- [{스코프 시작으로 이동합니다. V-를 누르면 비주얼 라인 선택이 켜집니다. %-버튼을 누르면 반대쪽으로 점프 }하여 전체 스코프를 선택합니다. 누르기 :s/-대체 명령 시작. <C-R>/-변수 이름 (누르기 전에 사용했던 이름)과 일치하는 패턴을 삽입 gd합니다. /newname/gc<CR>-검색을 시작하고 매 경기마다 확인으로 대체합니다.

이제 매크로를 기록하거나 더 나은 방법으로 키를 매핑해야합니다.

최종 매핑은 다음과 같습니다.

" For local replace
nnoremap gr gd[{V%::s/<C-R>///gc<left><left><left>

" For global replace
nnoremap gR gD:%s/<C-R>///gc<left><left><left>

이것을 당신에게 .vimrc두거나 그냥 실행하십시오. 이 후 gr로컬 변수를 누르면 :s명령을 입력 new_variable_name하고를 누르기 만하면 Enter됩니다.


40
내가 전에 알아야 할 5 가지 이상의 새로운 Vim 트릭을 배우면 +1. 감사합니다
Kenny Meyer

6
참고 : gd는 macvim의 Javascript 모드에서 정의의 즉각적인 범위에서 변수를 찾는 데 작동하지 않습니다. 파일의 일부 함수에서 변수 이름을 처음으로 사용하는 방법으로 이동합니다. (일부 범위 내에 있고 해당 범위를 선택하려는 경우 "va {"- "{"주위의 시각적 선택-가는 방법입니다. 나는 생각한다.
Srikumar

3
약간 개선 된 버전 : gist.github.com/048616a2e3f5d1b5a9ad의 메시지 사용자, 쇼 옛 이름은 위치에 커서 복원 후 교체
앤디 레이에게

7
+1 아주 좋은 vimgineering (나는 방금 새 용어를 만든 것 같습니다). 참고 : 실제로 콜론 ( :)을 두 번 눌러야 했습니다. 처음 눌렀을 때 :'<,'>. 내가 s/거기에서 입력하면 작동하지 않았습니다. 나는 s/.
Kelvin

6
<C-R>대체 명령 에는 필요하지 않습니다 . 단순히 검색을 생략하면 vim이 마지막으로 검색된 패턴을 사용하게됩니다.이 경우에는 gd명령 에서 생성되었습니다 . 따라서 단순히하는 :s//<newname>/gc것으로 충분합니다.
shangxiao

10

AFAIK, VIM에는 실제 리팩토링 지원이 없습니다. 리팩터링 목적으로 이름을 바꿀 때 일반적으로 다음 예방 조치를 취합니다.

  1. 마크를 사용하여 변경 범위를 제한하십시오.
  2. 정규식을 입력 할 때 이름을 \ <및>로 묶습니다. 이렇게하면 전체 단어와 일치하여 발생하는 잘못된 이름 변경 유형을 줄일 수 있습니다.
  3. 잘못된 교체 가능성을 줄이기 위해 여러 줄로 교체하지 마십시오.
  4. 작은 변화가 아니라면 코드 차이를주의 깊게 살펴보십시오.

내 최종 변경은 다음과 같습니다.

:'a,'bs/\<foo\>/bar

나는 VIM을위한 리팩토링 도구가 없다는 것에 대해 틀리고 싶지만 나는 그것을 보지 못했습니다.


Perl에서는 검색 패턴에 유형을 추가 할 수도 있습니다. 즉, 스칼라의 경우 $, 배열의 경우 @, 해시의 경우 %
Nathan Fellman

@Nathan : 안타깝게도 Perl (5.X)에서는 사용법에 따라 배열 및 해시의시길이 변경되므로 조금 더 어렵습니다. % hash-> whole hash, $ hash {key}-> single value, @hash { qw / ab /} 해시 슬라이스.
user55400

9

나는 그것이 오래된 질문이라는 것을 알고 있으며 @ mykola-golubyev의 방법은 분명히 OP 질문의 특정 경우에 대한 최선의 대답입니다 (동일한 var 이름을 가진 여러 블록을 가질 가능성이있는 난독 화 된 코드를 거치고 있다고 가정합니다) ; 그러나 Google 검색에서 여기에 오는 많은 사람들이 VIM에서 변수 이름을 변경하는 덜 상황 별 방법을 찾는 것과 같은 질문 이름을 사용하면 더 간결 할 수 있습니다.

나는 아무도 이렇게 제안하지 않았다는 것에 놀랐다.

* :s// NEWNAME /gc

*과 동일 gn는 커서 아래의 단어의 다음 선두로부터 검색하고 마지막 패턴을 검색하게 당신은 대체 명령에서 검색 패턴을 생략 할 때, VIM은이 검색 할 패턴이다 가정 -.

소량의 var 사본의 경우 더 빠른 사본 :

* cw NEWNAME <esc> 그런 다음 n.다른 항목에 대해 반복

발생을 검색 cw하기위한 명령입니다 변경 단어 , n마지막 검색 용어의 다음 항목으로 이동하고 .(있는 마지막 명령 반복 NEWNAME으로 변경 단어 )

(이 모든 것을 아는 크레딧은 Reddit의 @doomedbunnies 로 이동합니다 )

또 다른 멋진 트릭은 다음과 같습니다. ( @ nobe4 크레딧 )

* cgn NEWNAME <esc> 그런 다음 .다른 항목에 대해 반복

cgn"(다음 항목 찾기)의 결과를 변경하십시오"입니다. 이제이 명령마지막 명령n 이므로 다음 항목으로 이동 하는 데를 사용할 필요가 없습니다 . 따라서 다시 스트로크 횟수가 줄어들고 더 중요한 것은 n.. 그러나 분명히 이것은 발생을 건너 뛸 수있는 방법이 없다는 단점이 있습니다.

다음은 몇 가지 이점입니다.

  • 매핑이없고, .vimrc (또는 init.vim)가 없으므로 어떤 VIM 복사본에서도 사용할 수 있습니다 (예 : VPS를 구성하는 방법이 '빠른'목적을 무력화하는 일부 VPS 또는 친구의 컴퓨터에서 빠른 작업) )
  • 사용 *또는 gn단어 선택이 매우 빠르게 - 하나의 키 입력 (물론,의 1.5을 가정 해 봅시다)
  • 를 사용 *하거나 gn다른 단어 안에 일치하는 항목이 없는지 확인합니다 :%s/<C-R>//gc. :%s/\<OLDNAME\>/NEWNAME/gc손으로 타이핑하는 것 보다 낫습니다 . 저는 개인적으로 \<단어를 전체 단어로만 제한 하는 데 사용하는 것을 잊는 경향이 있습니다.
  • 스코프를 사용하지 않으면 n원치 않는 일치를 건너 뛰기 위해 몇 번의 추가 스트로크 만 발생합니다. 아마 범위를 제한하는 데 필요한 추가 스트로크보다 더 적을 것입니다. 정상적인 상황에서 변수는 어쨌든 특정 코드 블록으로 다소 지역화 될 가능성이 큽니다.

8

이것을 .vimrc에 넣으십시오.

" Function to rename the variable under the cursor
function! Rnvar()
  let word_to_replace = expand("<cword>")
  let replacement = input("new name: ")
  execute '%s/\(\W\)' . word_to_replace . '\(\W\)/\1' . replacement . '\2/gc'
endfunction

그것을 부르십시오 :call Rnvar()

expand("<cword>")커서 아래에 단어를 가져옵니다. 검색 문자열을 사용하는 %파일 범위에 대한, 그리고 \(\W\)패턴은 대체 할 수있는 단어의 경계에서 비 단어 문자를 찾습니다 변수에 저장 \1하고 \2있으므로으로는 대체 패턴으로 재 삽입 할 수 있습니다.


3

전역 검색에서 'c'수정자를 사용하고 각 교체에 대한 확인을 요청하는 교체를 사용할 수 있습니다. 시간이 더 걸리지 만 엄청난 코드 파일에서 작동 할 수 있습니다.

%s/\$var/\$foo/gc

c는 확인을 나타냅니다.


i는 무시 케이스를 나타냅니다. c를 원하고 모든 변경 사항을 확인하십시오.
Michael Kristofik

죄송합니다. 죄송합니다. 답변 수정
Adnan

답변이 아직 완전히 수정되지 않았습니다.)
user55400

탈출 한 $를 의미 했습니까? 그것은 제 개인적인 취향입니다. $는 이스케이프 없이도 작동하며 정규식 세계와 vi에서 $에는 특별한 의미가 있기 때문에 명확성을 위해 이스케이프하는 것을 좋아합니다.
Adnan

0

c에서는 cscope를 사용하여 약간의 진전을 이룰 수 있습니다. 구문을 이해하려고 시도하므로 문자가 언제 변수인지 알 수 있습니다.


0

이것이 여러 파일에 걸쳐있는 경우 sed를 살펴볼 수 있습니다. find를 사용하여 파일과 xargs 및 sed를 가져 와서 교체하십시오. * .c와 일치하는 모든 파일에서 a를 a_better_name으로 바꾸고 싶다면 다음을 수행 할 수 있습니다.

찾기 . -name "* .c"| xargs sed -i -e 's / a / a_better_name / g'

이것은 a의 모든 발생을 대체하므로 더 강력한 정규식을 원할 수 있습니다.

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