d [count] d를 어떻게 매핑 할 수 있습니까?


18

NB입니다 하지 의 중복 은 "d3fg"명령 작업을 수행하는 방법? 투표하기 전에 읽어보십시오!

작은 삭제가 큰 삭제 작업을 수행하려는퀘스트 에서 약간의 어려움을 겪었습니다 . 내가 가진 문제는과 같은 명령을 다시 매핑하는 방법을 알 수 없다는 것 d3d입니다. 사실, 나는 그들이 처음부터 어떻게 작동하는지 이해할 수 없으며 Vim의 도움으로 그에 대한 언급을 찾을 수 없습니다. *

d3j간단합니다 : d연산자를 3j동작에 적용합니다 .

3dd또한 "직접 dd"이 3 인 명령을 실행합니다 .

d3d 그것은 간단 해야하는 것처럼 보이며d 연산자를 적용 합니다 ...하지만 무엇 3d입니까? 움직임이 아닙니다. 3d자체적으로 입력 하는 경우 Vim은이 값을 연산자 다음에 카운트로 취급하고 추가 입력을 참을성있게 기다립니다.

그리고 다른 연산자에는 연산자를 적용 할 수 없습니다. dd도움말에는 두 연산자의 시퀀스로 설명되어 있지 않습니다. 별도의 2 키 스트로크 명령입니다. ( dc아무것도하지 않는 참조 )

또한 두 번의 키 입력이 필요한 명령에 대해 개수를 유연하게 배치 할 수없는 것 같습니다 2gj. 커서를 두 화면 줄 아래로 이동하지만 g2j처음 두 키 누르기를 완전히 버리고 커서를 한 줄 아래로 이동합니다.

어떻게 작동합니까? 이것은 Vim의 내부 코드에서 특별한 경우입니까? d[count]d매핑을 만들 수있는 방법이 있습니까?

편집 : 텍스트 개체입니까? :h text-objects"텍스트 개체 선택 명령" 목록에는 포함 되지 않지만 "작은 개체에서 큰 개체로 그룹화 된"삭제 목록에는 dd 포함됩니다. 그리고 d2aw커서 아래의 단어와 다음 하나를 삭제한다. 반면에, c2d아무것도하지 않습니다.

* 나는 그들에 대한 언급이 있어야한다고 확신하지만 찾을 수는 없습니다. 나는 읽었습니다 :help deleting, :help motion.txt그리고 노력 :helpgrep dNd1-9에서 N의 모든 값에 대해 .


2
나는 마지막 d이 확인의 역할을 한다고 생각한다 . 따라서와 동일합니다 d3<CR>. y3yc3c도움, VI (1), NVI (1) 또는 POSIX 사양 ...이 글은 같은 동작합니다 수행합니다 또한 빔 중 하나에 불구하고 나는이에있는 모든 문서를 찾을 수 없습니다 ... 동일하게 작동 vi하고 nviBTW .
Martin Tournoij 2016 년

1
어떤 식 으로든 dd동일합니다 d_. _( [count]-1) 번째 줄 의 첫 번째 공백이 아닌 커서로 커서를 가져옵니다. 그러나 줄 단위이므로 연산자와 쌍을 이루면 전체 줄에서 작동합니다. 따라서 두 ds 사이에 카운트가 나타날 수 있습니다 .
tommcdo

답변:


28

운영자 보류 모드

Vim은 연산자 (예 d: c, 또는 gU)와 모션 (예 w: i},, 또는 /foo<CR>)을 입력 할 때 연산자 보류 모드에 있습니다. 다음을 사용하여 이에 대한 매핑을 만들 수 있습니다 :omap:onoremap.

예제에서는 Operator-pending d을 로 매핑하겠습니다 w. 이것은 실제로 당신이 그것을 사용하기를 원했기 때문에 무작위 선택입니다.

오맵 만들기

d운영자 보류 모드에 대한 맵핑을 작성 하십시오. 여기서 VimScript를 작성한다고 가정 할 것입니다 (예 :) . .vimrc:의 s를 생략 합니다.

onoremap d w

이처럼 dd행동 dw합니다. 또한 d[count]d같은 행동을 d[count]w합니다. 그러나 나는 당신이 dd(즉, [count]공급 되지 않은 ) 행동에 영향을 미치지 않기를 바랍니다 .

