1

As example, my current buffer contains below lines

di=01;34
ln=01;36
mh=00
pi=40;33

I want to join all lines with :, and set entire buffer to the joined string.

How to achieve that, using :python command.

I tried below

py3 vim.current.buffer[:] = ':'.join(vim.current.buffer)
py3 vim.current.buffer = ':'.join(vim.current.buffer)

But neither works.

1

In vimscript, just as an alternative:

:1,$-1substitute/$/:
:global/^/join

In one line with abbreviated commands:

:1,$-1s/$/:/ | g/^/j
  • Nice solution, though I specifically want :python solution. BTW, need to change %s to 1,$-1s to match the join approach exactly. Alsokeepp and keepj can be used to avoid clustering search history & jumps, though only worth the effort if wrapped as a function or command. – qeatzy Sep 22 '19 at 0:58
1

vim.current.buffer refers to a buffer object.

vim.current.buffer[:] on the other hand, is a list of strings containing the content of the buffer.

You can manipulate the lines of the buffer by retrieving and assigning to this list:

py3 vim.current.buffer[:] = [ ':'.join(vim.current.buffer[:]) ]
  • I tried your solution, still not working. error is Traceback (most recent call last): File "<string>", line 1, in <module> TypeError: bad argument type for built-in operation – qeatzy Sep 22 '19 at 0:50
  • :version outputs +python3/dyn , invoked by vim -u ~/tmp/.vimrc, cat ~/tmp/.vimrc outputs set nocp. – qeatzy Sep 22 '19 at 0:52
  • found the answer, just change rhs to a list of string. – qeatzy Sep 22 '19 at 1:22
  • Sounds like we just need [ ':'.join(...) ] – D. Ben Knoble Sep 22 '19 at 3:54
0

As @Mass's answer said, to set buffer content, you cannot assign to the buffer object itself, you need to assign to the the sliced version, eg vim.current.buffer[:].

Currently what's missing from there is, you need to use a list of string instead of a string to assign to a sliced buffer object.

To summary

# set first line to a string
py3 vim.current.buffer[0] = "Hello world"
# replace whole buffer with a string
py3 vim.current.buffer[:] = ["a long long string"]
# replace whole buffer with two lines
py3 vim.current.buffer[:] = ["first line", "second line"]
# replace first 10 line with two lines
py3 vim.current.buffer[:10] = ["first line", "second line"]

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.