[vim/vim] :w !foo doesn't number lines, or add missing LF (#2340)

37 views
Skip to first unread message

Ralph Corderoy

unread,
Nov 15, 2017, 7:33:54 AM11/15/17
to vim/vim, Subscribed

Using vim 8.0.1272-1 on Arch Linux...

http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html#tag_20_40_13_48 says

The standard error and standard output of the program, if any, shall be written as described for the print command.

The print command adds line numbers with :se nu, but these aren't being shown for :w !seq 11 13.
A blank line precedes the output of seq; I don't think that should be there.

If the last character in that output is not a <newline>, a <newline> shall be written at the end of the output.

:w !printf foo does not add the LF.


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

Christian Brabandt

unread,
Nov 16, 2017, 2:23:24 AM11/16/17
to vim/vim, Subscribed

The print command adds line numbers with :se nu, but these aren't being shown for :w !seq 11 13.

Using :w !seq 11 13 does not show, whether line numbers have been seen. seq does seem to discard stdin and does nothing with it. Also please note, the idea of the :w !{cmd} command is to execute {cmd} with the selected lines as standard input. It does not make sense to add line numbers (which physically do not exist in the buffer) to the input of the external command. That would make the output of the external command inconsistent (whether or not line numbers are visible or not), e.g. a command like this:

:w !nl

Would number the lines once or twice, depending on whether :set nu was set. That sounds wrong.

:w !printf foo does not add the LF.

How do you know? Again, printf does not take its stdin into account and simply prints the output with a newline added.

Christian Brabandt

unread,
Nov 16, 2017, 2:26:45 AM11/16/17
to vim/vim, Subscribed

Or a more practical example:
:w !sha1sum would result in the wrong checksum.

Ralph Corderoy

unread,
Nov 16, 2017, 9:49:57 AM11/16/17
to vim/vim, Subscribed

@chrisbra, It doesn't matter that my example commands didn't read the buffer's lines written to them by ex as it is the stdout and stderr of the command that ex has to process; see my opening quote from the POSIX document, and it for more detail. Here's a repeat that meets your criteria, showing exactly the same deviations from POSIX.

    $ (exec -a ex vim)
    Entering Ex mode.  Type "visual" to go to Normal mode.
    :a
    abc
    def
    .
    :%p
    abc
    def
    :se nu
    :%p
      1 abc
      2 def
    :w !sed -n l

    abc$
    def$
    :w !head -c 5

    abc
    d:q!
    $ 

Again, the unwanted blank line is present before the output of the command making it appear part of the command's output. The output of sed should have line numbers. The output of head doesn't end with LF and ex should have added one before printing its : to which I entered q!.

Christian Brabandt

unread,
Nov 16, 2017, 11:02:02 AM11/16/17
to vim/vim, Subscribed

The point is, the buffers lines are feed to an external command as input. It does not make any sense to return the line numbers to the external command. Because as I said before, this will generate wrong output (think of generating a hashsum from the buffer input). I don't think that is intended by POSIX.

Ralph Corderoy

unread,
Nov 17, 2017, 6:37:39 PM11/17/17
to vim/vim, Subscribed

@chrisbra, Please discard what you think you know about this issue and start again. :-)

The :se nu is to be applied to the output of the command given to :w !.
It, of course, makes no sense to apply it to the input to the command.

$ (exec -a ex vim)
Entering Ex mode.  Type "visual" to go to Normal mode.
:se nu
:w !wc -c

0
:w !sha1sum

da39a3ee5e6b4b0d3255bfef95601890afd80709  -
:a
da39a3ee5e6b4b0d3255bfef95601890afd80709  -
..
:%p
  1 da39a3ee5e6b4b0d3255bfef95601890afd80709  -
:q!
$ 

Here the %p shows the output I would expect from the :w !sha1sum.
The wc -c output should also have been numbered.
Neither should have the misleading initial blank line.

K.Takata

unread,
Nov 17, 2017, 7:34:37 PM11/17/17
to vim/vim, Subscribed

I don't know what POSIX intended, but I don't think that the 'nu' option should be applied to :w.
BTW, how do other vi implementations (e.g. nvi) work?

Ralph Corderoy

unread,
Nov 18, 2017, 8:38:38 AM11/18/17
to vim/vim, Subscribed

@k-takata, Do you mean reading the POSIX I link to above is unclear? Their intention seems precise to me. In effect, it's as if the output of command foo in :w !foo ends up in a buffer that's then %p'd, taking into account :se nu and :se list, and thus appending a LF even if foo's output didn't have one. Yes, :se list is also not applied by vim to foo's output.

As for nvi, another re-implementation like vim and so not the command POSIX was documenting, it is a lot better, but not perfect.

:se nu list
:a
     1  a      b
     2  .
:%p
     1  a^Ib
:w !cat
a^Ib
!
:

I entered a tab between the a and b, as correctly shown by %p. It correctly doesn't add a blank line to the start of the output, unlike vim. It correctly applies se list, unlike vim.

:a
abcdefg
..
:w !head -c 3
abc
!

Here, nvi correctly appends a LF to head's LF-less output.

Reply all
Reply to author
Forward
0 new messages