vim-patch:8.1.2289: after :diffsplit closing the window does not disable diff

Problem:    After :diffsplit closing the window does not disable diff.
Solution:   Add "closeoff" to 'diffopt' and add it to the default.
c823477979
This commit is contained in:
Jan Edmund Lazo 2019-11-16 16:13:51 -05:00
parent da7bb53d99
commit b83027858a
No known key found for this signature in database
GPG Key ID: 64915E6E9F735B15
5 changed files with 71 additions and 4 deletions

View File

@ -1875,7 +1875,7 @@ A jump table for the options with a short description can be found at |Q_op|.
security reasons. security reasons.
*'dip'* *'diffopt'* *'dip'* *'diffopt'*
'diffopt' 'dip' string (default "internal,filler") 'diffopt' 'dip' string (default "internal,filler,closeoff")
global global
Option settings for diff mode. It can consist of the following items. Option settings for diff mode. It can consist of the following items.
All are optional. Items must be separated by a comma. All are optional. Items must be separated by a comma.
@ -1932,6 +1932,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 vertical Start diff mode with vertical splits (unless
explicitly specified otherwise). 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 hiddenoff Do not use diff mode for a buffer when it
becomes hidden. becomes hidden.

View File

@ -44,7 +44,7 @@
#include "nvim/os/shell.h" #include "nvim/os/shell.h"
static int diff_busy = false; // using diff structs, don't change them static int diff_busy = false; // using diff structs, don't change them
static int diff_need_update = false; // ex_diffupdate needs to be called static bool diff_need_update = false; // ex_diffupdate needs to be called
// Flags obtained from the 'diffopt' option // Flags obtained from the 'diffopt' option
#define DIFF_FILLER 0x001 // display filler lines #define DIFF_FILLER 0x001 // display filler lines
@ -57,8 +57,9 @@ static int diff_need_update = false; // ex_diffupdate needs to be called
#define DIFF_VERTICAL 0x080 // vertical splits #define DIFF_VERTICAL 0x080 // vertical splits
#define DIFF_HIDDEN_OFF 0x100 // diffoff when hidden #define DIFF_HIDDEN_OFF 0x100 // diffoff when hidden
#define DIFF_INTERNAL 0x200 // use internal xdiff algorithm #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) #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; static long diff_algorithm = 0;
@ -1474,6 +1475,13 @@ void ex_diffoff(exarg_T *eap)
diff_buf_clear(); 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. // Remove "hor" from from 'scrollopt' if there are no diff windows left.
if (!diffwin && (vim_strchr(p_sbo, 'h') != NULL)) { if (!diffwin && (vim_strchr(p_sbo, 'h') != NULL)) {
do_cmdline_cmd("set sbo-=hor"); do_cmdline_cmd("set sbo-=hor");
@ -1714,6 +1722,7 @@ static void diff_copy_entry(diff_T *dprev, diff_T *dp, int idx_orig,
/// ///
/// @param tp /// @param tp
void diff_clear(tabpage_T *tp) void diff_clear(tabpage_T *tp)
FUNC_ATTR_NONNULL_ALL
{ {
diff_T *p; diff_T *p;
diff_T *next_p; diff_T *next_p;
@ -2143,6 +2152,9 @@ int diffopt_changed(void)
} else if (STRNCMP(p, "hiddenoff", 9) == 0) { } else if (STRNCMP(p, "hiddenoff", 9) == 0) {
p += 9; p += 9;
diff_flags_new |= DIFF_HIDDEN_OFF; 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) { } else if (STRNCMP(p, "indent-heuristic", 16) == 0) {
p += 16; p += 16;
diff_indent_heuristic = XDF_INDENT_HEURISTIC; diff_indent_heuristic = XDF_INDENT_HEURISTIC;
@ -2218,6 +2230,13 @@ bool diffopt_hiddenoff(void)
return (diff_flags & DIFF_HIDDEN_OFF) != 0; return (diff_flags & DIFF_HIDDEN_OFF) != 0;
} }
// Return true if 'diffopt' contains "closeoff".
bool diffopt_closeoff(void)
FUNC_ATTR_PURE FUNC_ATTR_WARN_UNUSED_RESULT
{
return (diff_flags & DIFF_CLOSE_OFF) != 0;
}
/// Find the difference within a changed line. /// Find the difference within a changed line.
/// ///
/// @param wp window whose current buffer to check /// @param wp window whose current buffer to check

View File

@ -612,7 +612,7 @@ return {
alloced=true, alloced=true,
redraw={'current_window'}, redraw={'current_window'},
varname='p_dip', varname='p_dip',
defaults={if_true={vi="internal,filler"}} defaults={if_true={vi="internal,filler,closeoff"}}
}, },
{ {
full_name='digraph', abbreviation='dg', full_name='digraph', abbreviation='dg',

View File

@ -773,3 +773,28 @@ func Test_diff_of_diff()
call StopVimInTerminal(buf) call StopVimInTerminal(buf)
call delete('Xtest_diff_diff') call delete('Xtest_diff_diff')
endfunc 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

View File

@ -2418,6 +2418,7 @@ int win_close(win_T *win, bool free_buf)
bool help_window = false; bool help_window = false;
tabpage_T *prev_curtab = curtab; tabpage_T *prev_curtab = curtab;
frame_T *win_frame = win->w_floating ? NULL : win->w_frame->fr_parent; frame_T *win_frame = win->w_floating ? NULL : win->w_frame->fr_parent;
const bool had_diffmode = win->w_p_diff;
if (last_window() && !win->w_floating) { if (last_window() && !win->w_floating) {
EMSG(_("E444: Cannot close last window")); EMSG(_("E444: Cannot close last window"));
@ -2642,6 +2643,22 @@ int win_close(win_T *win, bool free_buf)
if (help_window) if (help_window)
restore_snapshot(SNAP_HELP_IDX, close_curwin); restore_snapshot(SNAP_HELP_IDX, close_curwin);
// 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;
FOR_ALL_WINDOWS_IN_TAB(dwin, curtab) {
if (dwin->w_p_diff) {
diffcount++;
}
}
if (diffcount == 1) {
do_cmdline_cmd("diffoff!");
}
}
curwin->w_pos_changed = true; curwin->w_pos_changed = true;
redraw_all_later(NOT_VALID); redraw_all_later(NOT_VALID);
return OK; return OK;