[VIM]Scalaの入力補完をAdoptOpenJDK+coc-metalsでやってみた

Scala補完用にいれたensimeが既にArchive扱いになっていたため、現在も絶賛更新中であるmetalsvimに変更してみました。補完動作衝突を回避するために、deopleteを外す必要があります。
2020.06.04

この記事は公開されてから1年以上経過しています。情報が古い可能性がありますので、ご注意ください。

はじめに

Scalaをvimで編集するために環境を整えてみましたが、TwitterにてensimeはArchive入(今後修正や更新が入らない!)していることを知り、同等の機能を持つcoc-metalsに差し替えてみました。

coc-metalsについて

Scala言語サーバMetals用のcoc.nvim拡張プラグインです。TypeScript製です。

coc.nvimはVim8及びNeovimのインテリセンスエンジンであり、coc-metalsはこのインテリセンスエンジンをScalaで最適化するためのプラグインとなります。

注意点

deopleteが既に入っている場合は入力補完動作時に機能が衝突します。

It is coc feature. coc changes completeopt internally and if other plugins change it, it is detected. deoplete changes completeopt, so it is conflicted with coc. You should not mix coc and deoplete.

導入済みプラグインの停止

衝突を解消するため、deoplete関連のプラグインとensume-vimを外します。プラグインそのものは関連していない場合でも、init.vim内で設定に用いている場合はinit.vimの設定含めて念の為にoffにします。

今回は以下のプラグインが対象になりました。

  • deoplete
  • deoplete-jedi
  • deoplete-dictionary
  • neosnippet
  • neosnippet-neosnippets
  • ensime

プラグイン指定をそれぞれ削除するかコメントアウトした後に、以下のコマンドを実行してクリーンアップします。

:call map(dein#check_clean(), "delete(v:val, 'rf')")
:call dein#recache_runtimepath()

Java11のインストール

coc-metalsの動作にはJava8かJava11が必要です。OpenJDK 11はすでにサポートされていないため、AdoptOpenJDKを導入します。

ダウンロードにかなりの時間が掛かります。

brew tap AdoptOpenJDK/openjdk
brew cask install adoptopenjdk11

java_homeコマンドでパスを確認し、環境変数JAVA_HOMEに設定します。

% /usr/libexec/java_home -v 11
/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
% vim ~/.zshrc
export JAVA_HOME=/Library/Java/JavaVirtualMachines/adoptopenjdk-11.jdk/Contents/Home
PATH=\${JAVA_HOME}/bin:${PATH}
% exec $SHELL -l

cocのインストール

関連するcocプラグインもあわせてインストールしていきます。

dein.tomlにcoc.nvimを設定します。各記事でやり方が様々だったため、「これが鉄板」というものはないようです。

[[plugins]]
repo = 'neoclide/coc.nvim'
source = 'release'
build = 'coc#util#install()'

言語サーバ設定追加

今回はPythonとScalaを設定しています。

% vim $HOME/.config/nvim/coc-settings.json
{
  "suggest.noselect": true,
  "suggest.preferCompleteThanJumpPlaceholder": true,
  "languageserver": {
    "metals": {
      "command": "metals-vim",
      "rootPatterns": ["build.sbt"],
      "filetypes": ["scala", "sbt"]
    },
    "python": {
      "command": "python",
      "args": [
        "-mpyls",
        "-vv",
        "--log-file",
        "/tmp/lsp_python.log"
      ],
      "trace.server": "verbose",
      "filetypes": [
        "python"
      ],
      "settings": {
        "pyls": {
          "enable": true,
          "trace": {
            "server": "verbose"
          },
          "commandPath": "",
          "configurationSources": [
            "pycodestyle"
          ],
          "plugins": {
            "jedi_completion": {
              "enabled": true
            },
            "jedi_hover": {
              "enabled": true
            },
            "jedi_references": {
              "enabled": true
            },
            "jedi_signature_help": {
              "enabled": true
            },
            "jedi_symbols": {
              "enabled": true,
              "all_scopes": true
            },
            "mccabe": {
              "enabled": true,
              "threshold": 15
            },
            "preload": {
              "enabled": true
            },
            "pycodestyle": {
              "enabled": true
            },
            "pydocstyle": {
              "enabled": false,
              "match": "(?!test_).<em>\.py",
              "matchDir": "[^\.].</em>"
            },
            "pyflakes": {
              "enabled": true
            },
            "rope_completion": {
              "enabled": true
            },
            "yapf": {
              "enabled": true
            }
          }
        }
      }
    }
  }
}

補完を機能させるため、夫々の拡張を追加します。

% vim
:CocInstall coc-java coc-json coc-tsserver coc-python coc-metals
Install finished
- ✓ coc-java Installed extension coc-java@1.4.11 at $HOME/.config/coc/extensions/node_modules/coc-java
- ✓ coc-json Installed extension coc-json@1.2.6 at $HOME/.config/coc/extensions/node_modules/coc-json
- ✓ coc-tsserver Installed extension coc-tsserver@1.5.1 at $HOME/.config/coc/extensions/node_modules/coc-tsserver
- ✓ coc-python Installed extension coc-python@1.2.12 at $HOME/.config/coc/extensions/node_modules/coc-python
- ✓ coc-metals Installed extension coc-metals@0.8.3 at $HOME/.config/coc/extensions/node_modules/coc-metals

metals-vimのビルド

metals-vimをビルドしていない場合、以下のログが残ります。この辺り割愛されている記事が多いので、別途ビルドが必要だということに気がつくまで結構掛かりました…。

[coc.nvim] Server languageserver.metals failed to start: Launching server "languageserver.metals" using command metals-vim failed.

ビルドにあたってはcoursierが必要になります。

% brew install coursier/formulas/coursier
% coursier bootstrap \
  --java-opt -Xss4m \
  --java-opt -Xms100m \
  --java-opt -Dmetals.client=vim-lsc \
  org.scalameta:metals_2.12:0.9.0 \
  -r bintray:scalacenter/releases \
  -r sonatype:snapshots \
  -o /usr/local/bin/metals-vim -f

> Wrote /usr/local/bin/metals-vim

できあがったmetals-vimにパスを通します

辞書データを元に補完を追加したい場合

neoclide/coc-sourcesからcoc-dictionary を利用します。

% vim ~/.config/nvim/init.vim
setlocal dictionary+=/path/to/file
% cat /path/to/file
aaaa
bbbb
cccc

:CocInstall coc-dictionary
Install finished

- ✓ coc-dictionary Installed extension coc-dictionary@1.2.2 at $HOME/.config/coc/extensions/node_modules/coc-dictionary↲

あとがき

deopleteの補完と並行できないかと思いましたが、作者が直々に「無理」だとしていたため完全に切り替えることにしました。

coc関係のドキュメント更新頻度は高いことを確認したため、今回まとめた記事もあっという間に古くなる可能性があります。「何かがおかしい」と感じたら、以下の参考リンクからOfficialのものを参照することもおすすめします。

参考