[vim/vim] ":write" with a range that spans the whole buffer will set the buffer name with a new buffer (#744)

34 views
Skip to first unread message

Daniel Hahler

unread,
Apr 9, 2016, 7:51:08 PM4/9/16
to vim/vim

This will cause the buffer to get the temporary name:

vim -u NONE -c 'norm ifoo' -c ".w$(mktemp -u)" -c 'echom bufname("%")'

While this won't:

vim -u NONE -c 'norm ifoo' -c 'norm ofoo' -c ".w$(mktemp -u)" -c 'echom bufname("%")'

This confused me when running a function to write something to a temporary file from a new buffer, and the buffer name was changed to the temporary file.

It looks like there is some internal check being done for "has the whole buffer been written?", which should be "has a range been given?" instead maybe?

The help says:

The default [range] for the ":w" command is the whole buffer (1,$). If you
write the whole buffer, it is no longer considered changed. When you
write it to a different file with ":w somefile" it depends on the "+" flag in
'cpoptions'. When included, the write command will reset the 'modified' flag,
even though the buffer itself may still be different from its file.

Is it possible for Vim to distinguish between 1,$, ., and no range provided at this point?

If this behavior is intentional (I could understand it), it should be documented probably.

exe a:firstline.",".a:lastline."w ".tmpfile can be replaced by call writefile(getbufline(bufnr('%'), a:firstline, a:lastline), tmpfile), which is not affected by this behavior.


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

Ralph Corderoy

unread,
Nov 15, 2017, 7:27:32 AM11/15/17
to vim/vim, Subscribed

POSIX says if there's no current pathname then any write sets that name. See 4a at http://pubs.opengroup.org/onlinepubs/9699919799/utilities/ex.html#tag_20_40_13_01

So vim shouldn't be checking if it's the whole buffer, or if a range is given?


You are receiving this because you are subscribed to this thread.

Reply to this email directly, view it on GitHub

Tony Mechelynck

unread,
Nov 15, 2017, 9:21:10 AM11/15/17
to vim/vim, Subscribed

This is documented under the help for the appropriate 'cpoptions' flag (and remember that all flags are set in POSIX-compatible mode, most flags are set in (vi-)compatible mode, and aABceFs are set by default in 'nocompatible' mode);

								*cpo-F*
		F	When included, a ":write" command with a file name
			argument will set the file name for the current
			buffer, if the current buffer doesn't have a file name
			yet.  Also see |cpo-P|.

[…]

								*cpo-P*
		P	When included, a ":write" command that appends to a
			file will set the file name for the current buffer, if
			the current buffer doesn't have a file name yet and
			the 'F' flag is also included |cpo-F|.

Apparently, the F flag only applies when writing the whole file (including when writing just the current line of a one-line buffer). It can be regarded as a bug or a feature (I think it's a feature), but I think the documentation and the actual behaviour should agree. @brammool ? This is in your department.

Best regards,
Tony.


You are receiving this because you are subscribed to this thread.

Christian Brabandt

unread,
Nov 15, 2017, 9:27:07 AM11/15/17
to vim/vim, Subscribed

If I understand the bug correctly, I would consider this a feature. The reason being, if you write only part of the lines to a new filename, you most likely do not want that a default :w will overwrite your file.


You are receiving this because you are subscribed to this thread.

James McCoy

unread,
Nov 15, 2017, 10:20:05 AM11/15/17
to vim/vim, Subscribed

The reason being, if you write only part of the lines to a new filename, you most likely do not want that a default :w will overwrite your file.

That sounds like Daniel's expectations, too. However, those expectations don't match reality.

The problem is that performing :.w foo (note the explicit range of .) in a single-line, unnamed buffer will set the buffer's name to foo.

This really seems like a UI issue. It's clear that :w foo (no explicit range) should set the buffer name. The issue arises in distinguishing the behavior when different types of ranges are used, especially since the code doesn't currently provide a way to distinguish between :1,$/:% and :. in a single-line buffer. Those can clearly have different meanings to a user.


You are receiving this because you are subscribed to this thread.

Ralph Corderoy

unread,
Nov 15, 2017, 10:32:51 AM11/15/17
to vim/vim, Subscribed

If it's thought POSIX is wrong then it would seem only polite to go back to Opengroup and ask if they really meant a given set of outcomes. Presumably, that needs to be known to clarify compatibility behaviour should vim decide to deviate from POSIX.


You are receiving this because you are subscribed to this thread.

Houl

unread,
Nov 15, 2017, 12:18:55 PM11/15/17
to vim/vim, Subscribed

Reminds me of https://groups.google.com/d/topic/vim_dev/1I5ccGnRA4Y


You are receiving this because you are subscribed to this thread.

Christian Brabandt

unread,
Nov 16, 2017, 1:47:31 AM11/16/17
to vim/vim, Subscribed

The problem is that performing :.w foo (note the explicit range of .) in a single-line, unnamed buffer will set the buffer's name to foo.

I find that (inconsistent behaviour) acceptable, since .w is the same as 1,$ for this specific case.


You are receiving this because you are subscribed to this thread.

Reply all
Reply to author
Forward
0 new messages