changeset 15709:2e2f07561f4b v8.1.0862

patch 8.1.0862: no verbose version of character classes commit https://github.com/vim/vim/commit/221cd9f4dd866503777b2fffa721c1403716ad63 Author: Bram Moolenaar <Bram@vim.org> Date: Thu Jan 31 15:34:40 2019 +0100 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)
author Bram Moolenaar <Bram@vim.org>
date Thu, 31 Jan 2019 15:45:06 +0100
parents 8a6b91646ba7
children 83f00bd3ddb0
files runtime/doc/pattern.txt src/regexp.c src/regexp_nfa.c src/testdir/test_regexp_utf8.vim src/version.c
diffstat 5 files changed, 120 insertions(+), 1 deletions(-) [+]
line wrap: on
line diff
--- a/runtime/doc/pattern.txt
+++ b/runtime/doc/pattern.txt
@@ -1118,6 +1118,9 @@ x	A single character, with no special me
 *[: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,
--- a/src/regexp.c
+++ b/src/regexp.c
@@ -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, l
 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
@@ -3590,6 +3612,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".
  */
     static char_u *
--- a/src/regexp_nfa.c
+++ b/src/regexp_nfa.c
@@ -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 */
--- a/src/testdir/test_regexp_utf8.vim
+++ b/src/testdir/test_regexp_utf8.vim
@@ -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()
--- a/src/version.c
+++ b/src/version.c
@@ -784,6 +784,8 @@ static char *(features[]) =
 static int included_patches[] =
 {   /* Add new patch number below this line */
 /**/
+    862,
+/**/
     861,
 /**/
     860,