Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add recording events to refresh events #1227

Open
wants to merge 1 commit into
base: master
Choose a base branch
from

Conversation

mikesmithgh
Copy link

@mikesmithgh mikesmithgh commented Apr 9, 2024

I'd like to add the events RecordingEnter and RecordingLeave to the default refresh events.

This is useful for cases where the recording register (e.g., vim.fn.reg_recording()) is displayed in lualine. Currently, lualine has to wait until the next refresh which causes a delay. Adding the events RecordingEnter and RecordingLeave immediately triggers an update for a better experience.

For example, noice.nvim does this with the following snippet from its README.

{
  require('noice').api.status.mode.get,
  cond = require('noice').api.status.mode.has,
  color = { fg = '#ff9e64' },
}

This could also be accomplished manually via:

local rec_msg = ''
vim.api.nvim_create_autocmd({ 'RecordingEnter', 'RecordingLeave' }, {
  group = vim.api.nvim_create_augroup('LualineRecordingSection', { clear = true }),
  callback = function(e)
    if e.event == 'RecordingLeave' then
      rec_msg = ''
    else
      rec_msg = 'recording @' .. vim.fn.reg_recording()
    end
  end,
})

and with the lualine section:

{
  function()
    return rec_msg
  end,
  color = { fg = '#ff9e64' },
}

@smartinellimarco
Copy link

@mikesmithgh I came across a post somewhere, stating that the register holding the macro data isn't cleared immediately after RecordingLeave. This means that even if you refresh lualine at that point, vim.fn.reg_recording() may still return a value.

Here's the related code snippet:

vim.api.nvim_create_autocmd('RecordingEnter', {
  callback = function()
    require('lualine').refresh({ place = { 'statusline' } })
  end,
})

-- The register does not clean up immediately after
-- recording stops, so we wait a bit (50ms) before refreshing.
vim.api.nvim_create_autocmd('RecordingLeave', {
  callback = function()
    local timer = vim.loop.new_timer()
    timer:start(
      50,
      0,
      vim.schedule_wrap(function()
        require('lualine').refresh({ place = { 'statusline' } })
      end)
    )
  end,
})

@darrenchang
Copy link

@mikesmithgh I came across a post somewhere, stating that the register holding the macro data isn't cleared immediately after RecordingLeave. This means that even if you refresh lualine at that point, vim.fn.reg_recording() may still return a value.

Here's the related code snippet:

vim.api.nvim_create_autocmd('RecordingEnter', {
  callback = function()
    require('lualine').refresh({ place = { 'statusline' } })
  end,
})

-- The register does not clean up immediately after
-- recording stops, so we wait a bit (50ms) before refreshing.
vim.api.nvim_create_autocmd('RecordingLeave', {
  callback = function()
    local timer = vim.loop.new_timer()
    timer:start(
      50,
      0,
      vim.schedule_wrap(function()
        require('lualine').refresh({ place = { 'statusline' } })
      end)
    )
  end,
})

Same here. Leaving recording mode doesn't immediately register the nvim state.
I forgot where I copied this code snippet from: https://github.com/darrenchang/nvim-config/blob/71d4d88ac50a8977297e7ccefccfe223a32d7833/lua/plugins/lualine.lua#L151C1-L152C1
Here is a lualine plugin that uses the same technique to get nvim's recording state: https://github.com/yavorski/lualine-macro-recording.nvim/blob/e2dcf63ba74e6111b53e1520a4f8a17a3d7427a1/lua/lualine/components/macro_recording.lua#L18

@mikesmithgh
Copy link
Author

@smartinellimarco @darrenchang

Thanks for the info, I wasn't aware of this.

I suppose it depends on the implementation. @darrenchang for example yours https://github.com/darrenchang/nvim-config/blob/71d4d88ac50a8977297e7ccefccfe223a32d7833/lua/plugins/lualine.lua#L2

-- Format function for displaying macro recording status
local function show_macro_recording()
  local recording_register = vim.fn.reg_recording()
  if recording_register == "" then
    return ""
  else
    return "Recording @" .. recording_register
  end
end

is depending on the result of vim.fn.reg_recording().

But in my example,

function(e)
    if e.event == 'RecordingLeave' then
      rec_msg = ''
    else
      rec_msg = 'recording @' .. vim.fn.reg_recording()
    end

it doesn't rely on the result of vim.fn.reg_recording() being an empty string, it uses the event RecordingLeave.

But, I can see how this can be a problem and don't have any strong opinions, so I'm fine if we want to just close this as won't do.

My workaround at the moment is to explicitly call require('lualine').refresh() in the autocmd callback. https://github.com/mikesmithgh/nvim/blob/acf2c824aafa02f1b56fc60c3fcabb336968aa39/lua/plugins/lualine-nvim.lua#L31

    local rec_msg = ''
    vim.api.nvim_create_autocmd({ 'RecordingEnter', 'RecordingLeave' }, {
      group = vim.api.nvim_create_augroup('LualineRecordingSection', { clear = true }),
      callback = function(e)
        if e.event == 'RecordingLeave' then
          rec_msg = ''
        else
          rec_msg = 'recording @' .. vim.fn.reg_recording()
        end
        require('lualine').refresh()
      end,
    })

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

Successfully merging this pull request may close these issues.

3 participants