vim switch文のcase毎に折り畳む

switch( a )
{
	case 0:
		~~~~
		break;
	case 1:
		~~~~
		break;
	case 2:
		~~~~
		break;
	default:
		~~~~
		break;
}

C言語のswitch文でcase分岐が多過ぎて、一望できない場合などにcase毎に折り畳む方法。

  1. 対象のswitch文の{}内に移動する

  2. 'viB'で、{}内を選択

:'<,'>g/^\s\{-}case/,/\(case\|default\)/-1 fo

解説

グローバルコマンドである'g'を起点にExコマンドを組み立てます。グローバルコマンドは、マッチする全ての行に対して、後に続けるExコマンドを実行するという強力なExコマンドです。こういうコマンドや検索条件が長い入力は、1つ1つ分解すると理解しやすいです。

:'<,'>

ビジュアルモードで選択した範囲内でグローバルコマンドを実行するよ、ということです。これがない場合、普通のExコマンドだと現在の行だけで実行するのですが、グローバルコマンドは特殊でバッファ全体が対象になります。

g/^\s\{-}case/

空白を除く行の先頭に'case'文字がある全ての行で、続くExコマンドを実行するよ、となります。

次に'fo'コマンドで折り畳みを実行するのですが、このExコマンドは範囲指定で、どこからどこまで折り畳むかを指定します。
例えば、

:.,+5 fo

は、現在の行から5行の範囲で折り畳むということになります。

グローバルコマンドはマッチする全ての行に対してExコマンドを実行するということなので、全てのマッチする行に次々移動して、以下のコマンドを毎回実行することと同じになります。

:.,/\(case\|default\)/-1 fo

範囲には行数だけでなく、検索条件も指定することができるので、'case'、または'default'にマッチする1行前、となります。

まとめると、

  1. 選択範囲内で、

  2. 'case'で始まる全ての行に対して、

  3. 次の'case'、または'default'にマッチする1行前まで

  4. 折り畳む

因みに、今回のコマンドではdefault部分は折り畳まれませんし、switch文が入れ子になっていたりすると思い通りの結果にならないかもしれません。検索条件をもっと厳密にしたり、スクリプト関数にしてもっと複雑な判定を組み立てていくといいと思います。

この記事が気に入ったらサポートをしてみませんか?