From 9aa4608401384a59ea54e0ba800ce063775e8ae9 Mon Sep 17 00:00:00 2001 From: "Justin M. Keyes" Date: Wed, 20 May 2026 17:33:01 -0400 Subject: refactor: introduce nvim_on internally #39883 Problem: `nvim_create_autocmd` is too verbose and its `callback` requires extra "nesting". Solution: Introduce `nvim_on`. Start using it internally. Then we can get a feel for how it should look before making it public. --- runtime/lua/vim/treesitter/dev.lua | 213 ++++++++++++++++--------------------- 1 file changed, 90 insertions(+), 123 deletions(-) (limited to 'runtime/lua/vim/treesitter/dev.lua') diff --git a/runtime/lua/vim/treesitter/dev.lua b/runtime/lua/vim/treesitter/dev.lua index a1dd988497..64d9a1352e 100644 --- a/runtime/lua/vim/treesitter/dev.lua +++ b/runtime/lua/vim/treesitter/dev.lua @@ -1,4 +1,5 @@ local api = vim.api +local nvim_on = require('vim._core.util').nvim_on local Range = require('vim.treesitter._range') @@ -469,107 +470,83 @@ function M.inspect_tree(opts) local group = api.nvim_create_augroup('nvim.treesitter.dev', {}) - api.nvim_create_autocmd('CursorMoved', { - group = group, - buf = b, - callback = function() - if not api.nvim_buf_is_loaded(buf) then - return true - end + nvim_on('CursorMoved', group, { buf = b }, function() + if not api.nvim_buf_is_loaded(buf) then + return true + end - w = api.nvim_get_current_win() - api.nvim_buf_clear_namespace(buf, treeview.ns, 0, -1) - local row = api.nvim_win_get_cursor(w)[1] - local lnum, col, end_lnum, end_col = treeview:get(row).node:range() - api.nvim_buf_set_extmark(buf, treeview.ns, lnum, col, { - end_row = end_lnum, - end_col = math.max(0, end_col), - hl_group = 'Visual', - }) + w = api.nvim_get_current_win() + api.nvim_buf_clear_namespace(buf, treeview.ns, 0, -1) + local row = api.nvim_win_get_cursor(w)[1] + local lnum, col, end_lnum, end_col = treeview:get(row).node:range() + api.nvim_buf_set_extmark(buf, treeview.ns, lnum, col, { + end_row = end_lnum, + end_col = math.max(0, end_col), + hl_group = 'Visual', + }) - -- update source window if original was closed - if not api.nvim_win_is_valid(win) then - win = assert(vim.fn.win_findbuf(buf)[1]) - end + -- update source window if original was closed + if not api.nvim_win_is_valid(win) then + win = assert(vim.fn.win_findbuf(buf)[1]) + end - local topline, botline = vim.fn.line('w0', win), vim.fn.line('w$', win) + local topline, botline = vim.fn.line('w0', win), vim.fn.line('w$', win) - -- Move the cursor if highlighted range is completely out of view - if lnum < topline and end_lnum < topline then - api.nvim_win_set_cursor(win, { end_lnum + 1, 0 }) - elseif lnum > botline and end_lnum > botline then - api.nvim_win_set_cursor(win, { lnum + 1, 0 }) - end - end, - }) + -- Move the cursor if highlighted range is completely out of view + if lnum < topline and end_lnum < topline then + api.nvim_win_set_cursor(win, { end_lnum + 1, 0 }) + elseif lnum > botline and end_lnum > botline then + api.nvim_win_set_cursor(win, { lnum + 1, 0 }) + end + end) - api.nvim_create_autocmd('CursorMoved', { - group = group, - buf = buf, - callback = function() - if not api.nvim_buf_is_loaded(b) then - return true - end + nvim_on('CursorMoved', group, { buf = buf }, function() + if not api.nvim_buf_is_loaded(b) then + return true + end - set_inspector_cursor(treeview, opts.lang, buf, b, w) - end, - }) + set_inspector_cursor(treeview, opts.lang, buf, b, w) + end) - api.nvim_create_autocmd({ 'TextChanged', 'InsertLeave' }, { - group = group, - buf = buf, - callback = function() - if not api.nvim_buf_is_loaded(b) then - return true - end + nvim_on({ 'TextChanged', 'InsertLeave' }, group, { buf = buf }, function() + if not api.nvim_buf_is_loaded(b) then + return true + end - local treeview_opts = treeview.opts - treeview = assert(TSTreeView:new(buf, opts.lang)) - treeview.opts = treeview_opts - treeview:draw(b) - end, - }) + local treeview_opts = treeview.opts + treeview = assert(TSTreeView:new(buf, opts.lang)) + treeview.opts = treeview_opts + treeview:draw(b) + end) - api.nvim_create_autocmd('BufLeave', { - group = group, - buf = b, - callback = function() - if not api.nvim_buf_is_loaded(buf) then - return true - end - api.nvim_buf_clear_namespace(buf, treeview.ns, 0, -1) - end, - }) + nvim_on('BufLeave', group, { buf = b }, function() + if not api.nvim_buf_is_loaded(buf) then + return true + end + api.nvim_buf_clear_namespace(buf, treeview.ns, 0, -1) + end) - api.nvim_create_autocmd('BufLeave', { - group = group, - buf = buf, - callback = function() - if not api.nvim_buf_is_loaded(b) then - return true - end - api.nvim_buf_clear_namespace(b, treeview.ns, 0, -1) - end, - }) + nvim_on('BufLeave', group, { buf = buf }, function() + if not api.nvim_buf_is_loaded(b) then + return true + end + api.nvim_buf_clear_namespace(b, treeview.ns, 0, -1) + end) - api.nvim_create_autocmd({ 'BufHidden', 'BufUnload', 'QuitPre' }, { - group = group, - buf = buf, - callback = function() - -- don't close inpector window if source buffer - -- has more than one open window - if #vim.fn.win_findbuf(buf) > 1 then - return - end + nvim_on({ 'BufHidden', 'BufUnload', 'QuitPre' }, group, { buf = buf }, function() + -- don't close inpector window if source buffer + -- has more than one open window + if #vim.fn.win_findbuf(buf) > 1 then + return + end - -- close all tree windows - for _, window in pairs(vim.fn.win_findbuf(b)) do - close_win(window) - end + -- close all tree windows + for _, window in pairs(vim.fn.win_findbuf(b)) do + close_win(window) + end - return true - end, - }) + return true + end) end local edit_ns = api.nvim_create_namespace('nvim.treesitter.dev_edit') @@ -671,53 +648,43 @@ function M.edit_query(lang) api.nvim_buf_set_name(query_buf, string.format('%s/query_editor.scm', lang)) local group = api.nvim_create_augroup('nvim.treesitter.dev_edit', {}) - api.nvim_create_autocmd({ 'TextChanged', 'InsertLeave' }, { - group = group, + nvim_on({ 'TextChanged', 'InsertLeave' }, group, { buf = query_buf, desc = 'Update query editor diagnostics when the query changes', - callback = function() - vim.treesitter.query.lint(query_buf, { langs = lang, clear = false }) - end, - }) - api.nvim_create_autocmd({ 'TextChanged', 'InsertLeave', 'CursorMoved', 'BufEnter' }, { - group = group, + }, function() + vim.treesitter.query.lint(query_buf, { langs = lang, clear = false }) + end) + nvim_on({ 'TextChanged', 'InsertLeave', 'CursorMoved', 'BufEnter' }, group, { buf = query_buf, desc = 'Update query editor highlights when the cursor moves', - callback = function() - if api.nvim_win_is_valid(win) then - update_editor_highlights(query_win, win, lang) - end - end, - }) - api.nvim_create_autocmd('BufLeave', { - group = group, + }, function() + if api.nvim_win_is_valid(win) then + update_editor_highlights(query_win, win, lang) + end + end) + nvim_on('BufLeave', group, { buf = query_buf, desc = 'Clear highlights when leaving the query editor', - callback = function() - api.nvim_buf_clear_namespace(buf, edit_ns, 0, -1) - end, - }) - api.nvim_create_autocmd('BufLeave', { - group = group, + }, function() + api.nvim_buf_clear_namespace(buf, edit_ns, 0, -1) + end) + nvim_on('BufLeave', group, { buf = buf, desc = 'Clear the query editor highlights when leaving the source buffer', - callback = function() - if not api.nvim_buf_is_loaded(query_buf) then - return true - end + }, function() + if not api.nvim_buf_is_loaded(query_buf) then + return true + end - api.nvim_buf_clear_namespace(query_buf, edit_ns, 0, -1) - end, - }) - api.nvim_create_autocmd({ 'BufHidden', 'BufUnload' }, { - group = group, + api.nvim_buf_clear_namespace(query_buf, edit_ns, 0, -1) + end) + nvim_on({ 'BufHidden', 'BufUnload' }, group, { buf = buf, desc = 'Close the editor window when the source buffer is hidden or unloaded', once = true, - callback = function() - close_win(query_win) - end, - }) + }, function() + close_win(query_win) + end) api.nvim_buf_set_lines(query_buf, 0, -1, false, { ';; Write queries here (see $VIMRUNTIME/queries/ for examples).', -- cgit