Skip to content

Commit 221cd9f

Browse files
committed
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)
1 parent 60f807b commit 221cd9f

5 files changed

Lines changed: 120 additions & 1 deletion

File tree

runtime/doc/pattern.txt

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1118,6 +1118,9 @@ x A single character, with no special meaning, matches itself
11181118
*[:tab:]* [:tab:] the <Tab> character
11191119
*[:escape:]* [:escape:] the <Esc> character
11201120
*[:backspace:]* [:backspace:] the <BS> character
1121+
*[:ident:]* [:ident:] identifier character (same as "\i")
1122+
*[:keyword:]* [:keyword:] keyword character (same as "\k")
1123+
*[:fname:]* [:fname:] file name character (same as "\f")
11211124
The brackets in character class expressions are additional to the
11221125
brackets delimiting a collection. For example, the following is a
11231126
plausible pattern for a UNIX filename: "[-./[:alnum:]_~]\+" That is,

src/regexp.c

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -484,6 +484,12 @@ get_char_class(char_u **pp)
484484
#define CLASS_BACKSPACE 14
485485
"escape:]",
486486
#define CLASS_ESCAPE 15
487+
"ident:]",
488+
#define CLASS_IDENT 16
489+
"keyword:]",
490+
#define CLASS_KEYWORD 17
491+
"fname:]",
492+
#define CLASS_FNAME 18
487493
};
488494
#define CLASS_NONE 99
489495
int i;
@@ -698,6 +704,7 @@ static char_u *re_put_long(char_u *pr, long_u val);
698704
static int read_limits(long *, long *);
699705
static void regtail(char_u *, char_u *);
700706
static void regoptail(char_u *, char_u *);
707+
static int reg_iswordc(int);
701708

702709
static regengine_T bt_regengine;
703710
static regengine_T nfa_regengine;
@@ -2545,6 +2552,21 @@ regatom(int *flagp)
25452552
case CLASS_ESCAPE:
25462553
regc('\033');
25472554
break;
2555+
case CLASS_IDENT:
2556+
for (cu = 1; cu <= 255; cu++)
2557+
if (vim_isIDc(cu))
2558+
regmbc(cu);
2559+
break;
2560+
case CLASS_KEYWORD:
2561+
for (cu = 1; cu <= 255; cu++)
2562+
if (reg_iswordc(cu))
2563+
regmbc(cu);
2564+
break;
2565+
case CLASS_FNAME:
2566+
for (cu = 1; cu <= 255; cu++)
2567+
if (vim_isfilec(cu))
2568+
regmbc(cu);
2569+
break;
25482570
}
25492571
}
25502572
else
@@ -3589,6 +3611,16 @@ free_regexp_stuff(void)
35893611
}
35903612
#endif
35913613

3614+
/*
3615+
* Return TRUE if character 'c' is included in 'iskeyword' option for
3616+
* "reg_buf" buffer.
3617+
*/
3618+
static int
3619+
reg_iswordc(int c)
3620+
{
3621+
return vim_iswordc_buf(c, rex.reg_buf);
3622+
}
3623+
35923624
/*
35933625
* Get pointer to the line "lnum", which is relative to "reg_firstlnum".
35943626
*/

src/regexp_nfa.c

Lines changed: 28 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -226,7 +226,10 @@ enum
226226
NFA_CLASS_TAB,
227227
NFA_CLASS_RETURN,
228228
NFA_CLASS_BACKSPACE,
229-
NFA_CLASS_ESCAPE
229+
NFA_CLASS_ESCAPE,
230+
NFA_CLASS_IDENT,
231+
NFA_CLASS_KEYWORD,
232+
NFA_CLASS_FNAME
230233
};
231234

232235
/* Keep in sync with classchars. */
@@ -1718,6 +1721,15 @@ nfa_regatom(void)
17181721
case CLASS_ESCAPE:
17191722
EMIT(NFA_CLASS_ESCAPE);
17201723
break;
1724+
case CLASS_IDENT:
1725+
EMIT(NFA_CLASS_IDENT);
1726+
break;
1727+
case CLASS_KEYWORD:
1728+
EMIT(NFA_CLASS_KEYWORD);
1729+
break;
1730+
case CLASS_FNAME:
1731+
EMIT(NFA_CLASS_FNAME);
1732+
break;
17211733
}
17221734
EMIT(NFA_CONCAT);
17231735
continue;
@@ -2555,6 +2567,9 @@ nfa_set_code(int c)
25552567
case NFA_CLASS_RETURN: STRCPY(code, "NFA_CLASS_RETURN"); break;
25562568
case NFA_CLASS_BACKSPACE: STRCPY(code, "NFA_CLASS_BACKSPACE"); break;
25572569
case NFA_CLASS_ESCAPE: STRCPY(code, "NFA_CLASS_ESCAPE"); break;
2570+
case NFA_CLASS_IDENT: STRCPY(code, "NFA_CLASS_IDENT"); break;
2571+
case NFA_CLASS_KEYWORD: STRCPY(code, "NFA_CLASS_KEYWORD"); break;
2572+
case NFA_CLASS_FNAME: STRCPY(code, "NFA_CLASS_FNAME"); break;
25582573

