--- Highlights given words in a buffer. --- Word matching is case sensitive. --- @param bufnr number Number of buffer to highlight. If 0, current buffer is used. --- @param words table Word to highlight group name mapping. Every occurrence with keys in this table, will be --- highlighted with its mapped value, which is expected to be a highlight group name. local function buffer( bufnr, words ) vim.validate( 'bufnr', bufnr, 'number' ) vim.validate( 'words', words, 'table' ) local namespace = vim.api.nvim_create_namespace( 'light_up_ns' ) vim.api.nvim_buf_clear_namespace( bufnr, namespace, 0, -1 ) local handler = function ( event, buffer_handle, tick, first_line, last_line_changed, last_line_updated, bytes ) assert( event == 'lines', 'this handler is for `on_lines` notification' ) local last = math.max( last_line_updated, last_line_changed ) local lines if last < 0 then lines = vim.api.nvim_buf_get_lines( bufnr, first_line, -1, true ) else lines = vim.api.nvim_buf_get_lines( bufnr, first_line, last, true ) end for index, line in ipairs( lines ) do local current_line = first_line + index - 1 for word, highlight_group in pairs( words ) do local s = 1 while s <= #line do local word_start = line:find( word, s, true ) if not word_start then break end local before_char = line:sub( word_start - 1, word_start - 1 ) local after_char = line:sub( word_start + #word, word_start + #word ) local before_ok = #before_char == 0 or before_char:match( '[%s%.]' ) local after_ok = #after_char == 0 or after_char:match( '[%s%.]' ) if before_ok and after_ok then local start_col = word_start - 1 local end_col = word_start + #word - 1 vim.api.nvim_buf_set_extmark( bufnr, namespace, current_line, start_col, { end_col = end_col, hl_group = highlight_group, } ) end s = word_start + 1 end end end end local ok = vim.api.nvim_buf_attach( bufnr, false, { on_lines = handler } ) if not ok then error( 'unable to attach to buffer ' .. bufnr ) end handler( 'lines', bufnr, nil, 0, -1, -1, nil ) return namespace end --- @return table groups A map of all highlight group names, mapping to themselves. local function get_vim_highlight_groups() local groups = {} for name in pairs( vim.api.nvim_get_hl( 0, {} ) ) do groups[name] = name end return groups end return { buffer = buffer, get_vim_highlight_groups = get_vim_highlight_groups, }