Livedoorブログからの移動

前回までで最低限の設定は終わり, 後はキーバインドとかを好き放題いじるだけ, みたいな状態には持ってきた(と信じたい).

今回は, snippetsを追加することでscalaの記述速度の向上(というかIntelliJの時の機能の復元)をしたい.

デフォルトのクラスの作成

scalaはJavaと同じく, ファイル名とpublicなクラス名が等しく, 基本的に1クラス1ファイルであることが求められている(公式のStyle Guide). なので, ファイル名と同名のクラスを生成するsnippetsを書いた.

<snippet>
    <content>
        <![CDATA[
/** ${1: Description of class}
   * @constructor ${2: Description of constructor}
   */
class ${TM_FILENAME/\.scala$//g}() {
}
]]>
    </content>
    <tabTrigger>class</tabTrigger>
    <scope>source.scala</scope>
</snippet>

そこまで変なものは書いてないので読めばわかると思う. scalaのソース内で, classでtabを押すと起動し, scaladocのコメント付きclass定義が挿入される. クラス名は, ${TM_FILENAME}でファイル名をもってきて, /\.scala$//gで末尾の.scalaを消して生成している.

本当は, 基本的にはファイル名と同名のクラスを生成するが, ファイル名が小文字スタートなら, sealed traitを生成する, みたいなものを作りたかったが, まぁ今はいいや. そもそもそういうのは, Sublime Text的には, sealedみたいな別snippetsでやったほうがいいのだろう.

package宣言の挿入

正直Sublime Textにして一番面倒だったのがpackage宣言を自分で書かないといけないことだった. IntelliJ IDEAならプロジェクトのソースディレクトリから勝手に挿入してくれるので.

そこで, ディレクトリパスから, 適切なパッケージ名を推測して, 挿入するsnippetsを書いた.

<snippet>
    <content>
        <![CDATA[package ${TM_FILEPATH/^.*\/src\/(main|test)\/scala\/|\/[^\/]*\.scala$|(\/)/?2.:/g}]]>
    </content>
    <tabTrigger>package</tabTrigger>
    <scope>source.scala</scope>
    <description>Insert a package declaration of a scala file in sbt project</description>
</snippet>

正規表現が非常にややこしいので, 構文木っぽいのだけ置いときます. 解説は面倒臭いので読み取ってください.

  • 変数部分
    • ${TM_FILEPATH
  • 正規表現部分
    • or(以下のいずれかにマッチしたら)
      1. ^.*\/src\/(main|test)\/scala\/
        • パスの先頭から, src/main/scala/またはscr/test/scala/まで
      2. \/[^\/]*\.scala$
        • いわゆるファイル名の部分
      3. (\/)
        • a,bにマッチしない箇所の"/"(ディレクトリの区切り文字)
  • 処理部分
    • ?2.:
    • もし$2(cにあたる)にマッチしていたら"."に, そうでなければ""に置換する.
  • g
    • 当てはまる箇所全てのこの処理をする.

このsnippetsの前提条件は,

  1. sbtまたはmavenを用いた, scalaファイルである.
  2. パッケージ名とディレクトリ構造に一対一の関係がある(相対パスfoo/barならパッケージ名はfoo.barというような).

の2点となっている.

参考

今回の参考ページは, unofficial document. 思ったよりわかりやすいページでした.