vimtricks.wiki Concise Vim tricks, one at a time.

How do I programmatically populate the quickfix list from Vimscript?

Answer

setqflist()

Explanation

setqflist() lets you build the quickfix list from a Vimscript list of dictionaries rather than relying on compiler output or :vimgrep. This is the foundation for writing custom linters, test runners, or any tool that feeds results into Vim's quickfix workflow.

How it works

Each entry in the list passed to setqflist() is a dictionary with any combination of these keys:

  • bufnr or filename — the file the entry points to
  • lnum — line number
  • col — column number
  • text — the message shown in the quickfix window
  • type'E' for error, 'W' for warning, 'I' for info
  • valid1 if the entry is a valid jump target

The second argument controls the action: ' ' to create a new list, 'a' to append, 'r' to replace the current list.

Example

Create a quickfix list of every TODO comment in the current buffer:

function! CollectTodos()
  let l:items = []
  for l:lnum in range(1, line('$'))
    let l:line = getline(l:lnum)
    if l:line =~# 'TODO'
      call add(l:items, {
        \ 'bufnr': bufnr('%'),
        \ 'lnum': l:lnum,
        \ 'text': trim(l:line),
        \ 'type': 'W'
        \ })
    endif
  endfor
  call setqflist(l:items, ' ')
  copen
endfunction

nnoremap <leader>T :call CollectTodos()<CR>

Tips

  • Use getqflist() to read the current quickfix list back into a variable for further processing
  • Pass {'title': 'My Tool'} as the third argument to label the quickfix window: setqflist(items, ' ', {'title': 'TODOs'})
  • Combine with :cdo or :cfdo to act on all generated entries
  • setloclist(winnr(), items) works identically but targets the window-local location list instead

Next

How do I right-justify a line of text to a specific width using a built-in Vim command?