0

I am writing a plugin for Neovim using Lua.

If I have a text and some predefined arbitrary types, for example:

chita 
wolf
grizzly

types: dog(green), cat(blue), bear(yellow)

And I know positions/indices of words that belong to the types.

What is a better approach to highlight words in the buffer according to the types using Lua?

Update

Looks like I can set custom highlight groups for this purpose:

hi MyDog guifg=red ctermfg=red
match MyDog /wolf/

But I still do not understand how to apply a highlight group not by pattern matching, but by positions in text.

3
  • 3
    With vim probably text properties. Not sure about neovim/lua
    – D. Ben Knoble
    Aug 23, 2021 at 11:56
  • 2
    Patterns can accept line/col numbers: :help /\%c I think
    – D. Ben Knoble
    Aug 23, 2021 at 21:17
  • 1
    I did not know about text properties, they can be quite useful at some point, thanks @D. Ben Knoble. The matchaddpods() highlights positions in line/col grid (it is fine for my current plugin), while text properties allow to connect highlighting to text itself.
    – dimus
    Aug 27, 2021 at 11:23

1 Answer 1

0

I found matchaddpos function that did allow to solve highlighting programmatically.

Given a text:

wolf, cat black bear,
lion, dog, grizzly,
puma, bear, fox, chita,

I can highlight entries by categories with this function:

local M = {}

M.highlight = function()
  vim.cmd "hi Dogs guifg=green ctermfg=green"
  vim.cmd "hi Cats guifg=yellow ctermfg=yellow"
  vim.cmd "hi Bears guifg=cyan ctermfg=cyan"
  local data = {
    {group = "Dogs", line = 1, pos = 1, len = 4},
    {group = "Cats", line = 1, pos = 7, len = 3},
    {group = "Bears", line = 1, pos = 11, len = 10},
    {group = "Cats", line = 2, pos = 1, len = 4},
    {group = "Dogs", line = 2, pos = 7, len = 3},
    {group = "Bears", line = 2, pos = 12, len = 7},
    {group = "Cats", line = 3, pos = 1, len = 4},
    {group = "Bears", line = 3, pos = 7, len = 4},
    {group = "Dogs", line = 3, pos = 13, len = 3},
    {group = "Cats", line = 3, pos = 18, len = 5}
  }

  for _, datum in pairs(data) do
    local hi_cmd =
      vim.fn.printf('call matchaddpos("%s", [[%d, %d, %d]])', datum.group, datum.line, datum.pos, datum.len)
    vim.cmd(hi_cmd)
  end
end

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge that you have read and understand our privacy policy and code of conduct.

Not the answer you're looking for? Browse other questions tagged or ask your own question.