1local api = vim.api 2 3local highlight = {} 4 5---@private 6function highlight.create(higroup, hi_info, default) 7 local options = {} 8 -- TODO: Add validation 9 for k, v in pairs(hi_info) do 10 table.insert(options, string.format("%s=%s", k, v)) 11 end 12 vim.cmd(string.format([[highlight %s %s %s]], default and "default" or "", higroup, table.concat(options, " "))) 13end 14 15---@private 16function highlight.link(higroup, link_to, force) 17 vim.cmd(string.format([[highlight%s link %s %s]], force and "!" or " default", higroup, link_to)) 18end 19 20 21--- Highlight range between two positions 22--- 23---@param bufnr number of buffer to apply highlighting to 24---@param ns namespace to add highlight to 25---@param higroup highlight group to use for highlighting 26---@param rtype type of range (:help setreg, default charwise) 27---@param inclusive boolean indicating whether the range is end-inclusive (default false) 28function highlight.range(bufnr, ns, higroup, start, finish, rtype, inclusive) 29 rtype = rtype or 'v' 30 inclusive = inclusive or false 31 32 -- sanity check 33 if start[2] < 0 or finish[1] < start[1] then return end 34 35 local region = vim.region(bufnr, start, finish, rtype, inclusive) 36 for linenr, cols in pairs(region) do 37 api.nvim_buf_add_highlight(bufnr, ns, higroup, linenr, cols[1], cols[2]) 38 end 39 40end 41 42local yank_ns = api.nvim_create_namespace('hlyank') 43--- Highlight the yanked region 44--- 45--- use from init.vim via 46--- au TextYankPost * lua vim.highlight.on_yank() 47--- customize highlight group and timeout via 48--- au TextYankPost * lua vim.highlight.on_yank {higroup="IncSearch", timeout=150} 49--- customize conditions (here: do not highlight a visual selection) via 50--- au TextYankPost * lua vim.highlight.on_yank {on_visual=false} 51--- 52-- @param opts dictionary with options controlling the highlight: 53-- - higroup highlight group for yanked region (default "IncSearch") 54-- - timeout time in ms before highlight is cleared (default 150) 55-- - on_macro highlight when executing macro (default false) 56-- - on_visual highlight when yanking visual selection (default true) 57-- - event event structure (default vim.v.event) 58function highlight.on_yank(opts) 59 vim.validate { 60 opts = { opts, 61 function(t) if t == nil then return true else return type(t) == 'table' end end, 62 'a table or nil to configure options (see `:h highlight.on_yank`)', 63 }} 64 opts = opts or {} 65 local event = opts.event or vim.v.event 66 local on_macro = opts.on_macro or false 67 local on_visual = (opts.on_visual ~= false) 68 69 if (not on_macro) and vim.fn.reg_executing() ~= '' then return end 70 if event.operator ~= 'y' or event.regtype == '' then return end 71 if (not on_visual) and event.visual then return end 72 73 local higroup = opts.higroup or "IncSearch" 74 local timeout = opts.timeout or 150 75 76 local bufnr = api.nvim_get_current_buf() 77 api.nvim_buf_clear_namespace(bufnr, yank_ns, 0, -1) 78 79 local pos1 = vim.fn.getpos("'[") 80 local pos2 = vim.fn.getpos("']") 81 82 pos1 = {pos1[2] - 1, pos1[3] - 1 + pos1[4]} 83 pos2 = {pos2[2] - 1, pos2[3] - 1 + pos2[4]} 84 85 highlight.range(bufnr, yank_ns, higroup, pos1, pos2, event.regtype, event.inclusive) 86 87 vim.defer_fn( 88 function() 89 if api.nvim_buf_is_valid(bufnr) then 90 api.nvim_buf_clear_namespace(bufnr, yank_ns, 0, -1) 91 end 92 end, 93 timeout 94 ) 95end 96 97return highlight 98