Skip to content

Commit acf95bf

Browse files
committed
Merge remote-tracking branch 'vim/master'
2 parents d02a194 + 110bd60 commit acf95bf

31 files changed

Lines changed: 710 additions & 199 deletions

runtime/doc/autocmd.txt

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -656,6 +656,11 @@ FileChangedRO Before making the first change to a read-only
656656
*E881*
657657
If the number of lines changes saving for undo
658658
may fail and the change will be aborted.
659+
*DiffUpdated*
660+
DiffUpdated After diffs have been updated. Depending on
661+
what kind of diff is being used (internal or
662+
external) this can be triggered on every
663+
change or when doing |:diffupdate|.
659664
*DirChanged*
660665
DirChanged The working directory has changed in response
661666
to the |:cd| or |:lcd| commands, or as a

runtime/doc/eval.txt

Lines changed: 27 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2417,6 +2417,7 @@ submatch({nr} [, {list}]) String or List
24172417
substitute({expr}, {pat}, {sub}, {flags})
24182418
String all {pat} in {expr} replaced with {sub}
24192419
swapinfo({fname}) Dict information about swap file {fname}
2420+
swapname({expr}) String swap file of buffer {expr}
24202421
synID({lnum}, {col}, {trans}) Number syntax ID at {lnum} and {col}
24212422
synIDattr({synID}, {what} [, {mode}])
24222423
String attribute {what} of syntax ID {synID}
@@ -2475,6 +2476,8 @@ test_null_partial() Funcref null value for testing
24752476
test_null_string() String null value for testing
24762477
test_option_not_set({name}) none reset flag indicating option was set
24772478
test_override({expr}, {val}) none test with Vim internal overrides
2479+
test_scrollbar({which}, {value}, {dragging})
2480+
none scroll in the GUI for testing
24782481
test_settime({expr}) none set current time for testing
24792482
timer_info([{id}]) List information about timers
24802483
timer_pause({id}, {pause}) none pause or unpause a timer
@@ -8040,6 +8043,13 @@ swapinfo({fname}) *swapinfo()*
80408043
Not a swap file: does not contain correct block ID
80418044
Magic number mismatch: Info in first block is invalid
80428045

8046+
swapname({expr}) *swapname()*
8047+
The result is the swap file path of the buffer {expr}.
8048+
For the use of {expr}, see |bufname()| above.
8049+
If buffer {expr} is the current buffer, the result is equal to
8050+
|:swapname| (unless no swap file).
8051+
If buffer {expr} has no swap file, returns an empty string.
8052+
80438053
synID({lnum}, {col}, {trans}) *synID()*
80448054
The result is a Number, which is the syntax ID at the position
80458055
{lnum} and {col} in the current window.
@@ -8773,6 +8783,23 @@ test_override({name}, {val}) *test_override()*
87738783
< The value of "starting" is saved. It is restored by: >
87748784
call test_override('starting', 0)
87758785
8786+
test_scrollbar({which}, {value}, {dragging}) *test_scrollbar()*
8787+
Pretend using scrollbar {which} to move it to position
8788+
{value}. {which} can be:
8789+
left Left scrollbar of the current window
8790+
right Right scrollbar of the current window
8791+
hor Horizontal scrollbar
8792+
8793+
For the vertical scrollbars {value} can be 1 to the
8794+
line-count of the buffer. For the horizontal scrollbar the
8795+
{value} can be between 1 and the maximum line length, assuming
8796+
'wrap' is not set.
8797+
8798+
When {dragging} is non-zero it's like dragging the scrollbar,
8799+
otherwise it's like clicking in the scrollbar.
8800+
Only works when the {which} scrollbar actually exists,
8801+
obviously only when using the GUI.
8802+
87768803
test_settime({expr}) *test_settime()*
87778804
Set the time Vim uses internally. Currently only used for
87788805
timestamps in the history, as they are used in viminfo, and

src/Make_all.mak

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ NEW_TESTS = \
1414
test_autoload \
1515
test_backspace_opt \
1616
test_backup \
17+
test_behave \
1718
test_blockedit \
1819
test_breakindent \
1920
test_bufline \

src/Makefile

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2782,7 +2782,7 @@ SHADOWDIR = shadow
27822782

