2

I could not find this in :h sessionoptions.
If this cannot be done, is there another way to save quickfix list to some file and reload it?

2 Answers 2

7
+50

Quickfix lists (shortened to "qflist" from here on) are not saved with :mksession. Probably because the list is saved in a temporary file which is scrubbed when exiting the current vim session. But you can save the qflist manually and load it back with :h cgetbuffer.

$ vim
:grep 'pattern'
:copen
:w list.qf
:q
$ vim
:cfile list.qf

But this requires handling another file beside the session file. We can incorporate setting the qflist inside the session file itself, with :h getqflist() and :h setqflist().

Let's incorporate that into a custom MakeSession command.

function! MakeSession(filename, bang) abort
  let filename = a:filename == '' ? 'Session.vim' : a:filename

  " Save window view
  let _w = winsaveview()

  " Get qflist and its title
  let _qflist = getqflist()
  let _qfinfo = getqflist({'title' : 1})
  let _qfopen = !empty(filter(tabpagebuflist(), 'getbufvar(v:val, "&buftype") ==# "quickfix"'))

  " Set all buffers listed in qflist as buflisted
  " Cause an unlisted buffer isn't saved in session file
  " `:h getqflist()` returns file info in the form of `:h bufnr()`
  " If buffer is unlisted and thus not opened with session file
  " then qflist will have nil entries for those files
  for entry in _qflist | call setbufvar(entry['bufnr'], '&buflisted', 1) | endfor

  " Close qflist window
  " because the window is saved in session file as an empty buffer
  " and will open a qflist-window-sized empty buffer
  " in the new vim instance when the session file is sourced
  cclose

  " Save Save the session file
  execute 'mksession' . (a:bang == 1 ? '! ' : ' ') . filename

  " Open the qflist window again
  if _qfopen | cwindow | wincmd p | endif

  " Save the qflist
  let _setqflist = 'call setqflist(' . string(_qflist) . ')'
  let _setqfinfo = 'call setqflist(' . '[],"a",' . string(_qfinfo) . ')'
  call writefile([_setqflist, _setqfinfo], filename, 'a')
  if _qfopen | call writefile(['cwindow', 'wincmd p'], filename, 'a') | endif

  " Restore window view
  call winrestview(_w)
endfunction

command! -nargs=? -bang MakeSession call MakeSession(<q-args>, <bang>0)

REMARKS: The function above has the following limitations.

  • I have fixed all the limitations I could find. See the edit history of this answer; you'll see. But if some new issue rears up, alert me or edit this answer by either fixing it or adding a remark.
2
  • Can someone write this in lua? I'm not experienced enough to convert it but will try. Commented Oct 11, 2022 at 19:27
  • 1
    @ArielFrischer Just put it all in :h vim.cmd and call the function with :h vim.fn.
    – 3N4N
    Commented Oct 11, 2022 at 20:20
0

I've converted the vimscript to lua and have ONLY saved the qflist to a file, save session logic will work if you uncomment it. Also created a load Load_qf_list global lua function as well.

function Save_qf_list(filename, bang)
  filename = filename == "" and "qflist.vim" or filename

  -- Save window view
  local _w = vim.fn.winsaveview()

  -- Get qflist and its title
  local _qflist = vim.fn.getqflist()
  local _qfinfo = vim.fn.getqflist { title = 1 }
  local _qfopen = not vim.tbl_isempty(vim.tbl_filter(function(v)
    return vim.fn.getbufvar(v, "&buftype") == "quickfix"
  end, vim.fn.tabpagebuflist()))

  -- Set all buffers listed in qflist as buflisted
  for _, entry in ipairs(_qflist) do
    vim.fn.setbufvar(entry.bufnr, "&buflisted", 1)
  end

  -- Close qflist window
  vim.cmd "cclose"

  -- Save a session file if needed
  -- vim.cmd(string.format('mksession %s %s', bang == 1 and '!' or '', filename))

  -- Open the qflist window again
  if _qfopen then
    vim.cmd "cwindow"
    vim.cmd "wincmd p"
  end

  -- Save the qflist
  local _setqflist = string.format("call setqflist(%s)", vim.fn.string(_qflist))
  local _setqfinfo = string.format('call setqflist([], "a", %s)', vim.fn.string(_qfinfo))
  vim.fn.writefile({ _setqflist, _setqfinfo }, filename, "a")
  if _qfopen then
    vim.fn.writefile({ "cwindow", "wincmd p" }, filename, "a")
  end

  -- Restore window view
  vim.fn.winrestview(_w)
end

vim.cmd "command! -nargs=? -bang SaveQfList lua Save_qf_list(<q-args>, <bang>0)"

function Load_qf_list(filename)
  filename = filename == '' and 'qflist.vim' or filename
  vim.cmd(string.format('source %s', filename))
end

vim.cmd("command! -nargs=? LoadQfList lua Load_qf_list(<q-args>)")

I may modify this behaviour to save the file to the neovim ~/.local/share/nvim directory or allow a path to be given by default or passed as an arg.

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.