How to use "repeat" on timer_start in a lua function

Hi guys, I have a function to “flash” my cursorline, it works great, but I would like to improve it by adding a “repeat” to my function. It uses “timer_start” to count some milliseconds so my cursorline flashes during this time. The only change I want is to add repetitions so it flashes twice or more. The function is:

-- https://vi.stackexchange.com/questions/31206
M.flash_cursorline = function()
    -- local cursorline_state = vim.opt.cursorline:get()
    vim.opt.cursorline = true
    vim.cmd([[hi CursorLine guifg=#FFFFFF guibg=#FF9509]])
    vim.fn.timer_start(200, function()
        vim.cmd([[hi CursorLine guifg=NONE guibg=NONE]])
        vim.opt.cursorline = false
    end)
end

OBS: As I have the cursorline disabled by default, the function enables and disables it during its execution, “we” could improve it to get the cursorline state and keep it, in case of those who already have the cursorline enabled.

Bellow a mapping example I use, so each time I press Ctrl-o or Ctrl-i I will auto call this function:

map('n', '<c-o>', '<c-o>zv:lua require("utils").flash_cursorline()<cr>', { silent = true})
map('n', '<c-i>', '<c-i>zv:lua require("utils").flash_cursorline()<cr>', { silent = true})

-- another mapping to flash the cursorline when you make jumps like 10k or 15j.
map(
  "n",
  "j",
  [[v:count ? (v:count > 5 ? "m'" . v:count : '') . 'j:lua require("utils").flash_cursorline()<cr>' : 'gj']],
  { expr = true }
)
map(
  "n",
  "k",
  [[v:count ? (v:count > 5 ? "m'" . v:count : '') . 'k:lua require("utils").flash_cursorline()<cr>' : 'gk']],
  { expr = true }
)

Here my autocmd file with an autocmd to flash the cursorline each time I enter another window:

-- File: /home/sergio/.config/nvim/lua/autocmd.lua
-- Last Change: Mon, 06 Dec 2021 16:41

--- This function is taken from https://github.com/norcalli/nvim_utils
function nvim_create_augroups(definitions)
  for group_name, definition in pairs(definitions) do
    vim.api.nvim_command("augroup " .. group_name)
    vim.api.nvim_command("autocmd!")
    for _, def in ipairs(definition) do
      local command = table.concat(vim.tbl_flatten({ "autocmd", def }), " ")
      vim.api.nvim_command(command)
    end
    vim.api.nvim_command("augroup END")
  end
end

local autocmds = {
  reload_vimrc = {
    -- Reload vim config automatically
    -- {"BufWritePost",[[$VIM_PATH/{*.vim,*.yaml,vimrc} nested source $MYVIMRC | redraw]]};
    { "BufWritePre", "$MYVIMRC", "lua require('utils').ReloadConfig()" },
  },
  change_header = {
    {"BufWritePre", "*", "lua require('utils').changeheader()"};
  };
  packer = {
    { "BufWritePost", "plugins.lua", "PackerCompile" },
  },
  terminal_job = {
    { "TermOpen", "*", [[tnoremap <buffer> <Esc> <c-\><c-n>]] },
    { "TermOpen", "*", [[tnoremap <buffer> <leader>x <c-\><c-n>:bd!<cr>]] },
    { "TermOpen", "*", [[tnoremap <expr> <A-r> '<c-\><c-n>"'.nr2char(getchar()).'pi' ]] },
    { "TermOpen", "*", "startinsert" },
    { "TermOpen", "*", [[nnoremap <buffer> <C-c> i<C-c>]] },
    { "TermOpen", "*", "setlocal listchars= nonumber norelativenumber" },
  },
  restore_cursor = {
    { "BufRead", "*", [[call setpos(".", getpos("'\""))]] },
  },
  -- save_shada = {
  --     -- { "VimLeave", "*", "wshada!"};
  --     { "CursorHold", "*", [[rshada|wshada]]};
  -- };
  resize_windows_proportionally = {
    { "VimResized", "*", ":wincmd =" },
  },
  toggle_search_highlighting = {
    { "InsertEnter", "*", "setlocal nohlsearch" },
  },
  lua_highlight = {
    { "TextYankPost", "*", [[silent! lua vim.highlight.on_yank() {higroup="IncSearch", timeout=400}]] },
  },
  auto_working_directory = {
    { "BufEnter", "*", "silent! lcd %:p:h" },
  },
  clean_trailing_spaces = {
    { "BufWritePre", "*", [[lua require("utils").preserve('%s/\\s\\+$//ge')]] },
  },
  -- ansi_esc_log = {
  --     { "BufEnter", "*.log", ":AnsiEsc" };
  -- };
  flash_cursor_line = {
    { "WinEnter", "*", "lua require('utils').flash_cursorline()" },
  },
  -- attatch_colorizer = {
  -- 	-- {BufReadPost *.conf setl ft=conf};
  -- 	{"BufReadPost", "config", "setl ft=conf"};
  -- 	{"FileType", "conf", "ColorizerAttachToBuffer<CR>"};
  -- };
}

nvim_create_augroups(autocmds)
-- autocommands END

Look at vim.loop.new_timer() (which exposes LibUV timers). See :h lua-loop-callbacks for an example with a repeat.

1 Like