Mercurial > vim
comparison src/syntax.c @ 7687:61354fabf8a2 v7.4.1142
commit https://github.com/vim/vim/commit/b8060fe862f684b591f9ac679eac5b2594d6c5a0
Author: Bram Moolenaar <Bram@vim.org>
Date: Tue Jan 19 22:29:28 2016 +0100
patch 7.4.1142
Problem: Cannot define keyword characters for a syntax file.
Solution: Add the ":syn iskeyword" command. (Christian Brabandt)
author | Christian Brabandt <cb@256bit.org> |
---|---|
date | Tue, 19 Jan 2016 22:30:07 +0100 |
parents | 616460b73ee3 |
children | 0b6c37dd858d |
comparison
equal
deleted
inserted
replaced
7686:fad587cb360a | 7687:61354fabf8a2 |
---|---|
374 static int current_line_id = 0; /* unique number for current line */ | 374 static int current_line_id = 0; /* unique number for current line */ |
375 | 375 |
376 #define CUR_STATE(idx) ((stateitem_T *)(current_state.ga_data))[idx] | 376 #define CUR_STATE(idx) ((stateitem_T *)(current_state.ga_data))[idx] |
377 | 377 |
378 static void syn_sync __ARGS((win_T *wp, linenr_T lnum, synstate_T *last_valid)); | 378 static void syn_sync __ARGS((win_T *wp, linenr_T lnum, synstate_T *last_valid)); |
379 static void save_chartab(char_u *chartab); | |
380 static void restore_chartab(char_u *chartab); | |
379 static int syn_match_linecont __ARGS((linenr_T lnum)); | 381 static int syn_match_linecont __ARGS((linenr_T lnum)); |
380 static void syn_start_line __ARGS((void)); | 382 static void syn_start_line __ARGS((void)); |
381 static void syn_update_ends __ARGS((int startofline)); | 383 static void syn_update_ends __ARGS((int startofline)); |
382 static void syn_stack_alloc __ARGS((void)); | 384 static void syn_stack_alloc __ARGS((void)); |
383 static int syn_stack_cleanup __ARGS((void)); | 385 static int syn_stack_cleanup __ARGS((void)); |
456 static void clear_keywtab __ARGS((hashtab_T *ht)); | 458 static void clear_keywtab __ARGS((hashtab_T *ht)); |
457 static void add_keyword __ARGS((char_u *name, int id, int flags, short *cont_in_list, short *next_list, int conceal_char)); | 459 static void add_keyword __ARGS((char_u *name, int id, int flags, short *cont_in_list, short *next_list, int conceal_char)); |
458 static char_u *get_group_name __ARGS((char_u *arg, char_u **name_end)); | 460 static char_u *get_group_name __ARGS((char_u *arg, char_u **name_end)); |
459 static char_u *get_syn_options __ARGS((char_u *arg, syn_opt_arg_T *opt, int *conceal_char)); | 461 static char_u *get_syn_options __ARGS((char_u *arg, syn_opt_arg_T *opt, int *conceal_char)); |
460 static void syn_cmd_include __ARGS((exarg_T *eap, int syncing)); | 462 static void syn_cmd_include __ARGS((exarg_T *eap, int syncing)); |
463 static void syn_cmd_iskeyword __ARGS((exarg_T *eap, int syncing)); | |
461 static void syn_cmd_keyword __ARGS((exarg_T *eap, int syncing)); | 464 static void syn_cmd_keyword __ARGS((exarg_T *eap, int syncing)); |
462 static void syn_cmd_match __ARGS((exarg_T *eap, int syncing)); | 465 static void syn_cmd_match __ARGS((exarg_T *eap, int syncing)); |
463 static void syn_cmd_region __ARGS((exarg_T *eap, int syncing)); | 466 static void syn_cmd_region __ARGS((exarg_T *eap, int syncing)); |
464 #ifdef __BORLANDC__ | 467 #ifdef __BORLANDC__ |
465 static int _RTLENTRYF syn_compare_stub __ARGS((const void *v1, const void *v2)); | 468 static int _RTLENTRYF syn_compare_stub __ARGS((const void *v1, const void *v2)); |
982 } | 985 } |
983 | 986 |
984 validate_current_state(); | 987 validate_current_state(); |
985 } | 988 } |
986 | 989 |
990 static void | |
991 save_chartab(char_u *chartab) | |
992 { | |
993 if (syn_block->b_syn_isk != empty_option) | |
994 { | |
995 mch_memmove(chartab, syn_buf->b_chartab, (size_t)32); | |
996 mch_memmove(syn_buf->b_chartab, syn_win->w_s->b_syn_chartab, | |
997 (size_t)32); | |
998 } | |
999 } | |
1000 | |
1001 static void | |
1002 restore_chartab(char_u *chartab) | |
1003 { | |
1004 if (syn_win->w_s->b_syn_isk != empty_option) | |
1005 mch_memmove(syn_buf->b_chartab, chartab, (size_t)32); | |
1006 } | |
1007 | |
987 /* | 1008 /* |
988 * Return TRUE if the line-continuation pattern matches in line "lnum". | 1009 * Return TRUE if the line-continuation pattern matches in line "lnum". |
989 */ | 1010 */ |
990 static int | 1011 static int |
991 syn_match_linecont(lnum) | 1012 syn_match_linecont(lnum) |
992 linenr_T lnum; | 1013 linenr_T lnum; |
993 { | 1014 { |
994 regmmatch_T regmatch; | 1015 regmmatch_T regmatch; |
995 int r; | 1016 int r; |
1017 char_u buf_chartab[32]; /* chartab array for syn iskyeyword */ | |
996 | 1018 |
997 if (syn_block->b_syn_linecont_prog != NULL) | 1019 if (syn_block->b_syn_linecont_prog != NULL) |
998 { | 1020 { |
1021 /* use syntax iskeyword option */ | |
1022 save_chartab(buf_chartab); | |
999 regmatch.rmm_ic = syn_block->b_syn_linecont_ic; | 1023 regmatch.rmm_ic = syn_block->b_syn_linecont_ic; |
1000 regmatch.regprog = syn_block->b_syn_linecont_prog; | 1024 regmatch.regprog = syn_block->b_syn_linecont_prog; |
1001 r = syn_regexec(®match, lnum, (colnr_T)0, | 1025 r = syn_regexec(®match, lnum, (colnr_T)0, |
1002 IF_SYN_TIME(&syn_block->b_syn_linecont_time)); | 1026 IF_SYN_TIME(&syn_block->b_syn_linecont_time)); |
1003 syn_block->b_syn_linecont_prog = regmatch.regprog; | 1027 syn_block->b_syn_linecont_prog = regmatch.regprog; |
1028 restore_chartab(buf_chartab); | |
1004 return r; | 1029 return r; |
1005 } | 1030 } |
1006 return FALSE; | 1031 return FALSE; |
1007 } | 1032 } |
1008 | 1033 |
1889 int do_keywords; | 1914 int do_keywords; |
1890 regmmatch_T regmatch; | 1915 regmmatch_T regmatch; |
1891 lpos_T pos; | 1916 lpos_T pos; |
1892 int lc_col; | 1917 int lc_col; |
1893 reg_extmatch_T *cur_extmatch = NULL; | 1918 reg_extmatch_T *cur_extmatch = NULL; |
1919 char_u buf_chartab[32]; /* chartab array for syn iskyeyword */ | |
1894 char_u *line; /* current line. NOTE: becomes invalid after | 1920 char_u *line; /* current line. NOTE: becomes invalid after |
1895 looking for a pattern match! */ | 1921 looking for a pattern match! */ |
1896 | 1922 |
1897 /* variables for zero-width matches that have a "nextgroup" argument */ | 1923 /* variables for zero-width matches that have a "nextgroup" argument */ |
1898 int keep_next_list; | 1924 int keep_next_list; |
1943 | 1969 |
1944 /* Init the list of zero-width matches with a nextlist. This is used to | 1970 /* Init the list of zero-width matches with a nextlist. This is used to |
1945 * avoid matching the same item in the same position twice. */ | 1971 * avoid matching the same item in the same position twice. */ |
1946 ga_init2(&zero_width_next_ga, (int)sizeof(int), 10); | 1972 ga_init2(&zero_width_next_ga, (int)sizeof(int), 10); |
1947 | 1973 |
1974 /* use syntax iskeyword option */ | |
1975 save_chartab(buf_chartab); | |
1976 | |
1948 /* | 1977 /* |
1949 * Repeat matching keywords and patterns, to find contained items at the | 1978 * Repeat matching keywords and patterns, to find contained items at the |
1950 * same column. This stops when there are no extra matches at the current | 1979 * same column. This stops when there are no extra matches at the current |
1951 * column. | 1980 * column. |
1952 */ | 1981 */ |
1953 do | 1982 do |
1954 { | 1983 { |
1955 found_match = FALSE; | 1984 found_match = FALSE; |
1956 keep_next_list = FALSE; | 1985 keep_next_list = FALSE; |
1957 syn_id = 0; | 1986 syn_id = 0; |
1987 | |
1958 | 1988 |
1959 /* | 1989 /* |
1960 * 1. Check for a current state. | 1990 * 1. Check for a current state. |
1961 * Only when there is no current state, or if the current state may | 1991 * Only when there is no current state, or if the current state may |
1962 * contain other things, we need to check for keywords and patterns. | 1992 * contain other things, we need to check for keywords and patterns. |
2307 found_match = TRUE; | 2337 found_match = TRUE; |
2308 } | 2338 } |
2309 | 2339 |
2310 } while (found_match); | 2340 } while (found_match); |
2311 | 2341 |
2342 restore_chartab(buf_chartab); | |
2343 | |
2312 /* | 2344 /* |
2313 * Use attributes from the current state, if within its highlighting. | 2345 * Use attributes from the current state, if within its highlighting. |
2314 * If not, use attributes from the current-but-one state, etc. | 2346 * If not, use attributes from the current-but-one state, etc. |
2315 */ | 2347 */ |
2316 current_attr = 0; | 2348 current_attr = 0; |
2913 regmmatch_T regmatch; | 2945 regmmatch_T regmatch; |
2914 regmmatch_T best_regmatch; /* startpos/endpos of best match */ | 2946 regmmatch_T best_regmatch; /* startpos/endpos of best match */ |
2915 lpos_T pos; | 2947 lpos_T pos; |
2916 char_u *line; | 2948 char_u *line; |
2917 int had_match = FALSE; | 2949 int had_match = FALSE; |
2950 char_u buf_chartab[32]; /* chartab array for syn option iskyeyword */ | |
2918 | 2951 |
2919 /* just in case we are invoked for a keyword */ | 2952 /* just in case we are invoked for a keyword */ |
2920 if (idx < 0) | 2953 if (idx < 0) |
2921 return; | 2954 return; |
2922 | 2955 |
2959 re_extmatch_in = ref_extmatch(start_ext); | 2992 re_extmatch_in = ref_extmatch(start_ext); |
2960 | 2993 |
2961 matchcol = startpos->col; /* start looking for a match at sstart */ | 2994 matchcol = startpos->col; /* start looking for a match at sstart */ |
2962 start_idx = idx; /* remember the first END pattern. */ | 2995 start_idx = idx; /* remember the first END pattern. */ |
2963 best_regmatch.startpos[0].col = 0; /* avoid compiler warning */ | 2996 best_regmatch.startpos[0].col = 0; /* avoid compiler warning */ |
2997 | |
2998 /* use syntax iskeyword option */ | |
2999 save_chartab(buf_chartab); | |
3000 | |
2964 for (;;) | 3001 for (;;) |
2965 { | 3002 { |
2966 /* | 3003 /* |
2967 * Find end pattern that matches first after "matchcol". | 3004 * Find end pattern that matches first after "matchcol". |
2968 */ | 3005 */ |
3114 } | 3151 } |
3115 | 3152 |
3116 /* no match for an END pattern in this line */ | 3153 /* no match for an END pattern in this line */ |
3117 if (!had_match) | 3154 if (!had_match) |
3118 m_endpos->lnum = 0; | 3155 m_endpos->lnum = 0; |
3156 | |
3157 restore_chartab(buf_chartab); | |
3119 | 3158 |
3120 /* Remove external matches. */ | 3159 /* Remove external matches. */ |
3121 unref_extmatch(re_extmatch_in); | 3160 unref_extmatch(re_extmatch_in); |
3122 re_extmatch_in = NULL; | 3161 re_extmatch_in = NULL; |
3123 } | 3162 } |
3480 /* assume spell checking changed, force a redraw */ | 3519 /* assume spell checking changed, force a redraw */ |
3481 redraw_win_later(curwin, NOT_VALID); | 3520 redraw_win_later(curwin, NOT_VALID); |
3482 } | 3521 } |
3483 | 3522 |
3484 /* | 3523 /* |
3524 * Handle ":syntax iskeyword" command. | |
3525 */ | |
3526 static void | |
3527 syn_cmd_iskeyword(eap, syncing) | |
3528 exarg_T *eap; | |
3529 int syncing UNUSED; | |
3530 { | |
3531 char_u *arg = eap->arg; | |
3532 char_u save_chartab[32]; | |
3533 char_u *save_isk; | |
3534 | |
3535 if (eap->skip) | |
3536 return; | |
3537 | |
3538 arg = skipwhite(arg); | |
3539 if (*arg == NUL) | |
3540 { | |
3541 MSG_PUTS("\n"); | |
3542 MSG_PUTS(_("syntax iskeyword ")); | |
3543 if (curwin->w_s->b_syn_isk != empty_option) | |
3544 msg_outtrans(curwin->w_s->b_syn_isk); | |
3545 else | |
3546 msg_outtrans((char_u *)"not set"); | |
3547 } | |
3548 else | |
3549 { | |
3550 if (STRNICMP(arg, "clear", 5) == 0) | |
3551 { | |
3552 mch_memmove(curwin->w_s->b_syn_chartab, curbuf->b_chartab, | |
3553 (size_t)32); | |
3554 clear_string_option(&curwin->w_s->b_syn_isk); | |
3555 } | |
3556 else | |
3557 { | |
3558 mch_memmove(save_chartab, curbuf->b_chartab, (size_t)32); | |
3559 save_isk = curbuf->b_p_isk; | |
3560 curbuf->b_p_isk = vim_strsave(arg); | |
3561 | |
3562 buf_init_chartab(curbuf, FALSE); | |
3563 mch_memmove(curwin->w_s->b_syn_chartab, curbuf->b_chartab, | |
3564 (size_t)32); | |
3565 mch_memmove(curbuf->b_chartab, save_chartab, (size_t)32); | |
3566 clear_string_option(&curwin->w_s->b_syn_isk); | |
3567 curwin->w_s->b_syn_isk = curbuf->b_p_isk; | |
3568 curbuf->b_p_isk = save_isk; | |
3569 } | |
3570 } | |
3571 redraw_win_later(curwin, NOT_VALID); | |
3572 } | |
3573 | |
3574 /* | |
3485 * Clear all syntax info for one buffer. | 3575 * Clear all syntax info for one buffer. |
3486 */ | 3576 */ |
3487 void | 3577 void |
3488 syntax_clear(block) | 3578 syntax_clear(block) |
3489 synblock_T *block; | 3579 synblock_T *block; |
3521 vim_free(block->b_syn_linecont_pat); | 3611 vim_free(block->b_syn_linecont_pat); |
3522 block->b_syn_linecont_pat = NULL; | 3612 block->b_syn_linecont_pat = NULL; |
3523 #ifdef FEAT_FOLDING | 3613 #ifdef FEAT_FOLDING |
3524 block->b_syn_folditems = 0; | 3614 block->b_syn_folditems = 0; |
3525 #endif | 3615 #endif |
3616 clear_string_option(&block->b_syn_isk); | |
3526 | 3617 |
3527 /* free the stored states */ | 3618 /* free the stored states */ |
3528 syn_stack_free_all(block); | 3619 syn_stack_free_all(block); |
3529 invalidate_current_state(); | 3620 invalidate_current_state(); |
3530 | 3621 |
3567 | 3658 |
3568 vim_regfree(curwin->w_s->b_syn_linecont_prog); | 3659 vim_regfree(curwin->w_s->b_syn_linecont_prog); |
3569 curwin->w_s->b_syn_linecont_prog = NULL; | 3660 curwin->w_s->b_syn_linecont_prog = NULL; |
3570 vim_free(curwin->w_s->b_syn_linecont_pat); | 3661 vim_free(curwin->w_s->b_syn_linecont_pat); |
3571 curwin->w_s->b_syn_linecont_pat = NULL; | 3662 curwin->w_s->b_syn_linecont_pat = NULL; |
3572 | 3663 clear_string_option(&curwin->w_s->b_syn_isk); |
3573 syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ | 3664 |
3665 syn_stack_free_all(curwin->w_s); /* Need to recompute all syntax. */ | |
3574 } | 3666 } |
3575 | 3667 |
3576 /* | 3668 /* |
3577 * Remove one pattern from the buffer's pattern list. | 3669 * Remove one pattern from the buffer's pattern list. |
3578 */ | 3670 */ |
3775 int syncing UNUSED; | 3867 int syncing UNUSED; |
3776 { | 3868 { |
3777 eap->nextcmd = check_nextcmd(eap->arg); | 3869 eap->nextcmd = check_nextcmd(eap->arg); |
3778 if (!eap->skip) | 3870 if (!eap->skip) |
3779 { | 3871 { |
3872 clear_string_option(&curwin->w_s->b_syn_isk); | |
3780 set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"reset"); | 3873 set_internal_string_var((char_u *)"syntax_cmd", (char_u *)"reset"); |
3781 do_cmdline_cmd((char_u *)"runtime! syntax/syncolor.vim"); | 3874 do_cmdline_cmd((char_u *)"runtime! syntax/syncolor.vim"); |
3782 do_unlet((char_u *)"g:syntax_cmd", TRUE); | 3875 do_unlet((char_u *)"g:syntax_cmd", TRUE); |
3783 } | 3876 } |
3784 } | 3877 } |
6251 {"clear", syn_cmd_clear}, | 6344 {"clear", syn_cmd_clear}, |
6252 {"cluster", syn_cmd_cluster}, | 6345 {"cluster", syn_cmd_cluster}, |
6253 {"conceal", syn_cmd_conceal}, | 6346 {"conceal", syn_cmd_conceal}, |
6254 {"enable", syn_cmd_enable}, | 6347 {"enable", syn_cmd_enable}, |
6255 {"include", syn_cmd_include}, | 6348 {"include", syn_cmd_include}, |
6349 {"iskeyword", syn_cmd_iskeyword}, | |
6256 {"keyword", syn_cmd_keyword}, | 6350 {"keyword", syn_cmd_keyword}, |
6257 {"list", syn_cmd_list}, | 6351 {"list", syn_cmd_list}, |
6258 {"manual", syn_cmd_manual}, | 6352 {"manual", syn_cmd_manual}, |
6259 {"match", syn_cmd_match}, | 6353 {"match", syn_cmd_match}, |
6260 {"on", syn_cmd_on}, | 6354 {"on", syn_cmd_on}, |
6329 curwin->w_p_spell = FALSE; /* No spell checking */ | 6423 curwin->w_p_spell = FALSE; /* No spell checking */ |
6330 clear_string_option(&curwin->w_s->b_p_spc); | 6424 clear_string_option(&curwin->w_s->b_p_spc); |
6331 clear_string_option(&curwin->w_s->b_p_spf); | 6425 clear_string_option(&curwin->w_s->b_p_spf); |
6332 clear_string_option(&curwin->w_s->b_p_spl); | 6426 clear_string_option(&curwin->w_s->b_p_spl); |
6333 #endif | 6427 #endif |
6428 clear_string_option(&curwin->w_s->b_syn_isk); | |
6334 } | 6429 } |
6335 | 6430 |
6336 /* save value of b:current_syntax */ | 6431 /* save value of b:current_syntax */ |
6337 old_value = get_var_value((char_u *)"b:current_syntax"); | 6432 old_value = get_var_value((char_u *)"b:current_syntax"); |
6338 if (old_value != NULL) | 6433 if (old_value != NULL) |