From bdb81afab3e5c43a33267666c2689feb284f6b52 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Sat, 25 May 2024 20:37:33 +0800 Subject: refactor(lua): rewrite vim.highlight.range() (#28986) - Use getregionpos(). - Use a single extmark for non-blockwise selection. --- runtime/lua/vim/highlight.lua | 55 +++++++++++++++++++++++++++++++++---------- 1 file changed, 42 insertions(+), 13 deletions(-) (limited to 'runtime/lua/vim/highlight.lua') diff --git a/runtime/lua/vim/highlight.lua b/runtime/lua/vim/highlight.lua index f278bd357f..89298ce568 100644 --- a/runtime/lua/vim/highlight.lua +++ b/runtime/lua/vim/highlight.lua @@ -20,8 +20,8 @@ M.priorities = { --- @class vim.highlight.range.Opts --- @inlinedoc --- ---- Type of range. See [setreg()] ---- (default: `'charwise'`) +--- Type of range. See [getregtype()] +--- (default: `'v'` i.e. charwise) --- @field regtype? string --- --- Indicates whether the range is end-inclusive @@ -49,20 +49,49 @@ function M.range(bufnr, ns, higroup, start, finish, opts) local priority = opts.priority or M.priorities.user local scoped = opts._scoped or false - -- TODO: in case of 'v', 'V' (not block), this should calculate equivalent - -- bounds (row, col, end_row, end_col) as multiline regions are natively - -- supported now - local region = vim.region(bufnr, start, finish, regtype, inclusive) - for linenr, cols in pairs(region) do - local end_row - if cols[2] == -1 then - end_row = linenr + 1 - cols[2] = 0 + local pos1 = type(start) == 'string' and vim.fn.getpos(start) + or { bufnr, start[1] + 1, start[2] + 1, 0 } + local pos2 = type(finish) == 'string' and vim.fn.getpos(finish) + or { bufnr, finish[1] + 1, finish[2] + 1, 0 } + + local buf_line_count = vim.api.nvim_buf_line_count(bufnr) + pos1[2] = math.min(pos1[2], buf_line_count) + pos2[2] = math.min(pos2[2], buf_line_count) + + if pos1[2] <= 0 or pos1[3] <= 0 or pos2[2] <= 0 or pos2[3] <= 0 then + return + end + + vim.api.nvim_buf_call(bufnr, function() + local max_col1 = vim.fn.col({ pos1[2], '$' }) + pos1[3] = math.min(pos1[3], max_col1) + local max_col2 = vim.fn.col({ pos2[2], '$' }) + pos2[3] = math.min(pos2[3], max_col2) + end) + + local region = vim.fn.getregionpos(pos1, pos2, { + type = regtype, + exclusive = not inclusive, + eol = true, + }) + -- For non-blockwise selection, use a single extmark. + if regtype == 'v' or regtype == 'V' then + region = { { region[1][1], region[#region][2] } } + end + + for _, res in ipairs(region) do + local start_row = res[1][2] - 1 + local start_col = res[1][3] - 1 + local end_row = res[2][2] - 1 + local end_col = res[2][3] + if regtype == 'V' then + end_row = end_row + 1 + end_col = 0 end - api.nvim_buf_set_extmark(bufnr, ns, linenr, cols[1], { + api.nvim_buf_set_extmark(bufnr, ns, start_row, start_col, { hl_group = higroup, end_row = end_row, - end_col = cols[2], + end_col = end_col, priority = priority, strict = false, scoped = scoped, -- cgit From 43bd9c9c1cacb2f069c7e84330a608623c874d74 Mon Sep 17 00:00:00 2001 From: zeertzjq Date: Wed, 5 Jun 2024 16:47:43 +0800 Subject: fix(lua): don't clamp -1 or v:maxcol in vim.highlight.range() (#29203) --- runtime/lua/vim/highlight.lua | 40 ++++++++++++++++++++++++++++++---------- 1 file changed, 30 insertions(+), 10 deletions(-) (limited to 'runtime/lua/vim/highlight.lua') diff --git a/runtime/lua/vim/highlight.lua b/runtime/lua/vim/highlight.lua index 89298ce568..e972ffaa8c 100644 --- a/runtime/lua/vim/highlight.lua +++ b/runtime/lua/vim/highlight.lua @@ -49,10 +49,22 @@ function M.range(bufnr, ns, higroup, start, finish, opts) local priority = opts.priority or M.priorities.user local scoped = opts._scoped or false + local v_maxcol = vim.v.maxcol + local pos1 = type(start) == 'string' and vim.fn.getpos(start) - or { bufnr, start[1] + 1, start[2] + 1, 0 } + or { + bufnr, + start[1] + 1, + start[2] ~= -1 and start[2] ~= v_maxcol and start[2] + 1 or v_maxcol, + 0, + } local pos2 = type(finish) == 'string' and vim.fn.getpos(finish) - or { bufnr, finish[1] + 1, finish[2] + 1, 0 } + or { + bufnr, + finish[1] + 1, + finish[2] ~= -1 and start[2] ~= v_maxcol and finish[2] + 1 or v_maxcol, + 0, + } local buf_line_count = vim.api.nvim_buf_line_count(bufnr) pos1[2] = math.min(pos1[2], buf_line_count) @@ -63,10 +75,14 @@ function M.range(bufnr, ns, higroup, start, finish, opts) end vim.api.nvim_buf_call(bufnr, function() - local max_col1 = vim.fn.col({ pos1[2], '$' }) - pos1[3] = math.min(pos1[3], max_col1) - local max_col2 = vim.fn.col({ pos2[2], '$' }) - pos2[3] = math.min(pos2[3], max_col2) + if pos1[3] ~= v_maxcol then + local max_col1 = vim.fn.col({ pos1[2], '$' }) + pos1[3] = math.min(pos1[3], max_col1) + end + if pos2[3] ~= v_maxcol then + local max_col2 = vim.fn.col({ pos2[2], '$' }) + pos2[3] = math.min(pos2[3], max_col2) + end end) local region = vim.fn.getregionpos(pos1, pos2, { @@ -77,6 +93,14 @@ function M.range(bufnr, ns, higroup, start, finish, opts) -- For non-blockwise selection, use a single extmark. if regtype == 'v' or regtype == 'V' then region = { { region[1][1], region[#region][2] } } + if + regtype == 'V' + or region[1][2][2] == pos1[2] and pos1[3] == v_maxcol + or region[1][2][2] == pos2[2] and pos2[3] == v_maxcol + then + region[1][2][2] = region[1][2][2] + 1 + region[1][2][3] = 0 + end end for _, res in ipairs(region) do @@ -84,10 +108,6 @@ function M.range(bufnr, ns, higroup, start, finish, opts) local start_col = res[1][3] - 1 local end_row = res[2][2] - 1 local end_col = res[2][3] - if regtype == 'V' then - end_row = end_row + 1 - end_col = 0 - end api.nvim_buf_set_extmark(bufnr, ns, start_row, start_col, { hl_group = higroup, end_row = end_row, -- cgit From f3632e14e3a75114415050ab01c2d04a06036009 Mon Sep 17 00:00:00 2001 From: altermo <107814000+altermo@users.noreply.github.com> Date: Fri, 7 Jun 2024 17:33:40 +0200 Subject: feat: get/set namespace properties #28728 ref https://github.com/neovim/neovim/pull/28432 ref https://github.com/neovim/neovim/issues/28469 --- runtime/lua/vim/highlight.lua | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) (limited to 'runtime/lua/vim/highlight.lua') diff --git a/runtime/lua/vim/highlight.lua b/runtime/lua/vim/highlight.lua index e972ffaa8c..233bc50237 100644 --- a/runtime/lua/vim/highlight.lua +++ b/runtime/lua/vim/highlight.lua @@ -31,8 +31,6 @@ M.priorities = { --- Indicates priority of highlight --- (default: `vim.highlight.priorities.user`) --- @field priority? integer ---- ---- @field package _scoped? boolean --- Apply highlight group to range of text. --- @@ -47,7 +45,6 @@ function M.range(bufnr, ns, higroup, start, finish, opts) local regtype = opts.regtype or 'v' local inclusive = opts.inclusive or false local priority = opts.priority or M.priorities.user - local scoped = opts._scoped or false local v_maxcol = vim.v.maxcol @@ -114,7 +111,6 @@ function M.range(bufnr, ns, higroup, start, finish, opts) end_col = end_col, priority = priority, strict = false, - scoped = scoped, }) end end @@ -178,19 +174,18 @@ function M.on_yank(opts) yank_cancel() end - vim.api.nvim__win_add_ns(winid, yank_ns) + vim.api.nvim__ns_set(yank_ns, { wins = { winid } }) M.range(bufnr, yank_ns, higroup, "'[", "']", { regtype = event.regtype, inclusive = event.inclusive, priority = opts.priority or M.priorities.user, - _scoped = true, }) yank_cancel = function() yank_timer = nil yank_cancel = nil pcall(vim.api.nvim_buf_clear_namespace, bufnr, yank_ns, 0, -1) - pcall(vim.api.nvim__win_del_ns, winid, yank_ns) + pcall(vim.api.nvim__ns_set, { wins = {} }) end yank_timer = vim.defer_fn(yank_cancel, timeout) -- cgit From aa6b9c677d83d76d448c3bb0973bf8d14bfdf922 Mon Sep 17 00:00:00 2001 From: dundargoc Date: Sat, 8 Jun 2024 21:40:18 +0200 Subject: refactor: use `vim._with` where possible This mostly means replacing `nvim_buf_call` and `nvim_win_call` with `vim._with`. --- runtime/lua/vim/highlight.lua | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'runtime/lua/vim/highlight.lua') diff --git a/runtime/lua/vim/highlight.lua b/runtime/lua/vim/highlight.lua index 233bc50237..a8d88db372 100644 --- a/runtime/lua/vim/highlight.lua +++ b/runtime/lua/vim/highlight.lua @@ -71,7 +71,7 @@ function M.range(bufnr, ns, higroup, start, finish, opts) return end - vim.api.nvim_buf_call(bufnr, function() + vim._with({ buf = bufnr }, function() if pos1[3] ~= v_maxcol then local max_col1 = vim.fn.col({ pos1[2], '$' }) pos1[3] = math.min(pos1[3], max_col1) -- cgit