In Neovim, can I undo a lua function call that wrote to 2 different buffers at once with a single :undo command?

51 Views Asked by At

I wrote this lua function to manipulate "todo.txt" files. It is supposed to do the following:

  1. Mark the task from the current line as "done" (i.e. prepend it with "x " and remove its priority in case it has one - priorities are represented by a single uppercase letter in parenthesis)
  2. If there is a "done.txt" file in this same directory, move the done task to the top of that file instead, removing it from current file:
local function mark_current_task_as_done()
  local line = vim.fn.getline(".")

  if line:match("^x ") then
    print("Current task is already marked as done")
    return
  end

  local new_line = line:gsub("^%([A-Z]%)? ", ""):gsub("^", "x ")

  local done_file = vim.fn.expand("%:p:h") .. "/done.txt"
  if vim.fn.filereadable(done_file) == 0 then
    print("No done.txt file found in current directory, marking task as done in current file")
    vim.fn.setline(".", new_line)
    return
  end

  vim.fn.bufload(done_file)
  local cur_file_buffer = vim.fn.bufnr("%")
  local done_file_buffer = vim.fn.bufnr(done_file)
  vim.fn.appendbufline(done_file_buffer, "^", new_line)
  vim.api.nvim_command("silent! " .. done_file_buffer .. "bufdo! write")

  vim.api.nvim_command("b" .. cur_file_buffer)
  vim.api.nvim_del_current_line()
  vim.api.nvim_command("silent! write")
end

I want to be able to undo this whole operation simply by running ":undo" (i.e. tapping "u" in normal mode). Is this possible?

I tried to add a vim.cmd.undojoin() line before vim.api.nvim_del_current_line(), but when I hit "u" after running the function, Neovim is only undoing the changes in the current buffer (the "todo.txt" file) and not in the "done.txt" file.

0

There are 0 best solutions below