vim-patch:9.0.0826: if 'endofline' is set CTRL-Z may be written in a wrong place (#20903)

Problem:    If 'endofline' is set the CTRL-Z may be written in the wrong
            place.
Solution:   Write CTRL-Z at the end of the file.  Update the help to explain
            the possibilities better. (Ken Takata, closes vim/vim#11486)

3af982196b

Co-authored-by: K.Takata <kentkt@csc.jp>
This commit is contained in:
zeertzjq
2022-11-02 08:02:52 +08:00
committed by GitHub
parent b05d1943f0
commit 41f308feab
4 changed files with 131 additions and 15 deletions

View File

@@ -1624,23 +1624,31 @@ failed:
error = false;
}
// In Dos format ignore a trailing CTRL-Z, unless 'binary' is set.
// In old days the file length was in sector count and the CTRL-Z the
// marker where the file really ended. Assuming we write it to a file
// system that keeps file length properly the CTRL-Z should be dropped.
// Set the 'endoffile' option so the user can decide what to write later.
// In Unix format the CTRL-Z is just another character.
if (linerest != 0
&& !curbuf->b_p_bin
&& fileformat == EOL_DOS
&& ptr[-1] == Ctrl_Z) {
ptr--;
linerest--;
if (set_options) {
curbuf->b_p_eof = true;
}
}
// If we get EOF in the middle of a line, note the fact and
// complete the line ourselves.
// In Dos format ignore a trailing CTRL-Z, unless 'binary' set.
if (!error
&& !got_int
&& linerest != 0
// TODO(vim): should we handle CTRL-Z differently here for 'endoffile'?
&& !(!curbuf->b_p_bin
&& fileformat == EOL_DOS
&& *line_start == Ctrl_Z
&& ptr == line_start + 1)) {
&& linerest != 0) {
// remember for when writing
if (set_options) {
curbuf->b_p_eol = false;
if (*line_start == Ctrl_Z && ptr == line_start + 1) {
curbuf->b_p_eof = true;
}
}
*ptr = NUL;
len = (colnr_T)(ptr - line_start + 1);
@@ -3197,11 +3205,6 @@ restore_backup:
len = 0;
write_info.bw_start_lnum = lnum;
}
if (!buf->b_p_fixeol && buf->b_p_eof) {
// write trailing CTRL-Z
(void)write_eintr(write_info.bw_fd, "\x1a", 1);
}
// write failed or last line has no EOL: stop here
if (end == 0
|| (lnum == end
@@ -3253,6 +3256,11 @@ restore_backup:
nchars += len;
}
if (!buf->b_p_fixeol && buf->b_p_eof) {
// write trailing CTRL-Z
(void)write_eintr(write_info.bw_fd, "\x1a", 1);
}
// Stop when writing done or an error was encountered.
if (!checking_conversion || end == 0) {
break;

View File

@@ -48,4 +48,71 @@ func Test_fixeol()
enew!
endfunc
func Test_eof()
let data = 0z68656c6c6f.0d0a.776f726c64 " "hello\r\nworld"
" 1. Eol, Eof
" read
call writefile(data + 0z0d0a.1a, 'XXEolEof')
e! XXEolEof
call assert_equal(['hello', 'world'], getline(1, 2))
call assert_equal([1, 1], [&eol, &eof])
" write
set fixeol
w!
call assert_equal(data + 0z0d0a, readblob('XXEolEof'))
set nofixeol
w!
call assert_equal(data + 0z0d0a.1a, readblob('XXEolEof'))
" 2. NoEol, Eof
" read
call writefile(data + 0z1a, 'XXNoEolEof')
e! XXNoEolEof
call assert_equal(['hello', 'world'], getline(1, 2))
call assert_equal([0, 1], [&eol, &eof])
" write
set fixeol
w!
call assert_equal(data + 0z0d0a, readblob('XXNoEolEof'))
set nofixeol
w!
call assert_equal(data + 0z1a, readblob('XXNoEolEof'))
" 3. Eol, NoEof
" read
call writefile(data + 0z0d0a, 'XXEolNoEof')
e! XXEolNoEof
call assert_equal(['hello', 'world'], getline(1, 2))
call assert_equal([1, 0], [&eol, &eof])
" write
set fixeol
w!
call assert_equal(data + 0z0d0a, readblob('XXEolNoEof'))
set nofixeol
w!
call assert_equal(data + 0z0d0a, readblob('XXEolNoEof'))
" 4. NoEol, NoEof
" read
call writefile(data, 'XXNoEolNoEof')
e! XXNoEolNoEof
call assert_equal(['hello', 'world'], getline(1, 2))
call assert_equal([0, 0], [&eol, &eof])
" write
set fixeol
w!
call assert_equal(data + 0z0d0a, readblob('XXNoEolNoEof'))
set nofixeol
w!
call assert_equal(data, readblob('XXNoEolNoEof'))
call delete('XXEolEof')
call delete('XXNoEolEof')
call delete('XXEolNoEof')
call delete('XXNoEolNoEof')
set ff& fixeol& eof& eol&
enew!
endfunc
" vim: shiftwidth=2 sts=2 expandtab