summaryrefslogtreecommitdiff
path: root/src/window.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2014-06-17 17:48:32 +0200
committerBram Moolenaar <Bram@vim.org>2014-06-17 17:48:32 +0200
commitb3414595c713ca161f082776f89417faddec7d2d (patch)
tree5f03f600e04a2455ce84033c49db30b680d571c6 /src/window.c
parentec1561cac59006213dd5405d164a94dc7d002806 (diff)
downloadvim-git-b3414595c713ca161f082776f89417faddec7d2d.tar.gz
updated for version 7.4.330v7.4.330
Problem: Using a regexp pattern to highlight a specific position can be slow. Solution: Add matchaddpos() to highlight specific positions efficiently. (Alexey Radkov)
Diffstat (limited to 'src/window.c')
-rw-r--r--src/window.c147
1 files changed, 135 insertions, 12 deletions
diff --git a/src/window.c b/src/window.c
index 5215bb8e5..f76812a0e 100644
--- a/src/window.c
+++ b/src/window.c
@@ -6751,20 +6751,22 @@ win_hasvertsplit()
* Return ID of added match, -1 on failure.
*/
int
-match_add(wp, grp, pat, prio, id)
+match_add(wp, grp, pat, prio, id, pos_list)
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;
+ 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)
{
@@ -6789,7 +6791,7 @@ match_add(wp, grp, pat, prio, 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;
@@ -6810,12 +6812,111 @@ match_add(wp, grp, pat, prio, id)
m = (matchitem_T *)alloc(sizeof(matchitem_T));
m->id = id;
m->priority = prio;
- m->pattern = vim_strsave(pat);
+ m->pattern = pat == NULL ? NULL : vim_strsave(pat);
+ m->pos.cur = 0;
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; 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;
+
+ if (li == NULL)
+ {
+ m->pos.pos[i].lnum = 0;
+ break;
+ }
+ 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;
+ m->pos.pos[i].lnum = lnum;
+ if (lnum == 0)
+ {
+ --i;
+ continue;
+ }
+ 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)
+ 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;
+ }
+
+ /* 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;
@@ -6831,8 +6932,12 @@ match_add(wp, grp, pat, prio, id)
prev->next = m;
m->next = cur;
- redraw_later(SOME_VALID);
+ redraw_later(rtype);
return id;
+
+fail:
+ vim_free(m);
+ return -1;
}
/*
@@ -6845,8 +6950,9 @@ match_delete(wp, id, perr)
int id;
int perr;
{
- matchitem_T *cur = wp->w_match_head;
- matchitem_T *prev = cur;
+ matchitem_T *cur = wp->w_match_head;
+ matchitem_T *prev = cur;
+ int rtype = SOME_VALID;
if (id < 1)
{
@@ -6872,8 +6978,25 @@ match_delete(wp, id, perr)
prev->next = cur->next;
vim_regfree(cur->match.regprog);
vim_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;
+ }
vim_free(cur);
- redraw_later(SOME_VALID);
+ redraw_later(rtype);
return 0;
}