27832783
shadow: runtime pixmaps
27842784
$(MKDIR_P) $(SHADOWDIR)
2785-
cd $(SHADOWDIR); ln -s ../*.[chm] ../*.in ../*.sh ../*.xs ../*.xbm ../gui_gtk_res.xml ../toolcheck ../proto ../xdiff ../libvterm ../vimtutor ../gvimtutor ../install-sh ../Make_all.mak .
2785+
cd $(SHADOWDIR); ln -s ../*.[chm] ../*.in ../*.sh ../*.xs ../*.xbm ../gui_gtk_res.xml ../toolcheck ../proto ../libvterm ../vimtutor ../gvimtutor ../install-sh ../Make_all.mak .
27862786
mkdir $(SHADOWDIR)/auto
27872787
cd $(SHADOWDIR)/auto; ln -s ../../auto/configure .
27882788
$(MKDIR_P) $(SHADOWDIR)/po
@@ -2794,6 +2794,8 @@ shadow: runtime pixmaps
27942794
cp config.mk.dist $(SHADOWDIR)
27952795
$(MKDIR_P) $(SHADOWDIR)/xxd
27962796
cd $(SHADOWDIR)/xxd; ln -s ../../xxd/*.[ch] ../../xxd/Make* .
2797+
$(MKDIR_P) $(SHADOWDIR)/xdiff
2798+
cd $(SHADOWDIR)/xdiff; ln -s ../../xdiff/*.[ch] .
27972799
if test -d $(RSRC_DIR); then \
27982800
cd $(SHADOWDIR); \
27992801
ln -s ../infplist.xml .; \

src/diff.c

Lines changed: 94 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -21,16 +21,21 @@
2121

2222
#if defined(FEAT_DIFF) || defined(PROTO)
2323

24-
static int diff_busy = FALSE; /* ex_diffgetput() is busy */
24+
static int diff_busy = FALSE; // using diff structs, don't change them
25+
static int diff_need_update = FALSE; // ex_diffupdate needs to be called
2526

2627
/* flags obtained from the 'diffopt' option */
27-
#define DIFF_FILLER 1 // display filler lines
28-
#define DIFF_ICASE 2 // ignore case
29-
#define DIFF_IWHITE 4 // ignore change in white space
30-
#define DIFF_HORIZONTAL 8 // horizontal splits
31-
#define DIFF_VERTICAL 16 // vertical splits
32-
#define DIFF_HIDDEN_OFF 32 // diffoff when hidden
33-
#define DIFF_INTERNAL 64 // use internal xdiff algorithm
28+
#define DIFF_FILLER 0x001 // display filler lines
29+
#define DIFF_IBLANK 0x002 // ignore empty lines
30+
#define DIFF_ICASE 0x004 // ignore case
31+
#define DIFF_IWHITE 0x008 // ignore change in white space
32+
#define DIFF_IWHITEALL 0x010 // ignore all white space changes
33+
#define DIFF_IWHITEEOL 0x020 // ignore change in white space at EOL
34+
#define DIFF_HORIZONTAL 0x040 // horizontal splits
35+
#define DIFF_VERTICAL 0x080 // vertical splits
36+
#define DIFF_HIDDEN_OFF 0x100 // diffoff when hidden
37+
#define DIFF_INTERNAL 0x200 // use internal xdiff algorithm
38+
#define ALL_WHITE_DIFF (DIFF_IWHITE | DIFF_IWHITEALL | DIFF_IWHITEEOL)
3439
static int diff_flags = DIFF_INTERNAL | DIFF_FILLER;
3540

