🔨

Vim + TypeScript の環境を一から作ってみる

2023/12/07に公開

本記事は株式会社アルダグラム Advent Calendar 2023 7日目の記事です。
こんにちは! @takjin です。

アルダグラムではフロントエンドは常日頃 Vim Script TypeScript(React + Next.js) を使って開発をしています。
今回は Vim で TypeScript を書くための設定を一から構築していきたいと思います。

Vim をクローンしてくる

何はともあれ、Vimがなければ話が始まりません。Vimをクローンしてきます。

$ git clone https://github.com/vim/vim.git

Vim をビルドする

Vim をクローンしたら configure オプションを指定してビルドしていきます。

--prefix=/path/to/vim-9.0 で任意のディレクトリにインストールします。特に指定がなければ /usr/local/bin /usr/local/lib などにインストールされるようです。

また、Vim は他言語での拡張付きでコンパイルすることができます。例えば --enable-pythoninterpと指定すれば、python で書かれた Vim プラグインを動作させることができたりします。 コンパイルオプションは ./configure --help で確認することができます。

$ cd vim
$ ./configure \
--prefix=/path/to/vim-9.0

# 拡張付きで入れたいのであれば
# $ ./configure \
# --prefix=/path/to/vim-9.0
# --enable-pythoninterp \ # python拡張を指定
# --enable-luainterp \ # lua拡張を指定
# --enable-rubyinterp \ # ruby拡張を指定

$ make && make install

パスを通す

Vim のビルドが完了したら bashrc/zshrc などにパスを通しておきましょう。

export PATH="/path/to/vim-9.0/bin:$PATH"
alias vi=vim

これで、Vim が利用できるようになりました。Vim はほぼ毎日のように更新されているので、最新のものが使いたい時には、configure オプションなどをシェルスクリプトなどにしておくと、ビルドが楽になるでしょう。

プラグインマネージャーの導入

Vimが使えるようになったので、プラグインマネージャーを導入していきます。 vim-plugdpp.vimvim-jetpack など様々なプラグインマネージャーがありますが、筆者は minpac を利用しています。 minpac は Vim 標準の package 機能を利用していてシンプルで高速です。プラグインの利用数が全部で20個にも満たない私には必要十分です。もし、数百以上のプラグインを利用しているであれば、上述した別のプラグインマネージャーがより最適かもしれません。

$ git clone https://github.com/k-takata/minpac.git ~/.vim/pack/minpac/opt/minpac

クローンしてきたら、https://github.com/k-takata/minpac の readme を参考に設定していきます

if &compatible
  set nocompatible
endif

function! PackInit() abort
  packadd minpac

  call minpac#init()
  
  " ここにインストールしたいプラグインを記述していきます
  call minpac#add('prabirshrestha/vim-lsp')
  call minpac#add('mattn/vim-lsp-settings')
endfunction

command! PackUpdate call PackInit() | call minpac#update()
command! PackClean  call PackInit() | call minpac#clean()
command! PackStatus packadd minpac | call minpac#status()

これでプラグインが手軽にインストールできる環境が整いました。

LSP周りの設定

まずは Vim での開発を快適にするのに欠かせない Language Server 周りの設定です。
LSP クライアントには vim-lsptypescript-language-server の導入は vim-lsp-settings 経由で行っていきます。

vim-lsp-settings は、Language Server の導入の敷居を下げてくれるのと同時に、 vim-lsp に利用する Language Server の設定を記述する手間を省いてくれます。

" https://github.com/prabirshrestha/vim-lsp
" https://github.com/mattn/vim-lsp-settings

" minpac 経由でプラグインのインストール
call minpac#add('prabirshrestha/vim-lsp')
call minpac#add('mattn/vim-lsp-settings')

