【2020年冬】Vim/NeovimでDenoの開発環境を構築する


Deno Advent Calendar 2020 3日目の記事です🦕

今日は、Vim/NeovimでDenoの開発環境を構築する方法について説明します。

概要

この記事では、Vim/Neovimにおける主要なLSPクライアントであるcoc.nvim及びvim-lspのそれぞれについて、Denoの開発環境をセットアップする方法を説明します。

想定読者

この記事は以下のような方を想定して書かれています。

coc.nvimを使ってDenoの開発環境をセットアップする

要約

coc-denoを使うとよいと思います。

coc.nvimとは?

Node.jsを使って実装されたVim/NeovimのLSPクライアントです。詳しくはGitHubリポジトリまたは以下のページを参照ください

セットアップ方法

coc.nvimのインストール

まず、coc.nvimはNode.jsに依存しているため、入っていなければ事前にインストールしてください。(Node.jsの10.12以上のバージョンのものが必要です)

次に、coc.nvimをインストールします。

dein.vimをお使いの場合は、TOMLファイルに以下の記述を追加すればcoc.nvimをインストールできます。

dein.toml
 [[plugins]]
 repo = 'neoclide/coc.nvim'
 rev = 'release'
 merged = 0

vim-plugをお使いの場合は、vimrcまたはinit.vimに次のように記述すればインストールできると思います。

.vimrc
Plug 'neoclide/coc.nvim', {'branch': 'release'}

coc.nvimの拡張をインストール

次に、coc-tsservercoc-denoをインストールします。

coc-denoとは、coc.nvimでDenoの開発をサポートするための拡張です。
この拡張をcoc-tsserverと併用することで、Denoの開発が容易になります。

Vim/Neovimで以下のコマンドを実行すると、coc-tsserverとcoc-denoをインストールできます。

:CocInstall coc-tsserver coc-deno

動作例

上記セットアップを実施すると、自動補完やシンボルジャンプ等の便利な機能が使えるようになります。

より詳細なセットアップ方法については、以下を参照ください

vim-lspを使ってDenoの開発環境をセットアップする

要約

typescript-language-servertypescript-deno-plugin を併用するとよいと思います。

vim-lspとは?

VimScriptのみで実装されたLSPプラグインです。
詳しくはGitリポジトリまたは以下を参照ください

セットアップ方法

vim-lspのインストール

まず、vim-lspをインストールします。

必要に応じて、asyncomplete.vimasyncomplete-lsp.vim等を追加でインストールすると、自動補完ができるようになります。

dein.vimをお使いの場合は、TOMLファイルに以下の記述を追加するとインストールできます。

dein.toml
[[plugins]]
repo = 'prabirshrestha/vim-lsp'

# 以下の2つのプラグインは必要に応じてインストールする
[[plugins]]
repo = 'prabirshrestha/asyncomplete.vim'

[[plugins]]
repo = 'prabirshrestha/asyncomplete-lsp.vim'

vim-plugをお使いの場合は、vimrcまたはinit.vimで以下のように記述するとインストールできると思います。

.vimrc
Plug 'prabirshrestha/vim-lsp'
Plug 'prabirshrestha/asyncomplete.vim'
Plug 'prabirshrestha/asyncomplete-lsp.vim'

npmパッケージのインストール

次に、以下の3つのnpmパッケージをインストールします。

$ npm install -g typescript-language-server typescript typescript-deno-plugin

vim-lspの設定

以下の設定をvimrcまたはinit.vimに追加してください。

if executable("typescript-language-server")
  " グローバルインストールされたnpmモジュールの保存場所
  let s:npm_root = trim(system("npm root -g"))

  " vim-lspのinitialization_optionsを使用して、typescript-deno-pluginのインストール場所をtypescript-language-serverへ伝えます
  let s:has_typescript_deno_plugin = isdirectory(s:npm_root . "/typescript-deno-plugin")
  let s:plugins = s:has_typescript_deno_plugin
    \ ? [{ "name": "typescript-deno-plugin", "location": s:npm_root }]
    \ : []
  augroup LspTypeScript
    autocmd!
    autocmd User lsp_setup call lsp#register_server({
    \   "name": "typescript-language-server",
    \   "cmd": {server_info -> ["typescript-language-server", "--stdio"]},
    \   "root_uri": {server_info->lsp#utils#path_to_uri(lsp#utils#find_nearest_parent_file_directory(lsp#utils#get_buffer_path(), 'tsconfig.json'))},
    \   "whitelist": ["typescript", "typescript.tsx"],
    \   "initialization_options": { "plugins": s:plugins },
    \ })
  augroup END
endif

これでセットアップは完了です。

動作例

上記セットアップを実施すると、入力補完や診断等の機能が動作します。

注意点

この記事で紹介したtypescript-language-serverからtypescript-deno-pluginを読み込ませる手法は、typescript-language-serverのドキュメントには記載されていません。
そのため、将来的には同様の方法では動作しなくなる可能性があります。

補足

deno_stdやサードパーティモジュールの補完や型チェックが効かないときはどうしたいいの?

おそらく、依存モジュールがインストールされていないのが原因だと思います。
deno cacheコマンドで依存モジュールをインストールすれば動作すると思います。

$ deno cache mod.ts

typescript-deno-pluginとは?

Denoにはいくつか独自の機能が存在します。

標準ではtsserverは上記の機能を認識することができず、うまく機能しません。
typescript-deno-pluginを使用することで、tsserverが上記の機能を認識してくれるようになります。

vscodeで開発したいときはどうすればいいの?

vscode-denoというDenoのコアチームによってメンテナンスされているvscode拡張があります。
vscodeをお使いの方は、こちらの拡張を使用することをおすすめします。

coc.nvimとvim-lspのどちらを使ったらいいの?

それぞれに利点はあるものの、個人的な意見としては、以下のような理由から、特にこだわりがなければcoc.nvimがよいのではないかと思います

  • セットアップが容易であること
  • GitHubのスター数が多い

Denoの開発の将来について

現在、DenoではLanguage Serverの実装が計画されています

deno lspコマンドを叩くことで、Denoに組み込まれたLanguage Serverが起動するようになります。

このコマンドが実装されれば、この記事で紹介した手法に限らず、あらゆるエディタ・IDEでDenoを使った開発が容易になると想像しています

実は筆者はちょうどこのPR(#8515)が建てられる数日前にdeno-lspというLSPサーバを自作していました...

まとめ

この記事ではVim/NeovimでDenoの開発環境をセットアップする方法について紹介しました。

現時点では、vscode以外のエディタで開発する際は少々工夫が必要ですが、deno lspコマンドが実装されれば、この状況も改善されると思います

もし興味があれば、ぜひDenoを触ってみてください! 🦕