Neovim 0.11でシンタックスハイライトがちらつく問題の回避策

by
カテゴリ:
タグ:

Neovim 0.11ではシンタックスハイライトのパフォーマンス改善を狙った非同期処理が導入されました。

Treesitter highlighting is now asynchronous
https://neovim.io/doc/user/news-0.11.html#news-0.11

しかし、同一のバッファを複数のウィンドウで開くとちらつく場合があります。

Syntax highlight flicker when same buffer open in multiple windows at different scroll positions
https://github.com/neovim/neovim/issues/32660

この問題は0.11.2で修正予定とのことですが、不便すぎます。素朴にはvim.g._ts_force_sync_parsing = trueで同期処理に戻せますが、せっかくなら非同期処理を活用したいので、状況に応じて切り替える方法を紹介します。

vim.api.nvim_create_autocmd({ "BufWinEnter", "WinNew", "WinClosed", "TabEnter" }, {
  group = vim.api.nvim_create_augroup("ts_toggle_sync_parsing", {}),
  callback = function(ctx)
    local function exec()
      local wins = vim.api.nvim_tabpage_list_wins(vim.api.nvim_get_current_tabpage())
      local bufs = {}
      for _, win in ipairs(wins) do
        local buf = vim.api.nvim_win_get_buf(win)
        if bufs[buf] == true then
          local parsable = pcall(vim.treesitter.get_parser, buf)
          if parsable then
            vim.g._ts_force_sync_parsing = true
            return
          end
          -- set to false to avoid multiple tests on the availability of parser
          bufs[buf] = false
        end
        if bufs[buf] == nil then
          bufs[buf] = true
        end
      end
      vim.g._ts_force_sync_parsing = false
    end

    if ctx.event == "WinClosed" then
      -- WinClosedイベントは名前に反してウィンドウが閉じる直前に発火するので、遅延する
      return vim.schedule(exec)
    end
    return exec()
  end,
})

工夫箇所は以下。

こんなワークアラウンドを入れずともいいよう、早く修正されるといいですね。

ENJOY!!