1

I am trying to delete items from the quickfix list, using the same delete interface I am used to, visual delete and dd. The .vimrc code I am trying to use to accomplish this is below. It does not work. It skips every other line and moves the cursor several lines down probably related to how many lines were visually selected. dd works but visual selected is where it breaks down.

function! Delete()
    if &buftype == 'quickfix'
        call setqflist(filter(getqflist(), {idx -> idx != line('.') - 1}), 'r')
    else
        deletel
    endif
endfunction
nnoremap <silent> dd :call Delete()<cr>
vnoremap <silent> d :call Delete()<cr>
2

1) Use a function with range keyword (:h func-range) for processing your visual selection. Moreover, that also allows for [count] in Normal mode.

2) Prefer buffer-local mappings whenever it makes sense.

" using range-aware function
function! QFdelete(bufnr) range
    " get current qflist
    let l:qfl = getqflist()
    " no need for filter() and such; just drop the items in range
    call remove(l:qfl, a:firstline - 1, a:lastline - 1)
    " replace items in the current list, do not make a new copy of it;
    " this also preserves the list title
    call setqflist([], 'r', {'items': l:qfl})
    " restore current line
    call setpos('.', [a:bufnr, a:firstline, 1, 0])
endfunction

" using buffer-local mappings
" note: still have to check &bt value to filter out `:e quickfix` and such
augroup QFList | au!
    autocmd BufWinEnter quickfix if &bt ==# 'quickfix'
    autocmd BufWinEnter quickfix    nnoremap <silent><buffer>dd :call QFdelete(bufnr())<CR>
    autocmd BufWinEnter quickfix    vnoremap <silent><buffer>d  :call QFdelete(bufnr())<CR>
    autocmd BufWinEnter quickfix endif
augroup end
  • is there a way to preserve the cursor position after the delete has been executed so that it behaves fully like normal delete operations? Otherwise this is great! – Josh Lawrence Sep 22 at 18:00
  • @JoshLawrence Add call cursor(a:firstline, 1), for example. – Matt Sep 22 at 18:18
  • call cursor(a:firstline, 1) worked while call setpos('.', [a:bufnr, a:firstline, 1, 0]) did not – Josh Lawrence Sep 22 at 19:13
  • @JoshLawrence It should work; make sure you pass bufnr as argument to a function. cursor() would fail if the function would be called when quickfix is not an active buffer; that's not possible in this case, but in general that could be an issue. – Matt Sep 22 at 19:22

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

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