2

Given some text stored in a variable, is it possible to write this text to an arbitrary buffer in the background? I ask about buffers specifically because I'm aware of writefile(), but I want to write to a buffer with no associated file (i.e. buftype=acwrite). The buffer holds a representation of a database record.

This is possible via the Ruby API, but I can't figure out how to do with vimscript. append() only operates on the current buffer.

2

If your Vim version is more recent than 8.0.1039, you could use the setbufline() function. It allows you to replace a line in an arbitrary buffer with any text.

Usage example:

call setbufline(12, 34, 'hello world')

This should replace the text on the line 34 inside the buffer 12 with hello world.


What if the old content has more lines than the new content? Do you know how I would get rid of those lines?

Maybe you could replace the first lines of the buffer with the text you have stored in your variable, then replace all the rest with empty strings:

let your_buffer_number = 123
let your_new_lines = ['foo', 'bar', 'baz']
let remaining_lines = len(getbufline(your_buffer_number, 1, '$')) - len(your_new_lines)
call setbufline(your_buffer_number, 1, your_new_lines + repeat([''], remaining_lines))

This will not delete the superfluous lines, but it should make them empty.

Replace the buffer number 123 with the one you're actually using, and the list of texts ['foo', 'bar', 'baz'] with the ones you want to write in your buffer.

For more information, see:

:h getbufline()
:h setbufline()
:h repeat()

If you're using Neovim, and it's more recent than v0.2.0, then you could use the nvim_buf_set_lines() function.

Usage example:

call nvim_buf_set_lines(123, 0, len(getbufline(123, 1, '$')), 0, ['foo', 'bar', 'baz'])

This should replace all the lines in the 123th buffer with the lines foo, bar and baz.

As a result, this function would also delete the superfluous lines, if the old contents of the buffer is longer than the new one.

Note that I'm not sure about the exact Neovim version which introduced the function, but 0.2.0 is the one given by helpful.vim.

  • Thanks -- this solves part of my problem. Ultimately what I'm trying to do is to replace the entire content of the buffer. I don't want to just delete and recreate the buffer because I want to preserve it in any window it might be open in. setbufline() will allow me to overwrite some content, but what if the old content has more lines than the new content? Do you know how I would get rid of those lines? – Sean Mackesey Apr 26 '18 at 18:04
  • 2
    In todo.txt:| deletebufline() delete line in any buffer | appendbufline() append line in any buffer | appendbufline is somewhat useless given that setbufline can alreday append. there definitely ought to be a way to remove a line from a (non-active) buffer. – Mass Apr 27 '18 at 4:32
  • 2
    I made a patch – Christian Brabandt Apr 27 '18 at 13:20
  • Cool that this spawned a patch request. Thanks @ChristianBrabandt. Also thanks for the nvim solution, I guess there's currently no way to do this is vanilla vim so I'm accepting. – Sean Mackesey Apr 27 '18 at 16:26
  • a delbufline() function has been included as of 8.1.0039 – Christian Brabandt Jun 7 '18 at 16:37

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.