summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2019-11-10 21:00:27 +0100
committerBram Moolenaar <Bram@vim.org>2019-11-10 21:00:27 +0100
commitc8234779790dd873acb88331c50988adf94cc383 (patch)
treed3e58b31d9e4593956cd028e4468051ce3d79dfc
parent5c6b6187ac51a4d8545e823c1be6cdf70cac8a57 (diff)
patch 8.1.2289: after :diffsplit closing the window does not disable diffv8.1.2289
Problem: After :diffsplit closing the window does not disable diff. Solution: Add "closeoff" to 'diffopt' and add it to the default.
-rw-r--r--runtime/doc/options.txt11
-rw-r--r--src/diff.c25
-rw-r--r--src/optiondefs.h3
-rw-r--r--src/proto/diff.pro1
-rw-r--r--src/testdir/test_diffmode.vim25
-rw-r--r--src/version.c2
-rw-r--r--src/window.c20
7 files changed, 84 insertions, 3 deletions
diff --git a/runtime/doc/options.txt b/runtime/doc/options.txt
index 738dc7fcc9..42c7510cc3 100644
--- a/runtime/doc/options.txt
+++ b/runtime/doc/options.txt
@@ -2591,7 +2591,7 @@ A jump table for the options with a short description can be found at |Q_op|.
security reasons.
*'dip'* *'diffopt'*
-'diffopt' 'dip' string (default "internal,filler")
+'diffopt' 'dip' string (default "internal,filler,closeoff")
global
{not available when compiled without the |+diff|
feature}
@@ -2650,6 +2650,12 @@ A jump table for the options with a short description can be found at |Q_op|.
vertical Start diff mode with vertical splits (unless
explicitly specified otherwise).
+ closeoff When a window is closed where 'diff' is set
+ and there is only one window remaining in the
+ same tab page with 'diff' set, execute
+ `:diffoff` in that window. This undoes a
+ `:diffsplit` command.
+
hiddenoff Do not use diff mode for a buffer when it
becomes hidden.
@@ -2933,6 +2939,9 @@ A jump table for the options with a short description can be found at |Q_op|.
won't work by default.
NOTE: This option is set to the Vi default value when 'compatible' is
set and to the Vim default value when 'compatible' is reset.
+ NOTE: when this option is off then the |modifyOtherKeys| functionality
+ is disabled while in Insert mode to avoid ending Insert mode with any
+ key that has a modifier.
*'eventignore'* *'ei'*
'eventignore' 'ei' string (default "")
diff --git a/src/diff.c b/src/diff.c
index 120a544965..b16f7b6f3e 100644
--- a/src/diff.c
+++ b/src/diff.c
@@ -35,8 +35,9 @@ static int diff_need_update = FALSE; // ex_diffupdate needs to be called
#define DIFF_VERTICAL 0x080 // vertical splits
#define DIFF_HIDDEN_OFF 0x100 // diffoff when hidden
#define DIFF_INTERNAL 0x200 // use internal xdiff algorithm
+#define DIFF_CLOSE_OFF 0x400 // diffoff when closing window
#define ALL_WHITE_DIFF (DIFF_IWHITE | DIFF_IWHITEALL | DIFF_IWHITEEOL)
-static int diff_flags = DIFF_INTERNAL | DIFF_FILLER;
+static int diff_flags = DIFF_INTERNAL | DIFF_FILLER | DIFF_CLOSE_OFF;
static long diff_algorithm = 0;
@@ -1545,6 +1546,14 @@ ex_diffoff(exarg_T *eap)
if (eap->forceit)
diff_buf_clear();
+ if (!diffwin)
+ {
+ diff_need_update = FALSE;
+ curtab->tp_diff_invalid = FALSE;
+ curtab->tp_diff_update = FALSE;
+ diff_clear(curtab);
+ }
+
/* Remove "hor" from from 'scrollopt' if there are no diff windows left. */
if (!diffwin && vim_strchr(p_sbo, 'h') != NULL)
do_cmdline_cmd((char_u *)"set sbo-=hor");
@@ -2222,6 +2231,11 @@ diffopt_changed(void)
p += 9;
diff_flags_new |= DIFF_HIDDEN_OFF;
}
+ else if (STRNCMP(p, "closeoff", 8) == 0)
+ {
+ p += 8;
+ diff_flags_new |= DIFF_CLOSE_OFF;
+ }
else if (STRNCMP(p, "indent-heuristic", 16) == 0)
{
p += 16;
@@ -2310,6 +2324,15 @@ diffopt_hiddenoff(void)
}
/*
+ * Return TRUE if 'diffopt' contains "closeoff".
+ */
+ int
+diffopt_closeoff(void)
+{
+ return (diff_flags & DIFF_CLOSE_OFF) != 0;
+}
+
+/*
* Find the difference within a changed line.
* Returns TRUE if the line was added, no other buffer has it.
*/
diff --git a/src/optiondefs.h b/src/optiondefs.h
index 05e04064a6..881ec06a5e 100644
--- a/src/optiondefs.h
+++ b/src/optiondefs.h
@@ -846,7 +846,8 @@ static struct vimoption options[] =
|P_NODUP,
#ifdef FEAT_DIFF
(char_u *)&p_dip, PV_NONE,
- {(char_u *)"internal,filler", (char_u *)NULL}
+ {(char_u *)"internal,filler,closeoff",
+ (char_u *)NULL}
#else
(char_u *)NULL, PV_NONE,
{(char_u *)"", (char_u *)NULL}
diff --git a/src/proto/diff.pro b/src/proto/diff.pro
index b18c59b2b1..d14907e8d0 100644
--- a/src/proto/diff.pro
+++ b/src/proto/diff.pro
@@ -19,6 +19,7 @@ void diff_set_topline(win_T *fromwin, win_T *towin);
int diffopt_changed(void);
int diffopt_horizontal(void);
int diffopt_hiddenoff(void);
+int diffopt_closeoff(void);
int diff_find_change(win_T *wp, linenr_T lnum, int *startp, int *endp);
int diff_infold(win_T *wp, linenr_T lnum);
void nv_diffgetput(int put, long count);
diff --git a/src/testdir/test_diffmode.vim b/src/testdir/test_diffmode.vim
index 8ad86ada8f..6f4eaaf431 100644
--- a/src/testdir/test_diffmode.vim
+++ b/src/testdir/test_diffmode.vim
@@ -964,3 +964,28 @@ func Test_diff_of_diff()
call StopVimInTerminal(buf)
call delete('Xtest_diff_diff')
endfunc
+
+func CloseoffSetup()
+ enew
+ call setline(1, ['one', 'two', 'three'])
+ diffthis
+ new
+ call setline(1, ['one', 'tow', 'three'])
+ diffthis
+ call assert_equal(1, &diff)
+ only!
+endfunc
+
+func Test_diff_closeoff()
+ " "closeoff" included by default: last diff win gets 'diff' reset'
+ call CloseoffSetup()
+ call assert_equal(0, &diff)
+ enew!
+
+ " "closeoff" excluded: last diff win keeps 'diff' set'
+ set diffopt-=closeoff
+ call CloseoffSetup()
+ call assert_equal(1, &diff)
+ diffoff!
+ enew!
+endfunc
diff --git a/src/version.c b/src/version.c
index d2baa1facc..205f2dc453 100644
--- a/src/version.c
+++ b/src/version.c
@@ -742,6 +742,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 2289,
+/**/
2288,
/**/
2287,
diff --git a/src/window.c b/src/window.c
index abdbd50796..a1cda8304d 100644
--- a/src/window.c
+++ b/src/window.c
@@ -2438,6 +2438,9 @@ win_close(win_T *win, int free_buf)
int help_window = FALSE;
tabpage_T *prev_curtab = curtab;
frame_T *win_frame = win->w_frame->fr_parent;
+#ifdef FEAT_DIFF
+ int had_diffmode = win->w_p_diff;
+#endif
if (ERROR_IF_POPUP_WINDOW)
return FAIL;
@@ -2625,6 +2628,23 @@ win_close(win_T *win, int free_buf)
if (help_window)
restore_snapshot(SNAP_HELP_IDX, close_curwin);
+#ifdef FEAT_DIFF
+ // If the window had 'diff' set and now there is only one window left in
+ // the tab page with 'diff' set, and "closeoff" is in 'diffopt', then
+ // execute ":diffoff!".
+ if (diffopt_closeoff() && had_diffmode && curtab == prev_curtab)
+ {
+ int diffcount = 0;
+ win_T *dwin;
+
+ FOR_ALL_WINDOWS(dwin)
+ if (dwin->w_p_diff)
+ ++diffcount;
+ if (diffcount == 1)
+ do_cmdline_cmd((char_u *)"diffoff!");
+ }
+#endif
+
#if defined(FEAT_GUI)
/* When 'guioptions' includes 'L' or 'R' may have to remove scrollbars. */
if (gui.in_use && !win_hasvertsplit())