Vim에서 외부 명령을 사용하여 선택한 단어와 줄을 수정하는 방법은 무엇입니까?


22

다른 편집자에게 유용한 것으로 다음과 같은 기능이 있습니다.

  • 선택한 텍스트를 가지고
  • 외부 명령을 실행하고 선택을 전달하십시오. stdin
  • 외부 명령을 사용 stdout하여 현재 선택을 대체하십시오.

이렇게하면 기본 io를 할 수있는 모든 언어를 사용하여 선택에서 작동하는 유용한 텍스트 도구를 작성할 수 있습니다.

선택을 사용하여 vim으로 어떻게 이것을 할 수 있습니까? ... 단일 문자, 단어, 단락 등

(명령 행에서 직접 또는 키 바인딩을 통해?)


노트

!sort라인 레벨에서 작동하는 것과 같은 명령 은이 질문을하는 이유는 선택 작업을 수행하기 때문입니다. (즉, x눌렀을 때 제거 될 텍스트 ).

답변:


17

종종 가장 쉬운 방법은 비주얼 모드를 사용하여 v(또는 V전체 줄을 선택하는 데 대문자 ) 파이프하고 싶은 텍스트를 선택하는 것입니다.

그런 다음 다음을 입력하십시오.

:!cat

이것은 유용한 기능을 수행하지 않습니다. 내가 자주 사용하는 유용한 명령은 다음과 같습니다.

:!python -m json.tool

JSON 형식을 지정합니다.

시각적 모드없이 입력 만 할 수도 있습니다.

:<range>!command

예를 들어, 전체 파일의 경우 :

:%!python -m json.tool

또는 현재 줄의 경우 :

:.!python -m json.tool

이것과 함께 사용하는 또 다른 유용한 도구는 sort명령입니다.
코디 폴

4
@CodyPoll Vim의 문제점은 무엇입니까 :sort?
Martin Tournoij

5
@Carpetsmoker 외부 정렬 명령에는 더 많은 옵션이 있으며 (로케일 등에 따라) 다른 순서를 생성합니다.
derobert

1
한 줄에서 한 단어를 선택하면 작동하지 않습니다. (질문은 단어 수준 선택을 언급합니다)
ideasman42

@ ideasman42 오른쪽 ... 내가 원래 "선으로이 질문을 읽어 생각 이나 대신"라인의 말씀 " 라인, 비 명백한 UNIX 프로그램 작업입니다 단어 이렇게, 어떤 경우에는 ... 단어를"및 빔 예외는 아닙니다. 나는 몇 가지 실험을하고 해결책을 얻었지만 잘 작동하지 않습니다 ... 아마도 내 접근 방식이 잘못되었을 수 있으므로 며칠 동안 그대로두고 나중에 다시 돌아올 것입니다.
Martin Tournoij

7

나는 이것을 도울 수있는 express.vim 이라는 플러그인을 작성했습니다 . 플러그인은 g=모션 (또는 시각적 선택)을 통해 VimScript 표현식을 평가할 수 있는 연산자 를 정의합니다 . v:val모션이 적용되는 텍스트 (또는 다시 시각적 선택)의 자리 표시 자로 사용할 수있는 표현식을 요구합니다 .

이 경우 유용한 표현식은 system()외부 명령을 실행하는 함수를 사용합니다 .

system('tr a-z A-Z', v:val)

(여기서는 tr간단한 예제 외부 명령으로 사용했습니다.)

이 문제에 대해 express.vim을 사용하는 방법은 Visual 모드에서 텍스트를 선택한 다음 g=해당 표현식 을 입력 하고 다음을 누르는 것입니다 Enter.

g=system('tr a-z A-Z', v:val)<CR>

나는 사용하기 쉽지 않다는 것을 인정할 것이다. (사실, 나는이 플러그인을 거의 사용하지 않습니다!) 식을 시작하는 것과 같은 외부 명령을 호출하는 바로 가기를 추가하는 것을 고려하고 !있습니다. 내가 그렇게하면 업데이트를 여기에 게시 할 것입니다.

편집하다

!외부 명령으로 시작하는 표현식을 처리하도록 express.vim을 수정했습니다 . 따라서 tr예제를 사용하면 위의 내용이 훨씬 간단 해집니다. 시각적 선택 후 다음을 입력하십시오.

g=!tr a-z A-Z<CR>

설명:

  1. 다음과 같이 express 연산자를 호출하십시오. g=
  2. !tr a-z A-Z표현식으로 입력
  3. 프레스 Enter

4

Vim에서 필터 명령을 찾고 있습니다. 참조하십시오 :help filter. 관련 문서는 다음과 같습니다.

!{motion}{filter}   Filter {motion} text lines through the external
                    program {filter}.
!!{filter}          Filter [count] lines through the external program
                    {filter}.
{Visual}!{filter}   Filter the highlighted lines through the external
                    program {filter} (for {Visual} see |Visual-mode|).
                    {not in Vi}

:{range}![!]{filter} [!][arg]               *:range!*
                    Filter {range} lines through the external program
                   {filter}.  ...[See documentation for details]

입력 5!!sort하면 커서에서 시작하여 다음 5 줄이 정렬 됩니다 .


한 단어를 필터링 할 수 있습니까? (라인 레벨 아님)
ideasman42

예. 세 번째 옵션 (비주얼 모드)은 강조 표시된 항목 (단어, 부분 라인, 여러 줄, 사각형 블록 등)에 적용됩니다.
Sameer

1
세 번째 옵션은 또한 전체 라인을 필터링합니다. 하나의 단어를 선택하고 예를 들어 through를 통해 필터링하면 tr [:lower:] [:upper]vim이이 단어뿐만 아니라 전체 줄을 대문자로합니다.
maria s

0

다음과 같이 수행 할 수 있습니다.

  1. 원하는 것을 시각적으로 선택
  2. s^R=system('tr a-z A-Z', @")[:-2]^M( ^RCtrl + R, ^ M은 ENTER)

또한 selection + replace 같은 작업을 수행 할 수 있습니다 ci"^R=....


여러 줄 텍스트 선택에서 이것을 실행할 때 ( v커서를 누른 후 움직 인 후 ) 오류가 발생합니다 E16: Invalid range\nE16: Invalid range\nE476: Invalid command(Linux tr에서는 다른 기본 명령이 존재합니다).
ideasman42

s삽입 모드로 들어가거나 :s명령 을 눌렀 습니까?
Luc Hermitte

의심의 여지가 없지만 어떻게 의미하는지 확실하지 않은 경우, 아마도 예제가 이것을 키에 바인딩하는 방법을 보여줄 수 있습니까?
ideasman42

s비주얼 모드에서 직접 치는가, 아니면 :먼저 치는가 ? :내가 작성한 일련의 키 에는 관여 하지 않습니다 . 매핑은 다음과 같습니다 vnoremap µ s<c-r>=system('tr a-z A-Z', @")[:-2]<cr>.
Luc Hermitte
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.