To: vim-dev@vim.org Subject: Patch 6.2.219 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=ISO-8859-1 Content-Transfer-Encoding: 8bit ------------ Patch 6.2.219 Problem: Syntax highlighting hangs on an empty match of an item with a nextgroup. (Charles Campbell) Solution: Remember that the item has already matched and don't match it again at the same position. Files: src/syntax.c *** ../vim-6.2.218/src/syntax.c Sat Sep 27 19:26:33 2003 --- src/syntax.c Thu Jan 29 21:14:40 2004 *************** *** 348,354 **** static void validate_current_state __ARGS((void)); static int syn_finish_line __ARGS((int syncing)); static int syn_current_attr __ARGS((int syncing, int displaying)); ! static int did_match_already __ARGS((int idx)); static stateitem_T *push_next_match __ARGS((stateitem_T *cur_si)); static void check_state_ends __ARGS((void)); static void update_si_attr __ARGS((int idx)); --- 348,354 ---- static void validate_current_state __ARGS((void)); static int syn_finish_line __ARGS((int syncing)); static int syn_current_attr __ARGS((int syncing, int displaying)); ! static int did_match_already __ARGS((int idx, garray_T *gap)); static stateitem_T *push_next_match __ARGS((stateitem_T *cur_si)); static void check_state_ends __ARGS((void)); static void update_si_attr __ARGS((int idx)); *************** *** 1730,1737 **** --- 1730,1740 ---- reg_extmatch_T *cur_extmatch = NULL; char_u *line; /* current line. NOTE: becomes invalid after looking for a pattern match! */ + + /* variables for zero-width matches that have a "nextgroup" argument */ int keep_next_list; int zero_width_next_list = FALSE; + garray_T zero_width_next_ga; /* * No character, no attributes! Past end of line? *************** *** 1775,1780 **** --- 1778,1787 ---- && (syn_buf->b_keywtab != NULL || syn_buf->b_keywtab_ic != NULL); + /* Init the list of zero-width matches with a nextlist. This is used to + * avoid matching the same item in the same position twice. */ + ga_init2(&zero_width_next_ga, sizeof(int), 10); + /* * Repeat matching keywords and patterns, to find contained items at the * same column. This stops when there are no extra matches at the current *************** *** 1951,1957 **** * before, skip it. Must retry in the next * column, because it may match from there. */ ! if (did_match_already(idx)) { try_next_column = TRUE; continue; --- 1958,1964 ---- * before, skip it. Must retry in the next * column, because it may match from there. */ ! if (did_match_already(idx, &zero_width_next_ga)) { try_next_column = TRUE; continue; *************** *** 2070,2075 **** --- 2077,2092 ---- current_next_flags = lspp->sp_flags; keep_next_list = TRUE; zero_width_next_list = TRUE; + + /* Add the index to a list, so that we can check + * later that we don't match it again (and cause an + * endless loop). */ + if (ga_grow(&zero_width_next_ga, 1) == OK) + { + ((int *)(zero_width_next_ga.ga_data)) + [zero_width_next_ga.ga_len++] = next_match_idx; + --zero_width_next_ga.ga_room; + } next_match_idx = -1; } else *************** *** 2172,2177 **** --- 2189,2197 ---- && !(current_next_flags & (HL_SKIPNL | HL_SKIPEMPTY))) current_next_list = NULL; + if (zero_width_next_ga.ga_len > 0) + ga_clear(&zero_width_next_ga); + /* No longer need external matches. But keep next_match_extmatch. */ unref_extmatch(re_extmatch_out); re_extmatch_out = NULL; *************** *** 2185,2202 **** * Check if we already matched pattern "idx" at the current column. */ static int ! did_match_already(idx) ! int idx; { int i; for (i = current_state.ga_len; --i >= 0; ) - { if (CUR_STATE(i).si_m_startcol == (int)current_col && CUR_STATE(i).si_m_lnum == (int)current_lnum && CUR_STATE(i).si_idx == idx) return TRUE; ! } return FALSE; } --- 2205,2228 ---- * Check if we already matched pattern "idx" at the current column. */ static int ! did_match_already(idx, gap) ! int idx; ! garray_T *gap; { int i; for (i = current_state.ga_len; --i >= 0; ) if (CUR_STATE(i).si_m_startcol == (int)current_col && CUR_STATE(i).si_m_lnum == (int)current_lnum && CUR_STATE(i).si_idx == idx) return TRUE; ! ! /* Zero-width matches with a nextgroup argument are not put on the syntax ! * stack, and can only be matched once anyway. */ ! for (i = gap->ga_len; --i >= 0; ) ! if (((int *)(gap->ga_data))[i] == idx) ! return TRUE; ! return FALSE; } *** ../vim-6.2.218/src/version.c Sun Feb 1 19:59:21 2004 --- src/version.c Sun Feb 1 20:00:45 2004 *************** *** 639,640 **** --- 639,642 ---- { /* Add new patch number below this line */ + /**/ + 219, /**/ -- The Feynman problem solving Algorithm: 1) Write down the problem 2) Think real hard 3) Write down the answer /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// Sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ Project leader for A-A-P -- http://www.A-A-P.org /// \\\ Help AIDS victims, buy here: http://ICCF-Holland.org/click1.html ///