3641
static long diff_algorithm = 0;
@@ -288,6 +293,16 @@ diff_mark_adjust_tp(
288293
linenr_T lnum_deleted = line1; /* lnum of remaining deletion */
289294
int check_unchanged;
290295

296+
if (diff_internal())
297+
{
298+
// Will udpate diffs before redrawing. Set _invalid to update the
299+
// diffs themselves, set _update to also update folds properly just
300+
// before redrawing.
301+
tp->tp_diff_invalid = TRUE;
302+
tp->tp_diff_update = TRUE;
303+
return;
304+
}
305+
291306
if (line2 == MAXLNUM)
292307
{
293308
/* mark_adjust(99, MAXLNUM, 9, 0): insert lines */
@@ -636,7 +651,7 @@ diff_check_sanity(tabpage_T *tp, diff_T *dp)
636651
*/
637652
static void
638653
diff_redraw(
639-
int dofold) /* also recompute the folds */
654+
int dofold) // also recompute the folds
640655
{
641656
win_T *wp;
642657
int n;
@@ -698,7 +713,7 @@ diff_write_buffer(buf_T *buf, diffin_T *din)
698713

699714
// xdiff requires one big block of memory with all the text.
700715
for (lnum = 1; lnum <= buf->b_ml.ml_line_count; ++lnum)
701-
len += STRLEN(ml_get_buf(buf, lnum, FALSE)) + 1;
716+
len += (long)STRLEN(ml_get_buf(buf, lnum, FALSE)) + 1;
702717
ptr = lalloc(len, TRUE);
703718
if (ptr == NULL)
704719
{
@@ -859,7 +874,7 @@ diff_try_update(
859874
* Note that if the internal diff failed for one of the buffers, the external
860875
* diff will be used anyway.
861876
*/
862-
static int
877+
int
863878
diff_internal(void)
864879
{
865880
return (diff_flags & DIFF_INTERNAL) != 0 && *p_dex == NUL;
@@ -883,9 +898,9 @@ diff_internal_failed(void)
883898

884899
/*
885900
* Completely update the diffs for the buffers involved.
886-
* This uses the ordinary "diff" command.
887-
* The buffers are written to a file, also for unmodified buffers (the file
888-
* could have been produced by autocommands, e.g. the netrw plugin).
901+
* When using the external "diff" command the buffers are written to a file,
902+
* also for unmodified buffers (the file could have been produced by
903+
* autocommands, e.g. the netrw plugin).
889904
*/
890905
void
891906
ex_diffupdate(exarg_T *eap) // "eap" can be NULL
@@ -894,6 +909,12 @@ ex_diffupdate(exarg_T *eap) // "eap" can be NULL
894909
int idx_new;
895910
diffio_T diffio;
896911

912+
if (diff_busy)
913+
{
914+
diff_need_update = TRUE;
915+
return;
916+
}
917+
897918
// Delete all diffblocks.
898919
diff_clear(curtab);
899920
curtab->tp_diff_invalid = FALSE;
@@ -928,6 +949,8 @@ ex_diffupdate(exarg_T *eap) // "eap" can be NULL
928949
curwin->w_valid_cursor.lnum = 0;
929950

930951
diff_redraw(TRUE);
952+
953+
apply_autocmds(EVENT_DIFFUPDATED, NULL, NULL, FALSE, curbuf);
931954
}
932955

933956
/*
@@ -1050,6 +1073,12 @@ diff_file_internal(diffio_T *diffio)
10501073

10511074
if (diff_flags & DIFF_IWHITE)
10521075
param.flags |= XDF_IGNORE_WHITESPACE_CHANGE;
1076+
if (diff_flags & DIFF_IWHITEALL)
1077+
param.flags |= XDF_IGNORE_WHITESPACE;
1078+
if (diff_flags & DIFF_IWHITEEOL)
1079+
param.flags |= XDF_IGNORE_WHITESPACE_AT_EOL;
1080+
if (diff_flags & DIFF_IBLANK)
1081+
param.flags |= XDF_IGNORE_BLANK_LINES;
10531082

10541083
emit_cfg.ctxlen = 0; // don't need any diff_context here
10551084
emit_cb.priv = &diffio->dio_diff;
@@ -1106,14 +1135,17 @@ diff_file(diffio_T *dio)
11061135
// Build the diff command and execute it. Always use -a, binary
11071136
// differences are of no use. Ignore errors, diff returns
11081137
// non-zero when differences have been found.
1109-
vim_snprintf((char *)cmd, len, "diff %s%s%s%s%s %s",
1138+
vim_snprintf((char *)cmd, len, "diff %s%s%s%s%s%s%s%s %s",
11101139
diff_a_works == FALSE ? "" : "-a ",
11111140
#if defined(MSWIN)
11121141
diff_bin_works == TRUE ? "--binary " : "",
11131142
#else
11141143
"",
11151144
#endif
11161145
(diff_flags & DIFF_IWHITE) ? "-b " : "",
1146+
(diff_flags & DIFF_IWHITEALL) ? "-w " : "",
1147+
(diff_flags & DIFF_IWHITEEOL) ? "-Z " : "",
1148+
(diff_flags & DIFF_IBLANK) ? "-B " : "",
11171149
(diff_flags & DIFF_ICASE) ? "-i " : "",
11181150
tmp_orig, tmp_new);
11191151
append_redir(cmd, (int)len, p_srr, tmp_diff);
@@ -1946,17 +1978,25 @@ diff_cmp(char_u *s1, char_u *s2)
19461978
char_u *p1, *p2;
19471979
int l;
19481980

1949-
if ((diff_flags & (DIFF_ICASE | DIFF_IWHITE)) == 0)
1981+
if ((diff_flags & DIFF_IBLANK)
1982+
&& (*skipwhite(s1) == NUL || *skipwhite(s2) == NUL))
1983+
return 0;
1984+
1985+
if ((diff_flags & (DIFF_ICASE | ALL_WHITE_DIFF)) == 0)
19501986
return STRCMP(s1, s2);
1951-
if ((diff_flags & DIFF_ICASE) && !(diff_flags & DIFF_IWHITE))
1987+
if ((diff_flags & DIFF_ICASE) && !(diff_flags & ALL_WHITE_DIFF))
19521988
return MB_STRICMP(s1, s2);
19531989

1954-
/* Ignore white space changes and possibly ignore case. */
19551990
p1 = s1;
19561991
p2 = s2;
1992+
1993+
// Ignore white space changes and possibly ignore case.
19571994
while (*p1 != NUL && *p2 != NUL)
19581995
{
1959-
if (VIM_ISWHITE(*p1) && VIM_ISWHITE(*p2))
1996+
if (((diff_flags & DIFF_IWHITE)
1997+
&& VIM_ISWHITE(*p1) && VIM_ISWHITE(*p2))
1998+
|| ((diff_flags & DIFF_IWHITEALL)
1999+
&& (VIM_ISWHITE(*p1) || VIM_ISWHITE(*p2))))
19602000
{
19612001
p1 = skipwhite(p1);
19622002
p2 = skipwhite(p2);
@@ -1970,7 +2010,7 @@ diff_cmp(char_u *s1, char_u *s2)
19702010
}
19712011
}
19722012

1973-
/* Ignore trailing white space. */
2013+
// Ignore trailing white space.
19742014
p1 = skipwhite(p1);
19752015
p2 = skipwhite(p2);
19762016
if (*p1 != NUL || *p2 != NUL)
@@ -2142,11 +2182,26 @@ diffopt_changed(void)
21422182
p += 8;
21432183
diff_context_new = getdigits(&p);
21442184
}
2185+
else if (STRNCMP(p, "iblank", 6) == 0)
2186+
{
2187+
p += 6;
2188+
diff_flags_new |= DIFF_IBLANK;
2189+
}
21452190
else if (STRNCMP(p, "icase", 5) == 0)
21462191
{
21472192
p += 5;
21482193
diff_flags_new |= DIFF_ICASE;
21492194
}
2195+
else if (STRNCMP(p, "iwhiteall", 9) == 0)
2196+
{
2197+
p += 9;
2198+
diff_flags_new |= DIFF_IWHITEALL;
2199+
}
2200+
else if (STRNCMP(p, "iwhiteeol", 9) == 0)
2201+
{
2202+
p += 9;
2203+
diff_flags_new |= DIFF_IWHITEEOL;
2204+
}
21502205
else if (STRNCMP(p, "iwhite", 6) == 0)
21512206
{
21522207
p += 6;
@@ -2315,9 +2370,12 @@ diff_find_change(
23152370
si_org = si_new = 0;
23162371
while (line_org[si_org] != NUL)
23172372
{
2318-
if ((diff_flags & DIFF_IWHITE)
2319-
&& VIM_ISWHITE(line_org[si_org])
2320-
&& VIM_ISWHITE(line_new[si_new]))
2373+
if (((diff_flags & DIFF_IWHITE)
2374+
&& VIM_ISWHITE(line_org[si_org])
2375+
&& VIM_ISWHITE(line_new[si_new]))
2376+
|| ((diff_flags & DIFF_IWHITEALL)
2377+
&& (VIM_ISWHITE(line_org[si_org])
2378+
|| VIM_ISWHITE(line_new[si_new]))))
23212379
{
23222380
si_org = (int)(skipwhite(line_org + si_org) - line_org);
23232381
si_new = (int)(skipwhite(line_new + si_new) - line_new);
@@ -2351,9 +2409,12 @@ diff_find_change(
23512409
while (ei_org >= *startp && ei_new >= si_new
23522410
&& ei_org >= 0 && ei_new >= 0)
23532411
{
2354-
if ((diff_flags & DIFF_IWHITE)
2355-
&& VIM_ISWHITE(line_org[ei_org])
2356-
&& VIM_ISWHITE(line_new[ei_new]))
2412+
if (((diff_flags & DIFF_IWHITE)
2413+
&& VIM_ISWHITE(line_org[ei_org])
2414+
&& VIM_ISWHITE(line_new[ei_new]))
2415+
|| ((diff_flags & DIFF_IWHITEALL)
2416+
&& (VIM_ISWHITE(line_org[ei_org])
2417+
|| VIM_ISWHITE(line_new[ei_new]))))
23572418
{
23582419
while (ei_org >= *startp
23592420
&& VIM_ISWHITE(line_org[ei_org]))
@@ -2606,7 +2667,7 @@ ex_diffgetput(exarg_T *eap)
26062667
if (diff_buf_idx(curbuf) != idx_to)
26072668
{
26082669
EMSG(_("E787: Buffer changed unexpectedly"));
2609-
return;
2670+
goto theend;
26102671
}
26112672
}
26122673

@@ -2777,7 +2838,13 @@ ex_diffgetput(exarg_T *eap)
27772838
aucmd_restbuf(&aco);
27782839
}
27792840

2841+
theend:
27802842
diff_busy = FALSE;
2843+
if (diff_need_update)
2844+
{
2845+
diff_need_update = FALSE;
2846+
ex_diffupdate(NULL);
2847+
}
27812848

27822849
/* Check that the cursor is on a valid character and update it's position.
27832850
* When there were filler lines the topline has become invalid. */

0 commit comments

Comments
 (0)