1
0
forked from aniani/vim

updated for version 7.3.1112

Problem:    New regexp engine: \%V not supported.
Solution:   Implement \%V.  Add tests.
This commit is contained in:
Bram Moolenaar
2013-06-04 18:28:48 +02:00
parent f811509c03
commit dacd7de3fd
5 changed files with 111 additions and 75 deletions

View File

@@ -4165,6 +4165,85 @@ reg_prev_class()
}
#endif
#ifdef FEAT_VISUAL
static int reg_match_visual __ARGS((void));
/*
* Return TRUE if the current reginput position matches the Visual area.
*/
static int
reg_match_visual()
{
pos_T top, bot;
linenr_T lnum;
colnr_T col;
win_T *wp = reg_win == NULL ? curwin : reg_win;
int mode;
colnr_T start, end;
colnr_T start2, end2;
colnr_T cols;
/* Check if the buffer is the current buffer. */
if (reg_buf != curbuf || VIsual.lnum == 0)
return FALSE;
if (VIsual_active)
{
if (lt(VIsual, wp->w_cursor))
{
top = VIsual;
bot = wp->w_cursor;
}
else
{
top = wp->w_cursor;
bot = VIsual;
}
mode = VIsual_mode;
}
else
{
if (lt(curbuf->b_visual.vi_start, curbuf->b_visual.vi_end))
{
top = curbuf->b_visual.vi_start;
bot = curbuf->b_visual.vi_end;
}
else
{
top = curbuf->b_visual.vi_end;
bot = curbuf->b_visual.vi_start;
}
mode = curbuf->b_visual.vi_mode;
}
lnum = reglnum + reg_firstlnum;
if (lnum < top.lnum || lnum > bot.lnum)
return FALSE;
if (mode == 'v')
{
col = (colnr_T)(reginput - regline);
if ((lnum == top.lnum && col < top.col)
|| (lnum == bot.lnum && col >= bot.col + (*p_sel != 'e')))
return FALSE;
}
else if (mode == Ctrl_V)
{
getvvcol(wp, &top, &start, NULL, &end);
getvvcol(wp, &bot, &start2, NULL, &end2);
if (start2 < start)
start = start2;
if (end2 > end)
end = end2;
if (top.col == MAXCOL || bot.col == MAXCOL)
end = MAXCOL;
cols = win_linetabsize(wp, regline, (colnr_T)(reginput - regline));
if (cols < start || cols > end - (*p_sel == 'e'))
return FALSE;
}
return TRUE;
}
#endif
#define ADVANCE_REGINPUT() mb_ptr_adv(reginput)
/*
@@ -4347,80 +4426,9 @@ regmatch(scan)
case RE_VISUAL:
#ifdef FEAT_VISUAL
/* Check if the buffer is the current buffer. and whether the
* position is inside the Visual area. */
if (reg_buf != curbuf || VIsual.lnum == 0)
status = RA_NOMATCH;
else
{
pos_T top, bot;
linenr_T lnum;
colnr_T col;
win_T *wp = reg_win == NULL ? curwin : reg_win;
int mode;
if (VIsual_active)
{
if (lt(VIsual, wp->w_cursor))
{
top = VIsual;
bot = wp->w_cursor;
}
else
{
top = wp->w_cursor;
bot = VIsual;
}
mode = VIsual_mode;
}
else
{
if (lt(curbuf->b_visual.vi_start, curbuf->b_visual.vi_end))
{
top = curbuf->b_visual.vi_start;
bot = curbuf->b_visual.vi_end;
}
else
{
top = curbuf->b_visual.vi_end;
bot = curbuf->b_visual.vi_start;
}
mode = curbuf->b_visual.vi_mode;
}
lnum = reglnum + reg_firstlnum;
col = (colnr_T)(reginput - regline);
if (lnum < top.lnum || lnum > bot.lnum)
status = RA_NOMATCH;
else if (mode == 'v')
{
if ((lnum == top.lnum && col < top.col)
|| (lnum == bot.lnum
&& col >= bot.col + (*p_sel != 'e')))
status = RA_NOMATCH;
}
else if (mode == Ctrl_V)
{
colnr_T start, end;
colnr_T start2, end2;
colnr_T cols;
getvvcol(wp, &top, &start, NULL, &end);
getvvcol(wp, &bot, &start2, NULL, &end2);
if (start2 < start)
start = start2;
if (end2 > end)
end = end2;
if (top.col == MAXCOL || bot.col == MAXCOL)
end = MAXCOL;
cols = win_linetabsize(wp,
regline, (colnr_T)(reginput - regline));
if (cols < start || cols > end - (*p_sel == 'e'))
status = RA_NOMATCH;
}
}
#else
status = RA_NOMATCH;
if (!reg_match_visual())
#endif
status = RA_NOMATCH;
break;
case RE_LNUM:

View File

@@ -178,6 +178,7 @@ enum
NFA_VCOL, /* Match cursor virtual column */
NFA_VCOL_GT, /* Match > cursor virtual column */
NFA_VCOL_LT, /* Match < cursor virtual column */
NFA_VISUAL, /* Match Visual area */
NFA_FIRST_NL = NFA_ANY + ADD_NL,
NFA_LAST_NL = NFA_NUPPER + ADD_NL,
@@ -960,8 +961,7 @@ nfa_regatom()
break;
case 'V':
/* TODO: not supported yet */
return FAIL;
EMIT(NFA_VISUAL);
break;
case '[':
@@ -4733,6 +4733,13 @@ nfa_regmatch(prog, start, submatch, m)
t->pim, &listidx);
break;
case NFA_VISUAL:
result = reg_match_visual();
if (result)
addstate_here(thislist, t->state->out, &t->subs,
t->pim, &listidx);
break;
default: /* regular character */
{
int c = t->state->c;

View File

@@ -458,6 +458,14 @@ y$Gop:"
:.yank
Gop:"
:"
:" Check matching Visual area
/^Visual:
jfxvfx:s/\%Ve/E/g
jV:s/\%Va/A/g
jfxfxj:s/\%Vo/O/g
:/^Visual/+1,/^Visual/+4yank
Gop:"
:"
:" Check patterns matching cursor position.
:func! Postest()
new
@@ -520,4 +528,10 @@ xxxstart2
asdfasd<yy
xxstart3
Visual:
thexe the thexethe
andaxand andaxand
oooxofor foroxooo
oooxofor foroxooo
Results of test64:

View File

@@ -857,6 +857,11 @@ OK 2 - [0-9a-zA-Z]\{8}-\([0-9a-zA-Z]\{4}-\)\{3}[0-9a-zA-Z]\{12}
ghi
xxstart3
thexE thE thExethe
AndAxAnd AndAxAnd
oooxOfOr fOrOxooo
oooxOfOr fOrOxooo
-0-
ffo
bob

View File

@@ -728,6 +728,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
1112,
/**/
1111,
/**/