aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2014-09-05 20:57:41 -0400
committerJustin M. Keyes <justinkz@gmail.com>2014-09-05 20:57:41 -0400
commit3f5482d3251b3bbdc7c4df8a8e64eb3af7e5922c (patch)
treec3703170cc71c81da50b25fd0a8ff24af387d594
parentd66cd61b79d6d592436c4552dbdddb904dd1c22e (diff)
parentd860ba45e25231ae54c6fd12ecd00dc936780184 (diff)
downloadrneovim-3f5482d3251b3bbdc7c4df8a8e64eb3af7e5922c.tar.gz
rneovim-3f5482d3251b3bbdc7c4df8a8e64eb3af7e5922c.tar.bz2
rneovim-3f5482d3251b3bbdc7c4df8a8e64eb3af7e5922c.zip
Merge pull request #1107 from fmoralesc/matchaddpos
Add matchaddpos()-related vim patches. [vim-patch: 7.4.330, 7.4.334, 7.4.343, 7.4.344, 7.4.362]
-rw-r--r--src/nvim/buffer_defs.h23
-rw-r--r--src/nvim/eval.c74
-rw-r--r--src/nvim/ex_docmd.c2
-rw-r--r--src/nvim/screen.c176
-rw-r--r--src/nvim/testdir/test63.in25
-rw-r--r--src/nvim/testdir/test63.ok3
-rw-r--r--src/nvim/version.c10
-rw-r--r--src/nvim/window.c128
8 files changed, 369 insertions, 72 deletions
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index 3b12925119..de1b0985bb 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -880,6 +880,28 @@ typedef struct {
proftime_T tm; /* for a time limit */
} match_T;
+/// number of positions supported by matchaddpos()
+#define MAXPOSMATCH 8
+
+/// Same as lpos_T, but with additional field len.
+typedef struct
+{
+ linenr_T lnum; ///< line number
+ colnr_T col; ///< column number
+ int len; ///< length: 0 - to the end of line
+} llpos_T;
+
+/// posmatch_T provides an array for storing match items for matchaddpos()
+/// function.
+typedef struct posmatch posmatch_T;
+struct posmatch
+{
+ llpos_T pos[MAXPOSMATCH]; ///< array of positions
+ int cur; ///< internal position counter
+ linenr_T toplnum; ///< top buffer line
+ linenr_T botlnum; ///< bottom buffer line
+};
+
/*
* matchitem_T provides a linked list for storing match items for ":match" and
* the match functions.
@@ -892,6 +914,7 @@ struct matchitem {
char_u *pattern; /* pattern to highlight */
int hlg_id; /* highlight group ID */
regmmatch_T match; /* regexp program for pattern */
+ posmatch_T pos; // position matches
match_T hl; /* struct for doing the actual highlighting */
};
diff --git a/src/nvim/eval.c b/src/nvim/eval.c
index a9570ecc84..a61f082e59 100644
--- a/src/nvim/eval.c
+++ b/src/nvim/eval.c
@@ -6456,6 +6456,7 @@ static struct fst {
{"mapcheck", 1, 3, f_mapcheck},
{"match", 2, 4, f_match},
{"matchadd", 2, 4, f_matchadd},
+ {"matchaddpos", 2, 4, f_matchaddpos},
{"matcharg", 1, 1, f_matcharg},
{"matchdelete", 1, 1, f_matchdelete},
{"matchend", 2, 4, f_matchend},
@@ -9301,12 +9302,34 @@ static void f_getline(typval_T *argvars, typval_T *rettv)
static void f_getmatches(typval_T *argvars, typval_T *rettv)
{
matchitem_T *cur = curwin->w_match_head;
+ int i;
rettv_list_alloc(rettv);
while (cur != NULL) {
dict_T *dict = dict_alloc();
+ if (cur->match.regprog == NULL) {
+ // match added with matchaddpos()
+ for (i = 0; i < MAXPOSMATCH; ++i) {
+ llpos_T *llpos;
+ char buf[6];
+
+ llpos = &cur->pos.pos[i];
+ if (llpos->lnum == 0) {
+ break;
+ }
+ list_T *l = list_alloc();
+ list_append_number(l, (varnumber_T)llpos->lnum);
+ if (llpos->col > 0) {
+ list_append_number(l, (varnumber_T)llpos->col);
+ list_append_number(l, (varnumber_T)llpos->len);
+ }
+ sprintf(buf, "pos%d", i + 1);
+ dict_add_list(dict, buf, l);
+ }
+ } else {
+ dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
+ }
dict_add_nr_str(dict, "group", 0L, syn_id2name(cur->hlg_id));
- dict_add_nr_str(dict, "pattern", 0L, cur->pattern);
dict_add_nr_str(dict, "priority", (long)cur->priority, NULL);
dict_add_nr_str(dict, "id", (long)cur->id, NULL);
list_append_dict(rettv->vval.v_list, dict);
@@ -11105,7 +11128,52 @@ static void f_matchadd(typval_T *argvars, typval_T *rettv)
return;
}
- rettv->vval.v_number = match_add(curwin, grp, pat, prio, id);
+ rettv->vval.v_number = match_add(curwin, grp, pat, prio, id, NULL);
+}
+
+static void f_matchaddpos(typval_T *argvars, typval_T *rettv) FUNC_ATTR_NONNULL_ALL
+{
+ rettv->vval.v_number = -1;
+
+ char_u buf[NUMBUFLEN];
+ char_u *group;
+ group = get_tv_string_buf_chk(&argvars[0], buf);
+ if (group == NULL) {
+ return;
+ }
+
+ if (argvars[1].v_type != VAR_LIST) {
+ EMSG2(_(e_listarg), "matchaddpos()");
+ return;
+ }
+
+ list_T *l;
+ l = argvars[1].vval.v_list;
+ if (l == NULL) {
+ return;
+ }
+
+ int error = false;
+ int prio = 10;
+ int id = -1;
+
+ if (argvars[2].v_type != VAR_UNKNOWN) {
+ prio = get_tv_number_chk(&argvars[2], &error);
+ if (argvars[3].v_type != VAR_UNKNOWN) {
+ id = get_tv_number_chk(&argvars[3], &error);
+ }
+ }
+ if (error == true) {
+ return;
+ }
+
+ // id == 3 is ok because matchaddpos() is supposed to substitute :3match
+ if (id == 1 || id == 2) {
+ EMSGN("E798: ID is reserved for \"match\": %" PRId64, id);
+ return;
+ }
+
+ rettv->vval.v_number = match_add(curwin, group, NULL, prio, id, l);
}
/*
@@ -12927,7 +12995,7 @@ static void f_setmatches(typval_T *argvars, typval_T *rettv)
match_add(curwin, get_dict_string(d, (char_u *)"group", FALSE),
get_dict_string(d, (char_u *)"pattern", FALSE),
(int)get_dict_number(d, (char_u *)"priority"),
- (int)get_dict_number(d, (char_u *)"id"));
+ (int)get_dict_number(d, (char_u *)"id"), NULL);
li = li->li_next;
}
rettv->vval.v_number = 0;
diff --git a/src/nvim/ex_docmd.c b/src/nvim/ex_docmd.c
index ab7add1c5b..2dc5ad436d 100644
--- a/src/nvim/ex_docmd.c
+++ b/src/nvim/ex_docmd.c
@@ -8859,7 +8859,7 @@ static void ex_match(exarg_T *eap)
c = *end;
*end = NUL;
- match_add(curwin, g, p + 1, 10, id);
+ match_add(curwin, g, p + 1, 10, id, NULL);
free(g);
*end = c;
}
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index 811f265902..91db983525 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -2658,38 +2658,42 @@ win_line (
shl->startcol = MAXCOL;
shl->endcol = MAXCOL;
shl->attr_cur = 0;
- if (shl->rm.regprog != NULL) {
- v = (long)(ptr - line);
- next_search_hl(wp, shl, lnum, (colnr_T)v);
+ v = (long)(ptr - line);
+ if (cur != NULL) {
+ cur->pos.cur = 0;
+ }
+ next_search_hl(wp, shl, lnum, (colnr_T)v, cur);
- /* Need to get the line again, a multi-line regexp may have made it
- * invalid. */
- line = ml_get_buf(wp->w_buffer, lnum, FALSE);
- ptr = line + v;
+ // Need to get the line again, a multi-line regexp may have made it
+ // invalid.
+ line = ml_get_buf(wp->w_buffer, lnum, false);
+ ptr = line + v;
- if (shl->lnum != 0 && shl->lnum <= lnum) {
- if (shl->lnum == lnum)
- shl->startcol = shl->rm.startpos[0].col;
- else
- shl->startcol = 0;
- if (lnum == shl->lnum + shl->rm.endpos[0].lnum
- - shl->rm.startpos[0].lnum)
+ if (shl->lnum != 0 && shl->lnum <= lnum) {
+ if (shl->lnum == lnum) {
+ shl->startcol = shl->rm.startpos[0].col;
+ } else {
+ shl->startcol = 0;
+ }
+ if (lnum == shl->lnum + shl->rm.endpos[0].lnum
+ - shl->rm.startpos[0].lnum) {
shl->endcol = shl->rm.endpos[0].col;
- else
+ } else {
shl->endcol = MAXCOL;
- /* Highlight one character for an empty match. */
- if (shl->startcol == shl->endcol) {
- if (has_mbyte && line[shl->endcol] != NUL)
- shl->endcol += (*mb_ptr2len)(line + shl->endcol);
- else
- ++shl->endcol;
- }
- if ((long)shl->startcol < v) { /* match at leftcol */
- shl->attr_cur = shl->attr;
- search_attr = shl->attr;
- }
- area_highlighting = TRUE;
}
+ // Highlight one character for an empty match.
+ if (shl->startcol == shl->endcol) {
+ if (has_mbyte && line[shl->endcol] != NUL) {
+ shl->endcol += (*mb_ptr2len)(line + shl->endcol);
+ } else {
+ ++shl->endcol;
+ }
+ }
+ if ((long)shl->startcol < v) { // match at leftcol
+ shl->attr_cur = shl->attr;
+ search_attr = shl->attr;
+ }
+ area_highlighting = true;
}
if (shl != &search_hl && cur != NULL)
cur = cur->next;
@@ -2699,9 +2703,9 @@ win_line (
* when Visual mode is active, because it's not clear what is selected
* then. */
if (wp->w_p_cul && lnum == wp->w_cursor.lnum
- && !(wp == curwin && VIsual_active)) {
+ && !(wp == curwin && VIsual_active)) {
line_attr = hl_attr(HLF_CUL);
- area_highlighting = TRUE;
+ area_highlighting = true;
}
off = (unsigned)(current_ScreenLine - ScreenLines);
@@ -2942,15 +2946,22 @@ win_line (
shl_flag = TRUE;
} else
shl = &cur->hl;
- while (shl->rm.regprog != NULL) {
+ if (cur != NULL) {
+ cur->pos.cur = 0;
+ }
+ bool pos_inprogress = true; // mark that a position match search is
+ // in progress
+ while (shl->rm.regprog != NULL
+ || (cur != NULL && pos_inprogress)) {
if (shl->startcol != MAXCOL
&& v >= (long)shl->startcol
&& v < (long)shl->endcol) {
shl->attr_cur = shl->attr;
- } else if (v == (long)shl->endcol) {
+ } else if (v >= (long)shl->endcol) {
shl->attr_cur = 0;
- next_search_hl(wp, shl, lnum, (colnr_T)v);
+ next_search_hl(wp, shl, lnum, (colnr_T)v, cur);
+ pos_inprogress = !(cur == NULL || cur->pos.cur == 0);
/* Need to get the line again, a multi-line regexp
* may have made it invalid. */
@@ -5602,9 +5613,16 @@ static void prepare_search_hl(win_T *wp, linenr_T lnum)
NULL, NULL, TRUE, NULL))
break;
}
+ if (cur != NULL) {
+ cur->pos.cur = 0;
+ }
+ bool pos_inprogress = true; // mark that a position match search is
+ // in progress
n = 0;
- while (shl->first_lnum < lnum && shl->rm.regprog != NULL) {
- next_search_hl(wp, shl, shl->first_lnum, (colnr_T)n);
+ while (shl->first_lnum < lnum && (shl->rm.regprog != NULL
+ || (cur != NULL && pos_inprogress))) {
+ next_search_hl(wp, shl, shl->first_lnum, (colnr_T)n, cur);
+ pos_inprogress = !(cur == NULL || cur->pos.cur == 0);
if (shl->lnum != 0) {
shl->first_lnum = shl->lnum
+ shl->rm.endpos[0].lnum
@@ -5634,12 +5652,13 @@ next_search_hl (
win_T *win,
match_T *shl, /* points to search_hl or a match */
linenr_T lnum,
- colnr_T mincol /* minimal column for a match */
+ colnr_T mincol, /* minimal column for a match */
+ matchitem_T *cur /* to retrieve match positions if any */
)
{
linenr_T l;
colnr_T matchcol;
- long nmatched;
+ long nmatched = 0;
if (shl->lnum != 0) {
/* Check for three situations:
@@ -5674,8 +5693,8 @@ next_search_hl (
if (shl->lnum == 0)
matchcol = 0;
else if (vim_strchr(p_cpo, CPO_SEARCH) == NULL
- || (shl->rm.endpos[0].lnum == 0
- && shl->rm.endpos[0].col <= shl->rm.startpos[0].col)) {
+ || (shl->rm.endpos[0].lnum == 0
+ && shl->rm.endpos[0].col <= shl->rm.startpos[0].col)) {
char_u *ml;
matchcol = shl->rm.startpos[0].col;
@@ -5693,20 +5712,22 @@ next_search_hl (
matchcol = shl->rm.endpos[0].col;
shl->lnum = lnum;
- nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol,
- &(shl->tm)
- );
- if (called_emsg || got_int) {
- /* Error while handling regexp: stop using this regexp. */
- if (shl == &search_hl) {
- /* don't free regprog in the match list, it's a copy */
- vim_regfree(shl->rm.regprog);
- SET_NO_HLSEARCH(TRUE);
+ if (shl->rm.regprog != NULL) {
+ nmatched = vim_regexec_multi(&shl->rm, win, shl->buf, lnum, matchcol, &(shl->tm));
+ if (called_emsg || got_int) {
+ // Error while handling regexp: stop using this regexp.
+ if (shl == &search_hl) {
+ // don't free regprog in the match list, it's a copy
+ vim_regfree(shl->rm.regprog);
+ SET_NO_HLSEARCH(TRUE);
+ }
+ shl->rm.regprog = NULL;
+ shl->lnum = 0;
+ got_int = FALSE; // avoid the "Type :quit to exit Vim" message
+ break;
}
- shl->rm.regprog = NULL;
- shl->lnum = 0;
- got_int = FALSE; /* avoid the "Type :quit to exit Vim" message */
- break;
+ } else if (cur != NULL) {
+ nmatched = next_search_hl_pos(shl, lnum, &(cur->pos), matchcol);
}
if (nmatched == 0) {
shl->lnum = 0; /* no match found */
@@ -5722,6 +5743,59 @@ next_search_hl (
}
}
+static int
+next_search_hl_pos(
+ match_T *shl, // points to a match
+ linenr_T lnum,
+ posmatch_T *posmatch, // match positions
+ colnr_T mincol // minimal column for a match
+)
+{
+ int i;
+ int bot = -1;
+
+ shl->lnum = 0;
+ for (i = posmatch->cur; i < MAXPOSMATCH; i++) {
+ if (posmatch->pos[i].lnum == 0) {
+ break;
+ }
+ if (posmatch->pos[i].col < mincol) {
+ continue;
+ }
+ if (posmatch->pos[i].lnum == lnum) {
+ if (shl->lnum == lnum) {
+ // partially sort positions by column numbers
+ // on the same line
+ if (posmatch->pos[i].col < posmatch->pos[bot].col) {
+ llpos_T tmp = posmatch->pos[i];
+
+ posmatch->pos[i] = posmatch->pos[bot];
+ posmatch->pos[bot] = tmp;
+ }
+ } else {
+ bot = i;
+ shl->lnum = lnum;
+ }
+ }
+ }
+ posmatch->cur = 0;
+ if (shl->lnum == lnum) {
+ colnr_T start = posmatch->pos[bot].col == 0
+ ? 0: posmatch->pos[bot].col - 1;
+ colnr_T end = posmatch->pos[bot].col == 0
+ ? MAXCOL : start + posmatch->pos[bot].len;
+
+ shl->rm.startpos[0].lnum = 0;
+ shl->rm.startpos[0].col = start;
+ shl->rm.endpos[0].lnum = 0;
+ shl->rm.endpos[0].col = end;
+ posmatch->cur = bot + 1;
+ return true;
+ }
+ return false;
+}
+
+
static void screen_start_highlight(int attr)
{
attrentry_T *aep = NULL;
diff --git a/src/nvim/testdir/test63.in b/src/nvim/testdir/test63.in
index 74339c3e35..ea66ee6dea 100644
--- a/src/nvim/testdir/test63.in
+++ b/src/nvim/testdir/test63.in
@@ -1,5 +1,5 @@
Test for ":match", ":2match", ":3match", "clearmatches()", "getmatches()",
-"matchadd()", "matcharg()", "matchdelete()", and "setmatches()".
+"matchadd()", "matchaddpos()", "matcharg()", "matchdelete()", and "setmatches()".
STARTTEST
:so small.vim
@@ -147,9 +147,26 @@ STARTTEST
:unlet rf1
:unlet rf2
:unlet rf3
-:highlight clear MyGroup1
-:highlight clear MyGroup2
-:highlight clear MyGroup3
+:" --- Check that "matchaddpos()" positions matches correctly
+:let @r .= "*** Test 11:\n"
+:set nolazyredraw
+:call setline(1, 'abcdefghijklmnopq')
+:call matchaddpos("MyGroup1", [[1, 5], [1, 8, 3]], 10, 3)
+:1
+:redraw!
+:let v1 = screenattr(1, 1)
+:let v5 = screenattr(1, 5)
+:let v6 = screenattr(1, 6)
+:let v8 = screenattr(1, 8)
+:let v10 = screenattr(1, 10)
+:let v11 = screenattr(1, 11)
+:let @r .= string(getmatches())."\n"
+:if v1 != v5 && v6 == v1 && v8 == v5 && v10 == v5 && v11 == v1
+: let @r .= "OK\n"
+:else
+: let @r .= "FAILED\n"
+:endif
+:call clearmatches()
G"rp
:/^Results/,$wq! test.out
ENDTEST
diff --git a/src/nvim/testdir/test63.ok b/src/nvim/testdir/test63.ok
index 14973985eb..f804b693ac 100644
--- a/src/nvim/testdir/test63.ok
+++ b/src/nvim/testdir/test63.ok
@@ -9,3 +9,6 @@ Results of test63:
*** Test 8: OK
*** Test 9: OK
*** Test 10: OK
+*** Test 11:
+[{'group': 'MyGroup1', 'id': 3, 'priority': 10, 'pos1': [1, 5, 1], 'pos2': [1, 8, 3]}]
+OK
diff --git a/src/nvim/version.c b/src/nvim/version.c
index b164f94bb1..75b4ac4b4d 100644
--- a/src/nvim/version.c
+++ b/src/nvim/version.c
@@ -233,7 +233,7 @@ static int included_patches[] = {
//365,
//364,
//363,
- //362,
+ 362,
//361,
//360,
//359,
@@ -251,8 +251,8 @@ static int included_patches[] = {
//347,
346,
//345,
- //344,
- //343,
+ 344,
+ 343,
//342 NA
//341,
//340 NA
@@ -261,11 +261,11 @@ static int included_patches[] = {
//337,
//336,
335,
- //334,
+ 334,
//333 NA
//332 NA
331,
- //330,
+ 330,
329,
328,
327,
diff --git a/src/nvim/window.c b/src/nvim/window.c
index 3499b14688..becc21be89 100644
--- a/src/nvim/window.c
+++ b/src/nvim/window.c
@@ -5190,16 +5190,18 @@ void restore_buffer(buf_T *save_curbuf)
* If no particular ID is desired, -1 must be specified for 'id'.
* Return ID of added match, -1 on failure.
*/
-int match_add(win_T *wp, char_u *grp, char_u *pat, int prio, int id)
+int match_add(win_T *wp, char_u *grp, char_u *pat, int prio, int id, list_T *pos_list)
{
matchitem_T *cur;
matchitem_T *prev;
matchitem_T *m;
int hlg_id;
- regprog_T *regprog;
+ regprog_T *regprog = NULL;
+ int rtype = SOME_VALID;
- if (*grp == NUL || *pat == NUL)
+ if (*grp == NUL || (pat != NULL && *pat == NUL)) {
return -1;
+ }
if (id < -1 || id == 0) {
EMSGN("E799: Invalid ID: %" PRId64
" (must be greater than or equal to 1)",
@@ -5220,7 +5222,7 @@ int match_add(win_T *wp, char_u *grp, char_u *pat, int prio, int id)
EMSG2(_(e_nogroup), grp);
return -1;
}
- if ((regprog = vim_regcomp(pat, RE_MAGIC)) == NULL) {
+ if (pat != NULL && (regprog = vim_regcomp(pat, RE_MAGIC)) == NULL) {
EMSG2(_(e_invarg2), pat);
return -1;
}
@@ -5236,15 +5238,105 @@ int match_add(win_T *wp, char_u *grp, char_u *pat, int prio, int id)
}
/* Build new match. */
- m = xmalloc(sizeof(matchitem_T));
+ m = xcalloc(1, sizeof(matchitem_T));
m->id = id;
m->priority = prio;
- m->pattern = vim_strsave(pat);
+ m->pattern = pat == NULL ? NULL: vim_strsave(pat);
m->hlg_id = hlg_id;
m->match.regprog = regprog;
m->match.rmm_ic = FALSE;
m->match.rmm_maxcol = 0;
+ // Set up position matches
+ if (pos_list != NULL)
+ {
+ linenr_T toplnum = 0;
+ linenr_T botlnum = 0;
+ listitem_T *li;
+ int i;
+
+ for (i = 0, li = pos_list->lv_first; li != NULL && i < MAXPOSMATCH;
+ i++, li = li->li_next) {
+ linenr_T lnum = 0;
+ colnr_T col = 0;
+ int len = 1;
+ list_T *subl;
+ listitem_T *subli;
+ int error = false;
+
+ if (li->li_tv.v_type == VAR_LIST) {
+ subl = li->li_tv.vval.v_list;
+ if (subl == NULL) {
+ goto fail;
+ }
+ subli = subl->lv_first;
+ if (subli == NULL) {
+ goto fail;
+ }
+ lnum = get_tv_number_chk(&subli->li_tv, &error);
+ if (error == true) {
+ goto fail;
+ }
+ if (lnum == 0) {
+ --i;
+ continue;
+ }
+ m->pos.pos[i].lnum = lnum;
+ subli = subli->li_next;
+ if (subli != NULL) {
+ col = get_tv_number_chk(&subli->li_tv, &error);
+ if (error == true)
+ goto fail;
+ subli = subli->li_next;
+ if (subli != NULL) {
+ len = get_tv_number_chk(&subli->li_tv, &error);
+ if (error == true) {
+ goto fail;
+ }
+ }
+ }
+ m->pos.pos[i].col = col;
+ m->pos.pos[i].len = len;
+ } else if (li->li_tv.v_type == VAR_NUMBER) {
+ if (li->li_tv.vval.v_number == 0) {
+ --i;
+ continue;
+ }
+ m->pos.pos[i].lnum = li->li_tv.vval.v_number;
+ m->pos.pos[i].col = 0;
+ m->pos.pos[i].len = 0;
+ } else {
+ EMSG(_("List or number required"));
+ goto fail;
+ }
+ if (toplnum == 0 || lnum < toplnum) {
+ toplnum = lnum;
+ }
+ if (botlnum == 0 || lnum >= botlnum) {
+ botlnum = lnum + 1;
+ }
+ }
+
+ // Calculate top and bottom lines for redrawing area
+ if (toplnum != 0){
+ if (wp->w_buffer->b_mod_set) {
+ if (wp->w_buffer->b_mod_top > toplnum) {
+ wp->w_buffer->b_mod_top = toplnum;
+ }
+ if (wp->w_buffer->b_mod_bot < botlnum) {
+ wp->w_buffer->b_mod_bot = botlnum;
+ }
+ } else {
+ wp->w_buffer->b_mod_top = toplnum;
+ wp->w_buffer->b_mod_bot = botlnum;
+ }
+ m->pos.toplnum = toplnum;
+ m->pos.botlnum = botlnum;
+ wp->w_buffer->b_mod_set = TRUE;
+ rtype = VALID;
+ }
+ }
+
/* Insert new match. The match list is in ascending order with regard to
* the match priorities. */
cur = wp->w_match_head;
@@ -5259,8 +5351,12 @@ int match_add(win_T *wp, char_u *grp, char_u *pat, int prio, int id)
prev->next = m;
m->next = cur;
- redraw_later(SOME_VALID);
+ redraw_later(rtype);
return id;
+
+fail:
+ free(m);
+ return -1;
}
/*
@@ -5271,6 +5367,7 @@ int match_delete(win_T *wp, int id, int perr)
{
matchitem_T *cur = wp->w_match_head;
matchitem_T *prev = cur;
+ int rtype = SOME_VALID;
if (id < 1) {
if (perr == TRUE)
@@ -5294,8 +5391,23 @@ int match_delete(win_T *wp, int id, int perr)
prev->next = cur->next;
vim_regfree(cur->match.regprog);
free(cur->pattern);
+ if (cur->pos.toplnum != 0) {
+ if (wp->w_buffer->b_mod_set) {
+ if (wp->w_buffer->b_mod_top > cur->pos.toplnum) {
+ wp->w_buffer->b_mod_top = cur->pos.toplnum;
+ }
+ if (wp->w_buffer->b_mod_bot < cur->pos.botlnum) {
+ wp->w_buffer->b_mod_bot = cur->pos.botlnum;
+ }
+ } else {
+ wp->w_buffer->b_mod_top = cur->pos.toplnum;
+ wp->w_buffer->b_mod_bot = cur->pos.botlnum;
+ }
+ wp->w_buffer->b_mod_set = TRUE;
+ rtype = VALID;
+ }
free(cur);
- redraw_later(SOME_VALID);
+ redraw_later(rtype);
return 0;
}