나는 최근에 vim이 골프, 특히 kolmogorov-complexity에서 어떻게 잘 작동하는지 깨달았습니다 . 또한, 메타 vim 에 따르면 적어도이 사이트의 범위에서 완벽하게 수용 가능한 '프로그래밍 언어'입니다.
Vim에서 골프를 할 때 어떤 일반적인 팁이 있습니까? 코드 골프 문제에 적용 할 수 있고 Vim과 관련이있는 아이디어를 찾고 있습니다 (예 : "댓글 제거"는 답이 아닙니다).
답변 당 하나의 팁을 게시하십시오.
나는 최근에 vim이 골프, 특히 kolmogorov-complexity에서 어떻게 잘 작동하는지 깨달았습니다 . 또한, 메타 vim 에 따르면 적어도이 사이트의 범위에서 완벽하게 수용 가능한 '프로그래밍 언어'입니다.
Vim에서 골프를 할 때 어떤 일반적인 팁이 있습니까? 코드 골프 문제에 적용 할 수 있고 Vim과 관련이있는 아이디어를 찾고 있습니다 (예 : "댓글 제거"는 답이 아닙니다).
답변 당 하나의 팁을 게시하십시오.
답변:
일반적인 명령의 대문자 변형을 알고 있어야합니다. 이를 통해 많은 상황에서 한 번의 키 입력을 간단하게 저장할 수 있습니다. 예를 들면 다음과 같습니다.
A = $a
C = c$
D = d$
I = ^i
S = cc
X = dh
Y = yy
다른 하나는 G
대신에 gg
사용하는 것이지만 카운트를 사용하는 경우에만 사용하십시오! 예를 들어, 카운트가 gg
없으면 처음으로 G
이동하고 끝으로 이동합니다. 그러나 카운트를 사용하면 둘 다 지정한 줄로 이동하므로 5G
보다 짧지 만 같습니다 5gg
.
다른 하나는 H
대신에 사용 하는 gg
것이지만 입력이 기본 행 수보다 많은 것을 차지하지 않을 경우에만 작동한다는 점에 유의하는 것이 중요합니다 (24라고 생각하지만 다를 수 있음).
$
그래서 적어도 불구 C
하고 D
뭔가를 절약 할 수).
G
그리고 gg
해당되지 않습니다. 전자는 버퍼의 끝으로 이동하고 후자는 시작으로 이동합니다.
5G
합니다 5gg
. 예 를 들어와 같습니다 . 그 점에 대해 좀 더 자세히 설명하겠습니다.
명령이 실패 할 때마다 딩 노이즈가 발생하여 현재 매크로가 취소됩니다. 이것을 사용하여 원유 형태의 루프를 만들 수 있습니다. 예를 들어, <foobar>
버퍼에 3 줄 미만이 될 때까지 키 입력을 반복하려는 경우 . 넌 할 수있어
qq<foobar>3G``@qq
이는 다음을 의미합니다.
qq 'Start recording in register q
<foobar> 'Keystrokes
3G 'Go to line 3. If line 3 doesn't exist, this is effectively a "break" statement.
`` 'Jump back to previous cursor location
@q 'Call macro q
q 'Stop recording
vim 세션에서 이것을 테스트하는 경우 @q
매크로가에서로드되기 때문에 의도하지 않은 부작용 이 있을 수 있습니다 .vim_profile
. 이 문제를 해결하려면 몇 가지 방법이 있습니다. 아마도 가장 좋은 해결 방법은 vim을 시작하는 것입니다.
vim -i NONE
을 (를) 삭제할 수도 있습니다 .viminfo
.
이미 vim을 시작한 경우 다음을 입력 할 수 있습니다.
qqq
처음에는 매크로를 0으로 만듭니다.
3G를 대체 할 수있는 다른 조건은 다음과 같습니다.
f<char> 'Jump to first occurence of <char>. Also see F, t and T
또는
<number>| 'Go to the <number>'th character on the current line.
:%s/\n//g
이다 항상 동일합니다
:%s/\n//
이는 또한
:%s/\n
놀랍게도 충분합니다. 일반적으로 플래그가 없으면 :s
표현식 의 마지막 슬래시 는 필요하지 않습니다.
:%s/x
제거하지 않고 각 행의 첫 번째 항목 만 제거 합니다 .
:&&
대체 명령 과 플래그 를 반복하는 데 사용할 수도 있습니다 .
삽입 모드에 있고 단일 일반 모드 명령을 만들고 싶다고 가정 해 봅시다. 다음과 같이 작성할 수 있습니다.
isome_text<esc><foobar>gisome_more_text
그렇게하지 마십시오. 대신을 사용 <C-o>
하여 단일 일반 명령을 실행 한 다음 즉시 삽입 모드로 돌아갑니다.
isome_text<C-o><foobar>some_more_text
<CR>
후를 <foobar>
명령을 보내?
:
, /
또는 ?
)
세 가지 "변경 사례"연산자가 있습니다.
gu "Convert to lowercase
gU "Convert to uppercase
g~ "Toggle case
이들은 연산자이므로 동작을 취하므로 현재 문자를 소문자로 변환하십시오.
gul
재미있는 트릭이 나오는 곳은 다음과 같습니다. :) 단일 문자 또는 현재 줄의 대소 문자를 변경하려면 시각적 모드에서 바이트가 짧습니다. 예를 들어 gul
동등
vu
그리고 gu_
(_는 현재 줄)은
Vu
이 트릭은 시각 모드에서 뒤로 검색을 트리거 하기 때문에 전환을 위해 작동 하지 않습니다.v?
v/
반대 방향으로 이동)을vg?
. 그러나 여기에 ~
연산자를 사용하여 더 많은 바이트를 절약 할 수 있습니다 ! (이 점을 지적 해 주셔서 감사합니다 @Doorknob)
내 vim 답변과 here 및 post의 동등한 V 답변 에서이 트릭이 실제로 작동하는 것을 볼 수 있습니다 .
~
커서 아래 문자의 대소 문자를 전환하고 오른쪽으로 이동하는를 잊지 마십시오 !
"aY
나중에 사용하기 위해 텍스트를 특정 레지스터 (예 :)에 담 그거나 삭제하는 것이 항상 필요한 것은 아닙니다. Vim에는 여러 명령의 주제로 자동으로 채워지는 몇 개의 레지스터가 있습니다. :help registers
모든 내용을 보려면 입력 하십시오. 그러나 다음은 몇 가지 참고 사항입니다.
등록하지 ""
않음 : -마지막으로 삭제되었거나 삭제 된 마지막 텍스트.
번호가 매겨진 레지스터 "0
-마지막으로 눌린 텍스트입니다.
번호가 매겨진 레지스터 "1
–- "9
한 줄 미만이 아니면 삭제 된 마지막 텍스트. "1
채워질 때마다 이전 내용이 등으로 이동됩니다 "2
.
작은 삭제 레지스터 : "-
- 삭제 된 한 줄보다 짧은 마지막 텍스트.
마지막으로 삽입 된 텍스트 : ".
특히, "-
및 "1
레지스터는 예를 들어, 일부 텍스트를 삭제 할 수 있도록 유용한 함께 될 수 dd
에 "1
레지스터와 함께 다른 텍스트를 삭제 D
에 "-
(물론, 의미가 동일하지 않은,하지만 종종이 될 필요가 없습니다 ).
모든 레지스터를 추적하기가 약간 어려울 수 있지만을 입력하여 언제든지 모든 레지스터의 내용을 볼 수 있습니다 :registers
.
이것은 이전 에 대화에서 나왔 으므로 전체 팁으로 게시 할 수도 있다고 생각했습니다.
<C-a>
및 <C-x>
증가와 감소 줄에 다음 번호. 이것은 간단한 수학에 매우 유용한 기능이지만 깔끔한 해킹도 가능합니다.
다음 숫자로 넘어 가야한다고합시다. 예를 들어 변경해야합니다
I need 2 spell better
에
I need to spell better
확실한 방법은 2로 건너 뛰고 다음을 수행하는 것입니다.
sto "Synonymous with 'clto'
이보다 짧기 때문에
:s/2/to<cr>
2로 넘어가는 방법은 여러 가지가 있습니다. 예를 들어
/2<cr>
ww
2w
ee
2e
8|
f2
다른 많은 방법도 있습니다.
이것들은 모두 2 회 이상의 키 스트로크입니다. 그러나 이후 <C-a>
및 <C-x>
뿐만 아니라 증가 /의 감소 번호뿐만 아니라, 다음 숫자로 이동, 우리와 떨어져 바이트를 취할 수
<C-a>sto
종종 텍스트 블록으로 작업하는 경우 (특히 아스키 아트 과제에서) 버퍼의 첫 번째 또는 마지막 문자로 이동해야합니다. G
그리고 gg
꽤 좋은, 그러나 어떤 성가신 일이있다. 예를 들어, 마지막 문자를 얻으려면, 당신은 필요 G$
하고 gg
공백을 선도가 있다면 반드시 첫 번째 열에서 당신을 넣어하지 않습니다. 여기에 더 멋진 움직임이 있지만 텍스트의 중간에 빈 줄이없는 경우에만 작동합니다.
버퍼의 첫 문자 : {
보다 낫습니다 gg0
. 텍스트 중간에 빈 줄이 있으면 go
버퍼의 첫 번째 문자가 무엇이든 사용할 수 있습니다.
버퍼의 마지막 문자 : }
보다 낫다G$
이것들은 또한 연산자에 대한 논증으로서 작용하지만 그것들은 선으로 움직이는 것이 아니라 캐릭터로 움직이는 것입니다!
H
보다 golfier입니다gg
H
는 신뢰할 수 없습니다. 동작은 보이는 창의 크기와 버퍼의 위치에 따라 다릅니다. (이 혼란을 피하기 위해 V로 리 맵핑 됨)
일반 모드와 삽입 모드 모두에서 계산을 수행 할 수 있습니다.
일반 모드에서 입력하면 @=
커서가 명령 행으로 이동하여 표현식을 입력 할 수 있습니다. Enter 키를 누르면 표현식 결과가 일반 모드 명령으로 실행됩니다.
예를 들어, 현재 행의 중간 열로 이동한다고 가정하십시오. 함수 호출 col('$')
은 행의 열 수를 반환하므로 다음을 입력하여 수행 할 수 있습니다.
@=col('$')/2<CR>|
Enter 키를 누르면 커서가 버퍼로 돌아가고 vim은 |
마치 숫자를 입력 한 것처럼 연산자 (예 :)를 기다립니다 . 또는 다음을 입력했을 수 있습니다.
@=col('$')/2.'|'
... 물론 바이트가 더 많습니다.
<Ctrl-r>=
대신을 눌러 표현식 모드를 삽입 모드에서도 사용할 수 있습니다 @=
. 입력 한 표현식의 결과가 삽입 모드에서 실행된다는 점을 제외하고는 일반 모드에서 동일하게 작동합니다. 예를 들어을 입력하면 입력 한 것처럼 <Ctrl-r>=col('$')<CR>
현재 행의 열 수가 커서에 삽입됩니다.
식 레지스터에 대한 자세한 내용을 보려면을 입력하십시오 :help "=
.
마지막으로 사용한식이 식 레지스터에 저장됩니다 "=
. 입력하면 @=<CR>
일반 모드에서 또는 <Ctrl-r>=<CR>
삽입 모드로하면 매크로처럼 많이 사용할 수 있도록 다시 식을 평가합니다.
정규 표현식 대체를 수행 할 때 표현식도 평가할 수 있습니다. 로 교체를 시작하기 만하면됩니다 \=
. 예를 들어,이 파일의 행 번호를 지정한다고 가정하십시오.
foo
bar
baz
함수 호출 line('.')
은 현재 줄 번호를 반환하므로 작업이 쉽습니다. 이것을 입력 :
:s/^/\=line('.').' '/g<CR>
... 원하는 결과를 산출합니다 :
1 foo
2 bar
3 baz
당신이 사용할 수있는 이러한 표현에 캡처 그룹을 사용하려면 submatch()
예를 들어이 기능 submatch(0)
에 해당 \0
일반 교체 교체를 submatch(1)
하는 것과 같습니다 \1
불행하게도, 등, 키 입력의 많은 업이 먹는다.
식 대체에 대한 자세한 내용을 보려면을 입력하십시오 :help sub-replace-expression
.
i1 <esc>bqqywjPb<C-a>@qq@q
5 바이트 더 짧은 순수한 표준 모드 솔루션이 있습니다. 그리고 유닉스에 있다면 할 수도 있습니다 :%!nl
. 그래도 좋은 팁!
매크로의 텍스트를 직접 수정할 수 있으며 복잡한 조건부보다 훨씬 짧을 수 있습니다. 예를 들어 붙여 넣기를 원한다고 가정 해 보겠습니다. N 배, n은 사용자 입력입니다. 나는 이것을 먼저 시도했다.
qq/[1-9]<enter><c-x>``p@qq@q
설명:
qq #Start Recording
/[1-9]<enter> #Search for a number that isn't 0.
<c-x> #Decrement that number
``p #jump back to your previous location and paste.
@q #Recursive call to macro 'q'
q@q #Stop recording, and run the macro
이것은 18 번의 키 입력이며 실제로는 못생긴 방법입니다. 대신 해당 번호의 위치로 이동하여 다음을 수행하십시오.
Ap<esc>"qdd@q
설명:
Ap<esc> #Append a 'p' to the end of the current line.
"qdd #Delete the current line into register q
@q #Run macro q.
이것은 9 번의 키 입력으로 크게 개선되었습니다.
더 짧은 것은 숫자에 대한 매크로를 실행 한 다음 명령을 입력하는 것입니다. 예를 들면 다음과 같습니다.
"qdd@qp
설명:
"qdd #Delete the current line into register q
@q #Run register q
p #Paste
7 개의 키 스트로크.
D
하지 말고을 사용하십시오 dd
. 2. 명령에 레지스터가 포함되어 있지 않으면 더 짧게 만들 수 있습니다. 예를 들어 x
커서 아래의 숫자만큼 문자를 반복하려면 대신을 "qD@qix<esc>
사용하십시오 D@"ix<esc>
.