To: vim_dev@googlegroups.com Subject: Patch 9.0.0826 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 9.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) Files: runtime/doc/editing.txt, runtime/doc/options.txt, src/bufwrite.c, src/fileio.c, src/testdir/test_fixeol.vim *** ../vim-9.0.0825/runtime/doc/editing.txt 2022-08-25 18:12:00.350668422 +0100 --- runtime/doc/editing.txt 2022-11-01 20:07:41.081352720 +0000 *************** *** 578,583 **** --- 578,620 ---- You can encrypt files that are written by setting the 'key' option. This provides some security against others reading your files. |encryption| + END OF LINE AND END OF FILE *eol-and-eof* + + Vim has several options to control the file format: + 'fileformat' the style: Unix, DOS, Mac + 'endofline' whether the last line ends with a + 'endooffile' whether the file ends with a CTRL-Z + 'fixendofline' whether to fix eol and eof + + The first three values are normally detected automatically when reading the + file and are used when writing the text to a file. While editing the buffer + it looks like every line has a line ending and the CTRL-Z isn't there (an + exception is when 'binary' is set, it works differently then). + + The 'fixendofline' option can be used to choose what to write. You can also + change the option values to write the file differently than how it was read. + + Here are some examples how to use them. + + If you want files in Unix format (every line NL terminated): > + setl ff=unix fixeol + You should probably do this on any Unix-like system. Also modern MS-Windows + systems tend to work well with this. It is recommended to always use this + format for Vim scripts. + + If you want to use an old MS-DOS file in a modern environment, fixing line + endings and dropping CTRL-Z, but keeping the style : > + setl ff=dos fixeol + This is useful for many MS-Windows programs, they regularly expect the + line endings. + + If you want to drop the final and add a final CTRL-Z (e.g. for an old + system like CP/M): > + setl ff=dos nofixeol noeol eof + + If you want to preserve the fileformat exactly as-is, including any final + and final CTRL-Z: > + setl nofixeol ============================================================================== 3. The argument list *argument-list* *arglist* *** ../vim-9.0.0825/runtime/doc/options.txt 2022-10-15 16:04:43.994187227 +0100 --- runtime/doc/options.txt 2022-11-01 19:50:05.568875402 +0000 *************** *** 3021,3026 **** --- 3048,3063 ---- When 'encoding' is set to a Unicode encoding, and 'fileencodings' was not set yet, the default for 'fileencodings' is changed. + *'endoffile'* *'eof'* *'noendoffile'* *'noeof'* + 'endoffile' 'eof' boolean (default on) + local to buffer + Indicates that a CTRL-Z character was found at the end of the file + when reading it. Normally only happens when 'fileformat' is "dos". + When writing a file and this option is off and the 'binary' option + is on, or 'fixeol' option is off, no CTRL-Z will be written at the + end of the file. + See |eol-and-eof| for example settings. + *'endofline'* *'eol'* *'noendofline'* *'noeol'* 'endofline' 'eol' boolean (default on) local to buffer *************** *** 3035,3040 **** --- 3072,3078 ---- to remember the presence of a for the last line in the file, so that when you write the file the situation from the original file can be kept. But you can change it if you want to. + See |eol-and-eof| for example settings. *'equalalways'* *'ea'* *'noequalalways'* *'noea'* 'equalalways' 'ea' boolean (default on) *************** *** 3425,3435 **** 'fixendofline' 'fixeol' boolean (default on) local to buffer When writing a file and this option is on, at the end of file ! will be restored if missing. Turn this option off if you want to preserve the situation from the original file. When the 'binary' option is set the value of this option doesn't matter. See the 'endofline' option. *'fkmap'* *'fk'* *'nofkmap'* *'nofk'* 'fkmap' 'fk' boolean (default off) --- 3463,3474 ---- 'fixendofline' 'fixeol' boolean (default on) local to buffer When writing a file and this option is on, at the end of file ! will be restored if missing. Turn this option off if you want to preserve the situation from the original file. When the 'binary' option is set the value of this option doesn't matter. See the 'endofline' option. + See |eol-and-eof| for example settings. *'fkmap'* *'fk'* *'nofkmap'* *'nofk'* 'fkmap' 'fk' boolean (default off) *** ../vim-9.0.0825/src/bufwrite.c 2022-10-22 10:06:38.428322861 +0100 --- src/bufwrite.c 2022-11-01 19:50:05.568875402 +0000 *************** *** 2050,2059 **** len = 0; write_info.bw_start_lnum = lnum; } - if (!buf->b_p_fixeol && buf->b_p_eof) - // write trailing CTRL-Z - (void)write_eintr(ip->bw_fd, "\x1a", 1); - // write failed or last line has no EOL: stop here if (end == 0 || (lnum == end --- 2050,2055 ---- *************** *** 2158,2163 **** --- 2154,2166 ---- 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; *** ../vim-9.0.0825/src/fileio.c 2022-10-29 19:54:03.849448379 +0100 --- src/fileio.c 2022-11-01 20:15:40.798171983 +0000 *************** *** 2271,2297 **** 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. ! */ 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)) { // 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) --- 2271,2302 ---- if (error && read_count == 0) 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 by resetting ! // 'endofline' and add the line normally. if (!error && !got_int ! && linerest != 0) { // remember for when writing if (set_options) curbuf->b_p_eol = FALSE; *ptr = NUL; len = (colnr_T)(ptr - line_start + 1); if (ml_append(lnum, line_start, len, newfile) == FAIL) *** ../vim-9.0.0825/src/testdir/test_fixeol.vim 2022-10-29 19:54:03.849448379 +0100 --- src/testdir/test_fixeol.vim 2022-11-01 19:50:05.568875402 +0000 *************** *** 48,51 **** --- 48,118 ---- 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 *** ../vim-9.0.0825/src/version.c 2022-11-01 18:34:02.783964409 +0000 --- src/version.c 2022-11-01 20:27:27.876045394 +0000 *************** *** 697,698 **** --- 697,700 ---- { /* Add new patch number below this line */ + /**/ + 826, /**/ -- login: yes password: I don't know, please tell me password is incorrect login: yes password: incorrect /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///