[vim/vim] systemlist() does not return trailing blank lines (#2534)

31 views
Skip to first unread message

pkay42

unread,
Jan 6, 2018, 12:53:53 PM1/6/18
to vim/vim, Subscribed

Bug:

systemlist() does not return/cuts off last lines that are blank.

Example function demonstrating problem:
function TestSystemList()
let l:lines=['','', 'ABC', '', '']
echo "Using as input the lines:"
echo l:lines
let l:syslist=systemlist("cat", l:lines) " return lines exactly as given
echo "Calling systemlist("cat", l:lines) returns:"
echo l:syslist
let l:sysblock=system("cat", l:lines)
echo "Calling system("cat", l:lines) returns:"
echo l:sysblock
echo " (which includes all the lines)"
let l:split1=split(l:sysblock, "\n", 1)
echo "Using split(l:sysblock, "\n", 1) shows all the lines:"
echo l:split1
let l:split2=split(l:sysblock, "\n")
echo "Using split(l:sysblock, "\n") cuts off preceeding blank lines and the last line:"
echo l:split2
echo "systemlist() appears to be losing only the trailing line"
endfunction

Motivation:
A file that ends with multiple blank lines loses lines after a similar
systemlist() call:
Line 1:ABC
Line 2:
Line 3:

Proposed fixes:
A. clearly document that systemlist() does not preserve terminating
blank lines, advise using system() and split(...{keepempty})
B. (preferred by me) change systemlist() behavior to preserve last blank lines

Running:

Linux computer_name 4.9.0-4-amd64 #1 SMP Debian 4.9.65-3+deb9u1
(2017-12-23) x86_64 GNU/Linux

VIM - Vi IMproved 8.0 (2016 Sep 12, compiled Sep 30 2017 18:21:38)
Included patches: 1-197, 322, 377-378, 550, 703, 706-707


You are receiving this because you are subscribed to this thread.
Reply to this email directly, view it on GitHub

Nikolai Aleksandrovich Pavlov

unread,
Jan 6, 2018, 4:42:11 PM1/6/18
to vim/vim, Subscribed

This is now an issue of backwards compatibility, so Neovim team has already decided on the third option: add an argument which determines whether trailing newlines are to be preserved. Note that systemlist() was initially designed to get binary contents, but I made a bug during the implementation which was not fixed in time, so option A is not actually valid; meanwhile you can actually achieve intended behaviour either by using constructs like echo systemlist('bincmd ; echo') or like call system('bincmd > fname') | echo readfile('fname', 'b') | call delete('fname').

pkay42

unread,
Jan 6, 2018, 10:09:52 PM1/6/18
to vim/vim, Subscribed
An argument works very well, and while in many ways inconvenient and
confusing (more tying, and why is only 1 trailing newline removed and not
all of them w/o the flag, etc?), it does give that backward compatibility!

I got my desired behaviour using let l:temp=system(etc) | let
l:lines=split(l:temp, "\n", 1) or something like that.


On Sat, Jan 6, 2018 at 4:42 PM, Nikolai Aleksandrovich Pavlov <
notifi...@github.com> wrote:

> This is now an issue of backwards compatibility, so Neovim team has
> already decided on the third option: add an argument which determines
> whether trailing newlines are to be preserved. Note that systemlist() was
> initially designed to get binary contents, but I made a bug during the
> implementation which was not fixed in time, so option A is not actually
> valid; meanwhile you can actually achieve intended behaviour either by
> using constructs like echo systemlist('bincmd ; echo') or like call
> system('bincmd > fname') | echo readfile('fname', 'b') | call
> delete('fname').
>
> —
> You are receiving this because you authored the thread.

> Reply to this email directly, view it on GitHub
> <https://github.com/vim/vim/issues/2534#issuecomment-355779997>, or mute
> the thread
> <https://github.com/notifications/unsubscribe-auth/AEdofNTr5sXRJZwvk7EYGjVsVfmwHoirks5tH-iwgaJpZM4RVYnN>
> .

Nikolai Aleksandrovich Pavlov

unread,
Jan 7, 2018, 10:38:38 AM1/7/18
to vim/vim, Subscribed

Why should it remove more? In the current state it is rather convenient to get newline-separated text contents, even though it was not actual intention: normally under those circumstances you have exactly one trailing newline (because text is not newline-separated, but newline-terminated) and not many of them. And I actually find behaviour of $() (if you think this has something to do with that) extremely annoying: should I want to preserve newline I am out of the most convenient option of VAR="$(cmd ; echo)" and need to use VAR="$(cmd ; echo A)"; VAR="${VAR%A}" instead, but I never saw myself in a situation when command outputs a bunch of newlines which I want to remove.

pkay42

unread,
Jan 7, 2018, 4:02:21 PM1/7/18
to vim/vim, Subscribed
Ah! I understand the usefulness of the current behavior now! Thank you.
I was approaching the function from a very different angle and chopping off
that last bit was an unpleasant surprise for me - not a feature. (Losing a
line as opposed to getting rid of an annoying empty string) A {keepempty}
argument that defaults to 0 seems the way to go then.


On Sun, Jan 7, 2018 at 10:38 AM, Nikolai Aleksandrovich Pavlov <
notifi...@github.com> wrote:

> Why should it remove more? In the current state it is rather convenient to
> get newline-separated text contents, even though it was not actual
> intention: normally under those circumstances you have exactly one trailing
> newline (because text is not newline-separated, but newline-terminated) and
> not many of them. And I actually find behaviour of $() (if you think this
> has something to do with that) extremely annoying: should I want to
> preserve newline I am out of the most convenient option of VAR="$(cmd ;
> echo)" and need to use VAR="$(cmd ; echo A)"; VAR="${VAR%A}" instead, but
> I never saw myself in a situation when command outputs a bunch of newlines
> which I want to remove.
>
> —
> You are receiving this because you authored the thread.

> Reply to this email directly, view it on GitHub
> <https://github.com/vim/vim/issues/2534#issuecomment-355831029>, or mute
> the thread
> <https://github.com/notifications/unsubscribe-auth/AEdofJhtpLMhvNjrorqRy_EM-6eJZzuWks5tIOT2gaJpZM4RVYnN>
> .
Reply all
Reply to author
Forward
0 new messages