Tuesday, August 15, 2017

Re: Silently edit a buffer

2017-08-15 21:56 GMT+03:00 Dmitry Zotikov <xio@ungrund.org>:
> Dear all,
>
> what would be the best way to silently edit a buffer? In particular, I want
> to
> be able to write the content of a variable to it, as well as to delete all
> of
> its content.
>
> The story goes, I'm writing a plugin that among other things reads from a
> network socket using Vim 8 channels and jobs; this is the corresponding
> call:
>
> call job_start(command_cmd, {'out_io': 'buffer', 'out_name': '_out'})
>
> The problem is that on the other side of the socket there's a server process
> which doesn't append a newline after it finishes its write. Consequently,
> reading from the channel set to NL mode would always leave one line of input
> in
> the socket, and so I'm forced to either fall back to RAW mode, or to check
> whether there's something left in the socket and read it later with a
> separate
> ch_read call:
>
> - Writing in RAW mode directly to the buffer leaves ^@ in place of proper
> linefeeds, meaning a callback function would have to be called, that would
> substitute ^@ with ^M and only then write to the buffer; this is where the
> initial question stems from.

I would say that what you see looks like a bug: ^@ is LF (also known
as NL or "\n", byte 0xA), but in a buffer LF is used to represent NUL
and this is why it appears as ^@ (see `:h NL-used-for-Nul`). So if you
have a server which outputs LF separators and buffer is opened with
`unix` `&fileformat` appearing ^@ should be a bug. Though if the
server actually outputs NUL bytes it is not a bug.

Note that ^M or CR or `\r` or byte 0xD is *not* a line feed. Just
`:put` converts *both* CR and LF to a newline, so you probably don't
need to do any substitutions.

(And note that newline in a buffer is neither CR nor LF. It is "NUL"
which terminates a C string which represents a buffer line, conversion
to CR, LF or CRLF is done on write according to `&fileformat` option.)

> - ch_read() call would also have to be performed by a callback function that
> will, again, need a way to somehow write to the buffer.
>
> The closest solution I've got is to do something like
>
> :bufnr('_out') bufdo put =msg
>
> but that switches the current window to "_out" buffer.

You may try using Python `vim.Buffer` class, I am not aware of
anything else which may do update without switching buffers
explicitly. Or just write in a scratch tab page, with all commands to
create it protected by &eventignore='all' and &lazyredraw=1, scratch
tab is to be destroyed after writing. Or create a wrapper script which
will add a newline at the end and which should be communicated with in
place of the server directly.

>
> --
> Regards,
> Dmitry
>
>
> --
> --
> You received this message from the "vim_use" maillist.
> Do not top-post! Type your reply below the text you are replying to.
> For more information, visit http://www.vim.org/maillist.php
>
> ---
> You received this message because you are subscribed to the Google Groups
> "vim_use" group.
> To unsubscribe from this group and stop receiving emails from it, send an
> email to vim_use+unsubscribe@googlegroups.com.
> For more options, visit https://groups.google.com/d/optout.

--
--
You received this message from the "vim_use" maillist.
Do not top-post! Type your reply below the text you are replying to.
For more information, visit http://www.vim.org/maillist.php

---
You received this message because you are subscribed to the Google Groups "vim_use" group.
To unsubscribe from this group and stop receiving emails from it, send an email to vim_use+unsubscribe@googlegroups.com.
For more options, visit https://groups.google.com/d/optout.

No comments: