Vim - vim-lsp で Typescript 開発環境を構築する

              · ·

Language server + Vim 8.1 + vim-lsp 構成で Typescript 向けの開発環境を構築した時の作業ログ

コード補完やフォーマットなどの開発支援を受けられる環境を構築する screen-cast

モチベーション

ここ最近のお仕事は主に Golang で CLIツール やら WebAPI を書いている。 開発環境を色々と試した結果、 Vim 8.1 + golang.org/x/tools/cmd/gopls 1 + prabirshrestha/vim-lsp で落ち着いた。

これを機に 趣味で Typescript を書く際にも Vim で開発したなったので環境を構築してみた。

なお、基本的には vim-lsp/wiki に記載されている内容を参考にしている。

language server のインストール

世の中には Typescript 向けの language-server 実装は複数ある。 microsoft.github.io のimplementers/servers によると、 以下の2つが候補だろうか

実装内容に若干の差はある様だが、とりあえず深入りせず、 vim-lsp/wiki にておすすめされている theia-ide/typescript-language-server を導入してみる。 npm にて導入が可能とのことなので、以下でグローバルにインストール:

npm install -g typescript typescript-language-server

インストールが成功すると、 tsserver コマンドおよび typescript-language-server コマンドが実行可能となっているはず。

micheam:~$ which tsserver
/usr/local/bin/tsserver

micheam:~$ which typescript-language-server
/usr/local/bin/typescript-language-server
micheam:~$ typescript-language-server --version
0.3.8

language server の登録

Language server が実行可能となったので、クライアント (Vim) 側の設定に入る。 前述の通り、今回は language server client に vim-lsp を採用している。

vim-plug での管理の場合 .vimrc に追加の上、 :PlugInstall を実行:

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

続いて、 vim-lsp に対して language server を登録する。 .vimrc に記述しても良いが、今回は 他の language server 設定とまとめて管理したかったので プラグインとして切り出した。

micheam/vim-lsp-settings

" 一部を抜粋
if executable('typescript-language-server')
    augroup LspTypeScript
        au!
        autocmd User lsp_setup call lsp#register_server({
                    \ 'name': 'typescript-language-server',
                    \ 'cmd': {server_info->[&shell, &shellcmdflag, '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'],
                    \ })
        autocmd FileType typescript setlocal omnifunc=lsp#complete
    augroup END :echomsg "vim-lsp with `typescript-language-server` enabled"
else
    :echomsg "vim-lsp for typescript unavailable"
endif

ちなみに

vim-lsp/wiki では vim-lsp-typescript という、 typescript language server を vim-lsp に自動登録するプラグイン を導入することがおすすめされているようだ。 私自身は、言語ごとの設定を1 箇所にまとめたかったので、自前で設定することとした。

動作の確認

ここまで設定を行うと、以下のGIFにあるようなコード補完やフォーマットが可能となる。

(再掲) screen-cast

README によると、theia-ide/typescript-language-server は lsp で規定されている全ての機能を実装済みとのこと。

theia-ide typescript-language-server TypeScript-and-JavaScript Language Server

そのため、 vim-lsp で定義されているコマンドを実行するか、好みのキーにマッピングするのが良いだろう。

Vim-lsp の提供するコマンド

:h vim-lsp-commands から抜粋して意訳したものを一応記載しておくが、 詳細については vim-lsp#suported-commands もしくは Vimヘルプ を参照のこと。

コマンド 概要
:LspCodeAction ファイル修正のために適用可能なコマンドのリストを取得する(quick fix)
:LspDocumentDiagnostics カレントドキュメントを診断する
:LspDeclaration 宣言に移動する
:LspDefinition 定義に移動する
:LspDocumentFormat ドキュメント全体をフォーマットする
:LspDocumentFormatSync LspDocumentFormat と同じ。ただし処理が終了するまで操作をブロックする
:LspDocumentRangeFormat 選択範囲をフォーマットする
:LspDocumentSymbol カレントドキュメント内のシンボルを取得する
:LspHover hover 情報を取得し、プレビューウィンドウに表示する
:LspNextError 次の診断エラーにジャンプする
:LspNextReference カーソル下のシンボルの次の参照へジャンプする
:LspPreviousError 前の診断エラーにジャンプする
:LspPreviousReference カーソル下のシンボルの前の参照へジャンプする
:LspImplementation インターフェースの全ての実装を捜索する
:LspReferences 全ての参照を捜索する
:LspRename シンボルをリネームする
:LspTypeDefinition 型の定義へ移動する
:LspWorkspaceSymbol ワークスペース内のシンボルを検索し表示する
:LspStatus 登録済み language server 全てのステータスを表示する

コマンドのキーマッピング

特によく使うコマンドは使いやすいようにマッピングしてみた。 ここら辺は使ってゆく中で随時改善してゆく。

nmap <buffer> <F12> <Plug>(lsp-definition)
nmap <buffer> <C-]> <Plug>(lsp-definition)
nmap <buffer> K <Plug>(lsp-hover)
nmap <buffer> <C-n> <plug>(lsp-next-error)
nmap <buffer> <C-p> <plug>(lsp-previous-error)
nmap <buffer> <S-F12> <plug>(lsp-references)
nmap <buffer> <S-F6> <plug>(lsp-rename)
nmap <buffer> =- <plug>(lsp-document-format)
nmap <buffer> <F11> <plug>(lsp-implementation)
nmap <buffer> <F2> <plug>(lsp-type-definition)

以下に置いてある
micheam/vim-lsp-settings/ftplugin/typescript.vim

おわり


  1. ちなみに、Bingoの作者 が拡張した機能拡張バージョンを使用している。(早く本体に取り込まれたらいいのに) [return]

comments powered by Disqus