📝

Neovimのnvim_win_call APIの紹介

2021/06/27に公開

Neovimにnvim_win_call()を追加したのでその紹介をする。

https://github.com/neovim/neovim/pull/14717

ちなみに実装はwin_execute()が使ってる関数を呼んでいるだけで、
全ては元々のVimでの実装とそれをNeovimに持ってきてるパッチのおかげ。

使い方

ウィンドウを指定してコマンドを実行できるwin_execute()をLuaで扱いやすくしたようなAPIになっている。
以下のようにfunctionを渡して気軽に値をやり取りできる。

-- 何かウィンドウを開く(カレントウィンドウにはしない)
local bufnr = vim.api.nvim_create_buf(false, true)
vim.api.nvim_buf_set_lines(bufnr, 0, -1, false, vim.fn["repeat"]({""}, 100))
local window_id = vim.api.nvim_open_win(bufnr, false, {
  width = 50,
  height = 10,
  relative = "editor",
  row = 10,
  col = 10,
})
vim.api.nvim_win_set_cursor(window_id, {50, 0})

-- カレントウィンドウに対して動くコマンドや関数を実行
local view
local first_row = vim.api.nvim_win_call(window_id, function()
  view = vim.fn.winsaveview() -- function外の変数を扱ったり
  vim.cmd("normal! G")
  local result = vim.fn.line("w0")
  vim.fn.winrestview(view)
  return result -- 値を返したり
end)

print(first_row) -- 91
print(view.topline) -- 46

実例

実際の使用感を試すため、
表示範囲だけを検索できるプラグインreacher.nvimを複数ウィンドウに対応させてみた。

ヘビーに使っても問題なさげで便利。

Discussion