私は最近、vimがゴルフ、特にkolmogorov-complexityに最適であることを認識しました。また、meta vim によれば、少なくともこのサイトの範囲では、完全に受け入れ可能な「プログラミング言語」です。
Vimでゴルフをするための一般的なヒントは何ですか?私は、コードゴルフの問題に適用でき、少なくともある程度Vimに固有のアイデアを探しています(たとえば、「コメントの削除」は答えではありません)。
回答ごとに1つのヒントを投稿してください。
私は最近、vimがゴルフ、特にkolmogorov-complexityに最適であることを認識しました。また、meta vim によれば、少なくともこのサイトの範囲では、完全に受け入れ可能な「プログラミング言語」です。
Vimでゴルフをするための一般的なヒントは何ですか?私は、コードゴルフの問題に適用でき、少なくともある程度Vimに固有のアイデアを探しています(たとえば、「コメントの削除」は答えではありません)。
回答ごとに1つのヒントを投稿してください。
回答:
一般的なコマンドの大文字のバリエーションに注意してください。これにより、多くのコンテキストで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であると信じていますが、変化する可能性があります)。
$
、けれどもそう少なくともC
とD
何かを保存します)。
G
とgg
同等ではありません。前者はバッファの最後に移動し、後者は先頭に移動します。
5G
しました5gg
。例えば、と同等です。その点についてさらに詳細を追加します。
コマンドが失敗するたびに、現在のマクロをキャンセルする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.
:%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>
コマンドを送信するために?
:
、/
または?
)
「ケースの変更」演算子は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の回答で確認できます。
~
カーソルの下の文字の大文字と小文字を切り替え、右に移動することを忘れないでください!
後で使用するためにテキストを特定のレジスターにヤンクまたは削除する(例:)"aY
は必ずしも必要ではありません。Vimには、さまざまなコマンドのサブジェクトが自動的に入力されるいくつかのレジスタがあります。:help registers
それらをすべて表示するには入力しますが、いくつかの特別な注意事項があります。
名前のないレジスタ:""
-ヤンクまたは削除された最後のテキスト。
番号付きレジスタ"0
-ヤンクされた最後のテキスト。
番号のレジスタ"1
- "9
-それは未満1行でない限り、削除された最後のテキスト。"1
満たされるたびに、以前のコンテンツがにシフトさ"2
れます。
小さな削除レジスタ:"-
- 削除された1行より短い最後のテキスト。
最後に挿入されたテキスト: ".
特に、"-
および"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
テキストのブロックを使用している場合(特にascii-artチャレンジで)頻繁に、バッファー内の最初または最後の文字に移動する必要があります。G
そして、gg
かなり良いですが、いくつかの迷惑なものがあります。たとえば、最後の文字を取得するには、次のものが必要G$
とgg
先頭の空白があるかどう必ずしも最初の列の上にあなたを置くことはありません。ここにいくつかのより良い動きがありますが、テキストの途中に空行がない場合にのみ機能することに注意してください:
バッファーの最初の文字:{
は、より優れていgg0
ます。テキストの中央に空の行がある場合は、go
これを使用して、バッファの最初の文字に何があっても移動できます。
バッファーの最後の文字:}
より良いG$
これらは演算子への引数としても機能しますが、行単位の動きではなく、文字単位の動きであることに注意してください!
H
よりゴルファーです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バイト短い純粋なノーマルモードソリューションです。また、Unixを使用している場合は、実行することもできます:%!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>
。