" vim-lsp
function! s:onLspBufferEnabled() abort
  setlocal omnifunc=lsp#complete
  setlocal signcolumn=yes
  if exists('+tagfunc') | setlocal tagfunc=lsp#tagfunc | endif

  nnoremap <buffer> gd <plug>(lsp-definition)
  nnoremap <buffer> gs <plug>(lsp-document-symbol-search)
  nnoremap <buffer> gS <plug>(lsp-workspace-symbol-search)
  nnoremap <buffer> gr <plug>(lsp-references)
  nnoremap <buffer> gi <plug>(lsp-implementation)
  nnoremap <buffer> gt <plug>(lsp-type-definition)
  nnoremap <buffer> gn <plug>(lsp-rename)
  nnoremap <buffer> [g <plug>(lsp-previous-diagnostic)
  nnoremap <buffer> ]g <plug>(lsp-next-diagnostic)
  nnoremap <buffer> K <plug>(lsp-hover)
  nnoremap <buffer> <C-l>d <Cmd>rightbelow LspDefinition<CR>

  let g:lsp_format_sync_timeout = 1000
endfunction

augroup lsp_install
  au!
  autocmd User lsp_buffer_enabled call s:onLspBufferEnabled()
augroup END

" vim-lsp-settins
let g:lsp_settings_filetype_javascript = ['typescript-language-server']
let g:lsp_settings_filetype_javascriptreact = ['typescript-language-server']
let g:lsp_settings_filetype_typescript = ['typescript-language-server']
let g:lsp_settings_filetype_typescriptreact = ['typescript-language-server']

vim-lsp-settings のインストールが完了したら typescript-language-server をインストールしていきます。
:LspInstallServer コマンドは filetype に応じた Language Server をインストールしてくれます。例えば、 .tsx.ts ファイルを開いた状態で、 :LspInstallServer とすると typescript-language-server がインストールされます。(便利
また :LspManageServer とすれば一覧が表示されるので、ここから任意の Language Server をインストール/アンイストールすることができます。 i でインストール、 x でアンイストールです。

補完、lint周りの設定

次に 補完、lint 周りの設定を行っていきます。設定方法は色々あるようですが、補完には asyncomplete 、lint 周りは ale を使っています。また、 vim-lspale をよしなに橋渡ししてくれる vim-lsp-ale も一緒に入れておくと良いでしょう。

" https://github.com/prabirshrestha/asyncomplete.vim
" https://github.com/prabirshrestha/asyncomplete-lsp.vim
" https://github.com/dense-analysis/ale
" https://github.com/rhysd/vim-lsp-ale
call minpac#add('prabirshrestha/asyncomplete.vim')
call minpac#add('prabirshrestha/asyncomplete-lsp.vim')
call minpac#add('dense-analysis/ale')
call minpac#add('rhysd/vim-lsp-ale')

" ale.vim
let g:ale_floating_preview = 1

" エラーが発生している行の直下にエラーメッセージを表示します
" 'all' or '2' or 2 エラーが発生している全ての行でメッセージを表示
" 'current' or '1' or 1 エラーが発生している行にカーソルを置くと表示
" 'disabled' or '0' or 0 エラーが発生している行に表示しない。エラーが発生している行にカーソルを置くとコマンドラインモードには表示してくれる
let g:ale_virtualtext_cursor = 'disabled' 

" linter を有効にする
let g:ale_linters_explicit = 1

" 編集中のバッファを保存するタイミングで自動でコード修正をしてくれる
let g:ale_fix_on_save = 1

let g:ale_fixers = {
  'typescript': ['eslint', 'prettier'],
  'typescriptreact': ['eslint', 'prettier'],
}
let g:ale_linters = {
  'typescript': ['eslint'],
  'typescriptreact': ['eslint'],
}

これで、pritter で lint をかけながら typescript-language-server で型チェックを行えるようになりました。
以上で Vim + TypeScript の環境構築は完了です。
Vimのプラグインはヘルプがしっかり書かれているものが多いですので、:help [plugin-name] で自分好みの設定を探してみるのも良いでしょう。
それではよき Vimライフを。

もっとアルダグラムエンジニア組織を知りたい人、ぜひ下記の情報をチェックしてみてください!

アルダグラム Tech Blog

Discussion