mirror of
https://github.com/neovim/neovim.git
synced 2026-05-27 15:25:33 +00:00
feat(vim.hl): vim.hl.hl_op() #39777
Problem: vim.hl.on_yank() only works for TextYankPost, not TextPutPost. Solution: Introduce hl_op(). Deprecate on_yank().
This commit is contained in:
@@ -8,7 +8,7 @@ local M = {}
|
||||
--- - `semantic_tokens`: `125`, used for LSP semantic token highlighting
|
||||
--- - `diagnostics`: `150`, used for code analysis such as diagnostics
|
||||
--- - `user`: `200`, used for user-triggered highlights such as LSP document
|
||||
--- symbols or `on_yank` autocommands
|
||||
--- symbols or `hl_op` autocommands
|
||||
M.priorities = {
|
||||
syntax = 50,
|
||||
treesitter = 100,
|
||||
@@ -144,26 +144,34 @@ function M.range(buf, ns, higroup, start, finish, opts)
|
||||
end
|
||||
end
|
||||
|
||||
local yank_timer --- @type uv.uv_timer_t?
|
||||
local yank_hl_clear --- @type fun()?
|
||||
local yank_ns = api.nvim_create_namespace('nvim.hlyank')
|
||||
---@private
|
||||
---@class (private) vim.hl.OnEventState
|
||||
---@field timer? uv.uv_timer_t Timer to clear the highlight.
|
||||
---@field clear? fun() Function to clear the highlight immediately.
|
||||
|
||||
--- Highlight the yanked text during a |TextYankPost| event.
|
||||
--- @type { [string]: vim.hl.OnEventState }
|
||||
local hl_op_state = {}
|
||||
|
||||
local events_ns = api.nvim_create_namespace('nvim.hl.events')
|
||||
|
||||
--- Highlight the related text region during a |TextYankPost| or |TextPutPost|
|
||||
--- event.
|
||||
---
|
||||
--- Add the following to your `init.vim`:
|
||||
---
|
||||
--- ```vim
|
||||
--- autocmd TextYankPost * silent! lua vim.hl.on_yank {higroup='Visual', timeout=300}
|
||||
--- autocmd TextYankPost * silent! lua vim.hl.hl_op {higroup='Visual', timeout=300}
|
||||
--- autocmd TextPutPost * silent! lua vim.hl.hl_op {higroup='Visual', timeout=300}
|
||||
--- ```
|
||||
---
|
||||
--- @param opts table|nil Optional parameters
|
||||
--- - event event structure (default vim.v.event)
|
||||
--- - higroup highlight group for yanked region (default "IncSearch")
|
||||
--- - higroup highlight group for the text region (default "IncSearch")
|
||||
--- - on_macro highlight when executing macro (default false)
|
||||
--- - on_visual highlight when yanking visual selection (default true)
|
||||
--- - on_visual highlight when the event is in |Visual| mode (default true)
|
||||
--- - priority integer priority (default |vim.hl.priorities|`.user`)
|
||||
--- - timeout time in ms before highlight is cleared (default 150)
|
||||
function M.on_yank(opts)
|
||||
function M.hl_op(opts)
|
||||
vim.validate('opts', opts, 'table', true)
|
||||
opts = opts or {}
|
||||
local event = opts.event or vim.v.event
|
||||
@@ -173,31 +181,52 @@ function M.on_yank(opts)
|
||||
if not on_macro and vim.fn.reg_executing() ~= '' then
|
||||
return
|
||||
end
|
||||
if event.operator ~= 'y' or event.regtype == '' then
|
||||
if event.regtype == '' then
|
||||
return
|
||||
end
|
||||
if not on_visual and event.visual then
|
||||
return
|
||||
end
|
||||
|
||||
local state_key --- @type string
|
||||
if event.operator == 'y' then
|
||||
state_key = 'yank'
|
||||
elseif event.operator == 'p' or event.operator == 'P' then
|
||||
state_key = 'put'
|
||||
else
|
||||
return
|
||||
end
|
||||
|
||||
local higroup = opts.higroup or 'IncSearch'
|
||||
|
||||
local bufnr = api.nvim_get_current_buf()
|
||||
local winid = api.nvim_get_current_win()
|
||||
|
||||
if yank_timer and not yank_timer:is_closing() then
|
||||
yank_timer:close()
|
||||
assert(yank_hl_clear)
|
||||
yank_hl_clear()
|
||||
local state = hl_op_state[state_key]
|
||||
if state ~= nil and state.timer and not state.timer:is_closing() then
|
||||
state.timer:close()
|
||||
assert(state.clear)
|
||||
state.clear()
|
||||
end
|
||||
|
||||
api.nvim__ns_set(yank_ns, { wins = { winid } })
|
||||
yank_timer, yank_hl_clear = M.range(bufnr, yank_ns, higroup, "'[", "']", {
|
||||
api.nvim__ns_set(events_ns, { wins = { winid } })
|
||||
local timer, clear = M.range(bufnr, events_ns, higroup, "'[", "']", {
|
||||
regtype = event.regtype,
|
||||
inclusive = true,
|
||||
priority = opts.priority or M.priorities.user,
|
||||
timeout = opts.timeout or 150,
|
||||
})
|
||||
|
||||
hl_op_state[state_key] = {
|
||||
timer = timer,
|
||||
clear = clear,
|
||||
}
|
||||
end
|
||||
|
||||
--- @deprecated Please use |vim.hl.hl_op()| instead.
|
||||
function M.on_yank(opts)
|
||||
vim.deprecate('vim.hl.on_yank', 'vim.hl.hl_op', '0.13')
|
||||
return M.hl_op(opts)
|
||||
end
|
||||
|
||||
return M
|
||||
|
||||
Reference in New Issue
Block a user