Skip to content
Permalink
Browse files

patch 8.1.0862: no verbose version of character classes

Problem:    No verbose version of character classes.
Solution:   Add [:ident:], [:keyword:] and [:fname:]. (Ozaki Kiichi,
            closes #1373)
  • Loading branch information...
brammool committed Jan 31, 2019
1 parent 60f807b commit 221cd9f4dd866503777b2fffa721c1403716ad63
Showing with 120 additions and 1 deletion.
  1. +3 −0 runtime/doc/pattern.txt
  2. +32 −0 src/regexp.c
  3. +28 −1 src/regexp_nfa.c
  4. +55 −0 src/testdir/test_regexp_utf8.vim
  5. +2 −0 src/version.c
@@ -1118,6 +1118,9 @@ x A single character, with no special meaning, matches itself
*[:tab:]* [:tab:] the <Tab> character
*[:escape:]* [:escape:] the <Esc> character
*[:backspace:]* [:backspace:] the <BS> character
*[:ident:]* [:ident:] identifier character (same as "\i")
*[:keyword:]* [:keyword:] keyword character (same as "\k")
*[:fname:]* [:fname:] file name character (same as "\f")
The brackets in character class expressions are additional to the
brackets delimiting a collection. For example, the following is a
plausible pattern for a UNIX filename: "[-./[:alnum:]_~]\+" That is,
@@ -484,6 +484,12 @@ get_char_class(char_u **pp)
#define CLASS_BACKSPACE 14
"escape:]",
#define CLASS_ESCAPE 15
"ident:]",
#define CLASS_IDENT 16
"keyword:]",
#define CLASS_KEYWORD 17
"fname:]",
#define CLASS_FNAME 18
};
#define CLASS_NONE 99
int i;
@@ -698,6 +704,7 @@ static char_u *re_put_long(char_u *pr, long_u val);
static int read_limits(long *, long *);
static void regtail(char_u *, char_u *);
static void regoptail(char_u *, char_u *);
static int reg_iswordc(int);

static regengine_T bt_regengine;
static regengine_T nfa_regengine;
@@ -2545,6 +2552,21 @@ regatom(int *flagp)
case CLASS_ESCAPE:
regc('\033');
break;
case CLASS_IDENT:
for (cu = 1; cu <= 255; cu++)
if (vim_isIDc(cu))
regmbc(cu);
break;
case CLASS_KEYWORD:
for (cu = 1; cu <= 255; cu++)
if (reg_iswordc(cu))
regmbc(cu);
break;
case CLASS_FNAME:
for (cu = 1; cu <= 255; cu++)
if (vim_isfilec(cu))
regmbc(cu);
break;
}
}
else
@@ -3589,6 +3611,16 @@ free_regexp_stuff(void)
}
#endif

/*
* Return TRUE if character 'c' is included in 'iskeyword' option for
* "reg_buf" buffer.
*/
static int
reg_iswordc(int c)
{
return vim_iswordc_buf(c, rex.reg_buf);
}

/*
* Get pointer to the line "lnum", which is relative to "reg_firstlnum".
*/
@@ -226,7 +226,10 @@ enum
NFA_CLASS_TAB,
NFA_CLASS_RETURN,
NFA_CLASS_BACKSPACE,
NFA_CLASS_ESCAPE
NFA_CLASS_ESCAPE,
NFA_CLASS_IDENT,
NFA_CLASS_KEYWORD,
NFA_CLASS_FNAME
};