식 매핑

식 매핑을 사용하면 VimScript 식을 평가하여 매핑의 오른쪽을 생성 할 수 있습니다. 표현식은 문자열로 평가되어야합니다. 표현식 매핑은 <expr>키워드 로 표시됩니다 .

Vim에는 다양한 시간에 채워지는 내장 변수가 있으며 종종 매핑 중에 유용합니다. 그 중 하나는 v:count은 IS하는 [count]운영자 나 움직임에 공급된다.

이 모든 것을 하나로합시다. 어떤이 경우 [count]공급, v:count수 없습니다 0. d이 경우 에만 사용하도록 매핑에 지시 할 수 있습니다 .

onoremap <expr> d v:count == 0 ? 'd' : 'w'

이제 dd기본값 d[count]d처럼 작동 하지만 (행을 삭제함), 처럼 동작 d[count]w합니다. 멋있는!

d운영자 이후에 사용하도록 제한

그래도 뭔가 알아 차릴 수 있습니다. 이제는 다음 cd과 같이 동작 cw합니다. 이것은 문제가되지 않을 수도 있지만, 완전성을 위해 제한하여 d운영자 후에 만 작동하도록하십시오 .

Vim에는 v:operator가장 최근에 사용한 연산자를 포함하는 또 다른 변수 가 있습니다. 특별한 일을하기 전에 그 내용도 확인해 봅시다.

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : 'w'

참고 : 때문에 :map명령이 함께 체인 될 수있다 |, 우리는 여기에 우리의 식을 탈출해야합니다. 따라서 논리 OR 연산자 ||가됩니다 \|\|.

쿨, 그렇게 cd하고 c[count]d다시 그들은 예전처럼 아무것도하지에 있습니다. 이것은 다른 플러그인이 정의 할 수 있도록하는 것이 좋습니다 cd.

다른 동작을 삭제하고 싶지 않습니다.

d[count]d완전히 다른 무언가 에 매핑 하고 싶 거나 텍스트 삭제와 아무런 관련이 없다면 우리도 그 일을 할 수 있습니다.

일반 모드에서 명령을 입력 할 때 실수로 명령을 입력하기 시작하면 <Esc>해당 명령을 취소 할 수 있습니다 . 매핑에도 동일하게 적용됩니다.

d[count]d현재 줄을 무엇이든 바꾸 도록합시다 [count].

onoremap <expr> d (v:count == 0 \|\| v:operator != 'd') ? 'd' : '<Esc>cc' . v:count . '<Esc>'

매핑의 마지막 부분은 VimScript 식 <Esc>cc' . v:count . '<Esc>'입니다. 그건 <Esc>보류중인 취소하려면 d다음 명령을 cc, 현재 행을 변경할 수 v:count의 값을 입력 [count](삽입 모드)를, 그리고 <Esc>일반 모드로 돌아갑니다. VimScript 연결 연산자를 사용하여 여기에 문자열을 작성합니다 ..


실제 사용 사례는 여기에 설명 된 내용과 다를 수 있지만 볼이 구르는 데 도움이되기를 바랍니다.

행복한 바이 밍!


좋은 답변입니다! 공감. 질문이 시작될 때 내 유스 케이스 (vi.SE에도 있음)에 연결했지만 놓친 것 같습니다. 기본적으로 :omap d d(!) 를 수행해야 하지만 불행히도 운영자 보류 모드는 사용자 정의 연산자 기능을 설정하는 d에 대한 매핑으로 인해 실제로 도달하지 않습니다. d3d그래도 작업 방식 을 조정하여 원하는 방식으로 조정할 수 있기를 바랍니다 . (당신이 어떤 아이디어가 있는지 알려 주시거나 원하는 경우 다른 질문에 대한 완전한 해결책을 자유롭게 게시하십시오.) 곧 알아낼 수 없다면, 나는 이것을 받아들이고 다른 더 구체적인 질문을 게시 할 것입니다. 감사!
Rich

1
사실, 두 번째 생각에, 나는 이것을 지금 받아들이고 있습니다. 이러한 매핑을 만드는 방법과 내가 요청한 두 가지 인 후드에서 작동하는 방법을 설명했습니다.
Rich
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.