]> granicus.if.org Git - vim/commitdiff
patch 8.1.2289: after :diffsplit closing the window does not disable diff v8.1.2289
authorBram Moolenaar <Bram@vim.org>
Sun, 10 Nov 2019 20:00:27 +0000 (21:00 +0100)
committerBram Moolenaar <Bram@vim.org>
Sun, 10 Nov 2019 20:00:27 +0000 (21:00 +0100)
Problem:    After :diffsplit closing the window does not disable diff.
Solution:   Add "closeoff" to 'diffopt' and add it to the default.

runtime/doc/options.txt
src/diff.c
src/optiondefs.h
src/proto/diff.pro
src/testdir/test_diffmode.vim
src/version.c
src/window.c

index 738dc7fcc945e5f1dae567567f2b7f0ef868a9af..42c7510cc31063c2f9c5e7f187826c987dad3d51 100644 (file)
@@ -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 "")
index 120a544965c961be641d1b8f9c52288d8f08f5dd..b16f7b6f3e127df055f95e2ce2df7a560b23720f 100644 (file)
@@ -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;
@@ -2309,6 +2323,15 @@ diffopt_hiddenoff(void)
     return (diff_flags & DIFF_HIDDEN_OFF) != 0;
 }
 
+/*
+ * 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.
index 05e04064a6d5a6332ad18b48258acb5e5137d9fc..881ec06a5e04f398462fc204a5b919936d533e4b 100644 (file)
@@ -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}
index b18c59b2b1fe3e818fd93577a42e48a7faebdbd8..d14907e8d0273b2834200f81deccbd79f466eb45 100644 (file)
@@ -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);
index 8ad86ada8f8c872ae8d0cc22595378686981c222..6f4eaaf4316832f645d9978addde01539f23a905 100644 (file)
@@ -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
index d2baa1faccf20d4b6629d965093a89f794d698c3..205f2dc4532811f1cdc807af1e5dea32d71ea468 100644 (file)
@@ -741,6 +741,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    2289,
 /**/
     2288,
 /**/
index abdbd507969afc28fed38cfa7de648f83f102e0c..a1cda8304d790cdbcfbf2e6a284396b74e68e4c5 100644 (file)
@@ -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())