/* Keep in sync with classchars. */
@@ -1718,6 +1721,15 @@ nfa_regatom(void)
case CLASS_ESCAPE:
EMIT(NFA_CLASS_ESCAPE);
break;
case CLASS_IDENT:
EMIT(NFA_CLASS_IDENT);
break;
case CLASS_KEYWORD:
EMIT(NFA_CLASS_KEYWORD);
break;
case CLASS_FNAME:
EMIT(NFA_CLASS_FNAME);
break;
}
EMIT(NFA_CONCAT);
continue;
@@ -2555,6 +2567,9 @@ nfa_set_code(int c)
case NFA_CLASS_RETURN: STRCPY(code, "NFA_CLASS_RETURN"); break;
case NFA_CLASS_BACKSPACE: STRCPY(code, "NFA_CLASS_BACKSPACE"); break;
case NFA_CLASS_ESCAPE: STRCPY(code, "NFA_CLASS_ESCAPE"); break;
case NFA_CLASS_IDENT: STRCPY(code, "NFA_CLASS_IDENT"); break;
case NFA_CLASS_KEYWORD: STRCPY(code, "NFA_CLASS_KEYWORD"); break;
case NFA_CLASS_FNAME: STRCPY(code, "NFA_CLASS_FNAME"); break;

case NFA_ANY: STRCPY(code, "NFA_ANY"); break;
case NFA_IDENT: STRCPY(code, "NFA_IDENT"); break;
@@ -4846,6 +4861,18 @@ check_char_class(int class, int c)
if (c == '\033')
return OK;
break;
case NFA_CLASS_IDENT:
if (vim_isIDc(c))
return OK;
break;
case NFA_CLASS_KEYWORD:
if (reg_iswordc(c))
return OK;
break;
case NFA_CLASS_FNAME:
if (vim_isfilec(c))
return OK;
break;

default:
/* should not be here :P */
@@ -51,6 +51,12 @@ func s:classes_test()
let tabchar = ''
let upperchars = ''
let xdigitchars = ''
let identchars = ''
let identchars1 = ''
let kwordchars = ''
let kwordchars1 = ''
let fnamechars = ''
let fnamechars1 = ''
let i = 1
while i <= 255
let c = nr2char(i)
@@ -102,6 +108,24 @@ func s:classes_test()
if c =~ '[[:xdigit:]]'
let xdigitchars .= c
endif
if c =~ '[[:ident:]]'
let identchars .= c
endif
if c =~ '\i'
let identchars1 .= c
endif
if c =~ '[[:keyword:]]'
let kwordchars .= c
endif
if c =~ '\k'
let kwordchars1 .= c
endif
if c =~ '[[:fname:]]'
let fnamechars .= c
endif
if c =~ '\f'
let fnamechars1 .= c
endif
let i += 1
endwhile

@@ -121,6 +145,37 @@ func s:classes_test()
call assert_equal("\t\n\x0b\f\r ", spacechars)
call assert_equal("\t", tabchar)
call assert_equal('0123456789ABCDEFabcdef', xdigitchars)

if has('win32')
let identchars_ok = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
let kwordchars_ok = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyzµÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
elseif has('ebcdic')
let identchars_ok = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz€ŒŽœž¬®µº¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
let kwordchars_ok = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz€ŒŽœž¬®µº¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
else
let identchars_ok = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyzµÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
let kwordchars_ok = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyzµÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
endif

if has('win32')
let fnamechars_ok = '!#$%+,-./0123456789:=@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]_abcdefghijklmnopqrstuvwxyz{}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
elseif has('amiga')
let fnamechars_ok = '$+,-./0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
elseif has('vms')
let fnamechars_ok = '#$%+,-./0123456789:;<>ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
elseif has('ebcdic')
let fnamechars_ok = '#$%+,-./=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
else
let fnamechars_ok = '#$%+,-./0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
endif

call assert_equal(identchars_ok, identchars)
call assert_equal(kwordchars_ok, kwordchars)
call assert_equal(fnamechars_ok, fnamechars)

call assert_equal(identchars1, identchars)
call assert_equal(kwordchars1, kwordchars)
call assert_equal(fnamechars1, fnamechars)
endfunc

func Test_classes_re1()
@@ -783,6 +783,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
862,
/**/
861,
/**/

0 comments on commit 221cd9f

Please sign in to comment.
You can’t perform that action at this time.