patch 8.2.4343: when reloading not all properties are detected

Problem:    When reloading not all properties are detected.
Solution:   Add the "edit" value to v:fcs_choice. (Rob Pilling, closes #9579)
This commit is contained in:
Rob Pilling
2022-02-11 15:12:10 +00:00
committed by Bram Moolenaar
parent 92f645bef7
commit 8196e94a8b
8 changed files with 145 additions and 17 deletions

View File

@ -1650,6 +1650,11 @@ If you don't get warned often enough you can use the following command.
if it exists now.
Once a file has been checked the timestamp is reset,
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] [N]

View File

@ -2070,6 +2070,11 @@ v:fcs_choice What should happen after a |FileChangedShell| event was
do with the affected buffer:
reload Reload the buffer (does not work if
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
was no autocommand. Except that when
only the timestamp changed nothing

View File

@ -2697,7 +2697,7 @@ readfile_linenr(
}
/*
* 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().
* Returns OK or FAIL.
*/
@ -4041,7 +4041,11 @@ buf_check_timestamp(
char *mesg = NULL;
char *mesg2 = "";
int helpmesg = FALSE;
int reload = FALSE;
enum {
RELOAD_NONE,
RELOAD_NORMAL,
RELOAD_DETECT
} reload = RELOAD_NONE;
char *reason;
#if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
int can_reload = FALSE;
@ -4117,7 +4121,7 @@ buf_check_timestamp(
*/
else if ((buf->b_p_ar >= 0 ? buf->b_p_ar : p_ar)
&& !bufIsChanged(buf) && stat_res >= 0)
reload = TRUE;
reload = RELOAD_NORMAL;
else
{
if (stat_res < 0)
@ -4158,7 +4162,9 @@ buf_check_timestamp(
#ifdef FEAT_EVAL
s = get_vim_var_str(VV_FCS_CHOICE);
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)
n = FALSE;
else
@ -4239,10 +4245,18 @@ buf_check_timestamp(
STRCAT(tbuf, "\n");
STRCAT(tbuf, mesg2);
}
if (do_dialog(VIM_WARNING, (char_u *)_("Warning"),
(char_u *)tbuf,
(char_u *)_("&OK\n&Load File"), 1, NULL, TRUE) == 2)
reload = TRUE;
switch (do_dialog(VIM_WARNING, (char_u *)_("Warning"),
(char_u *)tbuf,
(char_u *)_("&OK\n&Load File\nLoad File &and Options"),
1, NULL, TRUE))
{
case 2:
reload = RELOAD_NORMAL;
break;
case 3:
reload = RELOAD_DETECT;
break;
}
}
else
#endif
@ -4287,10 +4301,10 @@ buf_check_timestamp(
}
}
if (reload)
if (reload != RELOAD_NONE)
{
// Reload the buffer.
buf_reload(buf, orig_mode);
buf_reload(buf, orig_mode, reload == RELOAD_DETECT);
#ifdef FEAT_PERSISTENT_UNDO
if (buf->b_p_udf && buf->b_ffname != NULL)
{
@ -4326,7 +4340,7 @@ buf_check_timestamp(
* buf->b_orig_mode may have been reset already.
*/
void
buf_reload(buf_T *buf, int orig_mode)
buf_reload(buf_T *buf, int orig_mode, int reload_options)
{
exarg_T ea;
pos_T old_cursor;
@ -4337,14 +4351,20 @@ buf_reload(buf_T *buf, int orig_mode)
int saved = OK;
aco_save_T aco;
int flags = READ_NEW;
int prepped = OK;
// set curwin/curbuf for "buf" and save some things
aucmd_prepbuf(&aco, buf);
// We only want to read the text from the file, not reset the syntax
// highlighting, clear marks, diff status, etc. Force the fileformat
// and encoding to be the same.
if (prep_exarg(&ea, buf) == OK)
// Unless reload_options is set, we only want to read the text from the
// file, not reset the syntax highlighting, clear marks, diff status, etc.
// Force the fileformat and encoding to be the same.
if (reload_options)
memset(&ea, 0, sizeof(ea));
else
prepped = prep_exarg(&ea, buf);
if (prepped == OK)
{
old_cursor = curwin->w_cursor;
old_topline = curwin->w_topline;

View File

@ -3752,6 +3752,8 @@ msg_advance(int col)
* Other buttons- use your imagination!
* A '&' in a button name becomes a shortcut, so each '&' should be before a
* different letter.
*
* Returns 0 if cancelled, otherwise the nth button (1-indexed).
*/
int
do_dialog(

View File

@ -28,7 +28,7 @@ int vim_fgets(char_u *buf, int size, FILE *fp);
int vim_rename(char_u *from, char_u *to);
int check_timestamps(int focus);
int buf_check_timestamp(buf_T *buf, int focus);
void buf_reload(buf_T *buf, int orig_mode);
void buf_reload(buf_T *buf, int orig_mode, int reload_options);
void buf_store_time(buf_T *buf, stat_T *st, char_u *fname);
void write_lnum_adjust(linenr_T offset);
int readdir_core(garray_T *gap, char_u *path, int withattr, void *context, int (*checkitem)(void *context, void *item), int sort);

View File

@ -6336,7 +6336,7 @@ spell_add_word(
// If the .add file is edited somewhere, reload it.
if (buf != NULL)
buf_reload(buf, buf->b_orig_mode);
buf_reload(buf, buf->b_orig_mode, FALSE);
redraw_all_later(SOME_VALID);
}

View File

@ -91,6 +91,100 @@ func Test_FileChangedShell_reload()
call delete('Xchanged_r')
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')
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')
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()
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()
CheckUnix
CheckNotGui

View File

@ -746,6 +746,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
4343,
/**/
4342,
/**/