aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorzeertzjq <zeertzjq@outlook.com>2022-10-30 08:33:29 +0800
committerGitHub <noreply@github.com>2022-10-30 08:33:29 +0800
commit75ec1b7208d4d8f38dff2adf4006de7ea82118d7 (patch)
tree5f2c5122641a4da14ae67029e76737298623f775 /src
parent8d38e1ad34552293de9e562b73c727ec119fd847 (diff)
parent4158ad38ecb107cfe3d1dd7472cc9e17039f6ee2 (diff)
downloadrneovim-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.c2
-rw-r--r--src/nvim/buffer_defs.h2
-rw-r--r--src/nvim/change.c4
-rw-r--r--src/nvim/fileio.c11
-rw-r--r--src/nvim/option.c2
-rw-r--r--src/nvim/option_defs.h2
-rw-r--r--src/nvim/options.lua9
-rw-r--r--src/nvim/testdir/test_fixeol.vim23
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