Merge pull request #20855 from zeertzjq/vim-fb0cf2357e0c

vim-patch:9.0.{0816,0819}: CTRL-Z at end of file is always dropped
This commit is contained in:
zeertzjq
2022-10-30 08:33:29 +08:00
committed by GitHub
11 changed files with 59 additions and 13 deletions

View File

@@ -2135,6 +2135,15 @@ A jump table for the options with a short description can be found at |Q_op|.
See 'fileencoding' to control file-content encoding. See 'fileencoding' to control file-content encoding.
*'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.
*'endofline'* *'eol'* *'noendofline'* *'noeol'* *'endofline'* *'eol'* *'noendofline'* *'noeol'*
'endofline' 'eol' boolean (default on) 'endofline' 'eol' boolean (default on)
local to buffer local to buffer
@@ -2490,7 +2499,7 @@ A jump table for the options with a short description can be found at |Q_op|.
'fixendofline' 'fixeol' boolean (default on) 'fixendofline' 'fixeol' boolean (default on)
local to buffer local to buffer
When writing a file and this option is on, <EOL> at the end of file When writing a file and this option is on, <EOL> at the end of file
will be restored if missing. Turn this option off if you want to will be restored if missing. Turn this option off if you want to
preserve the situation from the original file. preserve the situation from the original file.
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.

View File

@@ -689,6 +689,7 @@ Short explanation of each option: *option-list*
'display' 'dy' list of flags for how to display text 'display' 'dy' list of flags for how to display text
'eadirection' 'ead' in which direction 'equalalways' works 'eadirection' 'ead' in which direction 'equalalways' works
'encoding' 'enc' encoding used internally 'encoding' 'enc' encoding used internally
'endoffile' 'eof' write CTRL-Z at end of the file
'endofline' 'eol' write <EOL> for last line in file 'endofline' 'eol' write <EOL> for last line in file
'equalalways' 'ea' windows are automatically made the same size 'equalalways' 'ea' windows are automatically made the same size
'equalprg' 'ep' external program to use for "=" command 'equalprg' 'ep' external program to use for "=" command

View File

@@ -1,7 +1,7 @@
" These commands create the option window. " These commands create the option window.
" "
" Maintainer: Bram Moolenaar <Bram@vim.org> " Maintainer: Bram Moolenaar <Bram@vim.org>
" Last Change: 2022 Oct 15 " Last Change: 2022 Oct 28
" If there already is an option window, jump to that one. " If there already is an option window, jump to that one.
let buf = bufnr('option-window') let buf = bufnr('option-window')
@@ -956,6 +956,9 @@ call <SID>BinOptionL("bin")
call <SID>AddOption("endofline", gettext("last line in the file has an end-of-line")) call <SID>AddOption("endofline", gettext("last line in the file has an end-of-line"))
call append("$", "\t" .. s:local_to_buffer) call append("$", "\t" .. s:local_to_buffer)
call <SID>BinOptionL("eol") call <SID>BinOptionL("eol")
call <SID>AddOption("endoffile", gettext("last line in the file followed by CTRL-Z"))
call append("$", "\t" .. s:local_to_buffer)
call <SID>BinOptionL("eof")
call <SID>AddOption("fixendofline", gettext("fixes missing end-of-line at end of text file")) call <SID>AddOption("fixendofline", gettext("fixes missing end-of-line at end of text file"))
call append("$", "\t" .. s:local_to_buffer) call append("$", "\t" .. s:local_to_buffer)
call <SID>BinOptionL("fixeol") call <SID>BinOptionL("fixeol")

View File

