1

:files is nice, but I want to delete a bunch of buffers at once. I know about :bd n1 n2 ... and :m,nbd, but it'd be nice to manipulate the list (e.g. to delete buffers) in a 'regular' window.

Is there any way to do this with vanilla Vim? Or are the :bd commands about as good as it gets?

This is definitely related to this question:

But I definitely want to have the buffers listed in a window (and not need to run :files over and over in the 'temporary' window in which :files is shown by default), and none of the answers on the above question cover this.

I was hoping an answer on this question would answer my own:

Alas, it (the lone answer as-of now) does not.

5
  • 1
    Why do you want to delete so many buffers? (I ask bc this rarely comes up for me, other than occasionally deleting one or two. It’s possible there are alternatives, though certainly some code could be written to do what youre asking.)
    – D. Ben Knoble
    Sep 2, 2021 at 21:12
  • @D.BenKnoble I'm using Vim for programming and I often review a lot, e.g. dozens, of different files at various points, but then, after I finish a review, I don't need or want most of those files listed in my buffers list, mainly because I use the buffers list as a 'recently opened' files list, and it's useful for me to be able to open a new window for one of those files. (A fuzzy file/path search plugin might be helpful for this, but I don't have one installed.) Sep 3, 2021 at 15:28
  • 1
    Huh, I think my instinct at that point would be to quit vim—I probably have other things to do between reviews (git stuff, who knows), and would do that more comfortably from the shell or whatever. But i open and close vim all the time—that’s a big part of my workflow (sessions help with long-running context). Anyway, I’ll take a look this weekend at hacking something together: putting the buffers into a window is easy. Cleaning up when youre done is harder :)
    – D. Ben Knoble
    Sep 3, 2021 at 15:38
  • @D.BenKnoble I do the same thing, i.e. quit Vim. I would think there's a plugin for this, and maybe I'll look for one. I just figured there was probably a way to do this in vanilla Vim – there usually is! Sep 3, 2021 at 19:43
  • 1
    If the buffers you want to get rid belong to different projects, there is a :Project prjname :bd command hidden in my library plugin. Another possibility if the buffers you want to remove share a globbing pattern, this Q/A may help. Sep 4, 2021 at 10:17

2 Answers 2

2

Here is the proof of concept.

Create a function that deletes a buffer out of a line that has a buffer info:

func! DeleteBuffer() abort
    let bnr = matchstr(getline('.'), '^\s*\zs\d\+')
    exe "confirm bd" . bnr
endfunc
noremap <space>de :call DeleteBuffer()<CR>

Basically if you have a lines like:

  4  h   "templates\asciidoctor\options_ru" line 1
  5  h   "templates\asciidoctor\diagram" line 1

you can put your cursor on the line and press <space>de. Or select several lines and do the same.

To get list of buffers to some other buffer you might use:

:put=execute('ls')

So in the end it might look like this: enter image description here

1
  • The :put=execute('ls') goes a long way by itself to providing most of a 'manual' solution to what I want to be able to do. It'd be easy enough to use that output to create an Ex command to delete any number of buffers. I already have a keymap setup for myself to run the current line in a buffer as an Ex command. Thanks! Oct 5, 2021 at 15:13
1

Here's buffy, something I whipped up based on Martin's excellent batchy: Run :Buffy, edit the vimscript, and then run :Slay.

if exists('g:loaded_buffy')
  finish
endif
let g:loaded_buffy = 1

call prop_type_add('buffy', #{highlight: 'Special'})

function Buffy() abort
  const scriptfile = tempname()
  execute 'split' scriptfile
  setlocal nobuflisted bufhidden=wipe
  setfiletype buffy.vim
  command! -buffer Slay silent write | source % | close

  const buffers = getbufinfo(#{buflisted: v:true})
        \ ->filter({_, v -> !empty(v.name)})
        \ ->map({_, v -> '" bdelete ' .. v.name})
  const message = [
        \ '" Buffy the buffer slayer',
        \ '" Uncomment the buffers you want to delete',
        \ '" Then run :Slay to delete the buffers and close this window',
        \ ]
  silent put =buffers
  silent 0put =message
  silent write

  call prop_add(1, 1, #{end_lnum: 2, type: 'buffy'})
  call prop_add(2, 1, #{end_lnum: 3, type: 'buffy'})
  call prop_add(3, 1, #{end_lnum: 4, type: 'buffy'})
endfunction

command Buffy call Buffy()

Drop this in plugin/buffy.vim.

8
  • I'm actually running Neovim (via the VimR macOS app) and apparently Batchy doesn't work in Neovim. I'm getting some errors I imagine might be because of similar issue(s) with your script. (Apparently the -> Vimscript syntax has only maybe recently been implemented in Neovim.) Oct 4, 2021 at 20:58
  • 1
    @KennyEvitt yeah, I don't have time to port to NeoVim compatible, but it boils down to usually a->f(x) is like f(a, x).
    – D. Ben Knoble
    Oct 4, 2021 at 21:00
  • 1
    @KennyEvitt if the const buffers is the issue, try const buffers = map(filter(getbufinfo(#{buflisted: v:true}), {_, v -> !empty(v.name)}), {_, v -> '" bdelete ' .. v.name}) (a lot less readable, but should semantically be the same). Adjust if your vim does not have #{} literals, too, or -> lambdas (seen in the filter and map arguments). Those take a bit more to rewrite.
    – D. Ben Knoble
    Oct 4, 2021 at 23:11
  • 1
    @KennyEvitt that patch is for method syntax, not lambdas. Yeah, this function does something similar: it generates a script, which you modify, and then executes it. Here's without lambdas but with method syntax (and then you could still get rid of method syntax if you wanted): const buffers = getbufinfo(#{buflisted: v:true})->filter('!empty(v:val.name)')->map("'\" bdelete ' .. v:val.name")
    – D. Ben Knoble
    Oct 5, 2021 at 15:20
  • 1
    Let us continue this discussion in chat.
    – D. Ben Knoble
    Oct 5, 2021 at 16:01

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.