はじめに
Clojure (clojure-cli) を、Neovim用プラグインであるConjureで動かす。
導入方法 (Neovim/Plug)
NeovimとClojure CLI Toolsは、既に入っている前提。
-- init.lua
vim.g.maplocalleader = ','
vim.cmd([[
call plug#begin()
Plug 'tpope/vim-dispatch'
Plug 'clojure-vim/vim-jack-in'
Plug 'radenling/vim-dispatch-neovim'
Plug 'Olical/conjure'
call plug#end()
]])
- 上記を
init.lua
に記載した状態で:PlugInstall
する。-
maplocalleader
の文字は任意。 -
maplocalleader
の設定は、Plug
より前で行う必要がある。
-
-
:Clj
でclojure-cliのREPLを起動。- 起動後は、
C-\ C-n
でREPLから抜ける&他のバッファに変えてしまってもOK。 - このREPLは裏側で動いているだけで、基本的には使わない。
- 起動後は、
- 適当な
.clj
ファイルを開くと「REPLに接続しました」のポップアップが出て、Conjureが利用可能になる。- 上手くつながらなかった場合は、
:ConureConnect
で手動でつなげる。
- 上手くつながらなかった場合は、
基本操作
コマンド | 機能 |
---|---|
,ee |
カーソルが入っている括弧を評価 |
,eb |
バッファを評価 |
,E |
(ビジュアルモードで) 選択範囲を評価 |
,lv |
ウィンドウを縦に分割して、REPLを表示 |
,lq |
分割されたウィンドウを閉じる |
※ 上記の,
は<maplocalleader>
。「導入方法」の設定によって読み替える。
※ 他の操作はマニュアル (英語) 参照
※ :verbose :map ,
でも、,
から始まるキーマップを調べられる。
追加設定
自動補完
coc.nvim / asyncomplete.vim / nvim-cmp が利用可能であり、Conjure開発者がnvim-cmpを推奨しているため、これを設定。lspconfig
の設定で、clojure-lsp
ではなくclojure_lsp
である点に注意。
vim.cmd([[
call plug#begin()
Plug 'neovim/nvim-lspconfig'
Plug 'hrsh7th/cmp-nvim-lsp'
Plug 'hrsh7th/cmp-buffer'
Plug 'hrsh7th/cmp-path'
Plug 'hrsh7th/cmp-cmdline'
Plug 'hrsh7th/nvim-cmp'
Plug 'PaterJason/cmp-conjure'
call plug#end()
]])
local cmp = require'cmp'
cmp.setup({
snippet = {
expand = function(args)
vim.fn["vsnip#anonymous"](args.body) -- For `vsnip` users.
end,
},
window = {
},
mapping = cmp.mapping.preset.insert({
['<C-b>'] = cmp.mapping.scroll_docs(-4),
['<C-f>'] = cmp.mapping.scroll_docs(4),
['<C-Space>'] = cmp.mapping.complete(),
['<C-e>'] = cmp.mapping.abort(),
['<CR>'] = cmp.mapping.confirm({ select = true }),
}),
sources = cmp.config.sources({
{ name = 'nvim_lsp' },
}, {
{ name = 'buffer' },
})
})
cmp.setup.cmdline({ '/', '?' }, {
mapping = cmp.mapping.preset.cmdline(),
sources = {
{ name = 'buffer' }
}
})
cmp.setup.cmdline(':', {
mapping = cmp.mapping.preset.cmdline(),
sources = cmp.config.sources({
{ name = 'path' }
}, {
{ name = 'cmdline' }
})
})
local capabilities = require('cmp_nvim_lsp').default_capabilities()
require('lspconfig')['clojure_lsp'].setup {
capabilities = capabilities
}
下記でclojure-lspの本体も入れる。
# Mac/Linux
brew remove clojure-lsp # if you have old clojure-lsp installed via brew
brew install clojure-lsp/brew/clojure-lsp-native
# Script
sudo bash < <(curl -s https://raw.githubusercontent.com/clojure-lsp/clojure-lsp/master/install)
# Windows
scoop install clojure-lsp
Vim起動時に、REPLも自動起動させる
Vimを立ち上げる度に:Clj
を打つのが手間ならば、下記で自動化できる。'^['
の部分は^
と[
を打ち込むのではなく、<C-v><Esc>
をインサートモードで入力することに注意。
vim.api.nvim_create_autocmd({'VimEnter'}, {
pattern = {'*'},
callback = function()
vim.cmd([[
Clj
close!
call feedkeys('^[')
]])
end
})
neovim-session-managerと併用する
neovim-session-manager等のセッション管理系のプラグインが入っているとREPLもそのプラグインに保存され、次回起動時に復元されてしまう。上述のREPL自動起動は復元がなされているかどうかに関わらず新たにREPLを開いてしまうため、バッファがREPLであふれてしまう。
これでは具合が悪いので、下記のコードで①Vim終了時のREPLクローズと、②セッション復元後にREPL自動起動を行うようにする。
-- ①Vim終了時にREPLを閉じる
vim.api.nvim_create_autocmd({'ExitPre'}, {
pattern = {'*'},
callback = function()
vim.cmd('bd! term://')
end
})
-- ②REPL起動はセッション復元後 (前述コードの'VimEnter'が'SessionLoadPoist'になっている)
vim.api.nvim_create_autocmd({'SessionLoadPost'}, {
pattern = {'*'},
callback = function()
vim.cmd([[
Clj
close!
call feedkeys('')
]])
end
})
ポップアップの色を変える
ctermで利用できる色は、例えばこういったサイトで調べられる。
vim.cmd('highlight NormalFloat ctermbg=231')
ポップアップの位置を変える
私はnoice.vimを通知機能付きで使っているので、ポップアップが右上に出ると干渉する。そこで、ポップアップを右下に出るようにする。なお、ポップアップの設定をvim.cmd('let g:conjure#log#hud#enabled = 0')
で消せるとヘルプに書いてあるのだが、私の環境では機能しなかった。
vim.cmd('let g:conjure#log#hud#anchor = "SE"')
画面分割時に、REPLを右側に表示する
vim.cmd('let g:conjure#log#botright = 1')
同機能プラグインの紹介
同じような機能を持つプラグインに、fireplace.vim、vim-iced、spacevimのclojureレイヤーの3つがある。
vim-fireplaceはミニマムな機能を提供するもので、プラグイン操作が分かりやすい。ただし、ある値・関数を評価すると、その結果が返るまでVimが操作を受付けなくなるのが難点。vim-icedはその反対で、プロジェクト向けの機能が充実しているイメージ。"Asynchronous evaluation"ということで、時間がかかる評価をしてもVim上で編集を続けられる。REPLのデザイン・挙動が少しユニークに思えた。spacevimは機能の導入が非常に楽な代わりに、使っていて分かるレベルでVimの挙動が重くなる。Conjureはと言うと、開発者がclojure-cliを好きと言っており、全体的にシンプル1。
fireplace.vimの開発者は「Vim・プラグイン・アーティスト」を自称していて、vim-icedの場合は企業でClojureプロジェクトを進めているVimmer (日本人)。ConjureはLispラブなプログラマ。spacevimはコミュニティ駆動。各プラグインで開発者の特色が出ていて面白い。
私は1ファイルに収まるようなちょっとしたコードを書くためにClojureを利用しているので、今のところ、Conjureがちょうど良い。
デモ (英語)
curl -fL conjure.fun/school | sh
を打つと基本的操作のデモを、(curl
/sh
が動くなら) インストールなしで体験できる。これがなかなか良くできていて、このデモのおかげでConjureを利用しようと思えた。
参考
-
感覚的には、fireplace.vim=ミニマム、vim-iced=多機能、spacevim=イージー、conjure=シンプル。fireplace.vim以外は、"Asynchronous evaluation"の機能を持つ。 ↩