@@ -689,6 +689,8 @@ void buf_clear_file(buf_T *buf)
{ {
buf->b_ml.ml_line_count = 1; buf->b_ml.ml_line_count = 1;
unchanged(buf, true, true); unchanged(buf, true, true);
buf->b_p_eof = false;
buf->b_start_eof = false;
buf->b_p_eol = true; buf->b_p_eol = true;
buf->b_start_eol = true; buf->b_start_eol = true;
buf->b_p_bomb = false; buf->b_p_bomb = false;

View File

@@ -675,6 +675,7 @@ struct file_buffer {
char *b_p_cfu; ///< 'completefunc' char *b_p_cfu; ///< 'completefunc'
char *b_p_ofu; ///< 'omnifunc' char *b_p_ofu; ///< 'omnifunc'
char *b_p_tfu; ///< 'tagfunc' char *b_p_tfu; ///< 'tagfunc'
int b_p_eof; ///< 'endoffile'
int b_p_eol; ///< 'endofline' int b_p_eol; ///< 'endofline'
int b_p_fixeol; ///< 'fixendofline' int b_p_fixeol; ///< 'fixendofline'
int b_p_et; ///< 'expandtab' int b_p_et; ///< 'expandtab'
@@ -793,6 +794,7 @@ struct file_buffer {
linenr_T b_no_eol_lnum; // non-zero lnum when last line of next binary linenr_T b_no_eol_lnum; // non-zero lnum when last line of next binary
// write should not have an end-of-line // write should not have an end-of-line
int b_start_eof; // last line had eof (CTRL-Z) when it was read
int b_start_eol; // last line had eol when it was read int b_start_eol; // last line had eol when it was read
int b_start_ffc; // first char of 'ff' when edit started int b_start_ffc; // first char of 'ff' when edit started
char *b_start_fenc; // 'fileencoding' when edit started or NULL char *b_start_fenc; // 'fileencoding' when edit started or NULL

View File

@@ -539,6 +539,7 @@ void unchanged(buf_T *buf, int ff, bool always_inc_changedtick)
void save_file_ff(buf_T *buf) void save_file_ff(buf_T *buf)
{ {
buf->b_start_ffc = (unsigned char)(*buf->b_p_ff); buf->b_start_ffc = (unsigned char)(*buf->b_p_ff);
buf->b_start_eof = buf->b_p_eof;
buf->b_start_eol = buf->b_p_eol; buf->b_start_eol = buf->b_p_eol;
buf->b_start_bomb = buf->b_p_bomb; buf->b_start_bomb = buf->b_p_bomb;
@@ -573,7 +574,8 @@ bool file_ff_differs(buf_T *buf, bool ignore_empty)
if (buf->b_start_ffc != *buf->b_p_ff) { if (buf->b_start_ffc != *buf->b_p_ff) {
return true; return true;
} }
if ((buf->b_p_bin || !buf->b_p_fixeol) && buf->b_start_eol != buf->b_p_eol) { if ((buf->b_p_bin || !buf->b_p_fixeol)
&& (buf->b_start_eof != buf->b_p_eof || buf->b_start_eol != buf->b_p_eol)) {
return true; return true;
} }
if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb) { if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb) {

View File

@@ -524,6 +524,8 @@ int readfile(char *fname, char *sfname, linenr_T from, linenr_T lines_to_skip,
// Don't change 'eol' if reading from buffer as it will already be // Don't change 'eol' if reading from buffer as it will already be
// correctly set when reading stdin. // correctly set when reading stdin.
if (!read_buffer) { if (!read_buffer) {
curbuf->b_p_eof = false;
curbuf->b_start_eof = false;
curbuf->b_p_eol = true; curbuf->b_p_eol = true;
curbuf->b_start_eol = true; curbuf->b_start_eol = true;
} }
@@ -1628,6 +1630,7 @@ failed:
if (!error if (!error
&& !got_int && !got_int
&& linerest != 0 && linerest != 0
// TODO(vim): should we handle CTRL-Z differently here for 'endoffile'?
&& !(!curbuf->b_p_bin && !(!curbuf->b_p_bin
&& fileformat == EOL_DOS && fileformat == EOL_DOS
&& *line_start == Ctrl_Z && *line_start == Ctrl_Z
@@ -1635,6 +1638,9 @@ failed:
// 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);
@@ -3191,6 +3197,11 @@ 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

View File

@@ -3978,6 +3978,8 @@ static char_u *get_varp(vimoption_T *p)
return (char_u *)&(curbuf->b_p_cfu); return (char_u *)&(curbuf->b_p_cfu);
case PV_OFU: case PV_OFU:
return (char_u *)&(curbuf->b_p_ofu); return (char_u *)&(curbuf->b_p_ofu);
case PV_EOF:
return (char_u *)&(curbuf->b_p_eof);
case PV_EOL: case PV_EOL:
return (char_u *)&(curbuf->b_p_eol); return (char_u *)&(curbuf->b_p_eol);
case PV_FIXEOL: case PV_FIXEOL:

View File

@@ -497,6 +497,7 @@ EXTERN char_u *p_ef; // 'errorfile'
EXTERN char *p_efm; // 'errorformat' EXTERN char *p_efm; // 'errorformat'
EXTERN char *p_gefm; // 'grepformat' EXTERN char *p_gefm; // 'grepformat'
EXTERN char *p_gp; // 'grepprg' EXTERN char *p_gp; // 'grepprg'
EXTERN int p_eof; ///< 'endoffile'
EXTERN int p_eol; ///< 'endofline' EXTERN int p_eol; ///< 'endofline'
EXTERN char *p_ei; // 'eventignore' EXTERN char *p_ei; // 'eventignore'
EXTERN int p_et; ///< 'expandtab' EXTERN int p_et; ///< 'expandtab'
@@ -858,6 +859,7 @@ enum {
BV_CFU, BV_CFU,
BV_DEF, BV_DEF,
BV_INC, BV_INC,
BV_EOF,
BV_EOL, BV_EOL,
BV_FIXEOL, BV_FIXEOL,
BV_EP, BV_EP,

View File

@@ -640,6 +640,15 @@ return {
varname='p_enc', varname='p_enc',
defaults={if_true=macros('ENC_DFLT')} defaults={if_true=macros('ENC_DFLT')}
}, },
{
full_name='endoffile', abbreviation='eof',
short_desc=N_("write CTRL-Z for last line in file"),
type='bool', scope={'buffer'},
no_mkrc=true,
redraw={'statuslines'},
varname='p_eof',
defaults={if_true=true}
},
{ {
full_name='endofline', abbreviation='eol', full_name='endofline', abbreviation='eol',
short_desc=N_("write <EOL> for last line in file"), short_desc=N_("write <EOL> for last line in file"),

View File

@@ -1,16 +1,17 @@
" Tests for 'fixeol' and 'eol' " Tests for 'fixeol', 'eof' and 'eol'
func Test_fixeol() func Test_fixeol()
" first write two test files with and without trailing EOL " first write two test files with and without trailing EOL
" use Unix fileformat for consistency " use Unix fileformat for consistency
set ff=unix set ff=unix
enew! enew!
call setline('.', 'with eol') call setline('.', 'with eol or eof')
w! XXEol w! XXEol
enew! enew!
set noeol nofixeol set noeof noeol nofixeol
call setline('.', 'without eol') call setline('.', 'without eol or eof')
w! XXNoEol w! XXNoEol
set eol fixeol set eol eof fixeol
bwipe XXEol XXNoEol bwipe XXEol XXNoEol
" try editing files with 'fixeol' disabled " try editing files with 'fixeol' disabled
@@ -33,16 +34,18 @@ func Test_fixeol()
w >>XXTestEol w >>XXTestEol
w >>XXTestNoEol w >>XXTestNoEol
call assert_equal(['with eol', 'END'], readfile('XXEol')) call assert_equal(['with eol or eof', 'END'], readfile('XXEol'))
call assert_equal(['without eolEND'], readfile('XXNoEol')) call assert_equal(['without eol or eofEND'], readfile('XXNoEol'))
call assert_equal(['with eol', 'stays eol', 'END'], readfile('XXTestEol')) call assert_equal(['with eol or eof', 'stays eol', 'END'], readfile('XXTestEol'))
call assert_equal(['without eol', 'stays withoutEND'], call assert_equal(['without eol or eof', 'stays withoutEND'],
\ readfile('XXTestNoEol')) \ readfile('XXTestNoEol'))
call delete('XXEol') call delete('XXEol')
call delete('XXNoEol') call delete('XXNoEol')
call delete('XXTestEol') call delete('XXTestEol')
call delete('XXTestNoEol') call delete('XXTestNoEol')
set ff& fixeol& eol& set ff& fixeol& eof& eol&
enew! enew!
endfunc endfunc
" vim: shiftwidth=2 sts=2 expandtab