]> granicus.if.org Git - vim/commitdiff
patch 8.1.0862: no verbose version of character classes v8.1.0862
authorBram Moolenaar <Bram@vim.org>
Thu, 31 Jan 2019 14:34:40 +0000 (15:34 +0100)
committerBram Moolenaar <Bram@vim.org>
Thu, 31 Jan 2019 14:34:40 +0000 (15:34 +0100)
Problem:    No verbose version of character classes.
Solution:   Add [:ident:], [:keyword:] and [:fname:]. (Ozaki Kiichi,
            closes #1373)

runtime/doc/pattern.txt
src/regexp.c
src/regexp_nfa.c
src/testdir/test_regexp_utf8.vim
src/version.c

index b0c7f2e6a8ab4a334eb1e3ffb26de8422e523e03..f17db96829ec147915a2880ae780dbb723718256 100644 (file)
@@ -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,
index 20894ea72d5d1fc1aab4320d43fb48c6f5cb8be4..9e6cf702d9a94af553da0e8743909bdce15bd1ba 100644 (file)
@@ -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 @@ collection:
                            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".
  */
index 863ad6cacafe18f536df1908380e99b3bffa0738..031a6cf207cd532a252704592aee3afd147bce29 100644 (file)
@@ -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 @@ collection:
                                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 */
index f618870315f9bdb0f2f219512ee7ab6351c32b4b..98b9e73de603259a82e8af8b9b5493caac642bf5 100644 (file)
@@ -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\80\81\82\83\84\85\86\87\88\89\8a\8b\8c\8d\8e\8f\90\91\92\93\94\95\96\97\98\99\9a\9b\9c\9d\9e\9f ¡¢£¤¥¦§µÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõöøùúûüýþÿ'
+    let kwordchars_ok = '0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyzµÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖ×ØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
+  elseif has('ebcdic')
+    let identchars_ok = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz\80\8c\8d\8e\9c\9e¬®µº¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
+    let kwordchars_ok = 'ABCDEFGHIJKLMNOPQRSTUVWXYZ_abcdefghijklmnopqrstuvwxyz\80\8c\8d\8e\9c\9e¬®µº¿ÀÁÂÃÄÅÆÇÈÉÊËÌÍÎÏÐÑÒÓÔÕÖØÙÚÛÜÝÞßàáâãäåæçèéêëìíîïðñòóôõö÷øùúûüýþÿ'
+  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()
index 6470c46705e24906ff93474c2512db82f27d8cdb..1b4eef9f4026d1d1826513adbc13a0e19d17842d 100644 (file)
@@ -783,6 +783,8 @@ static char *(features[]) =
 
 static int included_patches[] =
 {   /* Add new patch number below this line */
+/**/
+    862,
 /**/
     861,
 /**/