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
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.
-
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
.– 3N4NCommented Oct 11, 2022 at 20:20
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.