Vim에서의 골프 팁


32

나는 최근에 vim이 골프, 특히 어떻게 잘 작동하는지 깨달았습니다 . 또한, 메타 vim 에 따르면 적어도이 사이트의 범위에서 완벽하게 수용 가능한 '프로그래밍 언어'입니다.

Vim에서 골프를 할 때 어떤 일반적인 팁이 있습니까? 코드 골프 문제에 적용 할 수 있고 Vim과 관련이있는 아이디어를 찾고 있습니다 (예 : "댓글 제거"는 답이 아닙니다).

답변 당 하나의 팁을 게시하십시오.


4
"vim에서의 골프 팁"과 "vim을 텍스트 편집기로 효율적으로 사용하기위한 팁"은 기본적으로 동일하기 때문에 이것은 특히 유용한 팁 질문입니다.
DLosc

답변:


15

일반적인 명령의 대문자 변형을 알고 있어야합니다. 이를 통해 많은 상황에서 한 번의 키 입력을 간단하게 저장할 수 있습니다. 예를 들면 다음과 같습니다.

A = $a
C = c$
D = d$
I = ^i
S = cc
X = dh
Y = yy

다른 하나는 G대신에 gg사용하는 것이지만 카운트를 사용하는 경우에만 사용하십시오! 예를 들어, 카운트가 gg없으면 처음으로 G이동하고 끝으로 이동합니다. 그러나 카운트를 사용하면 둘 다 지정한 줄로 이동하므로 5G보다 짧지 만 같습니다 5gg .

다른 하나는 H대신에 사용 하는 gg것이지만 입력이 기본 행 수보다 많은 것을 차지하지 않을 경우에만 작동한다는 점에 유의하는 것이 중요합니다 (24라고 생각하지만 다를 수 있음).


1
특히 도전 편집기 골프 (따라서 일반적으로 키 입력에 의해 득점)의 대문자가 아니라 두 개의 키 입력의 경우 (그래서입니다 $그래서 적어도 불구 C하고 D뭔가를 절약 할 수).
Martin Ender 2019

1
키 스트로크 점수를 매길 때 내가 알지 못하는 것은 Shift 키가 필요한 연속 문자가 그룹 당 한 번만 Shift 키를 계산하는지 여부입니다. 실제로 다른 목적으로는 다른 키를 누르는 동안 키를 누르고있을 수 있기 때문입니다.
Alex A.

6
@AlexA. 개인적으로 나는 수정자가 계산해서는 안된다고 생각합니다. 아마 우리는 이것에 대한 메타 게시물이 필요할 것입니다 ...
DJMcMayhem

G그리고 gg해당되지 않습니다. 전자는 버퍼의 끝으로 이동하고 후자는 시작으로 이동합니다.
Jordan

@Jordan 좋은 지적입니다. 카운트가 주어지면 동일하다는 것을 의미 5G합니다 5gg. 예 를 들어와 같습니다 . 그 점에 대해 좀 더 자세히 설명하겠습니다.
DJMcMayhem

11

명령이 실패 할 때마다 딩 노이즈가 발생하여 현재 매크로가 취소됩니다. 이것을 사용하여 원유 형태의 루프를 만들 수 있습니다. 예를 들어, <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.

8

더 짧은 버전의 ex 명령이 있다고 생각합니다. 예를 들어,을 :global단축 할 수 있다는 것을 이미 알고 있었지만 :g, :nnoremap이 값이 :nn?

:h :foo더 짧은 버전이 있는지 확인하기 위해 답에 사용중인 모든 ex 명령 을 실행하는 것이 좋습니다 .


6
:%s/\n//g

이다 항상 동일합니다

:%s/\n//

이는 또한

:%s/\n

놀랍게도 충분합니다. 일반적으로 플래그가 없으면 :s표현식 의 마지막 슬래시 는 필요하지 않습니다.


2
이것은 개행에는 작동하지만 한 줄에 두 번 이상 나타날 수있는 문자에는 작동하지 않습니다. 예를 들어 x의 모든 항목을 :%s/x제거하지 않고 각 행의 첫 번째 항목 만 제거 합니다 .
DJMcMayhem

1
:&&대체 명령 플래그 를 반복하는 데 사용할 수도 있습니다 .
DJMcMayhem

6

삽입 모드에 있고 단일 일반 모드 명령을 만들고 싶다고 가정 해 봅시다. 다음과 같이 작성할 수 있습니다.

isome_text<esc><foobar>gisome_more_text

그렇게하지 마십시오. 대신을 사용 <C-o>하여 단일 일반 명령을 실행 한 다음 즉시 삽입 모드로 돌아갑니다.

isome_text<C-o><foobar>some_more_text

나는 그 공간도 필요하다고 생각하지 않습니다
Fund Monica의 소송

@QPaysTaxes 당신 말이 맞아요. 나는 그것을 더 읽기 쉽게 할 것이라고 생각했다. 편집하겠습니다.
DJMcMayhem

당신은 필요하지 않습니다 <CR>후를 <foobar>명령을 보내?
기금 모니카의 소송

@QPaysTaxes ex 명령이거나 검색 인 경우에만 해당됩니다. (예 : 어떤 명령로 시작 :, /또는 ?)
DJMcMayhem

오, 나빠 나는 명령과 일반 모드를 혼동했다. 쿨 : D
자금 모니카의 소송

5

세 가지 "변경 사례"연산자가 있습니다.

gu    "Convert to lowercase
gU    "Convert to uppercase
g~    "Toggle case

이들은 연산자이므로 동작을 취하므로 현재 문자를 소문자로 변환하십시오.

gul

재미있는 트릭이 나오는 곳은 다음과 같습니다. :) 단일 문자 또는 현재 줄의 대소 문자를 변경하려면 시각적 모드에서 바이트가 짧습니다. 예를 들어 gul동등

