たぶんClojureを書いている人はEmacsを使っている人が多いと思いますがVS Codeも結構書きやすいと思うので僕がやっている方法について書きます。
使用するエクステンション:
Calva について
Calva は Emacs でいう Cider、IntelliJ でいう Cursive のようなエクステンションです。主に次のようなことができます。
- REPL を VS Code 内で起動したり、ターミナルなどで起動したREPLに接続する
- inline や file、 namespace単位でのコードの実行
- テストの実行
- code formatting
- 関数の定義場所にジャンプ
- Paredit
- ClojureScript も対応
かなり包括的にサポートされています。しばらく前まで Calva 関係のエクステンションはいくつかに分かれていましたが、近頃統合されて一つになりました。
REPLを起動するとこのようになります。
Calva の詳しい使い方は公式サイトを御覧ください。
https://marketplace.visualstudio.com/items?itemName=cospaia.clojure4vscodemarketplace.visualstudio.com
Clojure Warrior
Clojure のカッコを色付してコードを読みやすくしてくれるエクステンション。たまにカッコの数でコンパイルエラーしてしまうのであると便利。
VS Code - remote containers
Clojureの実行環境を Docker で用意して、 VS Code - remote containers をつかって container の中で開発をできるようにします。 僕は近頃は Docker を使った開発ばかりしています。何かしらのライブラリも Docker Image で公開されて、Image を取得するだけで使えるようになっていることも増えました。 本当に便利になりました。
remote containers エクステンションは Docker を用いた開発を更に便利にするものです。
通常、 Docker を用いた開発では docker コマンドや docker-compose コマンドを使ってコンテナを立ち上げて、portなどを使って外部からコンテナにアクセスして利用します。
例えば、remote containers を使わずに docker で動いている REPL に calva でアクセスするには docker-compose run clojure repl
などのようにして nREPL を起動して、その port 番号を calva に渡して接続します。
しかしこの方法では calva jack-in REPLの機能が使えないため、REPLの中で補完を行うなどのことができません。
どうしても docker や docker-compose コマンドを使いたいコマンドの前につける必要があるため、エクステンションの機能をフル活用することが難しいことが多いのです。
remote containers はこの問題を解決します。
remote containers は Docker container 内で VS Code が動いているかのようにしてくれます。たとえば、remote containers を使っているときに VS Code でターミナルを立ち上げると、 Docker container のシェルが起動します。
VS Code - remote containers で Clojure 環境を作る
remote containers 用の設定をリポジトリ内に作る必要があります。 .devcontainer
ディレクトリを作成して次のファイルを用意します。今回は PostgreSQL を利用する Web サーバーを想定しています。
.devcontainer/ * Dockerfile * devcontainer.json * docker-compose.yml
devcontainer.json
{ "name": "simple clojure rest", "dockerComposeFile": [ "docker-compose.yml" ], "service": "app", "workspaceFolder": "/simple-clojure-rest", "extensions": [ "betterthantomorrow.calva", "tonsky.clojure-warrior", "mtxr.sqltools" ], "settings":{ "calva.jokerPath": "/usr/bin", "parinfer.defaultMode": "disabled", "calva.autoAdjustIndent": true, "calva.lintOnSave": true, "editor.tabSize": 2, "files.insertFinalNewline": true, "files.trimFinalNewlines": true, "terminal.integrated.shell.linux": "/bin/bash" } }
devcontainer.json は remote containers の設定を記述するための json です。今回は docker-compose を使いたいので、 dockerComposeFile
で docker-compose.yml ファイルを指定します。
これは複数指定することもできます。配列の後に指定したほうの yml でそれ以前の yml の Key-Value がオーバーライドされます。これにより、プロジェクト用の docker-compose.yml とは別に VS Code remote containers 専用の設定を別の yml に定義してオーバーライドすることもできます。(今回はやってません)
service
は docker-compose 内の使いたい service 名を指定します。今回は app
という service 内で Clojure のコードを書いていけるようにします。
extensions
は remote containers を立ち上げたときにインストールする VS Code のエクステンションを指定できます。これにより remote containers を起動するだけでエクステンションを含めた開発環境が構築されます。
settings
は remote containers を立ち上げた環境用の設定を記述します。 extensions
で入れたエクステンション用の設定も記述できます。
devcontainer.json の詳細は次を参照してください。もちろん docker-compose を使わずに Dockerfile から環境を構築することもできます。
Dockerfile
FROM clojure:openjdk-8-lein-2.9.1 # setup environment variables ENV LANG C.UTF-8 ENV DEBIAN_FRONTEND noninteractive ENV JOKER_VERSION 0.12.5 ENV SHELL /bin/bash RUN apt-get update \ && apt-get -y install --no-install-recommends apt-utils 2>&1 \ # # Verify git, process tools, lsb-release (common in install instructions for CLIs) installed && apt-get -y install git procps lsb-release \ # # Clean up && apt-get autoremove -y \ && apt-get clean -y \ && rm -rf /var/lib/apt/lists/* \ # # install joker && wget https://github.com/candid82/joker/releases/download/v${JOKER_VERSION}/joker-${JOKER_VERSION}-linux-amd64.zip \ && unzip joker-${JOKER_VERSION}-linux-amd64.zip \ && rm joker-${JOKER_VERSION}-linux-amd64.zip \ && chmod a+x joker && mv joker /usr/bin # Switch back to dialog for any ad-hoc use of apt-get ENV DEBIAN_FRONTEND=dialog
clojure の公式 Image をベースにして環境を作ります。git、procps、lsb-release は remote container を使うために必要なのでインストールします。
Calva は joker を使って Lint ができるので joker をインストールします。 github.com
docker-compose.yml
version: '3' services: db: image: postgres ports: - 5432:5432 volumes: - /var/lib/postgresql/data app: build: context: ../ dockerfile: .devcontainer/Dockerfile command: sleep infinity # 起動したコンテナを終了させないためのコマンド ports: - 3000:3000 depends_on: - db volumes: - ~/.gitconfig:/root/.gitconfig # remote container内でgitを使うためホストの設定をコピーする - ..:/simple-clojure-rest - lib_data:/root/.m2/repository environment: - FOO=bar volumes: lib_data:
debug
残念ながら Calva は VS Code の debugger 機能に対応していません。 一応、 VS Code の debugger で Clojure をデバッグできるエクステンションもあるのですが、開発が盛んではなく現在はうまく動かないようです。
仕方がないので break point を設定したりすることは諦めて print デバッグ的な方向でデバッグを行っています。 これ系は色々ありますが、僕は次が気に入っています。
REBL というのもあるようなのでそれでもいいかも
おまけ: SQLTools
VS Code のエクステンションで使えるGUI SQL Client。MySQLやPostgreSQLなど複数のDBに対応しており便利。