summaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorK.Takata <kentkt@csc.jp>2022-11-01 20:36:19 +0000
committerBram Moolenaar <Bram@vim.org>2022-11-01 20:36:19 +0000
commit3af982196b1b973e953c35351961f2a96fe34172 (patch)
tree8b2bc31d033187b17b4c5fb6e51350f833cd984b /src
parent8e0ccb6bc21a446e5c6375b7fdf200fb53a129da (diff)
patch 9.0.0826: if 'endofline' is set CTRL-Z may be written in a wrong placev9.0.0826
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 #11486)
Diffstat (limited to 'src')
-rw-r--r--src/bufwrite.c11
-rw-r--r--src/fileio.c35
-rw-r--r--src/testdir/test_fixeol.vim67
-rw-r--r--src/version.c2
4 files changed, 96 insertions, 19 deletions
diff --git a/src/bufwrite.c b/src/bufwrite.c
index 12c5c7a474..f3adcc3e8e 100644
--- a/src/bufwrite.c
+++ b/src/bufwrite.c
@@ -2050,10 +2050,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
@@ -2158,6 +2154,13 @@ 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);
+ nchars++;
+ }
+
// Stop when writing done or an error was encountered.
if (!checking_conversion || end == 0)
break;
diff --git a/src/fileio.c b/src/fileio.c
index bca827152a..9916de8a63 100644
--- a/src/fileio.c
+++ b/src/fileio.c
@@ -2271,27 +2271,32 @@ failed:
if (error && read_count == 0)
error = FALSE;
- /*
- * 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.
- */
+ // 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 by resetting
+ // 'endofline' and add the line normally.
if (!error
&& !got_int
- && linerest != 0
- // TODO: 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);
if (ml_append(lnum, line_start, len, newfile) == FAIL)
diff --git a/src/testdir/test_fixeol.vim b/src/testdir/test_fixeol.vim
index 9d6c900bdb..41d47d6a06 100644
--- a/src/testdir/test_fixeol.vim
+++ b/src/testdir/test_fixeol.vim
@@ -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
diff --git a/src/version.c b/src/version.c
index c1875adc7b..86cf25ad0c 100644
--- a/src/version.c
+++ b/src/version.c
@@ -696,6 +696,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 826,
+/**/
825,
/**/
824,