순수한 vimscript로 대체 (`: s`없이)


12

내 vimrc에 다음이 있습니다.

func! AddSpaceBeforeEqual()
  s/\([a-z)_0-9"'\[\]]\)=/\1 =/ge
endfunc

vint 를 사용하여 vimrc를 보푸라기하고 다음 경고가 표시됩니다.

의도하지 않은 부작용이있는 명령 금지 의도하지 않은 부작용이있는 명령은 피하십시오. : s [ubstitute]는 커서를 이동하고 오류 메시지를 인쇄하므로 사용하지 마십시오. 스크립트에 더 적합한 함수 (예 : search ())를 선호하십시오. 많은 vim 명령의 경우 부작용이 적은 동일한 기능을 수행하는 함수가 있습니다. 내장 함수 목록은 : help functions ()를 참조하십시오. Google Vimscript 스타일 가이드

그러나 나는 그들이 :s명령 을 사용하지 않고 대체를 수행하는 방법이라고 생각하지 않습니다 .

예를 들어, search()함수는 패턴과 일치하는 행을 제공하지만 대체 방법은 없습니다. 이 substitute()함수는 문자열에서 작동하며 전체 파일을 대체하지 않습니다.

대체 방법을 직접 구현해야합니까, 아니면 함수를 다시 작성하는 것이 더 똑똑한 방법입니까?

답변:


10

다음은 다음과 substitute()같이 작성된 간단한 함수 구현입니다 .

function! AddSpaceBeforeEqualInWholeBuffer()
    let l = 1
    for line in getline(1,"$")
        call setline(l, substitute(line, '\([^= ]\)=', '\1 =', "g"))
        let l = l + 1
    endfor
endfunction

검색 패턴을 취향에 맞게 조정하십시오.


10

의도하지 않은 부작용에 대해 경고하는 이유 :substitute는 커서를 이동하고 이전 검색을 덮어 쓰기 때문입니다 (함수 외부에서 사용하는 경우) . 그러나의 부작용을 되돌릴 수 있으므로 사용해서는 안된다는 의미는 아닙니다 :substitute. 예를 들어 다음은 replace 명령을 사용하여 후행 공백을 제거하는 함수입니다.

function! StripTrailingWhitespace()
    " Save cursor position
    let l:save = winsaveview()
    " Remove trailing whitespace
    %s/\s\+$//e
    " Move cursor to original position
    call winrestview(l:save)
    echo "Stripped trailing whitespace"
endfunction

참고 당신은 또한 사용할 수 :mark커서 위치를 저장하는 명령을, 그러나 그것은 또한 당신이 사용하기로 결정 마크를 덮어 쓰기된다는 것을 의미합니다. 나는 이전에 빈트를 사용하지 않았지만, 린터에 대한 한 가지 팁은 소금 한 알로 경고를 할 수 있다는 것입니다. 이 경우 :substitute부작용이있는 것은 사실 이지만 예방할 수있는 부작용입니다. 또한 실제로 파일을 검색하고 바꾸는 더 좋은 방법은 없습니다.


6
마지막으로 사용한 검색어는 기능을 떠난 후 자동으로 복원되므로 기능 내에서 사용할 때 필요하지 않은 저장 및 복원이 가능합니다. 참조:help function-search-undo
Martin Tournoij

1
오히려 cursor () 대신 winsaveview () / winrestview ()를 사용하십시오.
Christian Brabandt

1

:s명령은 순수한 Vimscript 접근 방식입니다.

내 생각에 경고는 단지 사용 후 커서가 잘못 배치 될 가능성이 높다는 것을 의미합니다 (사용 winsaveview()전후 에 함수를 사용 하여 winrestview()commmand 를 사용하여 우회 할 수 있음 ). 또한 발생할 수있는 가능한 오류를 처리해야합니다. 일반적으로 e플래그 를 사용하여 처리됩니다 . 또한 깃발 gdefault의 의미를 뒤집는 설정과 같은 일부 설정을 처리해야합니다 g.

이러한 세부 사항을 관리해야하며 이는 해당 경고의 근본 원인 일 수 있습니다. 그러나 이것이 :s명령 사용을 피한다는 의미는 아닙니다 . :s현재 버퍼에서 무언가를 바꾸려면 명령 을 사용하는 것이 좋습니다 .

(물론 모든 줄을 반복하고 search () / getline () / setline () 접근 방식을 사용할 수는 있지만 일반적으로 느립니다.)

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