Mercurial > vim
comparison src/syntax.c @ 154:1a145815483e
updated for version 7.0047
author | vimboss |
---|---|
date | Wed, 02 Feb 2005 23:07:25 +0000 |
parents | 72aefd4c1e0d |
children | 4d9eabb1396e |
comparison
equal
deleted
inserted
replaced
153:19670b05ee32 | 154:1a145815483e |
---|---|
292 } stateitem_T; | 292 } stateitem_T; |
293 | 293 |
294 #define KEYWORD_IDX -1 /* value of si_idx for keywords */ | 294 #define KEYWORD_IDX -1 /* value of si_idx for keywords */ |
295 #define ID_LIST_ALL (short *)-1 /* valid of si_cont_list for containing all | 295 #define ID_LIST_ALL (short *)-1 /* valid of si_cont_list for containing all |
296 but contained groups */ | 296 but contained groups */ |
297 | |
298 /* | |
299 * Struct to reduce the number of arguments to get_syn_options(), it's used | |
300 * very often. | |
301 */ | |
302 typedef struct | |
303 { | |
304 int flags; /* flags for contained and transpartent */ | |
305 int keyword; /* TRUE for ":syn keyword" */ | |
306 int *sync_idx; /* syntax item for "grouphere" argument, NULL | |
307 if not allowed */ | |
308 char has_cont_list; /* TRUE if "cont_list" can be used */ | |
309 short *cont_list; /* group IDs for "contains" argument */ | |
310 short *cont_in_list; /* group IDs for "containedin" argument */ | |
311 short *next_list; /* group IDs for "nextgroup" argument */ | |
312 } syn_opt_arg_T; | |
297 | 313 |
298 /* | 314 /* |
299 * The next possible match in the current line for any pattern is remembered, | 315 * The next possible match in the current line for any pattern is remembered, |
300 * to avoid having to try for a match in each column. | 316 * to avoid having to try for a match in each column. |
301 * If next_match_idx == -1, not tried (in this line) yet. | 317 * If next_match_idx == -1, not tried (in this line) yet. |
399 static int syn_list_keywords __ARGS((int id, hashtab_T *ht, int did_header, int attr)); | 415 static int syn_list_keywords __ARGS((int id, hashtab_T *ht, int did_header, int attr)); |
400 static void syn_clear_keyword __ARGS((int id, hashtab_T *ht)); | 416 static void syn_clear_keyword __ARGS((int id, hashtab_T *ht)); |
401 static void clear_keywtab __ARGS((hashtab_T *ht)); | 417 static void clear_keywtab __ARGS((hashtab_T *ht)); |
402 static void add_keyword __ARGS((char_u *name, int id, int flags, short *cont_in_list, short *next_list)); | 418 static void add_keyword __ARGS((char_u *name, int id, int flags, short *cont_in_list, short *next_list)); |
403 static char_u *get_group_name __ARGS((char_u *arg, char_u **name_end)); | 419 static char_u *get_group_name __ARGS((char_u *arg, char_u **name_end)); |
404 static char_u *get_syn_options __ARGS((char_u *arg, int *flagsp, int keyword, int *sync_idx, short **cont_list, short **cont_in_list, short **next_list)); | 420 static char_u *get_syn_options __ARGS((char_u *arg, syn_opt_arg_T *opt)); |
405 static void syn_cmd_include __ARGS((exarg_T *eap, int syncing)); | 421 static void syn_cmd_include __ARGS((exarg_T *eap, int syncing)); |
406 static void syn_cmd_keyword __ARGS((exarg_T *eap, int syncing)); | 422 static void syn_cmd_keyword __ARGS((exarg_T *eap, int syncing)); |
407 static void syn_cmd_match __ARGS((exarg_T *eap, int syncing)); | 423 static void syn_cmd_match __ARGS((exarg_T *eap, int syncing)); |
408 static void syn_cmd_region __ARGS((exarg_T *eap, int syncing)); | 424 static void syn_cmd_region __ARGS((exarg_T *eap, int syncing)); |
409 #ifdef __BORLANDC__ | 425 #ifdef __BORLANDC__ |
3976 short *next_list; /* nextgroup for this keyword */ | 3992 short *next_list; /* nextgroup for this keyword */ |
3977 { | 3993 { |
3978 keyentry_T *kp; | 3994 keyentry_T *kp; |
3979 hashtab_T *ht; | 3995 hashtab_T *ht; |
3980 hashitem_T *hi; | 3996 hashitem_T *hi; |
3981 char_u *name_ic = name; | 3997 char_u *name_ic; |
3982 long_u hash; | 3998 long_u hash; |
3999 char_u name_folded[MAXKEYWLEN + 1]; | |
3983 | 4000 |
3984 if (curbuf->b_syn_ic) | 4001 if (curbuf->b_syn_ic) |
3985 { | 4002 name_ic = str_foldcase(name, (int)STRLEN(name), |
3986 name_ic = str_foldcase(name, (int)STRLEN(name), NULL, 0); | 4003 name_folded, MAXKEYWLEN + 1); |
3987 if (name_ic == NULL) | 4004 else |
3988 name_ic = name; | 4005 name_ic = name; |
3989 } | |
3990 kp = (keyentry_T *)alloc((int)(sizeof(keyentry_T) + STRLEN(name_ic))); | 4006 kp = (keyentry_T *)alloc((int)(sizeof(keyentry_T) + STRLEN(name_ic))); |
3991 if (kp == NULL) | 4007 if (kp == NULL) |
3992 return; | 4008 return; |
3993 STRCPY(kp->keyword, name_ic); | 4009 STRCPY(kp->keyword, name_ic); |
3994 if (name_ic != name) | |
3995 vim_free(name_ic); | |
3996 kp->k_syn.id = id; | 4010 kp->k_syn.id = id; |
3997 kp->k_syn.inc_tag = current_syn_inc_tag; | 4011 kp->k_syn.inc_tag = current_syn_inc_tag; |
3998 kp->flags = flags; | 4012 kp->flags = flags; |
3999 kp->k_syn.cont_in_list = copy_id_list(cont_in_list); | 4013 kp->k_syn.cont_in_list = copy_id_list(cont_in_list); |
4000 if (cont_in_list != NULL) | 4014 if (cont_in_list != NULL) |
4053 * collect all options in between other arguments. | 4067 * collect all options in between other arguments. |
4054 * Return a pointer to the next argument (which isn't an option). | 4068 * Return a pointer to the next argument (which isn't an option). |
4055 * Return NULL for any error; | 4069 * Return NULL for any error; |
4056 */ | 4070 */ |
4057 static char_u * | 4071 static char_u * |
4058 get_syn_options(arg, flagsp, keyword, sync_idx, cont_list, | 4072 get_syn_options(arg, opt) |
4059 cont_in_list, next_list) | 4073 char_u *arg; /* next argument to be checked */ |
4060 char_u *arg; /* next argument */ | 4074 syn_opt_arg_T *opt; /* various things */ |
4061 int *flagsp; /* flags for contained and transpartent */ | 4075 { |
4062 int keyword; /* TRUE for ":syn keyword" */ | |
4063 int *sync_idx; /* syntax item for "grouphere" argument, NULL | |
4064 if not allowed */ | |
4065 short **cont_list; /* group IDs for "contains" argument, NULL if | |
4066 not allowed */ | |
4067 short **cont_in_list; /* group IDs for "containedin" argument, NULL | |
4068 if not allowed */ | |
4069 short **next_list; /* group IDs for "nextgroup" argument */ | |
4070 { | |
4071 int flags; | |
4072 char_u *gname_start, *gname; | 4076 char_u *gname_start, *gname; |
4073 int syn_id; | 4077 int syn_id; |
4074 int len; | 4078 int len; |
4079 char *p; | |
4075 int i; | 4080 int i; |
4076 int fidx; | 4081 int fidx; |
4077 static struct flag | 4082 static struct flag |
4078 { | 4083 { |
4079 char *name; | 4084 char *name; |
4080 int len; | 4085 int argtype; |
4081 int val; | 4086 int flags; |
4082 } flagtab[] = { {"contained", 9, HL_CONTAINED}, | 4087 } flagtab[] = { {"cCoOnNtTaAiInNeEdD", 0, HL_CONTAINED}, |
4083 {"oneline", 7, HL_ONELINE}, | 4088 {"oOnNeElLiInNeE", 0, HL_ONELINE}, |
4084 {"keepend", 7, HL_KEEPEND}, | 4089 {"kKeEeEpPeEnNdD", 0, HL_KEEPEND}, |
4085 {"extend", 6, HL_EXTEND}, | 4090 {"eExXtTeEnNdD", 0, HL_EXTEND}, |
4086 {"excludenl", 9, HL_EXCLUDENL}, | 4091 {"eExXcClLuUdDeEnNlL", 0, HL_EXCLUDENL}, |
4087 {"transparent", 11, HL_TRANSP}, | 4092 {"tTrRaAnNsSpPaArReEnNtT", 0, HL_TRANSP}, |
4088 {"skipnl", 6, HL_SKIPNL}, | 4093 {"sSkKiIpPnNlL", 0, HL_SKIPNL}, |
4089 {"skipwhite", 9, HL_SKIPWHITE}, | 4094 {"sSkKiIpPwWhHiItTeE", 0, HL_SKIPWHITE}, |
4090 {"skipempty", 9, HL_SKIPEMPTY}, | 4095 {"sSkKiIpPeEmMpPtTyY", 0, HL_SKIPEMPTY}, |
4091 {"grouphere", 9, HL_SYNC_HERE}, | 4096 {"gGrRoOuUpPhHeErReE", 0, HL_SYNC_HERE}, |
4092 {"groupthere", 10, HL_SYNC_THERE}, | 4097 {"gGrRoOuUpPtThHeErReE", 0, HL_SYNC_THERE}, |
4093 {"display", 7, HL_DISPLAY}, | 4098 {"dDiIsSpPlLaAyY", 0, HL_DISPLAY}, |
4094 {"fold", 4, HL_FOLD}, | 4099 {"fFoOlLdD", 0, HL_FOLD}, |
4100 {"cCoOnNtTaAiInNsS", 1, 0}, | |
4101 {"cCoOnNtTaAiInNeEdDiInN", 2, 0}, | |
4102 {"nNeExXtTgGrRoOuUpP", 3, 0}, | |
4095 }; | 4103 }; |
4096 #define MLEN 12 | 4104 static char *first_letters = "cCoOkKeEtTsSgGdDfFnN"; |
4097 char lowname[MLEN]; | |
4098 int llen; | |
4099 | 4105 |
4100 if (arg == NULL) /* already detected error */ | 4106 if (arg == NULL) /* already detected error */ |
4101 return NULL; | 4107 return NULL; |
4102 | 4108 |
4103 flags = *flagsp; | |
4104 for (;;) | 4109 for (;;) |
4105 { | 4110 { |
4106 /* STRNICMP() is a bit slow, change arg to lowercase first and use | 4111 /* |
4107 * STRNCMP() */ | 4112 * This is used very often when a large number of keywords is defined. |
4108 for (llen = 0; llen < MLEN; ++llen) | 4113 * Need to skip quickly when no option name is found. |
4109 { | 4114 * Also avoid tolower(), it's slow. |
4110 if (!isalpha(arg[llen])) | 4115 */ |
4111 break; | 4116 if (strchr(first_letters, *arg) == NULL) |
4112 lowname[llen] = TOLOWER_ASC(arg[llen]); | 4117 break; |
4113 } | |
4114 | 4118 |
4115 for (fidx = sizeof(flagtab) / sizeof(struct flag); --fidx >= 0; ) | 4119 for (fidx = sizeof(flagtab) / sizeof(struct flag); --fidx >= 0; ) |
4116 { | 4120 { |
4117 len = flagtab[fidx].len; | 4121 p = flagtab[fidx].name; |
4118 if (len == llen | 4122 for (i = 0, len = 0; p[i] != NUL; i += 2, ++len) |
4119 && STRNCMP(lowname, flagtab[fidx].name, len) == 0 | 4123 if (arg[len] != p[i] && arg[len] != p[i + 1]) |
4120 && (ends_excmd(arg[len]) || vim_iswhite(arg[len]))) | 4124 break; |
4121 { | 4125 if (p[i] == NUL && (vim_iswhite(arg[len]) |
4122 if (keyword | 4126 || (flagtab[fidx].argtype > 0 |
4123 && (flagtab[fidx].val == HL_DISPLAY | 4127 ? arg[len] == '=' |
4124 || flagtab[fidx].val == HL_FOLD | 4128 : ends_excmd(arg[len])))) |
4125 || flagtab[fidx].val == HL_EXTEND)) | 4129 { |
4126 { | 4130 if (opt->keyword |
4131 && (flagtab[fidx].flags == HL_DISPLAY | |
4132 || flagtab[fidx].flags == HL_FOLD | |
4133 || flagtab[fidx].flags == HL_EXTEND)) | |
4127 /* treat "display", "fold" and "extend" as a keyword */ | 4134 /* treat "display", "fold" and "extend" as a keyword */ |
4128 fidx = -1; | 4135 fidx = -1; |
4129 break; | 4136 break; |
4137 } | |
4138 } | |
4139 if (fidx < 0) /* no match found */ | |
4140 break; | |
4141 | |
4142 if (flagtab[fidx].argtype == 1) | |
4143 { | |
4144 if (!opt->has_cont_list) | |
4145 { | |
4146 EMSG(_("E395: contains argument not accepted here")); | |
4147 return NULL; | |
4148 } | |
4149 if (get_id_list(&arg, 8, &opt->cont_list) == FAIL) | |
4150 return NULL; | |
4151 } | |
4152 else if (flagtab[fidx].argtype == 2) | |
4153 { | |
4154 #if 0 /* cannot happen */ | |
4155 if (opt->cont_in_list == NULL) | |
4156 { | |
4157 EMSG(_("E396: containedin argument not accepted here")); | |
4158 return NULL; | |
4159 } | |
4160 #endif | |
4161 if (get_id_list(&arg, 11, &opt->cont_in_list) == FAIL) | |
4162 return NULL; | |
4163 } | |
4164 else if (flagtab[fidx].argtype == 3) | |
4165 { | |
4166 if (get_id_list(&arg, 9, &opt->next_list) == FAIL) | |
4167 return NULL; | |
4168 } | |
4169 else | |
4170 { | |
4171 opt->flags |= flagtab[fidx].flags; | |
4172 arg = skipwhite(arg + len); | |
4173 | |
4174 if (flagtab[fidx].flags == HL_SYNC_HERE | |
4175 || flagtab[fidx].flags == HL_SYNC_THERE) | |
4176 { | |
4177 if (opt->sync_idx == NULL) | |
4178 { | |
4179 EMSG(_("E393: group[t]here not accepted here")); | |
4180 return NULL; | |
4130 } | 4181 } |
4131 | 4182 gname_start = arg; |
4132 flags |= flagtab[fidx].val; | 4183 arg = skiptowhite(arg); |
4133 arg = skipwhite(arg + len); | 4184 if (gname_start == arg) |
4134 | 4185 return NULL; |
4135 if (flagtab[fidx].val == HL_SYNC_HERE | 4186 gname = vim_strnsave(gname_start, (int)(arg - gname_start)); |
4136 || flagtab[fidx].val == HL_SYNC_THERE) | 4187 if (gname == NULL) |
4188 return NULL; | |
4189 if (STRCMP(gname, "NONE") == 0) | |
4190 *opt->sync_idx = NONE_IDX; | |
4191 else | |
4137 { | 4192 { |
4138 if (sync_idx == NULL) | 4193 syn_id = syn_name2id(gname); |
4194 for (i = curbuf->b_syn_patterns.ga_len; --i >= 0; ) | |
4195 if (SYN_ITEMS(curbuf)[i].sp_syn.id == syn_id | |
4196 && SYN_ITEMS(curbuf)[i].sp_type == SPTYPE_START) | |
4197 { | |
4198 *opt->sync_idx = i; | |
4199 break; | |
4200 } | |
4201 if (i < 0) | |
4139 { | 4202 { |
4140 EMSG(_("E393: group[t]here not accepted here")); | 4203 EMSG2(_("E394: Didn't find region item for %s"), gname); |
4204 vim_free(gname); | |
4141 return NULL; | 4205 return NULL; |
4142 } | 4206 } |
4143 gname_start = arg; | |
4144 arg = skiptowhite(arg); | |
4145 if (gname_start == arg) | |
4146 return NULL; | |
4147 gname = vim_strnsave(gname_start, (int)(arg - gname_start)); | |
4148 if (gname == NULL) | |
4149 return NULL; | |
4150 if (STRCMP(gname, "NONE") == 0) | |
4151 *sync_idx = NONE_IDX; | |
4152 else | |
4153 { | |
4154 syn_id = syn_name2id(gname); | |
4155 for (i = curbuf->b_syn_patterns.ga_len; --i >= 0; ) | |
4156 if (SYN_ITEMS(curbuf)[i].sp_syn.id == syn_id | |
4157 && SYN_ITEMS(curbuf)[i].sp_type == SPTYPE_START) | |
4158 { | |
4159 *sync_idx = i; | |
4160 break; | |
4161 } | |
4162 if (i < 0) | |
4163 { | |
4164 EMSG2(_("E394: Didn't find region item for %s"), gname); | |
4165 vim_free(gname); | |
4166 return NULL; | |
4167 } | |
4168 } | |
4169 | |
4170 vim_free(gname); | |
4171 arg = skipwhite(arg); | |
4172 } | 4207 } |
4208 | |
4209 vim_free(gname); | |
4210 arg = skipwhite(arg); | |
4211 } | |
4173 #ifdef FEAT_FOLDING | 4212 #ifdef FEAT_FOLDING |
4174 else if (flagtab[fidx].val == HL_FOLD | 4213 else if (flagtab[fidx].flags == HL_FOLD |
4175 && foldmethodIsSyntax(curwin)) | 4214 && foldmethodIsSyntax(curwin)) |
4176 { | 4215 /* Need to update folds later. */ |
4177 /* Need to update folds later. */ | 4216 foldUpdateAll(curwin); |
4178 foldUpdateAll(curwin); | |
4179 } | |
4180 #endif | 4217 #endif |
4181 break; | 4218 } |
4182 } | 4219 } |
4183 } | |
4184 if (fidx >= 0) | |
4185 continue; | |
4186 | |
4187 if (llen == 8 && STRNCMP(lowname, "contains", 8) == 0 | |
4188 && (vim_iswhite(arg[8]) || arg[8] == '=')) | |
4189 { | |
4190 if (cont_list == NULL) | |
4191 { | |
4192 EMSG(_("E395: contains argument not accepted here")); | |
4193 return NULL; | |
4194 } | |
4195 if (get_id_list(&arg, 8, cont_list) == FAIL) | |
4196 return NULL; | |
4197 } | |
4198 else if (llen == 11 && STRNCMP(lowname, "containedin", 11) == 0 | |
4199 && (vim_iswhite(arg[11]) || arg[11] == '=')) | |
4200 { | |
4201 if (cont_in_list == NULL) | |
4202 { | |
4203 EMSG(_("E396: containedin argument not accepted here")); | |
4204 return NULL; | |
4205 } | |
4206 if (get_id_list(&arg, 11, cont_in_list) == FAIL) | |
4207 return NULL; | |
4208 } | |
4209 else if (llen == 9 && STRNCMP(lowname, "nextgroup", 9) == 0 | |
4210 && (vim_iswhite(arg[9]) || arg[9] == '=')) | |
4211 { | |
4212 if (get_id_list(&arg, 9, next_list) == FAIL) | |
4213 return NULL; | |
4214 } | |
4215 else | |
4216 break; | |
4217 } | |
4218 | |
4219 *flagsp = flags; | |
4220 | 4220 |
4221 return arg; | 4221 return arg; |
4222 } | 4222 } |
4223 | 4223 |
4224 /* | 4224 /* |
4334 char_u *group_name_end; | 4334 char_u *group_name_end; |
4335 int syn_id; | 4335 int syn_id; |
4336 char_u *rest; | 4336 char_u *rest; |
4337 char_u *keyword_copy; | 4337 char_u *keyword_copy; |
4338 char_u *p; | 4338 char_u *p; |
4339 char_u *first_arg; | 4339 char_u *kw; |
4340 int round; | 4340 syn_opt_arg_T syn_opt_arg; |
4341 int flags = 0; | 4341 int cnt; |
4342 short *next_list = NULL; | |
4343 short *cont_in_list = NULL; | |
4344 | 4342 |
4345 rest = get_group_name(arg, &group_name_end); | 4343 rest = get_group_name(arg, &group_name_end); |
4346 | 4344 |
4347 if (rest != NULL) | 4345 if (rest != NULL) |
4348 { | 4346 { |
4350 | 4348 |
4351 /* allocate a buffer, for removing the backslashes in the keyword */ | 4349 /* allocate a buffer, for removing the backslashes in the keyword */ |
4352 keyword_copy = alloc((unsigned)STRLEN(rest) + 1); | 4350 keyword_copy = alloc((unsigned)STRLEN(rest) + 1); |
4353 if (keyword_copy != NULL) | 4351 if (keyword_copy != NULL) |
4354 { | 4352 { |
4353 syn_opt_arg.flags = 0; | |
4354 syn_opt_arg.keyword = TRUE; | |
4355 syn_opt_arg.sync_idx = NULL; | |
4356 syn_opt_arg.has_cont_list = FALSE; | |
4357 syn_opt_arg.cont_in_list = NULL; | |
4358 syn_opt_arg.next_list = NULL; | |
4359 | |
4355 /* | 4360 /* |
4356 * The options given apply to ALL keywords, so all options must be | 4361 * The options given apply to ALL keywords, so all options must be |
4357 * found before keywords can be created. | 4362 * found before keywords can be created. |
4358 * round 1: collect the options. | 4363 * 1: collect the options and copy the keywords to keyword_copy. |
4359 * round 2: create the keywords. | |
4360 */ | 4364 */ |
4361 first_arg = rest; | 4365 cnt = 0; |
4362 for (round = 1; round <= 2; ++round) | 4366 p = keyword_copy; |
4363 { | 4367 for ( ; rest != NULL && !ends_excmd(*rest); rest = skipwhite(rest)) |
4368 { | |
4369 rest = get_syn_options(rest, &syn_opt_arg); | |
4370 if (rest == NULL || ends_excmd(*rest)) | |
4371 break; | |
4372 /* Copy the keyword, removing backslashes, and add a NUL. */ | |
4373 while (*rest != NUL && !vim_iswhite(*rest)) | |
4374 { | |
4375 if (*rest == '\\' && rest[1] != NUL) | |
4376 ++rest; | |
4377 *p++ = *rest++; | |
4378 } | |
4379 *p++ = NUL; | |
4380 ++cnt; | |
4381 } | |
4382 | |
4383 if (!eap->skip) | |
4384 { | |
4385 /* Adjust flags for use of ":syn include". */ | |
4386 syn_incl_toplevel(syn_id, &syn_opt_arg.flags); | |
4387 | |
4364 /* | 4388 /* |
4365 * Isolate each keyword and add an entry for it. | 4389 * 2: Add an entry for each keyword. |
4366 */ | 4390 */ |
4367 for (rest = first_arg; rest != NULL && !ends_excmd(*rest); | 4391 for (kw = keyword_copy; --cnt >= 0; kw += STRLEN(kw) + 1) |
4368 rest = skipwhite(rest)) | |
4369 { | 4392 { |
4370 rest = get_syn_options(rest, &flags, TRUE, NULL, | 4393 for (p = vim_strchr(kw, '['); ; ) |
4371 NULL, &cont_in_list, &next_list); | |
4372 if (rest == NULL || ends_excmd(*rest)) | |
4373 break; | |
4374 p = keyword_copy; | |
4375 while (*rest != 0 && !vim_iswhite(*rest)) | |
4376 { | 4394 { |
4377 if (*rest == '\\' && rest[1] != NUL) | 4395 if (p != NULL) |
4378 ++rest; | 4396 *p = NUL; |
4379 *p++ = *rest++; | 4397 add_keyword(kw, syn_id, syn_opt_arg.flags, |
4380 } | 4398 syn_opt_arg.cont_in_list, |
4381 *p = NUL; | 4399 syn_opt_arg.next_list); |
4382 if (round == 2 && !eap->skip) | 4400 if (p == NULL || p[1] == NUL || p[1] == ']') |
4383 { | 4401 break; |
4384 for (p = vim_strchr(keyword_copy, '['); ; ) | 4402 #ifdef FEAT_MBYTE |
4403 if (has_mbyte) | |
4385 { | 4404 { |
4386 if (p != NULL) | 4405 int l = (*mb_ptr2len_check)(p + 1); |
4387 *p = NUL; | 4406 |
4388 add_keyword(keyword_copy, syn_id, flags, | 4407 mch_memmove(p, p + 1, l); |
4389 cont_in_list, next_list); | 4408 p += l; |
4390 if (p == NULL || p[1] == NUL || p[1] == ']') | 4409 } |
4391 break; | 4410 else |
4392 #ifdef FEAT_MBYTE | |
4393 if (has_mbyte) | |
4394 { | |
4395 int l = (*mb_ptr2len_check)(p + 1); | |
4396 | |
4397 mch_memmove(p, p + 1, l); | |
4398 p += l; | |
4399 } | |
4400 else | |
4401 #endif | 4411 #endif |
4402 { | 4412 { |
4403 p[0] = p[1]; | 4413 p[0] = p[1]; |
4404 ++p; | 4414 ++p; |
4405 } | |
4406 } | 4415 } |
4407 } | 4416 } |
4408 } | 4417 } |
4409 if (round == 1) | 4418 } |
4410 syn_incl_toplevel(syn_id, &flags); | 4419 |
4411 } | |
4412 vim_free(keyword_copy); | 4420 vim_free(keyword_copy); |
4413 } | 4421 } |
4414 } | 4422 } |
4415 | 4423 |
4416 if (rest != NULL) | 4424 if (rest != NULL) |
4417 eap->nextcmd = check_nextcmd(rest); | 4425 eap->nextcmd = check_nextcmd(rest); |
4418 else | 4426 else |
4419 EMSG2(_(e_invarg2), arg); | 4427 EMSG2(_(e_invarg2), arg); |
4420 | 4428 |
4421 vim_free(cont_in_list); | 4429 vim_free(syn_opt_arg.cont_in_list); |
4422 vim_free(next_list); | 4430 vim_free(syn_opt_arg.next_list); |
4423 redraw_curbuf_later(NOT_VALID); | 4431 redraw_curbuf_later(NOT_VALID); |
4424 syn_stack_free_all(curbuf); /* Need to recompute all syntax. */ | 4432 syn_stack_free_all(curbuf); /* Need to recompute all syntax. */ |
4425 } | 4433 } |
4426 | 4434 |
4427 /* | 4435 /* |
4438 char_u *group_name_end; | 4446 char_u *group_name_end; |
4439 char_u *rest; | 4447 char_u *rest; |
4440 synpat_T item; /* the item found in the line */ | 4448 synpat_T item; /* the item found in the line */ |
4441 int syn_id; | 4449 int syn_id; |
4442 int idx; | 4450 int idx; |
4443 int flags = 0; | 4451 syn_opt_arg_T syn_opt_arg; |
4444 int sync_idx = 0; | 4452 int sync_idx = 0; |
4445 short *cont_list = NULL; | |
4446 short *cont_in_list = NULL; | |
4447 short *next_list = NULL; | |
4448 | 4453 |
4449 /* Isolate the group name, check for validity */ | 4454 /* Isolate the group name, check for validity */ |
4450 rest = get_group_name(arg, &group_name_end); | 4455 rest = get_group_name(arg, &group_name_end); |
4451 | 4456 |
4452 /* Get options before the pattern */ | 4457 /* Get options before the pattern */ |
4453 rest = get_syn_options(rest, &flags, FALSE, | 4458 syn_opt_arg.flags = 0; |
4454 syncing ? &sync_idx : NULL, &cont_list, &cont_in_list, &next_list); | 4459 syn_opt_arg.keyword = FALSE; |
4460 syn_opt_arg.sync_idx = syncing ? &sync_idx : NULL; | |
4461 syn_opt_arg.has_cont_list = TRUE; | |
4462 syn_opt_arg.cont_list = NULL; | |
4463 syn_opt_arg.cont_in_list = NULL; | |
4464 syn_opt_arg.next_list = NULL; | |
4465 rest = get_syn_options(rest, &syn_opt_arg); | |
4455 | 4466 |
4456 /* get the pattern. */ | 4467 /* get the pattern. */ |
4457 init_syn_patterns(); | 4468 init_syn_patterns(); |
4458 vim_memset(&item, 0, sizeof(item)); | 4469 vim_memset(&item, 0, sizeof(item)); |
4459 rest = get_syn_pattern(rest, &item); | 4470 rest = get_syn_pattern(rest, &item); |
4460 if (vim_regcomp_had_eol() && !(flags & HL_EXCLUDENL)) | 4471 if (vim_regcomp_had_eol() && !(syn_opt_arg.flags & HL_EXCLUDENL)) |
4461 flags |= HL_HAS_EOL; | 4472 syn_opt_arg.flags |= HL_HAS_EOL; |
4462 | 4473 |
4463 /* Get options after the pattern */ | 4474 /* Get options after the pattern */ |
4464 rest = get_syn_options(rest, &flags, FALSE, | 4475 rest = get_syn_options(rest, &syn_opt_arg); |
4465 syncing ? &sync_idx : NULL, &cont_list, &cont_in_list, &next_list); | |
4466 | 4476 |
4467 if (rest != NULL) /* all arguments are valid */ | 4477 if (rest != NULL) /* all arguments are valid */ |
4468 { | 4478 { |
4469 /* | 4479 /* |
4470 * Check for trailing command and illegal trailing arguments. | 4480 * Check for trailing command and illegal trailing arguments. |
4474 rest = NULL; | 4484 rest = NULL; |
4475 else if (ga_grow(&curbuf->b_syn_patterns, 1) != FAIL | 4485 else if (ga_grow(&curbuf->b_syn_patterns, 1) != FAIL |
4476 && (syn_id = syn_check_group(arg, | 4486 && (syn_id = syn_check_group(arg, |
4477 (int)(group_name_end - arg))) != 0) | 4487 (int)(group_name_end - arg))) != 0) |
4478 { | 4488 { |
4479 syn_incl_toplevel(syn_id, &flags); | 4489 syn_incl_toplevel(syn_id, &syn_opt_arg.flags); |
4480 /* | 4490 /* |
4481 * Store the pattern in the syn_items list | 4491 * Store the pattern in the syn_items list |
4482 */ | 4492 */ |
4483 idx = curbuf->b_syn_patterns.ga_len; | 4493 idx = curbuf->b_syn_patterns.ga_len; |
4484 SYN_ITEMS(curbuf)[idx] = item; | 4494 SYN_ITEMS(curbuf)[idx] = item; |
4485 SYN_ITEMS(curbuf)[idx].sp_syncing = syncing; | 4495 SYN_ITEMS(curbuf)[idx].sp_syncing = syncing; |
4486 SYN_ITEMS(curbuf)[idx].sp_type = SPTYPE_MATCH; | 4496 SYN_ITEMS(curbuf)[idx].sp_type = SPTYPE_MATCH; |
4487 SYN_ITEMS(curbuf)[idx].sp_syn.id = syn_id; | 4497 SYN_ITEMS(curbuf)[idx].sp_syn.id = syn_id; |
4488 SYN_ITEMS(curbuf)[idx].sp_syn.inc_tag = current_syn_inc_tag; | 4498 SYN_ITEMS(curbuf)[idx].sp_syn.inc_tag = current_syn_inc_tag; |
4489 SYN_ITEMS(curbuf)[idx].sp_flags = flags; | 4499 SYN_ITEMS(curbuf)[idx].sp_flags = syn_opt_arg.flags; |
4490 SYN_ITEMS(curbuf)[idx].sp_sync_idx = sync_idx; | 4500 SYN_ITEMS(curbuf)[idx].sp_sync_idx = sync_idx; |
4491 SYN_ITEMS(curbuf)[idx].sp_cont_list = cont_list; | 4501 SYN_ITEMS(curbuf)[idx].sp_cont_list = syn_opt_arg.cont_list; |
4492 SYN_ITEMS(curbuf)[idx].sp_syn.cont_in_list = cont_in_list; | 4502 SYN_ITEMS(curbuf)[idx].sp_syn.cont_in_list = |
4493 if (cont_in_list != NULL) | 4503 syn_opt_arg.cont_in_list; |
4504 if (syn_opt_arg.cont_in_list != NULL) | |
4494 curbuf->b_syn_containedin = TRUE; | 4505 curbuf->b_syn_containedin = TRUE; |
4495 SYN_ITEMS(curbuf)[idx].sp_next_list = next_list; | 4506 SYN_ITEMS(curbuf)[idx].sp_next_list = syn_opt_arg.next_list; |
4496 ++curbuf->b_syn_patterns.ga_len; | 4507 ++curbuf->b_syn_patterns.ga_len; |
4497 | 4508 |
4498 /* remember that we found a match for syncing on */ | 4509 /* remember that we found a match for syncing on */ |
4499 if (flags & (HL_SYNC_HERE|HL_SYNC_THERE)) | 4510 if (syn_opt_arg.flags & (HL_SYNC_HERE|HL_SYNC_THERE)) |
4500 curbuf->b_syn_sync_flags |= SF_MATCH; | 4511 curbuf->b_syn_sync_flags |= SF_MATCH; |
4501 #ifdef FEAT_FOLDING | 4512 #ifdef FEAT_FOLDING |
4502 if (flags & HL_FOLD) | 4513 if (syn_opt_arg.flags & HL_FOLD) |
4503 ++curbuf->b_syn_folditems; | 4514 ++curbuf->b_syn_folditems; |
4504 #endif | 4515 #endif |
4505 | 4516 |
4506 redraw_curbuf_later(NOT_VALID); | 4517 redraw_curbuf_later(NOT_VALID); |
4507 syn_stack_free_all(curbuf); /* Need to recompute all syntax. */ | 4518 syn_stack_free_all(curbuf); /* Need to recompute all syntax. */ |
4512 /* | 4523 /* |
4513 * Something failed, free the allocated memory. | 4524 * Something failed, free the allocated memory. |
4514 */ | 4525 */ |
4515 vim_free(item.sp_prog); | 4526 vim_free(item.sp_prog); |
4516 vim_free(item.sp_pattern); | 4527 vim_free(item.sp_pattern); |
4517 vim_free(cont_list); | 4528 vim_free(syn_opt_arg.cont_list); |
4518 vim_free(cont_in_list); | 4529 vim_free(syn_opt_arg.cont_in_list); |
4519 vim_free(next_list); | 4530 vim_free(syn_opt_arg.next_list); |
4520 | 4531 |
4521 if (rest == NULL) | 4532 if (rest == NULL) |
4522 EMSG2(_(e_invarg2), arg); | 4533 EMSG2(_(e_invarg2), arg); |
4523 } | 4534 } |
4524 | 4535 |
4556 int matchgroup_id = 0; | 4567 int matchgroup_id = 0; |
4557 int not_enough = FALSE; /* not enough arguments */ | 4568 int not_enough = FALSE; /* not enough arguments */ |
4558 int illegal = FALSE; /* illegal arguments */ | 4569 int illegal = FALSE; /* illegal arguments */ |
4559 int success = FALSE; | 4570 int success = FALSE; |
4560 int idx; | 4571 int idx; |
4561 int flags = 0; | 4572 syn_opt_arg_T syn_opt_arg; |
4562 short *cont_list = NULL; | |
4563 short *cont_in_list = NULL; | |
4564 short *next_list = NULL; | |
4565 | 4573 |
4566 /* Isolate the group name, check for validity */ | 4574 /* Isolate the group name, check for validity */ |
4567 rest = get_group_name(arg, &group_name_end); | 4575 rest = get_group_name(arg, &group_name_end); |
4568 | 4576 |
4569 pat_ptrs[0] = NULL; | 4577 pat_ptrs[0] = NULL; |
4570 pat_ptrs[1] = NULL; | 4578 pat_ptrs[1] = NULL; |
4571 pat_ptrs[2] = NULL; | 4579 pat_ptrs[2] = NULL; |
4572 | 4580 |
4573 init_syn_patterns(); | 4581 init_syn_patterns(); |
4582 | |
4583 syn_opt_arg.flags = 0; | |
4584 syn_opt_arg.keyword = FALSE; | |
4585 syn_opt_arg.sync_idx = NULL; | |
4586 syn_opt_arg.has_cont_list = TRUE; | |
4587 syn_opt_arg.cont_list = NULL; | |
4588 syn_opt_arg.cont_in_list = NULL; | |
4589 syn_opt_arg.next_list = NULL; | |
4574 | 4590 |
4575 /* | 4591 /* |
4576 * get the options, patterns and matchgroup. | 4592 * get the options, patterns and matchgroup. |
4577 */ | 4593 */ |
4578 while (rest != NULL && !ends_excmd(*rest)) | 4594 while (rest != NULL && !ends_excmd(*rest)) |
4579 { | 4595 { |
4580 /* Check for option arguments */ | 4596 /* Check for option arguments */ |
4581 rest = get_syn_options(rest, &flags, FALSE, NULL, | 4597 rest = get_syn_options(rest, &syn_opt_arg); |
4582 &cont_list, &cont_in_list, &next_list); | |
4583 if (rest == NULL || ends_excmd(*rest)) | 4598 if (rest == NULL || ends_excmd(*rest)) |
4584 break; | 4599 break; |
4585 | 4600 |
4586 /* must be a pattern or matchgroup then */ | 4601 /* must be a pattern or matchgroup then */ |
4587 key_end = rest; | 4602 key_end = rest; |
4672 else if (item == ITEM_SKIP || item == ITEM_END) | 4687 else if (item == ITEM_SKIP || item == ITEM_END) |
4673 reg_do_extmatch = REX_USE; | 4688 reg_do_extmatch = REX_USE; |
4674 rest = get_syn_pattern(rest, ppp->pp_synp); | 4689 rest = get_syn_pattern(rest, ppp->pp_synp); |
4675 reg_do_extmatch = 0; | 4690 reg_do_extmatch = 0; |
4676 if (item == ITEM_END && vim_regcomp_had_eol() | 4691 if (item == ITEM_END && vim_regcomp_had_eol() |
4677 && !(flags & HL_EXCLUDENL)) | 4692 && !(syn_opt_arg.flags & HL_EXCLUDENL)) |
4678 ppp->pp_synp->sp_flags |= HL_HAS_EOL; | 4693 ppp->pp_synp->sp_flags |= HL_HAS_EOL; |
4679 ppp->pp_matchgroup_id = matchgroup_id; | 4694 ppp->pp_matchgroup_id = matchgroup_id; |
4680 ++pat_count; | 4695 ++pat_count; |
4681 } | 4696 } |
4682 } | 4697 } |
4705 rest = NULL; | 4720 rest = NULL; |
4706 else if (ga_grow(&(curbuf->b_syn_patterns), pat_count) != FAIL | 4721 else if (ga_grow(&(curbuf->b_syn_patterns), pat_count) != FAIL |
4707 && (syn_id = syn_check_group(arg, | 4722 && (syn_id = syn_check_group(arg, |
4708 (int)(group_name_end - arg))) != 0) | 4723 (int)(group_name_end - arg))) != 0) |
4709 { | 4724 { |
4710 syn_incl_toplevel(syn_id, &flags); | 4725 syn_incl_toplevel(syn_id, &syn_opt_arg.flags); |
4711 /* | 4726 /* |
4712 * Store the start/skip/end in the syn_items list | 4727 * Store the start/skip/end in the syn_items list |
4713 */ | 4728 */ |
4714 idx = curbuf->b_syn_patterns.ga_len; | 4729 idx = curbuf->b_syn_patterns.ga_len; |
4715 for (item = ITEM_START; item <= ITEM_END; ++item) | 4730 for (item = ITEM_START; item <= ITEM_END; ++item) |
4719 SYN_ITEMS(curbuf)[idx] = *(ppp->pp_synp); | 4734 SYN_ITEMS(curbuf)[idx] = *(ppp->pp_synp); |
4720 SYN_ITEMS(curbuf)[idx].sp_syncing = syncing; | 4735 SYN_ITEMS(curbuf)[idx].sp_syncing = syncing; |
4721 SYN_ITEMS(curbuf)[idx].sp_type = | 4736 SYN_ITEMS(curbuf)[idx].sp_type = |
4722 (item == ITEM_START) ? SPTYPE_START : | 4737 (item == ITEM_START) ? SPTYPE_START : |
4723 (item == ITEM_SKIP) ? SPTYPE_SKIP : SPTYPE_END; | 4738 (item == ITEM_SKIP) ? SPTYPE_SKIP : SPTYPE_END; |
4724 SYN_ITEMS(curbuf)[idx].sp_flags |= flags; | 4739 SYN_ITEMS(curbuf)[idx].sp_flags |= syn_opt_arg.flags; |
4725 SYN_ITEMS(curbuf)[idx].sp_syn.id = syn_id; | 4740 SYN_ITEMS(curbuf)[idx].sp_syn.id = syn_id; |
4726 SYN_ITEMS(curbuf)[idx].sp_syn.inc_tag = current_syn_inc_tag; | 4741 SYN_ITEMS(curbuf)[idx].sp_syn.inc_tag = current_syn_inc_tag; |
4727 SYN_ITEMS(curbuf)[idx].sp_syn_match_id = | 4742 SYN_ITEMS(curbuf)[idx].sp_syn_match_id = |
4728 ppp->pp_matchgroup_id; | 4743 ppp->pp_matchgroup_id; |
4729 if (item == ITEM_START) | 4744 if (item == ITEM_START) |
4730 { | 4745 { |
4731 SYN_ITEMS(curbuf)[idx].sp_cont_list = cont_list; | 4746 SYN_ITEMS(curbuf)[idx].sp_cont_list = |
4747 syn_opt_arg.cont_list; | |
4732 SYN_ITEMS(curbuf)[idx].sp_syn.cont_in_list = | 4748 SYN_ITEMS(curbuf)[idx].sp_syn.cont_in_list = |
4733 cont_in_list; | 4749 syn_opt_arg.cont_in_list; |
4734 if (cont_in_list != NULL) | 4750 if (syn_opt_arg.cont_in_list != NULL) |
4735 curbuf->b_syn_containedin = TRUE; | 4751 curbuf->b_syn_containedin = TRUE; |
4736 SYN_ITEMS(curbuf)[idx].sp_next_list = next_list; | 4752 SYN_ITEMS(curbuf)[idx].sp_next_list = |
4753 syn_opt_arg.next_list; | |
4737 } | 4754 } |
4738 ++curbuf->b_syn_patterns.ga_len; | 4755 ++curbuf->b_syn_patterns.ga_len; |
4739 ++idx; | 4756 ++idx; |
4740 #ifdef FEAT_FOLDING | 4757 #ifdef FEAT_FOLDING |
4741 if (flags & HL_FOLD) | 4758 if (syn_opt_arg.flags & HL_FOLD) |
4742 ++curbuf->b_syn_folditems; | 4759 ++curbuf->b_syn_folditems; |
4743 #endif | 4760 #endif |
4744 } | 4761 } |
4745 } | 4762 } |
4746 | 4763 |
4766 vim_free(ppp); | 4783 vim_free(ppp); |
4767 } | 4784 } |
4768 | 4785 |
4769 if (!success) | 4786 if (!success) |
4770 { | 4787 { |
4771 vim_free(cont_list); | 4788 vim_free(syn_opt_arg.cont_list); |
4772 vim_free(cont_in_list); | 4789 vim_free(syn_opt_arg.cont_in_list); |
4773 vim_free(next_list); | 4790 vim_free(syn_opt_arg.next_list); |
4774 if (not_enough) | 4791 if (not_enough) |
4775 EMSG2(_("E399: Not enough arguments: syntax region %s"), arg); | 4792 EMSG2(_("E399: Not enough arguments: syntax region %s"), arg); |
4776 else if (illegal || rest == NULL) | 4793 else if (illegal || rest == NULL) |
4777 EMSG2(_(e_invarg2), arg); | 4794 EMSG2(_(e_invarg2), arg); |
4778 } | 4795 } |