# HG changeset patch # User Bram Moolenaar # Date 1644592503 -3600 # Node ID 6ca2d8f4cd327eb892d985c8b50d8cce7f76a990 # Parent 9fe2fed9bb4b7315b42a8566c4686c8c20849c64 patch 8.2.4343: when reloading not all properties are detected Commit: https://github.com/vim/vim/commit/8196e94a8b72ed8618605cb66615571313097d78 Author: Rob Pilling Date: Fri Feb 11 15:12:10 2022 +0000 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 https://github.com/vim/vim/issues/9579) diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt --- a/runtime/doc/editing.txt +++ b/runtime/doc/editing.txt @@ -1650,6 +1650,11 @@ If you don't get warned often enough you 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] diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt --- a/runtime/doc/eval.txt +++ b/runtime/doc/eval.txt @@ -2070,6 +2070,11 @@ v:fcs_choice What should happen after a 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 diff --git a/src/fileio.c b/src/fileio.c --- a/src/fileio.c +++ b/src/fileio.c @@ -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; diff --git a/src/message.c b/src/message.c --- a/src/message.c +++ b/src/message.c @@ -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( diff --git a/src/proto/fileio.pro b/src/proto/fileio.pro --- a/src/proto/fileio.pro +++ b/src/proto/fileio.pro @@ -28,7 +28,7 @@ int vim_fgets(char_u *buf, int size, FIL 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); diff --git a/src/spellfile.c b/src/spellfile.c --- a/src/spellfile.c +++ b/src/spellfile.c @@ -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); } diff --git a/src/testdir/test_filechanged.vim b/src/testdir/test_filechanged.vim --- a/src/testdir/test_filechanged.vim +++ b/src/testdir/test_filechanged.vim @@ -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 diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -747,6 +747,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4343, +/**/ 4342, /**/ 4341,