vu

그리고 gu_(_는 현재 줄)은

Vu

이 트릭은 시각 모드에서 뒤로 검색을 트리거 하기 때문에 전환을 위해 작동 하지 않습니다.v?v/ 반대 방향으로 이동)을vg? . 그러나 여기에 ~연산자를 사용하여 더 많은 바이트를 절약 할 수 있습니다 ! (이 점을 지적 해 주셔서 감사합니다 @Doorknob)

vim 답변과 here 및 post의 동등한 V 답변 에서이 트릭이 실제로 작동하는 것을 볼 수 있습니다 .


1
~커서 아래 문자의 대소 문자를 전환하고 오른쪽으로 이동하는를 잊지 마십시오 !
Doorknob

5

10 번의 키 스트로크 알파벳

이 기술에 대한 모든 크레딧은 Lynn 사용합니다. 입니다. 나는 후손을 위해 여기에 쓰고 있습니다.

다음 10 가지 키 스트로크를 사용하여 소문자 알파벳을 잡아 당깁니다.

:h<_␍jjYZZ

( 캐리지 리턴, 즉 Enter 키가있는 곳 )

설명

:h<_␍v_b_<_example텍스트를 포함 하는 도움말 섹션 (시각적 블록 선택의 예)을 엽니 다 abcdefghijklmnopqrstuvwyxz. jjY해당 줄로 내려 가서 줄을 서서 ZZ도움말 창 을 닫습니다.


4

레지스터를 알고

"aY나중에 사용하기 위해 텍스트를 특정 레지스터 (예 :)에 담 그거나 삭제하는 것이 항상 필요한 것은 아닙니다. Vim에는 여러 명령의 주제로 자동으로 채워지는 몇 개의 레지스터가 있습니다. :help registers모든 내용을 보려면 입력 하십시오. 그러나 다음은 몇 가지 참고 사항입니다.

  • 등록하지 ""않음 : -마지막으로 삭제되었거나 삭제 된 마지막 텍스트.

  • 번호가 매겨진 레지스터 "0-마지막으로 눌린 텍스트입니다.

  • 번호가 매겨진 레지스터 "1–- "9한 줄 미만이 아니면 삭제 된 마지막 텍스트. "1채워질 때마다 이전 내용이 등으로 이동됩니다 "2.

  • 작은 삭제 레지스터 : "-- 삭제 된 한 줄보다 짧은 마지막 텍스트.

  • 마지막으로 삽입 된 텍스트 : ".

특히, "-"1레지스터는 예를 들어, 일부 텍스트를 삭제 할 수 있도록 유용한 함께 될 수 dd"1레지스터와 함께 다른 텍스트를 삭제 D"-(물론, 의미가 동일하지 않은,하지만 종종이 될 필요가 없습니다 ).

모든 레지스터를 추적하기가 약간 어려울 수 있지만을 입력하여 언제든지 모든 레지스터의 내용을 볼 수 있습니다 :registers.


3

이것은 이전 에 대화에서 나왔 으므로 전체 팁으로 게시 할 수도 있다고 생각했습니다.

<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

3

골퍼 운동

종종 텍스트 블록으로 작업하는 경우 (특히 과제에서) 버퍼의 첫 번째 또는 마지막 문자로 이동해야합니다. G그리고 gg꽤 좋은, 그러나 어떤 성가신 일이있다. 예를 들어, 마지막 문자를 얻으려면, 당신은 필요 G$하고 gg공백을 선도가 있다면 반드시 첫 번째 열에서 당신을 넣어하지 않습니다. 여기에 더 멋진 움직임이 있지만 텍스트의 중간에 빈 줄이없는 경우에만 작동합니다.

  • 버퍼의 첫 문자 : {보다 낫습니다 gg0. 텍스트 중간에 빈 줄이 있으면 go버퍼의 첫 번째 문자가 무엇이든 사용할 수 있습니다.

  • 버퍼의 마지막 문자 : }보다 낫다G$

이것들은 또한 연산자에 대한 논증으로서 작용하지만 그것들은 선으로 움직이는 것이 아니라 캐릭터로 움직이는 것입니다!


H보다 golfier입니다gg
Kritixi LITHOS

@KritixiLithos를 제외하고 H는 신뢰할 수 없습니다. 동작은 보이는 창의 크기와 버퍼의 위치에 따라 다릅니다. (이 혼란을 피하기 위해 V로 리 맵핑 됨)
DJMcMayhem

2

식 레지스터를 사용하여 계산

일반 모드와 삽입 모드 모두에서 계산을 수행 할 수 있습니다.

일반 모드

일반 모드에서 입력하면 @=커서가 명령 행으로 이동하여 표현식을 입력 할 수 있습니다. 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@q5 바이트 더 짧은 순수한 표준 모드 솔루션이 있습니다. 그리고 유닉스에 있다면 할 수도 있습니다 :%!nl. 그래도 좋은 팁!
DJMcMayhem

1
저의 목표는 기능을 사용하는 방법을 보여주는 것이 었습니다.
Jordan

1

매크로의 텍스트를 직접 수정할 수 있으며 복잡한 조건부보다 훨씬 짧을 수 있습니다. 예를 들어 붙여 넣기를 원한다고 가정 해 보겠습니다. 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 개의 키 스트로크.


1
사용 D하지 말고을 사용하십시오 dd. 2. 명령에 레지스터가 포함되어 있지 않으면 더 짧게 만들 수 있습니다. 예를 들어 x커서 아래의 숫자만큼 문자를 반복하려면 대신을 "qD@qix<esc>사용하십시오 D@"ix<esc>.
손잡이
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.