EclimでJavaの開発環境構築をしました。同様にちょっとしたScalaのアプリを書きたい時にEclipseやIntelliJ IDEAを起動するのも重たいのでいつものEmacsでScalaの開発環境を構築します。
開発用の仮想マシン
クラウド上にUbuntu 16.04.3の仮想マシンを用意してパッケージを更新しておきます。
$ sudo apt-get update && sudo apt-get dist-upgrade -y
SDKMAN!
SDKMAN!はGradleやsbtなどJVM言語のSDK管理ツールです。最近ではJavaのバージョン管理もできるようになりました。
ワンライナーでSDKMAN!をインストールします。
$ curl -s get.sdkman.io | /bin/bash
$ sdk version
SDKMAN 5.5.9+231
Java
SDKMAN!を使ってインストールできるJavaのバージョンを一覧します。
$ sdk list java
================================================================================
Available Java Versions
================================================================================
8u141-oracle
8u131-zulu
7u141-zulu
6u93-zulu
OpenJDKベースのZuluの8を使います。
$ sdk install java 8u131-zulu
シェルを起動し直して$JAVA_HOME
環境変数を確認します。
$ echo $JAVA_HOME
/home/cloud-user/.sdkman/candidates/java/current
Scalaとsbt
Scalaのインストール可能なバージョンです。
$ sdk list scala
================================================================================
Available Scala Versions
================================================================================
2.12.3
2.12.2
2.12.1
2.12.0
2.11.8
2.11.7
2.11.6
2.11.5
2.11.4
2.11.3
2.11.2
2.11.1
2.11.0
Scalaを最新の2.12.3
をインストールします。
$ sdk install scala 2.12.3
続いてsbtです。バージョンを指定しない場合は最新がインストールされます。
$ sdk install sbt
$ sdk current sbt
Using sbt version 0.13.15
Emacs
Emacs24とCaskをインストールします。
$ sudo apt-get install emacs24-nox emacs24-el -y
$ emacs --version
GNU Emacs 24.5.1
パッケージ管理のCaskです。インストールする時にGitとPythonが必要です。
$ sudo apt-get install git python -y
$ curl -fsSL https://raw.githubusercontent.com/cask/cask/master/go | python
$ echo 'export PATH="$HOME/.cask/bin:$PATH"' >> ~/.bashrc
$ source ~/.bashrc
~/.emacs.d
ディレクトリに以下のような設定ファイルを用意します。
$ tree ~/.emacs.d/
/home/cloud-user/.emacs.d/
├── Cask
└── init.el
init.elはinit-loaderで分割したい場合は前回の設定を確認してください。
(require 'cask "~/.cask/cask.el")
(cask-initialize)
Caskにインストールするパッケージを記述します。
(source gnu)
(source melpa)
(depends-on "cask")
;; ENSIME
(depends-on "ensime")
~/.emacs.d
ディレクトリに移動してパッケージをインストールします。
$ cd ~/.emacs.d
$ cask install
ユーザーごとの設定
sbtプラグインのsbt-ensimeはユーザー単位にインストールします。プラグインのディレクトリがない場合は作成します。
$ mkdir -p ~/.sbt/0.13/plugins/
plugins.sbt
sbtプラグインのsbt-ensimeをインストールします。ホームの~/.sbt
にplugins.sbtを作成します。
addSbtPlugin("org.ensime" % "sbt-ensime" % "1.12.14")
global.sbt
sbt-ensimeプラグインの設定を記述します。
import org.ensime.EnsimeKeys._
ensimeIgnoreMissingDirectories := true
cancelable in Global := true
カスタマイズの内容は以下を参考にしました。
-
scala_2.11
ディレクトリを作成しない
ensimeConfig creates directories java and scala-2.11, which I don't need -
C-c
でプロセスをキャンセルする
Cancel Proceses
プロジェクトごとの設定
簡単なsbtプロジェクトを作成してEmacsからENSIMEを利用してみます。
$ mkdir -p ~/scala_apps/spike && cd ~/scala_apps/spike
$ cd ~/scala_apps/spike
$ mkdir -p src/{main,test}/{java,resources,scala}
$ mkdir lib project target
build.sbt
プロジェクト定義をbuild.sbtに書きます。ScalaのバージョンはSDKMAN!でインストールした2.12.3
から2.11.8
に変えてみました。
name := "Spike"
version := "0.1"
scalaVersion := "2.11.8"
.ensime
プロジェクトのトップディレクトリでsbtを起動します。ensimeConfig
コマンドを実行して.ensime
ファイルを作成します。
$ cd ~/scala_apps/spike
$ sbt
> ensimeConfig
[info] ENSIME update.
[info] Updating {file:/home/cloud-user/scala_apps/spike/}spike...
[info] Resolving jline#jline;2.12.1 ...
[info] Done updating.
[info] Resolving org.scala-lang#scala-reflect;2.11.8 ...
[info] ENSIME processing spike (Spike)
ENSIMEの使い方
作成したScalaプロジェクトに簡単なHello Worldのコードを書きます。
起動
.ensime
ファイルがあるプロジェクトのトップディレクトリでEmacsを開きます。ENSIMEサーバーの起動には少し時間がかかります。
M-x ensime
ミニバッファにメッセージが出るとサーバーの起動終了です。
ENSIME ready. May the source be with you, always.
HelloWorld.scala
mainメソッドを実装したScalaのコードを書きます。
object HelloWorld {
def main(args: Array[String]): Unit = {
println("Hello World!")
}
}
scala-mode
scala-modeはENSIMEをインストールすると自動的に使えます。個別インストールも可能です。Scalaのコードを書く場合の基本的なモードです。例えばEmacsからScala REPLを起動してみます。キーバインドの意味はcontrol を押しながらc、v、controlを離してz
です。
C-c C-v z
プロジェクトのbuild.sbtに定義した2.11.8
のREPLが起動しました。
Welcome to Scala 2.11.8 (OpenJDK 64-Bit Server VM, Java 1.8.0_131).
Type in expressions for evaluation. Or try :help.
scala>
sbt-mode
sbt-modeも自動的に使えます。このモードではEmacsからsbtを操作するときに使います。sbtのセッションを起動します。
M-x sbt-start
runコマンドはプロジェクトのmainメソッドをプログラムを実行します。Hello worldが表示されました。
> run
[info] Running HelloWorld
Hello World!
[success] Total time: 0 s, completed Aug 9, 2017 9:07:09 AM