mirror of
https://github.com/vim/vim.git
synced 2025-09-30 04:44:14 -04:00
patch 9.0.0826: if 'endofline' is set CTRL-Z may be written in a wrong place
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)
This commit is contained in:
@@ -578,6 +578,43 @@ single <NL> characters are unexpectedly replaced with <CR><NL>.
|
|||||||
You can encrypt files that are written by setting the 'key' option. This
|
You can encrypt files that are written by setting the 'key' option. This
|
||||||
provides some security against others reading your files. |encryption|
|
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 <EOL> style: Unix, DOS, Mac
|
||||||
|
'endofline' whether the last line ends with a <EOL>
|
||||||
|
'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 <CR><NL> style <EOL>: >
|
||||||
|
setl ff=dos fixeol
|
||||||
|
This is useful for many MS-Windows programs, they regularly expect the
|
||||||
|
<CR><NL> line endings.
|
||||||
|
|
||||||
|
If you want to drop the final <EOL> 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
|
||||||
|
<EOL> and final CTRL-Z: >
|
||||||
|
setl nofixeol
|
||||||
|
|
||||||
==============================================================================
|
==============================================================================
|
||||||
3. The argument list *argument-list* *arglist*
|
3. The argument list *argument-list* *arglist*
|
||||||
|
@@ -3056,6 +3056,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
When writing a file and this option is off and the 'binary' option
|
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
|
is on, or 'fixeol' option is off, no CTRL-Z will be written at the
|
||||||
end of the file.
|
end of the file.
|
||||||
|
See |eol-and-eof| for example settings.
|
||||||
|
|
||||||
*'endofline'* *'eol'* *'noendofline'* *'noeol'*
|
*'endofline'* *'eol'* *'noendofline'* *'noeol'*
|
||||||
'endofline' 'eol' boolean (default on)
|
'endofline' 'eol' boolean (default on)
|
||||||
@@ -3071,6 +3072,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
to remember the presence of a <EOL> for the last line in the file, so
|
to remember the presence of a <EOL> for the last line in the file, so
|
||||||
that when you write the file the situation from the original file can
|
that when you write the file the situation from the original file can
|
||||||
be kept. But you can change it if you want to.
|
be kept. But you can change it if you want to.
|
||||||
|
See |eol-and-eof| for example settings.
|
||||||
|
|
||||||
*'equalalways'* *'ea'* *'noequalalways'* *'noea'*
|
*'equalalways'* *'ea'* *'noequalalways'* *'noea'*
|
||||||
'equalalways' 'ea' boolean (default on)
|
'equalalways' 'ea' boolean (default on)
|
||||||
@@ -3466,6 +3468,7 @@ A jump table for the options with a short description can be found at |Q_op|.
|
|||||||
When the 'binary' option is set the value of this option doesn't
|
When the 'binary' option is set the value of this option doesn't
|
||||||
matter.
|
matter.
|
||||||
See the 'endofline' option.
|
See the 'endofline' option.
|
||||||
|
See |eol-and-eof| for example settings.
|
||||||
|
|
||||||
*'fkmap'* *'fk'* *'nofkmap'* *'nofk'*
|
*'fkmap'* *'fk'* *'nofkmap'* *'nofk'*
|
||||||
'fkmap' 'fk' boolean (default off)
|
'fkmap' 'fk' boolean (default off)
|
||||||
|
@@ -2050,10 +2050,6 @@ restore_backup:
|
|||||||
len = 0;
|
len = 0;
|
||||||
write_info.bw_start_lnum = lnum;
|
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
|
// write failed or last line has no EOL: stop here
|
||||||
if (end == 0
|
if (end == 0
|
||||||
|| (lnum == end
|
|| (lnum == end
|
||||||
@@ -2158,6 +2154,13 @@ restore_backup:
|
|||||||
nchars += len;
|
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.
|
// Stop when writing done or an error was encountered.
|
||||||
if (!checking_conversion || end == 0)
|
if (!checking_conversion || end == 0)
|
||||||
break;
|
break;
|
||||||
|
35
src/fileio.c
35
src/fileio.c
@@ -2271,27 +2271,32 @@ failed:
|
|||||||
if (error && read_count == 0)
|
if (error && read_count == 0)
|
||||||
error = FALSE;
|
error = FALSE;
|
||||||
|
|
||||||
/*
|
// In Dos format ignore a trailing CTRL-Z, unless 'binary' is set.
|
||||||
* If we get EOF in the middle of a line, note the fact and
|
// In old days the file length was in sector count and the CTRL-Z the
|
||||||
* complete the line ourselves.
|
// marker where the file really ended. Assuming we write it to a file
|
||||||
* In Dos format ignore a trailing CTRL-Z, unless 'binary' set.
|
// 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
|
if (!error
|
||||||
&& !got_int
|
&& !got_int
|
||||||
&& linerest != 0
|
&& 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
|
// remember for when writing
|
||||||
if (set_options)
|
if (set_options)
|
||||||
{
|
|
||||||
curbuf->b_p_eol = FALSE;
|
curbuf->b_p_eol = FALSE;
|
||||||
if (*line_start == Ctrl_Z && ptr == line_start + 1)
|
|
||||||
curbuf->b_p_eof = TRUE;
|
|
||||||
}
|
|
||||||
*ptr = NUL;
|
*ptr = NUL;
|
||||||
len = (colnr_T)(ptr - line_start + 1);
|
len = (colnr_T)(ptr - line_start + 1);
|
||||||
if (ml_append(lnum, line_start, len, newfile) == FAIL)
|
if (ml_append(lnum, line_start, len, newfile) == FAIL)
|
||||||
|
@@ -48,4 +48,71 @@ func Test_fixeol()
|
|||||||
enew!
|
enew!
|
||||||
endfunc
|
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: shiftwidth=2 sts=2 expandtab
|
||||||
|
@@ -695,6 +695,8 @@ static char *(features[]) =
|
|||||||
|
|
||||||
static int included_patches[] =
|
static int included_patches[] =
|
||||||
{ /* Add new patch number below this line */
|
{ /* Add new patch number below this line */
|
||||||
|
/**/
|
||||||
|
826,
|
||||||
/**/
|
/**/
|
||||||
825,
|
825,
|
||||||
/**/
|
/**/
|
||||||
|
Reference in New Issue
Block a user