1

When closing Neovim, I'd like to store the session, but only if there are any files open. If I only have the dashboard open, or an empty unsaved buffer, I want to skip this step. So, I need a way to check if this is the case.

So-far

I thought I can just loop through the buffers and then through the lines of each buffer, like so:

function are_all_buffers_unnamed_and_empty()
  for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
    local bufname = vim.api.nvim_buf_get_name(bufnr)
    if bufname ~= '' then
      return false -- If any buffer has a name, return false
    end
    local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
    if #lines > 1 or (#lines == 1 and #lines[1] > 0) then
      return false -- If any buffer has content, return false
    end
  end
  return true -- All buffers are unnamed and empty
end

Problem

This almost works, but:

If there is a notification showing (i.e., drawn on top of the buffer), this is also looped over, and the function returns false. For example, in this case:

enter image description here

Is there a way to exclude these "trivial" buffers such as file explorers, dashboards, and notifications?

1
  • Do define “open”: showing in a window, buflisted, …?
    – D. Ben Knoble
    Commented May 15 at 22:01

2 Answers 2

0

I would us the filetype and the readonly option to determine if the buffer is relevant:

function are_all_buffers_unnamed_and_empty()
  for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
    local bufname = vim.api.nvim_buf_get_name(bufnr)
    if bufname ~= '' then
      return false -- If any buffer has a name, return false
    end

    local readonly = vim.api.nvim_buf_get_option(bufnr, 'readonly'))
    if readonly then
      return false
    end

    local listed = vim.api.nvim_buf_get_option(bufnr, 'buflisted'))
    if not listed then
      return false
    end

    local buftype = vim.api.nvim_buf_get_option(bufnr, 'buftype'))
    if buftype == 'terminal' then
      return false
    end
    if buftype == "quickfix" then
      return false
    end

    local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
    if #lines > 1 or (#lines == 1 and #lines[1] > 0) then
      return false -- If any buffer has content, return false
    end
  end
  return true -- All buffers are unnamed and empty
end


4
  • 1
    Thanks Vivian for your answer! I found a slightly different solution in the meantime. Instead of checking for filetype, I check for buflisted. I suspect it's more exhaustive.
    – ElRudi
    Commented May 15 at 21:28
  • 1
    Thanks for the feedback :-) It is different in my experience there are some buffers that are listed and irrelevant but I can be wrong. If you have a solution I encourage you to post it. You'll be a le to accept it two days later. It allow the question to rest :-) Commented May 16 at 3:34
  • 1
    Thanks for the feedback :-) I have updated the solution the buflisted works indeed fine for most of the case but not for the quickfix and the location list where I had to use the filetype. If you have a solution I encourage you to post it. You'll be a le to accept it two days later. It allow the question to rest :-) Commented May 16 at 6:06
  • PS: Another case of listed buffer that you would like probably to exclude are the terminal buffers (I have adapted the code accordingly ;-)) Commented May 16 at 6:26
0

I ended up using this:

local function no_buffers_worth_saving()
  for _, bufnr in ipairs(vim.api.nvim_list_bufs()) do
    if vim.api.nvim_buf_get_option(bufnr, 'buflisted') and not vim.api.nvim_buf_get_option(bufnr, 'readonly') then -- disregard unlisted buffers
      if vim.api.nvim_buf_get_name(bufnr) ~= '' then
        return false -- there is a buffer with a name
      end
      local lines = vim.api.nvim_buf_get_lines(bufnr, 0, -1, false)
      if #lines > 1 or (#lines == 1 and #lines[1] > 0) then
        return false -- there is a buffer with content
      end
    end
  end
  return true -- there are no listed, writable, named, nonempty buffers
end

(I renamed the function to focus on its use and not its implementation.)

Your Answer

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

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