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. 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]

View File

@ -2070,6 +2070,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

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(). * equal to the buffer "buf". Used for calling readfile().
* Returns OK or FAIL. * Returns OK or FAIL.
*/ */
@ -4041,7 +4041,11 @@ buf_check_timestamp(
char *mesg = NULL; char *mesg = NULL;
char *mesg2 = ""; char *mesg2 = "";
int helpmesg = FALSE; int helpmesg = FALSE;
int reload = FALSE; enum {
RELOAD_NONE,
RELOAD_NORMAL,
RELOAD_DETECT
} reload = RELOAD_NONE;
char *reason; char *reason;
#if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG) #if defined(FEAT_CON_DIALOG) || defined(FEAT_GUI_DIALOG)
int can_reload = FALSE; int can_reload = FALSE;
@ -4117,7 +4121,7 @@ buf_check_timestamp(
*/ */
else if ((buf->b_p_ar >= 0 ? buf->b_p_ar : p_ar) else if ((buf->b_p_ar >= 0 ? buf->b_p_ar : p_ar)
&& !bufIsChanged(buf) && stat_res >= 0) && !bufIsChanged(buf) && stat_res >= 0)
reload = TRUE; reload = RELOAD_NORMAL;
else else
{ {
if (stat_res < 0) if (stat_res < 0)
@ -4158,7 +4162,9 @@ buf_check_timestamp(
#ifdef FEAT_EVAL #ifdef FEAT_EVAL
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
@ -4239,10 +4245,18 @@ buf_check_timestamp(
STRCAT(tbuf, "\n"); STRCAT(tbuf, "\n");
STRCAT(tbuf, mesg2); STRCAT(tbuf, mesg2);
} }
if (do_dialog(VIM_WARNING, (char_u *)_("Warning"), switch (do_dialog(VIM_WARNING, (char_u *)_("Warning"),
(char_u *)tbuf, (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 else
#endif #endif
@ -4287,10 +4301,10 @@ buf_check_timestamp(
} }
} }
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);
#ifdef FEAT_PERSISTENT_UNDO #ifdef FEAT_PERSISTENT_UNDO
if (buf->b_p_udf && buf->b_ffname != NULL) 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. * buf->b_orig_mode may have been reset already.
*/ */
void void
buf_reload(buf_T *buf, int orig_mode) buf_reload(buf_T *buf, int orig_mode, int reload_options)
{ {
exarg_T ea; exarg_T ea;
pos_T old_cursor; pos_T old_cursor;
@ -4337,14 +4351,20 @@ buf_reload(buf_T *buf, int orig_mode)
int saved = OK; int saved = OK;
aco_save_T aco; aco_save_T aco;
int flags = READ_NEW; int flags = READ_NEW;
int prepped = OK;
// 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 // file, not reset the syntax highlighting, clear marks, diff status, etc.
// and encoding to be the same. // Force the fileformat and encoding to be the same.
if (prep_exarg(&ea, buf) == OK) if (reload_options)
memset(&ea, 0, sizeof(ea));
else
prepped = prep_exarg(&ea, buf);
if (prepped == OK)
{ {
old_cursor = curwin->w_cursor; old_cursor = curwin->w_cursor;
old_topline = curwin->w_topline; old_topline = curwin->w_topline;

View File

@ -3752,6 +3752,8 @@ msg_advance(int col)
* Other buttons- use your imagination! * Other buttons- use your imagination!
* A '&' in a button name becomes a shortcut, so each '&' should be before a * A '&' in a button name becomes a shortcut, so each '&' should be before a
* different letter. * different letter.
*
* Returns 0 if cancelled, otherwise the nth button (1-indexed).
*/ */
int int
do_dialog( 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 vim_rename(char_u *from, char_u *to);
int check_timestamps(int focus); int check_timestamps(int focus);
int buf_check_timestamp(buf_T *buf, 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 buf_store_time(buf_T *buf, stat_T *st, char_u *fname);
void write_lnum_adjust(linenr_T offset); 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); 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 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);
} }

View File

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

View File

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