この記事はGRIPHONE Advent Calendar 2021 17日目の記事です。
こんにちは。サーバーサイドエンジニアのtackです。
IntelliJには最初から様々な便利機能が入っています。その中に新しくソースコードのファイルを作る時に、自動的にコードのひな形を生成してくれる”File and Code Templates”という機能があるので、使い方を紹介します。
※この記事では、IntelliJを使っていますが、PHPStorm、Goland、PyCharmなどJetBrainsのIDEなら使えます。
FileTemplateとは
IntelliJのFileTemplateは、ファイルを新しく生成するときに使われます。Projectビューを右クリックしてNewを選ぶと、以下の画像の様に沢山のファイルが表示されます。これらのほとんどがFileTemplateで定義されています。
FileTemplateは既存の物を変更したり、新しく追加することもできます。
FileTemplateを見てみる
FileTemplateを変更するには“File”メニューから“Settings”を開き、“Editor”の中にある“File and Code Templates”を開きます。
設定画面の左側に出てくるリストがFileTemplateになります。この画面ではFileのテンプレート以外にもIncludes、Code、Otherというタブがあり、他のテンプレートも変更することができます。(今回はFileのみ紹介します)
リストの項目をクリックすることで、テンプレートの内容を確認、編集することができます。
テンプレートで使われている言語はVelocityで、if文やJava(JavaScriptではない)の処理を書くこともできるので、かなりカスタマイズできます。
FileTemplateをカスタマイズする
今回はGo言語のgoファイルの生成をプロジェクトに合わせてカスタマイズしてみます。
初期設定の状態で、goファイルを新規作成するとパッケージ名(ディレクトリと同じ名前)が書かれたgoファイルができます。ここではhoge/sample.go
を作りました。
同じディレクトリにテスト用のgoファイルhoge/sample_test.go
を作ってみます。
sample_test.go
ファイルが生成されました。ファイルの内容はsample.go
と同じpackage hoge
になっています。
例えば、プロジェクトの規約にテストコードのパッケージ名には_test
を付けるという決まりがあるとします。この場合、既存のテンプレートでは常にpackage hoge
となってしまうので、ファイルを生成した後に手動でpackage hoge_test
と書き換える必要があります。
この問題を解決するために、File Templateをカスタマイズしてみましょう。新しいGo Test File
というFile Templateを作ってもいいのですが、今回はファイル名に_test
というサフィックスがついていたらテストコードという判定にしました。
テンプレートのコードは以下の様になります。
#if($NAME.endsWith("_test"))
package ${GO_PACKAGE_NAME}_test
#else
package ${GO_PACKAGE_NAME}
#end
テンプレート内で変数を使う場合は${}を付け、括弧内に変数名を書きます。
${GO_PACKAGE_NAME}
最初から定義されている変数はDescriptionのところに説明があるので、参考にして下さい。
if文は以下の様な構文になります。
#if(条件式)
一致した場合
#else
それ以外
#end
条件式はJavaで書くことができます。$NAME
にはStringのファイル名が入っているので、endsWithメソッドで末尾に"_test"
が付いているかを判定できます。
ここで変数を使う場合は$変数名
と書きます。テンプレート内と違い${変数名}
とは書かないので注意して下さい。
#if($NAME.endsWith("_test"))
テンプレートを編集したらOKボタンをクリックして設定を保存し、再度sample.go
とsample_test.go
ファイルを作ってみます。
ファイル名に_testサフィックスが付いている場合はpackage hoge_test
、ついて居ない場合はpackage hoge
と書かれたコードが生成されました。
このようにテンプレートをカスタマイズすることで、ミスを減らし時短にもなるのでオススメです。
複雑なテンプレートを書いてみる
前の章では、packageの部分を変更するだけの簡単なテンプレートを紹介しましたが、もっと複雑な事もできます。
テストファイルの内容はだいたい決まっていて、以下の様なコードを必ず書くとします。
package hoge_test
import "testing"
func TestHoge(t *testing.T) {
}
これを毎回書くのは手間なので、テンプレートに追加します。ここで問題になるのが、スネークケースで書かれているファイル名から、Test関数名をキャメルケースで書かないといけない事です。今回は、スネークケースをキャメルケースに変換する処理をVelocityで書いてみました。
#if($NAME.endsWith("_test"))
#set($CamelCaseName = "")
#set($part = "")
#set($len = $NAME.length() - 5)
#foreach($part in $NAME.substring(0,$len).split("_"))
#set($CamelCaseName = "${CamelCaseName}$part.substring(0,1).toUpperCase()$part.substring(1).toLowerCase()")
#end
package ${GO_PACKAGE_NAME}_test
import "testing"
func Test${CamelCaseName}(t *testing.T) {
}
#else
package ${GO_PACKAGE_NAME}
#end
Velocityで変数に値を代入するには#set
を使います。値の部分はJavaの式が使えます。
#set($変数名 = 値)
以下のコードでは、$NAMEの文字数 - 5
を$len
変数に代入しています。
#set($len = $NAME.length() - 5)
配列の各要素に対してループを作るには#foreach
を使います。
#foreach($各要素を代入する変数名 in 配列)
#end
以下のコードでは、substringで$NAMEを$len文字に切り詰め、_で区切って配列にしています。
$lenは$NAMEの文字数 - 5
なので、$NAMEがhoge_fuga_test
なら、substringでhoge_fuga
に切り詰め、splitで["hoge", "fuga"]
の配列が作られます。
#foreach($part in $NAME.substring(0,$len).split("_"))
foreachの中では、$CamelCaseNameに先頭1文字を大文字にした単語を追加しています。
#set($CamelCaseName = "${CamelCaseName}$part.substring(0,1).toUpperCase()$part.substring(1).toLowerCase()")
これで、$NAMEの末尾から_test
を削除して、キャメルケースに変換した名前が$CamelCaseNameに入ります。
この変更を保存して、またsample_test.goファイルを生成してみます。
ここまで自動生成で生成されるとかなり楽になると思います。
最後に
今回は新しくファイルを生成する時に使われるFile Templateを簡単に紹介しました。IntelliJには他にも便利な機能が沢山あるので色々触ってみると面白いと思います。