summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--runtime/doc/editing.txt5
-rw-r--r--runtime/doc/eval.txt5
-rw-r--r--src/fileio.c50
-rw-r--r--src/message.c2
-rw-r--r--src/proto/fileio.pro2
-rw-r--r--src/spellfile.c2
-rw-r--r--src/testdir/test_filechanged.vim94
-rw-r--r--src/version.c2
8 files changed, 145 insertions, 17 deletions
diff --git a/runtime/doc/editing.txt b/runtime/doc/editing.txt
index 371450f4e..5c4b61a3e 100644
--- a/runtime/doc/editing.txt
+++ b/runtime/doc/editing.txt
@@ -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]
diff --git a/runtime/doc/eval.txt b/runtime/doc/eval.txt
index 9e1425b82..f016c4ab8 100644
--- a/runtime/doc/eval.txt
+++ b/runtime/doc/eval.txt
@@ -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
diff --git a/src/fileio.c b/src/fileio.c
index 5b5699d65..0812462da 100644
--- 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
index c13a94d14..af91bd813 100644
--- 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
index da6054b50..3f7b30d44 100644
--- a/src/proto/fileio.pro
+++ b/src/proto/fileio.pro
@@ -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);
diff --git a/src/spellfile.c b/src/spellfile.c
index b5c669396..5b34298d7 100644
--- 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
index 3dada636e..0b5b8e033 100644
--- 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
index d8640c7ff..238361f94 100644
--- 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,