vimでのゴルフのヒント


32

私は最近、vimがゴルフ、特に。また、meta vim によれば、少なくともこのサイトの範囲では、完全に受け入れ可能な「プログラミング言語」です。

Vimでゴルフをするための一般的なヒントは何ですか?私は、コードゴルフの問題に適用でき、少なくともある程度Vimに固有のアイデアを探しています(たとえば、「コメントの削除」は答えではありません)。

回答ごとに1つのヒントを投稿してください。


4
「vimでゴルフをするためのヒント」と「vimをテキストエディターとして効率的に使用するためのヒント」は基本的に同じであるため、これは特に役立つヒントの質問です。
DLosc

回答:


15

一般的なコマンドの大文字のバリエーションに注意してください。これにより、多くのコンテキストで1つのキーストロークを簡単に保存できます。例えば:

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

もう1つは、のG代わりにgg使用することですが、カウントを使用する場合のみです!たとえば、カウントなしでgg、先頭にG移動し、最後に移動します。ただし、カウントを使用すると、両方とも指定した行に移動するため、5Gより短くなりますが、と同等5gg です。

もう1つはH、の代わりに使用ggすることですが、これは、入力がデフォルトの行数を超えないことを保証できる場合にのみ機能することに注意することが重要です(これは24であると信じていますが、変化する可能性があります)。


1
具体的にエディタゴルフ(したがって、通常のキーストロークによってスコア)の課題は、大文字は(そうであるだけでなく2つのキーストロークである場合は$、けれどもそう少なくともCD何かを保存します)。
マーティンエンダー

1
キーストロークでスコアリングするときにはっきりしないのは、シフトキーを必要とする連続した文字がグループごとに1回だけシフトキーをカウントするかどうかです。これは、(少なくとも実際的な目的で)他のキーを押しながら押し続けることができるためです。
アレックスA.

6
@AlexA。個人的には、修飾子は考慮すべきではないと思います。これに関するメタ投稿が必要かもしれません...
DJMcMayhem

Ggg同等ではありません。前者はバッファの最後に移動し、後者は先頭に移動します。
ヨルダン

@ジョーダンそれは良い点です。カウントが与えられたとき、それらは同じであることを意味5Gしました5gg。例えば、と同等です。その点についてさらに詳細を追加します。
DJMcMayhem

11

コマンドが失敗するたびに、現在のマクロをキャンセルするdingノイズが発生します。これを(ab)使用して、粗い形式のループを作成できます。たとえば<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

最初にマクロをゼロにします。

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
これは改行では機能しますが、1行に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モニカの訴訟

@QPaysTaxesそうですね、そうではありません。もっと読みやすくなると思った。それを編集します。
DJMcMayhem

あなたは必要ありません<CR>した後に<foobar>コマンドを送信するために?
ファンドモニカの訴訟

@QPaysTaxes exコマンドまたは検索の場合のみ。(例えば、任意のコマンドで始まる:/または?
DJMcMayhem

ああ、私の悪い。コマンドモードと通常モードを混同しました。クール:D
モニカの訴訟に資金を

5

「ケースの変更」演算子は3つあり、

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

これらは演算子であるため、動きをとるので、現在の文字を小文字に変換するには

gul

ここからが面白いトリックの出番です。:)単一の文字または現在の行の大文字と小文字を変更する場合、ビジュアルモードでは1バイト短くなります。たとえば、次gulと同等です

vu

そしてgu_(_は現在の行)と同等です

Vu

このトリックはトグルでは機能しません。v?ビジュアルモードで逆方向の検索をトリガーするので(v/逆方向に移動するのと同じように)、vg?代わりに必要です。ただし、ここで~演算子を使用して、さらに多くのバイトを節約できます!(これを指摘してくれてありがとう@Doorknob)

このトリックの実際の動作は、こちらのvimの回答と、andとpostの同等のVの回答で確認できます。


1
~カーソルの下の文字の大文字と小文字を切り替え、右に移動することを忘れないでください!
ドアノブ

5

10回のキーストロークのアルファベット

この手法の功績はすべてLynnにあります。Lynnこの回答で最初に使用しました 後世のためにここに書いています。

次の10個のキーストロークを使用して、小文字のアルファベットをヤンクします。

:h<_␍jjYZZ

キャリッジリターン、つまりEnterキーはどこにありますか。)

説明

:h<_␍ヘルプセクションv_b_<_example(視覚的なブロック単位の選択の例)を開きます。このセクションには、テキストが含まれていますabcdefghijklmnopqrstuvwyxzjjYその行まで下に移動してヤンクし、ZZヘルプウィンドウを閉じます。


4

レジスタを知る

後で使用するためにテキストを特定のレジスターにヤンクまたは削除する(例:)"aYは必ずしも必要ではありません。Vimには、さまざまなコマンドのサブジェクトが自動的に入力されるいくつかのレジスタがあります。:help registersそれらをすべて表示するには入力しますが、いくつかの特別な注意事項があります。

  • 名前のないレジスタ:""-ヤンクまたは削除された最後のテキスト。

  • 番号付きレジスタ"0-ヤンクされた最後のテキスト。

  • 番号のレジスタ"1- "9-それは未満1行でない限り、削除された最後のテキスト。"1満たされるたびに、以前のコンテンツがにシフトさ"2れます。

  • 小さな削除レジスタ:"-- 削除された1行より短い最後のテキスト。

  • 最後に挿入されたテキスト: ".

特に、"-および"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よりゴルファーです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バイト短い純粋なノーマルモードソリューションです。また、Unixを使用している場合は、実行することもできます:%!nl。それでも良いヒントです!
DJMcMayhem

1
私の目標は、最小限のキーストロークで行に番号を付ける方法ではなく、この機能の使用方法を示すことでした。
ヨルダン

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
1. Dではなくを使用しますdd。2.コマンドにレジスタが含まれない場合は、さらに短くすることができます。たとえば、を使用するx代わりに"qD@qix<esc>、カーソルの下の数だけ文字を繰り返す場合は、を使用しますD@"ix<esc>
ドアノブ
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.