mirror of
https://github.com/neovim/neovim.git
synced 2025-09-07 03:48:18 +00:00
lua: Add highlight.on_yank (#12279)
* add lua function to highlight yanked region * extract namespace, better naming, default values * add default for event argument * free timer * factor out mark to position calculation * d'oh * make sure timer stops before callback (cf. luv example) * factor out timer, more documentation * fixup * validate function argument for schedule * fix block selection past eol * correct handling of multibyte characters * move arguments around, some cleanup * move utility functions to vim.lua * use anonymous namespaces, avoid local api * rename function * add test for schedule_fn * fix indent * turn hl-yank into proper (hightlight) module * factor out position-to-region function mark extraction now part of highlight.on_yank * rename schedule_fn to defer_fn * add test for vim.region * todo: handle double-width characters * remove debug printout * do not shadow arguments * defer also callable table * whitespace change * move highlight to vim/highlight.lua * add documentation * add @return documentation * test: add check before vim.defer fires * doc: fixup
This commit is contained in:
@@ -415,4 +415,67 @@ do
|
||||
vim.wo = new_win_opt_accessor(nil)
|
||||
end
|
||||
|
||||
--- Get a table of lines with start, end columns for a region marked by two points
|
||||
---
|
||||
--@param bufnr number of buffer
|
||||
--@param pos1 (line, column) tuple marking beginning of region
|
||||
--@param pos2 (line, column) tuple marking end of region
|
||||
--@param regtype type of selection (:help setreg)
|
||||
--@param inclusive boolean indicating whether the selection is end-inclusive
|
||||
--@return region lua table of the form {linenr = {startcol,endcol}}
|
||||
function vim.region(bufnr, pos1, pos2, regtype, inclusive)
|
||||
if not vim.api.nvim_buf_is_loaded(bufnr) then
|
||||
vim.fn.bufload(bufnr)
|
||||
end
|
||||
|
||||
-- in case of block selection, columns need to be adjusted for non-ASCII characters
|
||||
-- TODO: handle double-width characters
|
||||
local bufline
|
||||
if regtype:byte() == 22 then
|
||||
bufline = vim.api.nvim_buf_get_lines(bufnr, pos1[1], pos1[1] + 1, true)[1]
|
||||
pos1[2] = vim.str_utfindex(bufline, pos1[2])
|
||||
end
|
||||
|
||||
local region = {}
|
||||
for l = pos1[1], pos2[1] do
|
||||
local c1, c2
|
||||
if regtype:byte() == 22 then -- block selection: take width from regtype
|
||||
c1 = pos1[2]
|
||||
c2 = c1 + regtype:sub(2)
|
||||
-- and adjust for non-ASCII characters
|
||||
bufline = vim.api.nvim_buf_get_lines(bufnr, l, l + 1, true)[1]
|
||||
if c1 < #bufline then
|
||||
c1 = vim.str_byteindex(bufline, c1)
|
||||
end
|
||||
if c2 < #bufline then
|
||||
c2 = vim.str_byteindex(bufline, c2)
|
||||
end
|
||||
else
|
||||
c1 = (l == pos1[1]) and (pos1[2]) or 0
|
||||
c2 = (l == pos2[1]) and (pos2[2] + (inclusive and 1 or 0)) or -1
|
||||
end
|
||||
table.insert(region, l, {c1, c2})
|
||||
end
|
||||
return region
|
||||
end
|
||||
|
||||
--- Defers calling `fn` until `timeout` ms passes.
|
||||
---
|
||||
--- Use to do a one-shot timer that calls `fn`
|
||||
--@param fn Callback to call once `timeout` expires
|
||||
--@param timeout Number of milliseconds to wait before calling `fn`
|
||||
--@return timer luv timer object
|
||||
function vim.defer_fn(fn, timeout)
|
||||
vim.validate { fn = { fn, 'c', true}; }
|
||||
local timer = vim.loop.new_timer()
|
||||
timer:start(timeout, 0, vim.schedule_wrap(function()
|
||||
timer:stop()
|
||||
timer:close()
|
||||
|
||||
fn()
|
||||
end))
|
||||
|
||||
return timer
|
||||
end
|
||||
|
||||
return module
|
||||
|
Reference in New Issue
Block a user