25592574
case NFA_ANY: STRCPY(code, "NFA_ANY"); break;
25602575
case NFA_IDENT: STRCPY(code, "NFA_IDENT"); break;
@@ -4846,6 +4861,18 @@ check_char_class(int class, int c)
48464861
if (c == '\033')
48474862
return OK;
48484863
break;
4864+
case NFA_CLASS_IDENT:
4865+
if (vim_isIDc(c))
4866+
return OK;
4867+
break;
4868+
case NFA_CLASS_KEYWORD:
4869+
if (reg_iswordc(c))
4870+
return OK;
4871+
break;
4872+
case NFA_CLASS_FNAME:
4873+
if (vim_isfilec(c))
4874+
return OK;
4875+
break;
48494876

48504877
default:
48514878
/* should not be here :P */

src/testdir/test_regexp_utf8.vim

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -51,6 +51,12 @@ func s:classes_test()
5151
let tabchar = ''
5252
let upperchars = ''
5353
let xdigitchars = ''
54+
let identchars = ''
55+
let identchars1 = ''
56+
let kwordchars = ''
57+
let kwordchars1 = ''
58+
let fnamechars = ''
59+
let fnamechars1 = ''
5460
let i = 1
5561
while i <= 255
5662
let c = nr2char(i)
@@ -102,6 +108,24 @@ func s:classes_test()
102108
if c =~ '[[:xdigit:]]'
103109
let xdigitchars .= c
104110
endif
111+
if c =~ '[[:ident:]]'
112+
let identchars .= c
113+
endif
114+
if c =~ '\i'
115+
let identchars1 .= c
116+
endif
117+
if c =~ '[[:keyword:]]'
118+
let kwordchars .= c
119+
endif
120+
if c =~ '\k'
121+
let kwordchars1 .= c
122+
endif
123+
if c =~ '[[:fname:]]'
124+
let fnamechars .= c
125+
endif
126+
if c =~ '\f'
127+
let fnamechars1 .= c
128+
endif
105129
let i += 1
106130
endwhile
107131

@@ -121,6 +145,37 @@ func s:classes_test()
121145
call assert_equal("\t\n\x0b\f\r ", spacechars)
122146
call assert_equal("\t", tabchar)
123147
call assert_equal('0123456789ABCDEFabcdef', xdigitchars)
148+
149+
if has('win32')
150+
let identchars_ok = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz€‚ƒ„…†‡ˆ‰Š‹ŒŽ‘’“”•–—˜™š›œžŸ ¡¢£¤¥¦§µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
151+
let kwordchars_ok = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyzµÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
152+
elseif has('ebcdic')
153+
let identchars_ok = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz€ŒŽœž¬®µº¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
154+
let kwordchars_ok = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz€ŒŽœž¬®µº¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
155+
else
156+
let identchars_ok = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyzµÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
157+
let kwordchars_ok = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyzµÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
158+
endif
159+
160+
if has('win32')
161+
let fnamechars_ok = '!#$%+,-./0123456789:=@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]_abcdefghijklmnopqrstuvwxyz{}~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
162+
elseif has('amiga')
163+
let fnamechars_ok = '$+,-./0123456789:ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
164+
elseif has('vms')
165+
let fnamechars_ok = '#$%+,-./0123456789:;<>ABCDEFGHIJKLMNOPQRSTUVWXYZ[]_abcdefghijklmnopqrstuvwxyz~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
166+
elseif has('ebcdic')
167+
let fnamechars_ok = '#$%+,-./=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
168+
else
169+
let fnamechars_ok = '#$%+,-./0123456789=ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz~ ¡¢£¤¥¦§¨©ª«¬­®¯°±²³´µ¶·¸¹º»¼½¾¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖרÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
170+
endif
171+
172+
call assert_equal(identchars_ok, identchars)
173+
call assert_equal(kwordchars_ok, kwordchars)
174+
call assert_equal(fnamechars_ok, fnamechars)
175+
176+
call assert_equal(identchars1, identchars)
177+
call assert_equal(kwordchars1, kwordchars)
178+
call assert_equal(fnamechars1, fnamechars)
124179
endfunc
125180

126181
func Test_classes_re1()

src/version.c

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -783,6 +783,8 @@ static char *(features[]) =
783783

784784
static int included_patches[] =
785785
{ /* Add new patch number below this line */
786+
/**/
787+
862,
786788
/**/
787789
861,
788790
/**/

0 commit comments

Comments
 (0)