diff options
author | K.Takata <kentkt@csc.jp> | 2022-11-01 20:36:19 +0000 |
---|---|---|
committer | Bram Moolenaar <Bram@vim.org> | 2022-11-01 20:36:19 +0000 |
commit | 3af982196b1b973e953c35351961f2a96fe34172 (patch) | |
tree | 8b2bc31d033187b17b4c5fb6e51350f833cd984b /src | |
parent | 8e0ccb6bc21a446e5c6375b7fdf200fb53a129da (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.c | 11 | ||||
-rw-r--r-- | src/fileio.c | 35 | ||||
-rw-r--r-- | src/testdir/test_fixeol.vim | 67 | ||||
-rw-r--r-- | src/version.c | 2 |
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, |