Neovim で skkeleton を使う方法
前置き
この記事に続く Neovim の設定に関する記事です。今回は、Vim/Neovim 専用の日本語入力プラグインである vim-skk/skkeleton: SKK implements for Vim/Neovim with denops.vim の設定に関する情報を備忘録としてまとめます。
環境
OS
1エディション Windows 11 Pro
2バージョン 23H2
3インストール日 2022/07/11
4OS ビルド 22631.3807
5エクスペリエンス Windows Feature Experience Pack 1000.22700.1020.0
Neovim
1❯ nvim --version
2NVIM v0.9.4
3Build type: RelWithDebInfo
4LuaJIT 2.1.1696883897
5Compilation: C:/Program Files (x86)/Microsoft Visual Studio/2019/Enterprise/VC/Tools/MSVC/14.29.30133/bin/Hostx64/x64/cl.exe /MD /Zi /O2 /Ob1 -W3 -wd4311 -wd4146 -DUNIT_TESTING -D_CRT_SECURE_NO_WARNINGS -D_CRT_NONSTDC_NO_DEPRECATE -D_WIN32_WINNT=0x0602 -DMSWIN -DINCLUDE_GENERATED_DECLARATIONS -ID:/a/neovim/neovim/.deps/usr/include/luajit-2.1 -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/build/src/nvim/auto -ID:/a/neovim/neovim/build/include -ID:/a/neovim/neovim/build/cmake.config -ID:/a/neovim/neovim/src -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include -ID:/a/neovim/neovim/.deps/usr/include
6
7 システム vimrc: "$VIM\sysinit.vim"
8 省略時の $VIM: "C:/Program Files (x86)/nvim/share/nvim"
9
10Run :checkhealth for more info
プラグイン管理
プラグインは folke/lazy.nvim: 💤 A modern plugin manager for Neovim で管理しており、lazy.nvim にかかる init.lua
の設定は次のとおりです。プラグインごとに設定ファイルを分割したいので、プラグインの設定ファイルは 'C:\Users\(username)\AppData\Local\nvim\lua\plugins\'
ディレクトリに保存しています。
1local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
2if not (vim.uv or vim.loop).fs_stat(lazypath) then
3 vim.fn.system({
4 "git",
5 "clone",
6 "--filter=blob:none",
7 "https://github.com/folke/lazy.nvim.git",
8 "--branch=stable", -- latest stable release
9 lazypath,
10 })
11end
12vim.opt.rtp:prepend(lazypath)
13require("lazy").setup("plugins")
準備
関連するランタイムなどのインストール
skkeleton は Javascript/Typescript ランタイムの1つである Deno に依存していますので、まず Deno をインストールします。
公式サイトに記載されているインストール方法(Windows版)は、コマンドプロンプトで irm https://deno.land/install.ps1 | iex
コマンドを実行するという方法ですが、私は Github の Releases で配布されている .msi
をダウンロードしてインストールしました。
これで Deno をインストールできましたが、skkeleton は、Deno を利用して Vim/Neovim 双方で動くプラグインを作るためのエコシステムである denops.vim を利用して作成されていますので、denops.vim もインストールします。
denops.vim は、'C:\Users\(username)\AppData\Local\nvim\lua\plugins\denops.lua'
ファイルを作成して以下の設定を追記し、:Lazy
コマンドを実行してインストールします。
1return {
2 "vim-denops/denops.vim",
3 lazy = false,
4 priority = 500,
5 --config = true,
6}
辞書のインストール
SKK の変換に必要な辞書を SKK dictionary files gh-pages | dict からダウンロードします。保存場所は自由に決められます。私は C:\skk
ディレクトリに以下の辞書を保存しました。
- SKK-JISYO.L
- SKK-JISYO.jinmei
- SKK-JISYO.geo
- SKK-JISYO.propernoun
- SKK-JISYO.law
設定
これで必要なランタイムや辞書はインストールできましたので、init.lua
に設定を追加します。
1vim.api.nvim_set_keymap('i', '<C-j>', '<Plug>(skkeleton-enable)', {noremap = true})
2vim.api.nvim_set_keymap('c', '<C-j>', '<Plug>(skkeleton-enable)', {noremap = true})
3vim.api.nvim_set_keymap('i', '<C-l>', '<Plug>(skkeleton-disable)', {noremap = true})
4vim.api.nvim_set_keymap('c', '<C-l>', '<Plug>(skkeleton-disable)', {noremap = true})
5vim.fn['skkeleton#config']({
6 globalDictionaries = {
7 "C:/skk/SKK-JISYO.L",
8 "C:/skk/SKK-JISYO.geo",
9 "C:/skk/SKK-JISYO.jinmei",
10 "C:/skk/SKK-JISYO.lisp",
11 "C:/skk/SKK-JISYO.law",
12 },
13 eggLikeNewline = true,
14 keepState = true,
15 showCandidatesCount = 2,
16 registerConvertResult = true,
17})
18vim.fn['skkeleton#register_keymap']('input', '/', 'abbrev')
上の設定は、以下の動作を実現するための設定です。
vim.api.nvim_set_keymap( ~~~ )
ctrl-j
で skkeleton を有効化する(かな入力をオンにする)ctrl-l
で skkeleton を無効化する(かな入力をオフにする)
globalDictionaries = { ~~~ }
- 辞書は
C:/skk
ディレクトリに保存しているものを使う(フルパスで指定する)
- 辞書は
eggLikeNewLine = true
- 変換候補を選んで Enter キーをタイプしたときに確定のみ行う(
false
にすると改行される)
- 変換候補を選んで Enter キーをタイプしたときに確定のみ行う(
keepState = true
- Insert Mode を抜けても skkeleton の有効/無効の状態を保持する
showCandidatesCount = 2
- 2回目までの変換では複数の変換候補を表示しない
registerConvertResult = 2
- カタカナ変換等の結果を辞書に登録する
vim.fn['skkeleton#register_keymap']('input', '/', 'abbrev')
/
で abbrev モードに入る
追記1
上記の registerConvertResult = 2
は、正しくは registerConvertResult = true
です。
また、上記で設定した vim.fn['skkeleton#register_keymap']('input', '/', 'abbrev')
については、あまり使い道がなかったので、2024年7月時点では設定を削除しています。
さらに、辞書の保存場所を C:\Users\(username)\AppData\Local\nvim\skk_dict\
に変えましたが、globalDictionaries
に辞書のパスをハードコードするのはイマイチだと感じましたので、Vim の expand()
関数を使ってパスを展開することにしました。
1 vim.fn["expand"]('~/AppData/Local/nvim/skk_dict/SKK-JISYO.L'),
2 vim.fn["expand"]('~/AppData/Local/nvim/skk_dict/SKK-JISYO.geo'),
3 vim.fn["expand"]('~/AppData/Local/nvim/skk_dict/SKK-JISYO.jinmei'),
4 vim.fn["expand"]('~/AppData/Local/nvim/skk_dict/SKK-JISYO.law'),
補足
skkeleton の導入の説明は以上のとおりですが、動かせるようになるまでかなり苦戦しました。
と言いますのも、ctrl-j
で skkeleton を有効化しようとするとエラーが発生して有効化できないという状態が続いたためです。
エラーの様子は以下のスクリーンショットのとおりで、エラーメッセージで検索しても類似の事案が見当たらず、公式リポジトリの Issues にもそれらしい症状がありませんでした。なお、Neovim 起動時にもエラーが表示されていました。
起動時のエラーから denops のトラブルだと当たりを付けて :checkhealth
で問題の有無を調べましたが、問題はなさそうでした。そこでDeno を再インストールしたり、Deno のモジュールの @std/path - JSR をインストールしたり、さらにNeovim のバージョンを変えたりしたのですが解決できなかったので、Slack に用意された Vim-jp のチャットルームで相談しました。
すると :mes
コマンドで表示されるエラーメッセージの全文を見せて欲しいと言われましたので、Neovim を再起動して :mes
を実行してエラーメッセージの全文を確認したところ、「Deno のキャッシュに問題があるから call denops#cache#update(#{reload: v:true})
を実行して Neovim を再起動せよ」と書いてありました。
1[denops] ********************************************************************************
2[denops] Deno module cache issue is detected.
3[denops] Execute 'call denops#cache#update(#{reload: v:true})' and restart Vim/Neovim.
4[denops] See https://github.com/vim-denops/denops.vim/issues/358 for more detail.
5[denops] ********************************************************************************
6[denops] Failed to load plugin 'skkeleton': TypeError: Could not find constraint in the list of versions: @std/assert@^0.226.0
7[denops] Specifier: jsr:/@std/assert@^0.226.0/assert
8[denops] at https://jsr.io/@std/path/0.225.2/windows/join.ts:4:24
そこで call denops#cache#update(#{reload: v:true})
を実行して Neovim を再起動したところ、見事にエラーが発生しなくなりました。エラーの原因は Deno のキャッシュだったようですが、Slack の Vim-jp のチャットルームでも Deno のキャッシュ周りで色々トラブルが起きているという発言がありましたので、同じトラブルに巻き込まれてしまったようです。
追記2
このトラブルですが、WindowsTerminal + NuShell ではトラブルが続いているのに対し、WindowsTerminal + PowerShell では全く発生しません。原因は不明です。
SKK を使う理由
わざわざ SKK を使っている理由ですが、まず、文節区切りをユーザーが指定するという一手間が必要なものの、変換不要な平仮名入力では確定作業が不要なため、慣れればサクサク入力できるところに魅力を感じて使っています。文節区切りをユーザーが指定する手間についても、結局「漢字から平仮名に移り変わる部分を指定するだけ」と考えれば大した手間ではありません。
とはいえ、これだけならプラグインを導入しなくても Windows で動く SKK の corvusskk を導入すれば良い話で、Neovim 以外のアプリでは corvusskk を使っています。それでも skkeleton を使うのは、Vim/Neovim と IME の相性問題を解消するためです。
プラグインを使わなくても IME の状態を取得・変更できる外部アプリを使えば Vim/Neovim と IME の相性問題は解消できます。実際、以前 Vim を使っていたときはそうしたアプリを Vim から呼び出して IME のオン・オフを制御していました。
しかし、MS-IME を使う場合はこの方法で対応できますが、corvusskk を使う場合はダメでした。理由は、MS-IME だと「Normal Mode に入ったら IME オフ、Insert Mode に入ったら前回の Insert Mode での IME のオン・オフの状態を復元する」という制御で足りるのに対し、corvusskk では Insert Mode に入ったときに IME のオン・オフに加えて入力モードも復元する必要があり、その方法を見つけられなかったためです。
そのため、Vim/Neovim のプラグインとして提供されている SKK なら IME との相性問題を解決できるだろうと思い skkeleton を使うことにしました。