mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #17394 from zeertzjq/vim-8.2.4343
vim-patch:8.2.4343: when reloading not all properties are detected
This commit is contained in:
commit
8051fa1aff
@ -1450,6 +1450,11 @@ If you don't get warned often enough you can use the following command.
|
|||||||
if it exists now.
|
if it exists now.
|
||||||
Once a file has been checked the timestamp is reset,
|
Once a file has been checked the timestamp is reset,
|
||||||
you will not be warned again.
|
you will not be warned again.
|
||||||
|
Syntax highlighting, marks, diff status,
|
||||||
|
'fileencoding', 'fileformat' and 'binary' options
|
||||||
|
are not changed. See |v:fcs_choice| to reload these
|
||||||
|
too (for example, if a code formatting tools has
|
||||||
|
changed the file).
|
||||||
|
|
||||||
:[N]checkt[ime] {filename}
|
:[N]checkt[ime] {filename}
|
||||||
:[N]checkt[ime] [N]
|
:[N]checkt[ime] [N]
|
||||||
|
@ -1882,6 +1882,11 @@ v:fcs_choice What should happen after a |FileChangedShell| event was
|
|||||||
do with the affected buffer:
|
do with the affected buffer:
|
||||||
reload Reload the buffer (does not work if
|
reload Reload the buffer (does not work if
|
||||||
the file was deleted).
|
the file was deleted).
|
||||||
|
edit Reload the buffer and detect the
|
||||||
|
values for options such as
|
||||||
|
'fileformat', 'fileencoding', 'binary'
|
||||||
|
(does not work if the file was
|
||||||
|
deleted).
|
||||||
ask Ask the user what to do, as if there
|
ask Ask the user what to do, as if there
|
||||||
was no autocommand. Except that when
|
was no autocommand. Except that when
|
||||||
only the timestamp changed nothing
|
only the timestamp changed nothing
|
||||||
|
@ -2013,10 +2013,8 @@ static linenr_T readfile_linenr(linenr_T linecnt, char_u *p, char_u *endp)
|
|||||||
return lnum;
|
return lnum;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Fill "*eap" to force the 'fileencoding', 'fileformat' and 'binary' to be
|
||||||
* Fill "*eap" to force the 'fileencoding', 'fileformat' and 'binary to be
|
/// equal to the buffer "buf". Used for calling readfile().
|
||||||
* equal to the buffer "buf". Used for calling readfile().
|
|
||||||
*/
|
|
||||||
void prep_exarg(exarg_T *eap, const buf_T *buf)
|
void prep_exarg(exarg_T *eap, const buf_T *buf)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
@ -4901,13 +4899,11 @@ static int move_lines(buf_T *frombuf, buf_T *tobuf)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Check if buffer "buf" has been changed.
|
||||||
* Check if buffer "buf" has been changed.
|
/// Also check if the file for a new buffer unexpectedly appeared.
|
||||||
* Also check if the file for a new buffer unexpectedly appeared.
|
/// return 1 if a changed buffer was found.
|
||||||
* return 1 if a changed buffer was found.
|
/// return 2 if a message has been displayed.
|
||||||
* return 2 if a message has been displayed.
|
/// return 0 otherwise.
|
||||||
* return 0 otherwise.
|
|
||||||
*/
|
|
||||||
int buf_check_timestamp(buf_T *buf)
|
int buf_check_timestamp(buf_T *buf)
|
||||||
FUNC_ATTR_NONNULL_ALL
|
FUNC_ATTR_NONNULL_ALL
|
||||||
{
|
{
|
||||||
@ -4916,7 +4912,11 @@ int buf_check_timestamp(buf_T *buf)
|
|||||||
char *mesg = NULL;
|
char *mesg = NULL;
|
||||||
char *mesg2 = "";
|
char *mesg2 = "";
|
||||||
bool helpmesg = false;
|
bool helpmesg = false;
|
||||||
bool reload = false;
|
enum {
|
||||||
|
RELOAD_NONE,
|
||||||
|
RELOAD_NORMAL,
|
||||||
|
RELOAD_DETECT
|
||||||
|
} reload = RELOAD_NONE;
|
||||||
bool can_reload = false;
|
bool can_reload = false;
|
||||||
uint64_t orig_size = buf->b_orig_size;
|
uint64_t orig_size = buf->b_orig_size;
|
||||||
int orig_mode = buf->b_orig_mode;
|
int orig_mode = buf->b_orig_mode;
|
||||||
@ -4969,7 +4969,7 @@ int buf_check_timestamp(buf_T *buf)
|
|||||||
// If 'autoread' is set, the buffer has no changes and the file still
|
// If 'autoread' is set, the buffer has no changes and the file still
|
||||||
// exists, reload the buffer. Use the buffer-local option value if it
|
// exists, reload the buffer. Use the buffer-local option value if it
|
||||||
// was set, the global option value otherwise.
|
// was set, the global option value otherwise.
|
||||||
reload = true;
|
reload = RELOAD_NORMAL;
|
||||||
} else {
|
} else {
|
||||||
if (!file_info_ok) {
|
if (!file_info_ok) {
|
||||||
reason = "deleted";
|
reason = "deleted";
|
||||||
@ -5000,7 +5000,9 @@ int buf_check_timestamp(buf_T *buf)
|
|||||||
}
|
}
|
||||||
s = get_vim_var_str(VV_FCS_CHOICE);
|
s = get_vim_var_str(VV_FCS_CHOICE);
|
||||||
if (STRCMP(s, "reload") == 0 && *reason != 'd') {
|
if (STRCMP(s, "reload") == 0 && *reason != 'd') {
|
||||||
reload = true;
|
reload = RELOAD_NORMAL;
|
||||||
|
} else if (STRCMP(s, "edit") == 0) {
|
||||||
|
reload = RELOAD_DETECT;
|
||||||
} else if (STRCMP(s, "ask") == 0) {
|
} else if (STRCMP(s, "ask") == 0) {
|
||||||
n = false;
|
n = false;
|
||||||
} else {
|
} else {
|
||||||
@ -5064,9 +5066,15 @@ int buf_check_timestamp(buf_T *buf)
|
|||||||
xstrlcat(tbuf, "\n", tbuf_len - 1);
|
xstrlcat(tbuf, "\n", tbuf_len - 1);
|
||||||
xstrlcat(tbuf, mesg2, tbuf_len - 1);
|
xstrlcat(tbuf, mesg2, tbuf_len - 1);
|
||||||
}
|
}
|
||||||
if (do_dialog(VIM_WARNING, (char_u *)_("Warning"), (char_u *)tbuf,
|
switch (do_dialog(VIM_WARNING, (char_u *)_("Warning"), (char_u *)tbuf,
|
||||||
(char_u *)_("&OK\n&Load File"), 1, NULL, true) == 2) {
|
(char_u *)_("&OK\n&Load File\nLoad File &and Options"),
|
||||||
reload = true;
|
1, NULL, true)) {
|
||||||
|
case 2:
|
||||||
|
reload = RELOAD_NORMAL;
|
||||||
|
break;
|
||||||
|
case 3:
|
||||||
|
reload = RELOAD_DETECT;
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
} else if (State > NORMAL_BUSY || (State & CMDLINE) || already_warned) {
|
} else if (State > NORMAL_BUSY || (State & CMDLINE) || already_warned) {
|
||||||
if (*mesg2 != NUL) {
|
if (*mesg2 != NUL) {
|
||||||
@ -5100,9 +5108,9 @@ int buf_check_timestamp(buf_T *buf)
|
|||||||
xfree(tbuf);
|
xfree(tbuf);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (reload) {
|
if (reload != RELOAD_NONE) {
|
||||||
// Reload the buffer.
|
// Reload the buffer.
|
||||||
buf_reload(buf, orig_mode);
|
buf_reload(buf, orig_mode, reload == RELOAD_DETECT);
|
||||||
if (buf->b_p_udf && buf->b_ffname != NULL) {
|
if (buf->b_p_udf && buf->b_ffname != NULL) {
|
||||||
char_u hash[UNDO_HASH_SIZE];
|
char_u hash[UNDO_HASH_SIZE];
|
||||||
|
|
||||||
@ -5120,13 +5128,11 @@ int buf_check_timestamp(buf_T *buf)
|
|||||||
return retval;
|
return retval;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/// Reload a buffer that is already loaded.
|
||||||
* Reload a buffer that is already loaded.
|
/// Used when the file was changed outside of Vim.
|
||||||
* Used when the file was changed outside of Vim.
|
/// "orig_mode" is buf->b_orig_mode before the need for reloading was detected.
|
||||||
* "orig_mode" is buf->b_orig_mode before the need for reloading was detected.
|
/// buf->b_orig_mode may have been reset already.
|
||||||
* buf->b_orig_mode may have been reset already.
|
void buf_reload(buf_T *buf, int orig_mode, bool reload_options)
|
||||||
*/
|
|
||||||
void buf_reload(buf_T *buf, int orig_mode)
|
|
||||||
{
|
{
|
||||||
exarg_T ea;
|
exarg_T ea;
|
||||||
pos_T old_cursor;
|
pos_T old_cursor;
|
||||||
@ -5141,11 +5147,15 @@ void buf_reload(buf_T *buf, int orig_mode)
|
|||||||
// set curwin/curbuf for "buf" and save some things
|
// set curwin/curbuf for "buf" and save some things
|
||||||
aucmd_prepbuf(&aco, buf);
|
aucmd_prepbuf(&aco, buf);
|
||||||
|
|
||||||
// We only want to read the text from the file, not reset the syntax
|
// Unless reload_options is set, we only want to read the text from the
|
||||||
// highlighting, clear marks, diff status, etc. Force the fileformat and
|
// file, not reset the syntax highlighting, clear marks, diff status, etc.
|
||||||
// encoding to be the same.
|
// Force the fileformat and encoding to be the same.
|
||||||
|
if (reload_options) {
|
||||||
|
memset(&ea, 0, sizeof(ea));
|
||||||
|
} else {
|
||||||
|
prep_exarg(&ea, buf);
|
||||||
|
}
|
||||||
|
|
||||||
prep_exarg(&ea, buf);
|
|
||||||
old_cursor = curwin->w_cursor;
|
old_cursor = curwin->w_cursor;
|
||||||
old_topline = curwin->w_topline;
|
old_topline = curwin->w_topline;
|
||||||
|
|
||||||
|
@ -3464,6 +3464,7 @@ void msg_advance(int col)
|
|||||||
///
|
///
|
||||||
/// @param textfiel IObuff for inputdialog(), NULL otherwise
|
/// @param textfiel IObuff for inputdialog(), NULL otherwise
|
||||||
/// @param ex_cmd when TRUE pressing : accepts default and starts Ex command
|
/// @param ex_cmd when TRUE pressing : accepts default and starts Ex command
|
||||||
|
/// @returns 0 if cancelled, otherwise the nth button (1-indexed).
|
||||||
int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton,
|
int do_dialog(int type, char_u *title, char_u *message, char_u *buttons, int dfltbutton,
|
||||||
char_u *textfield, int ex_cmd)
|
char_u *textfield, int ex_cmd)
|
||||||
{
|
{
|
||||||
|
@ -5654,7 +5654,7 @@ void spell_add_word(char_u *word, int len, SpellAddType what, int idx, bool undo
|
|||||||
|
|
||||||
// If the .add file is edited somewhere, reload it.
|
// If the .add file is edited somewhere, reload it.
|
||||||
if (buf != NULL) {
|
if (buf != NULL) {
|
||||||
buf_reload(buf, buf->b_orig_mode);
|
buf_reload(buf, buf->b_orig_mode, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
redraw_all_later(SOME_VALID);
|
redraw_all_later(SOME_VALID);
|
||||||
|
@ -10,6 +10,7 @@ let s:did_load = 1
|
|||||||
set backspace=
|
set backspace=
|
||||||
set directory^=.
|
set directory^=.
|
||||||
set fillchars=vert:\|,fold:-
|
set fillchars=vert:\|,fold:-
|
||||||
|
set fsync
|
||||||
set laststatus=1
|
set laststatus=1
|
||||||
set listchars=eol:$
|
set listchars=eol:$
|
||||||
set joinspaces
|
set joinspaces
|
||||||
|
@ -1,9 +1,10 @@
|
|||||||
" Tests for when a file was changed outside of Vim.
|
" Tests for when a file was changed outside of Vim.
|
||||||
|
|
||||||
|
source check.vim
|
||||||
|
|
||||||
func Test_FileChangedShell_reload()
|
func Test_FileChangedShell_reload()
|
||||||
if !has('unix')
|
CheckUnix
|
||||||
return
|
|
||||||
endif
|
|
||||||
augroup testreload
|
augroup testreload
|
||||||
au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'reload'
|
au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'reload'
|
||||||
augroup END
|
augroup END
|
||||||
@ -90,11 +91,107 @@ func Test_FileChangedShell_reload()
|
|||||||
call delete('Xchanged_r')
|
call delete('Xchanged_r')
|
||||||
endfunc
|
endfunc
|
||||||
|
|
||||||
|
func Test_FileChangedShell_edit()
|
||||||
|
CheckUnix
|
||||||
|
|
||||||
|
new Xchanged_r
|
||||||
|
call setline(1, 'reload this')
|
||||||
|
set fileformat=unix
|
||||||
|
write
|
||||||
|
|
||||||
|
" File format changed, reload (content only, no 'ff' etc)
|
||||||
|
augroup testreload
|
||||||
|
au!
|
||||||
|
au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'reload'
|
||||||
|
augroup END
|
||||||
|
call assert_equal(&fileformat, 'unix')
|
||||||
|
sleep 10m " make the test less flaky in Nvim
|
||||||
|
call writefile(["line1\r", "line2\r"], 'Xchanged_r')
|
||||||
|
let g:reason = ''
|
||||||
|
checktime
|
||||||
|
call assert_equal('changed', g:reason)
|
||||||
|
call assert_equal(&fileformat, 'unix')
|
||||||
|
call assert_equal("line1\r", getline(1))
|
||||||
|
call assert_equal("line2\r", getline(2))
|
||||||
|
%s/\r
|
||||||
|
write
|
||||||
|
|
||||||
|
" File format changed, reload with 'ff', etc
|
||||||
|
augroup testreload
|
||||||
|
au!
|
||||||
|
au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'edit'
|
||||||
|
augroup END
|
||||||
|
call assert_equal(&fileformat, 'unix')
|
||||||
|
sleep 10m " make the test less flaky in Nvim
|
||||||
|
call writefile(["line1\r", "line2\r"], 'Xchanged_r')
|
||||||
|
let g:reason = ''
|
||||||
|
checktime
|
||||||
|
call assert_equal('changed', g:reason)
|
||||||
|
call assert_equal(&fileformat, 'dos')
|
||||||
|
call assert_equal('line1', getline(1))
|
||||||
|
call assert_equal('line2', getline(2))
|
||||||
|
set fileformat=unix
|
||||||
|
write
|
||||||
|
|
||||||
|
au! testreload
|
||||||
|
bwipe!
|
||||||
|
call delete(undofile('Xchanged_r'))
|
||||||
|
call delete('Xchanged_r')
|
||||||
|
endfunc
|
||||||
|
|
||||||
|
func Test_FileChangedShell_edit_dialog()
|
||||||
|
throw 'Skipped: requires a UI to be active'
|
||||||
|
CheckNotGui
|
||||||
|
|
||||||
|
new Xchanged_r
|
||||||
|
call setline(1, 'reload this')
|
||||||
|
set fileformat=unix
|
||||||
|
write
|
||||||
|
|
||||||
|
" File format changed, reload (content only) via prompt
|
||||||
|
augroup testreload
|
||||||
|
au!
|
||||||
|
au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'ask'
|
||||||
|
augroup END
|
||||||
|
call assert_equal(&fileformat, 'unix')
|
||||||
|
call writefile(["line1\r", "line2\r"], 'Xchanged_r')
|
||||||
|
let g:reason = ''
|
||||||
|
call feedkeys('L', 'L') " load file content only
|
||||||
|
checktime
|
||||||
|
call assert_equal('changed', g:reason)
|
||||||
|
call assert_equal(&fileformat, 'unix')
|
||||||
|
call assert_equal("line1\r", getline(1))
|
||||||
|
call assert_equal("line2\r", getline(2))
|
||||||
|
%s/\r
|
||||||
|
write
|
||||||
|
|
||||||
|
" File format changed, reload (file and options) via prompt
|
||||||
|
augroup testreload
|
||||||
|
au!
|
||||||
|
au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'ask'
|
||||||
|
augroup END
|
||||||
|
call assert_equal(&fileformat, 'unix')
|
||||||
|
call writefile(["line1\r", "line2\r"], 'Xchanged_r')
|
||||||
|
let g:reason = ''
|
||||||
|
call feedkeys('a', 'L') " load file content and options
|
||||||
|
checktime
|
||||||
|
call assert_equal('changed', g:reason)
|
||||||
|
call assert_equal(&fileformat, 'dos')
|
||||||
|
call assert_equal("line1", getline(1))
|
||||||
|
call assert_equal("line2", getline(2))
|
||||||
|
set fileformat=unix
|
||||||
|
write
|
||||||
|
|
||||||
|
au! testreload
|
||||||
|
bwipe!
|
||||||
|
call delete(undofile('Xchanged_r'))
|
||||||
|
call delete('Xchanged_r')
|
||||||
|
endfunc
|
||||||
|
|
||||||
func Test_file_changed_dialog()
|
func Test_file_changed_dialog()
|
||||||
throw 'Skipped: requires a UI to a active'
|
throw 'Skipped: requires a UI to be active'
|
||||||
if !has('unix') || has('gui_running')
|
CheckUnix
|
||||||
return
|
CheckNotGui
|
||||||
endif
|
|
||||||
au! FileChangedShell
|
au! FileChangedShell
|
||||||
|
|
||||||
new Xchanged_d
|
new Xchanged_d
|
||||||
|
@ -11,6 +11,11 @@ describe('file changed dialog', function()
|
|||||||
clear()
|
clear()
|
||||||
meths.ui_attach(80, 24, {})
|
meths.ui_attach(80, 24, {})
|
||||||
meths.set_option('autoread', false)
|
meths.set_option('autoread', false)
|
||||||
|
meths.set_option('fsync', true)
|
||||||
|
end)
|
||||||
|
|
||||||
|
it('works', function()
|
||||||
|
if helpers.pending_win32(pending) then return end
|
||||||
source([[
|
source([[
|
||||||
func Test_file_changed_dialog()
|
func Test_file_changed_dialog()
|
||||||
au! FileChangedShell
|
au! FileChangedShell
|
||||||
@ -66,11 +71,61 @@ describe('file changed dialog', function()
|
|||||||
call delete('Xchanged_d')
|
call delete('Xchanged_d')
|
||||||
endfunc
|
endfunc
|
||||||
]])
|
]])
|
||||||
end)
|
|
||||||
|
|
||||||
it('works', function()
|
|
||||||
if helpers.pending_win32(pending) then return end
|
|
||||||
call('Test_file_changed_dialog')
|
call('Test_file_changed_dialog')
|
||||||
expected_empty()
|
expected_empty()
|
||||||
end)
|
end)
|
||||||
|
|
||||||
|
it('works with FileChangedShell', function()
|
||||||
|
source([[
|
||||||
|
func Test_FileChangedShell_edit_dialog()
|
||||||
|
new Xchanged_r
|
||||||
|
call setline(1, 'reload this')
|
||||||
|
set fileformat=unix
|
||||||
|
silent write " Use :silent to prevent a hit-enter prompt
|
||||||
|
|
||||||
|
" File format changed, reload (content only) via prompt
|
||||||
|
augroup testreload
|
||||||
|
au!
|
||||||
|
au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'ask'
|
||||||
|
augroup END
|
||||||
|
call assert_equal(&fileformat, 'unix')
|
||||||
|
sleep 10m " make the test less flaky in Nvim
|
||||||
|
call writefile(["line1\r", "line2\r"], 'Xchanged_r')
|
||||||
|
let g:reason = ''
|
||||||
|
call nvim_input('L') " load file content only
|
||||||
|
checktime
|
||||||
|
call assert_equal('changed', g:reason)
|
||||||
|
call assert_equal(&fileformat, 'unix')
|
||||||
|
call assert_equal("line1\r", getline(1))
|
||||||
|
call assert_equal("line2\r", getline(2))
|
||||||
|
%s/\r
|
||||||
|
silent write " Use :silent to prevent a hit-enter prompt
|
||||||
|
|
||||||
|
" File format changed, reload (file and options) via prompt
|
||||||
|
augroup testreload
|
||||||
|
au!
|
||||||
|
au FileChangedShell Xchanged_r let g:reason = v:fcs_reason | let v:fcs_choice = 'ask'
|
||||||
|
augroup END
|
||||||
|
call assert_equal(&fileformat, 'unix')
|
||||||
|
sleep 10m " make the test less flaky in Nvim
|
||||||
|
call writefile(["line1\r", "line2\r"], 'Xchanged_r')
|
||||||
|
let g:reason = ''
|
||||||
|
call nvim_input('a') " load file content and options
|
||||||
|
checktime
|
||||||
|
call assert_equal('changed', g:reason)
|
||||||
|
call assert_equal(&fileformat, 'dos')
|
||||||
|
call assert_equal("line1", getline(1))
|
||||||
|
call assert_equal("line2", getline(2))
|
||||||
|
set fileformat=unix
|
||||||
|
silent write " Use :silent to prevent a hit-enter prompt
|
||||||
|
|
||||||
|
au! testreload
|
||||||
|
bwipe!
|
||||||
|
call delete(undofile('Xchanged_r'))
|
||||||
|
call delete('Xchanged_r')
|
||||||
|
endfunc
|
||||||
|
]])
|
||||||
|
call('Test_FileChangedShell_edit_dialog')
|
||||||
|
expected_empty()
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
Loading…
Reference in New Issue
Block a user