diff options
author | zeertzjq <zeertzjq@outlook.com> | 2022-10-30 08:33:29 +0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-10-30 08:33:29 +0800 |
commit | 75ec1b7208d4d8f38dff2adf4006de7ea82118d7 (patch) | |
tree | 5f2c5122641a4da14ae67029e76737298623f775 /src | |
parent | 8d38e1ad34552293de9e562b73c727ec119fd847 (diff) | |
parent | 4158ad38ecb107cfe3d1dd7472cc9e17039f6ee2 (diff) | |
download | rneovim-75ec1b7208d4d8f38dff2adf4006de7ea82118d7.tar.gz rneovim-75ec1b7208d4d8f38dff2adf4006de7ea82118d7.tar.bz2 rneovim-75ec1b7208d4d8f38dff2adf4006de7ea82118d7.zip |
Merge pull request #20855 from zeertzjq/vim-fb0cf2357e0c
vim-patch:9.0.{0816,0819}: CTRL-Z at end of file is always dropped
Diffstat (limited to 'src')
-rw-r--r-- | src/nvim/buffer.c | 2 | ||||
-rw-r--r-- | src/nvim/buffer_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/change.c | 4 | ||||
-rw-r--r-- | src/nvim/fileio.c | 11 | ||||
-rw-r--r-- | src/nvim/option.c | 2 | ||||
-rw-r--r-- | src/nvim/option_defs.h | 2 | ||||
-rw-r--r-- | src/nvim/options.lua | 9 | ||||
-rw-r--r-- | src/nvim/testdir/test_fixeol.vim | 23 |
8 files changed, 44 insertions, 11 deletions
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c index 8016904702..ade5c35450 100644 --- a/src/nvim/buffer.c +++ b/src/nvim/buffer.c @@ -689,6 +689,8 @@ void buf_clear_file(buf_T *buf) { buf->b_ml.ml_line_count = 1; unchanged(buf, true, true); + buf->b_p_eof = false; + buf->b_start_eof = false; buf->b_p_eol = true; buf->b_start_eol = true; buf->b_p_bomb = false; diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h index 043a31bf16..52449faa5b 100644 --- a/src/nvim/buffer_defs.h +++ b/src/nvim/buffer_defs.h @@ -675,6 +675,7 @@ struct file_buffer { char *b_p_cfu; ///< 'completefunc' char *b_p_ofu; ///< 'omnifunc' char *b_p_tfu; ///< 'tagfunc' + int b_p_eof; ///< 'endoffile' int b_p_eol; ///< 'endofline' int b_p_fixeol; ///< 'fixendofline' 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 // 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_ffc; // first char of 'ff' when edit started char *b_start_fenc; // 'fileencoding' when edit started or NULL diff --git a/src/nvim/change.c b/src/nvim/change.c index 2424a8a2eb..c6df98651d 100644 --- a/src/nvim/change.c +++ b/src/nvim/change.c @@ -539,6 +539,7 @@ void unchanged(buf_T *buf, int ff, bool always_inc_changedtick) void save_file_ff(buf_T *buf) { 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_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) { 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; } if (!buf->b_p_bin && buf->b_start_bomb != buf->b_p_bomb) { diff --git a/src/nvim/fileio.c b/src/nvim/fileio.c index cfdd6fe697..2ba2f4c9c9 100644 --- a/src/nvim/fileio.c +++ b/src/nvim/fileio.c @@ -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 // correctly set when reading stdin. if (!read_buffer) { + curbuf->b_p_eof = false; + curbuf->b_start_eof = false; curbuf->b_p_eol = true; curbuf->b_start_eol = true; } @@ -1628,6 +1630,7 @@ failed: if (!error && !got_int && linerest != 0 + // TODO(vim): should we handle CTRL-Z differently here for 'endoffile'? && !(!curbuf->b_p_bin && fileformat == EOL_DOS && *line_start == Ctrl_Z @@ -1635,6 +1638,9 @@ failed: // 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); @@ -3191,6 +3197,11 @@ 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 diff --git a/src/nvim/option.c b/src/nvim/option.c index 06662afd08..8de86ce76e 100644 --- a/src/nvim/option.c +++ b/src/nvim/option.c @@ -3978,6 +3978,8 @@ static char_u *get_varp(vimoption_T *p) return (char_u *)&(curbuf->b_p_cfu); case PV_OFU: return (char_u *)&(curbuf->b_p_ofu); + case PV_EOF: + return (char_u *)&(curbuf->b_p_eof); case PV_EOL: return (char_u *)&(curbuf->b_p_eol); case PV_FIXEOL: diff --git a/src/nvim/option_defs.h b/src/nvim/option_defs.h index 19e4780e0a..7c33773e41 100644 --- a/src/nvim/option_defs.h +++ b/src/nvim/option_defs.h @@ -497,6 +497,7 @@ EXTERN char_u *p_ef; // 'errorfile' EXTERN char *p_efm; // 'errorformat' EXTERN char *p_gefm; // 'grepformat' EXTERN char *p_gp; // 'grepprg' +EXTERN int p_eof; ///< 'endoffile' EXTERN int p_eol; ///< 'endofline' EXTERN char *p_ei; // 'eventignore' EXTERN int p_et; ///< 'expandtab' @@ -858,6 +859,7 @@ enum { BV_CFU, BV_DEF, BV_INC, + BV_EOF, BV_EOL, BV_FIXEOL, BV_EP, diff --git a/src/nvim/options.lua b/src/nvim/options.lua index ba483d3714..088aa40fda 100644 --- a/src/nvim/options.lua +++ b/src/nvim/options.lua @@ -641,6 +641,15 @@ return { 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', short_desc=N_("write <EOL> for last line in file"), type='bool', scope={'buffer'}, diff --git a/src/nvim/testdir/test_fixeol.vim b/src/nvim/testdir/test_fixeol.vim index 32cb059e26..9d6c900bdb 100644 --- a/src/nvim/testdir/test_fixeol.vim +++ b/src/nvim/testdir/test_fixeol.vim @@ -1,16 +1,17 @@ -" Tests for 'fixeol' and 'eol' +" Tests for 'fixeol', 'eof' and 'eol' + func Test_fixeol() " first write two test files – with and without trailing EOL " use Unix fileformat for consistency set ff=unix enew! - call setline('.', 'with eol') + call setline('.', 'with eol or eof') w! XXEol enew! - set noeol nofixeol - call setline('.', 'without eol') + set noeof noeol nofixeol + call setline('.', 'without eol or eof') w! XXNoEol - set eol fixeol + set eol eof fixeol bwipe XXEol XXNoEol " try editing files with 'fixeol' disabled @@ -33,16 +34,18 @@ func Test_fixeol() w >>XXTestEol w >>XXTestNoEol - call assert_equal(['with eol', 'END'], readfile('XXEol')) - call assert_equal(['without eolEND'], readfile('XXNoEol')) - call assert_equal(['with eol', 'stays eol', 'END'], readfile('XXTestEol')) - call assert_equal(['without eol', 'stays withoutEND'], + call assert_equal(['with eol or eof', 'END'], readfile('XXEol')) + call assert_equal(['without eol or eofEND'], readfile('XXNoEol')) + call assert_equal(['with eol or eof', 'stays eol', 'END'], readfile('XXTestEol')) + call assert_equal(['without eol or eof', 'stays withoutEND'], \ readfile('XXTestNoEol')) call delete('XXEol') call delete('XXNoEol') call delete('XXTestEol') call delete('XXTestNoEol') - set ff& fixeol& eol& + set ff& fixeol& eof& eol& enew! endfunc + +" vim: shiftwidth=2 sts=2 expandtab |