To: vim_dev@googlegroups.com Subject: Patch 8.1.2394 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.1.2394 Problem: Using old C style comments. Solution: Use // comments where appropriate. Files: src/popupmenu.c, src/pty.c, src/quickfix.c, src/regexp.c, src/regexp_nfa.c, src/screen.c, src/search.c, src/sha256.c, src/sign.c *** ../vim-8.1.2393/src/popupmenu.c 2019-12-01 15:23:07.464344509 +0100 --- src/popupmenu.c 2019-12-05 20:54:34.090926799 +0100 *************** *** 12,33 **** */ #include "vim.h" ! static pumitem_T *pum_array = NULL; /* items of displayed pum */ ! static int pum_size; /* nr of items in "pum_array" */ ! static int pum_selected; /* index of selected item or -1 */ ! static int pum_first = 0; /* index of top item */ static int call_update_screen = FALSE; ! static int pum_height; /* nr of displayed pum items */ ! static int pum_width; /* width of displayed pum items */ ! static int pum_base_width; /* width of pum items base */ ! static int pum_kind_width; /* width of pum items kind column */ ! static int pum_extra_width; /* width of extra stuff */ ! static int pum_scrollbar; /* TRUE when scrollbar present */ ! static int pum_row; /* top row of pum */ ! static int pum_col; /* left column of pum */ static win_T *pum_window = NULL; static int pum_win_row; --- 12,33 ---- */ #include "vim.h" ! static pumitem_T *pum_array = NULL; // items of displayed pum ! static int pum_size; // nr of items in "pum_array" ! static int pum_selected; // index of selected item or -1 ! static int pum_first = 0; // index of top item static int call_update_screen = FALSE; ! static int pum_height; // nr of displayed pum items ! static int pum_width; // width of displayed pum items ! static int pum_base_width; // width of pum items base ! static int pum_kind_width; // width of pum items kind column ! static int pum_extra_width; // width of extra stuff ! static int pum_scrollbar; // TRUE when scrollbar present ! static int pum_row; // top row of pum ! static int pum_col; // left column of pum static win_T *pum_window = NULL; static int pum_win_row; *************** *** 49,55 **** int i; int w; ! /* Compute the width of the widest match and the widest extra. */ pum_base_width = 0; pum_kind_width = 0; pum_extra_width = 0; --- 49,55 ---- int i; int w; ! // Compute the width of the widest match and the widest extra. pum_base_width = 0; pum_kind_width = 0; pum_extra_width = 0; *************** *** 83,90 **** pum_display( pumitem_T *array, int size, ! int selected) /* index of initially selected item, none if ! out of range */ { int def_width; int max_width; --- 83,90 ---- pum_display( pumitem_T *array, int size, ! int selected) // index of initially selected item, none if ! // out of range { int def_width; int max_width; *************** *** 103,110 **** above_row = 0; below_row = cmdline_row; ! /* Pretend the pum is already there to avoid that must_redraw is set ! * when 'cuc' is on. */ pum_array = (pumitem_T *)1; validate_cursor_col(); pum_array = NULL; --- 103,110 ---- above_row = 0; below_row = cmdline_row; ! // Pretend the pum is already there to avoid that must_redraw is set ! // when 'cuc' is on. pum_array = (pumitem_T *)1; validate_cursor_col(); pum_array = NULL; *************** *** 141,154 **** if (p_ph > 0 && pum_height > p_ph) pum_height = p_ph; ! /* Put the pum below "pum_win_row" if possible. If there are few lines ! * decide on where there is more room. */ if (pum_win_row + 2 >= below_row - pum_height && pum_win_row - above_row > (below_row - above_row) / 2) { ! /* pum above "pum_win_row" */ ! /* Leave two lines of context if possible */ if (curwin->w_wrow - curwin->w_cline_row >= 2) context_lines = 2; else --- 141,154 ---- if (p_ph > 0 && pum_height > p_ph) pum_height = p_ph; ! // Put the pum below "pum_win_row" if possible. If there are few lines ! // decide on where there is more room. if (pum_win_row + 2 >= below_row - pum_height && pum_win_row - above_row > (below_row - above_row) / 2) { ! // pum above "pum_win_row" ! // Leave two lines of context if possible if (curwin->w_wrow - curwin->w_cline_row >= 2) context_lines = 2; else *************** *** 172,180 **** } else { ! /* pum below "pum_win_row" */ ! /* Leave two lines of context if possible */ if (curwin->w_cline_row + curwin->w_cline_height - curwin->w_wrow >= 3) context_lines = 3; --- 172,180 ---- } else { ! // pum below "pum_win_row" ! // Leave two lines of context if possible if (curwin->w_cline_row + curwin->w_cline_height - curwin->w_wrow >= 3) context_lines = 3; *************** *** 191,197 **** pum_height = p_ph; } ! /* don't display when we only have room for one line */ if (pum_height < 1 || (pum_height == 1 && size > 1)) return; --- 191,197 ---- pum_height = p_ph; } ! // don't display when we only have room for one line if (pum_height < 1 || (pum_height == 1 && size > 1)) return; *************** *** 209,215 **** pum_compute_size(); max_width = pum_base_width; ! /* Calculate column */ #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl) cursor_col = curwin->w_wincol + curwin->w_width --- 209,215 ---- pum_compute_size(); max_width = pum_base_width; ! // Calculate column #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl) cursor_col = curwin->w_wincol + curwin->w_width *************** *** 218,224 **** #endif cursor_col = curwin->w_wincol + curwin->w_wcol; ! /* if there are more items than room we need a scrollbar */ if (pum_height < size) { pum_scrollbar = 1; --- 218,224 ---- #endif cursor_col = curwin->w_wincol + curwin->w_wcol; ! // if there are more items than room we need a scrollbar if (pum_height < size) { pum_scrollbar = 1; *************** *** 239,248 **** #endif )) { ! /* align pum with "cursor_col" */ pum_col = cursor_col; ! /* start with the maximum space available */ #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl) pum_width = pum_col - pum_scrollbar + 1; --- 239,248 ---- #endif )) { ! // align pum with "cursor_col" pum_col = cursor_col; ! // start with the maximum space available #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl) pum_width = pum_col - pum_scrollbar + 1; *************** *** 253,260 **** if (pum_width > max_width + pum_kind_width + pum_extra_width + 1 && pum_width > p_pw) { ! /* the width is more than needed for the items, make it ! * narrower */ pum_width = max_width + pum_kind_width + pum_extra_width + 1; if (pum_width < p_pw) pum_width = p_pw; --- 253,260 ---- if (pum_width > max_width + pum_kind_width + pum_extra_width + 1 && pum_width > p_pw) { ! // the width is more than needed for the items, make it ! // narrower pum_width = max_width + pum_kind_width + pum_extra_width + 1; if (pum_width < p_pw) pum_width = p_pw; *************** *** 267,273 **** #endif )) { ! /* align pum edge with "cursor_col" */ #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl && W_ENDCOL(curwin) < max_width + pum_scrollbar + 1) --- 267,273 ---- #endif )) { ! // align pum edge with "cursor_col" #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl && W_ENDCOL(curwin) < max_width + pum_scrollbar + 1) *************** *** 282,288 **** if (curwin->w_wincol > Columns - max_width - pum_scrollbar && max_width <= p_pw) { ! /* use full width to end of the screen */ pum_col = Columns - max_width - pum_scrollbar; if (pum_col < 0) pum_col = 0; --- 282,288 ---- if (curwin->w_wincol > Columns - max_width - pum_scrollbar && max_width <= p_pw) { ! // use full width to end of the screen pum_col = Columns - max_width - pum_scrollbar; if (pum_col < 0) pum_col = 0; *************** *** 326,332 **** } else if (Columns < def_width) { ! /* not enough room, will use what we have */ #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl) pum_col = Columns - 1; --- 326,332 ---- } else if (Columns < def_width) { ! // not enough room, will use what we have #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl) pum_col = Columns - 1; *************** *** 338,344 **** else { if (max_width > p_pw) ! max_width = p_pw; /* truncate */ #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl) pum_col = max_width - 1; --- 338,344 ---- else { if (max_width > p_pw) ! max_width = p_pw; // truncate #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl) pum_col = max_width - 1; *************** *** 348,356 **** pum_width = max_width - pum_scrollbar; } ! /* Set selected item and redraw. If the window size changed need to ! * redo the positioning. Limit this to two times, when there is not ! * much room the window size will keep changing. */ } while (pum_set_selected(selected, redo_count) && ++redo_count <= 2); } --- 348,356 ---- pum_width = max_width - pum_scrollbar; } ! // Set selected item and redraw. If the window size changed need to ! // redo the positioning. Limit this to two times, when there is not ! // much room the window size will keep changing. } while (pum_set_selected(selected, redo_count) && ++redo_count <= 2); } *************** *** 440,446 **** idx = i + pum_first; attr = (idx == pum_selected) ? attr_select : attr_norm; ! /* prepend a space if there is room */ #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl) { --- 440,446 ---- idx = i + pum_first; attr = (idx == pum_selected) ? attr_select : attr_norm; ! // prepend a space if there is room #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl) { *************** *** 452,459 **** if (pum_col > 0) screen_putchar(' ', row, pum_col - 1, attr); ! /* Display each entry, use two spaces for a Tab. ! * Do this 3 times: For the main text, kind and extra info */ col = pum_col; totwidth = 0; for (round = 1; round <= 3; ++round) --- 452,459 ---- if (pum_col > 0) screen_putchar(' ', row, pum_col - 1, attr); ! // Display each entry, use two spaces for a Tab. ! // Do this 3 times: For the main text, kind and extra info col = pum_col; totwidth = 0; for (round = 1; round <= 3; ++round) *************** *** 474,481 **** w = ptr2cells(p); if (*p == NUL || *p == TAB || totwidth + w > pum_width) { ! /* Display the text that fits or comes before a Tab. ! * First convert it to printable characters. */ char_u *st; int saved = *p; --- 474,481 ---- w = ptr2cells(p); if (*p == NUL || *p == TAB || totwidth + w > pum_width) { ! // Display the text that fits or comes before a Tab. ! // First convert it to printable characters. char_u *st; int saved = *p; *************** *** 508,518 **** if (size < pum_width) { ! /* Most left character requires ! * 2-cells but only 1 cell is ! * available on screen. Put a ! * '<' on the left of the pum ! * item */ *(--rt) = '<'; size++; } --- 508,518 ---- if (size < pum_width) { ! // Most left character requires ! // 2-cells but only 1 cell is ! // available on screen. Put a ! // '<' on the left of the pum ! // item *(--rt) = '<'; size++; } *************** *** 540,546 **** if (*p != TAB) break; ! /* Display two spaces for a Tab. */ #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl) { --- 540,546 ---- if (*p != TAB) break; ! // Display two spaces for a Tab. #ifdef FEAT_RIGHTLEFT if (curwin->w_p_rl) { *************** *** 555,561 **** col += 2; } totwidth += 2; ! s = NULL; /* start text at next char */ width = 0; } else --- 555,561 ---- col += 2; } totwidth += 2; ! s = NULL; // start text at next char width = 0; } else *************** *** 567,573 **** else n = 1; ! /* Stop when there is nothing more to display. */ if (round == 3 || (round == 2 && pum_array[idx].pum_extra == NULL) || (round == 1 && pum_array[idx].pum_kind == NULL --- 567,573 ---- else n = 1; ! // Stop when there is nothing more to display. if (round == 3 || (round == 2 && pum_array[idx].pum_extra == NULL) || (round == 1 && pum_array[idx].pum_kind == NULL *************** *** 693,700 **** { if (pum_first > pum_selected - 4) { ! /* scroll down; when we did a jump it's probably a PageUp then ! * scroll a whole page */ if (pum_first > pum_selected - 2) { pum_first -= pum_height - 2; --- 693,700 ---- { if (pum_first > pum_selected - 4) { ! // scroll down; when we did a jump it's probably a PageUp then ! // scroll a whole page if (pum_first > pum_selected - 2) { pum_first -= pum_height - 2; *************** *** 708,715 **** } else if (pum_first < pum_selected - pum_height + 5) { ! /* scroll up; when we did a jump it's probably a PageDown then ! * scroll a whole page */ if (pum_first < pum_selected - pum_height + 1 + 2) { pum_first += pum_height - 2; --- 708,715 ---- } else if (pum_first < pum_selected - pum_height + 5) { ! // scroll up; when we did a jump it's probably a PageDown then ! // scroll a whole page if (pum_first < pum_selected - pum_height + 1 + 2) { pum_first += pum_height - 2; *************** *** 720,740 **** pum_first = pum_selected - pum_height + 1; } ! /* Give a few lines of context when possible. */ if (context > 3) context = 3; if (pum_height > 2) { if (pum_first > pum_selected - context) { ! /* scroll down */ pum_first = pum_selected - context; if (pum_first < 0) pum_first = 0; } else if (pum_first < pum_selected + context - pum_height + 1) { ! /* scroll up */ pum_first = pum_selected + context - pum_height + 1; } } --- 720,740 ---- pum_first = pum_selected - pum_height + 1; } ! // Give a few lines of context when possible. if (context > 3) context = 3; if (pum_height > 2) { if (pum_first > pum_selected - context) { ! // scroll down pum_first = pum_selected - context; if (pum_first < 0) pum_first = 0; } else if (pum_first < pum_selected + context - pum_height + 1) { ! // scroll up pum_first = pum_selected + context - pum_height + 1; } } *************** *** 845,852 **** // delete the empty last line ml_delete(curbuf->b_ml.ml_line_count, FALSE); ! /* Increase the height of the preview window to show the ! * text, but no more than 'previewheight' lines. */ if (repeat == 0 && use_popup == USEPOPUP_NONE) { if (lnum > p_pvh) --- 845,852 ---- // delete the empty last line ml_delete(curbuf->b_ml.ml_line_count, FALSE); ! // Increase the height of the preview window to show the ! // text, but no more than 'previewheight' lines. if (repeat == 0 && use_popup == USEPOPUP_NONE) { if (lnum > p_pvh) *************** *** 886,905 **** if (curtab != curtab_save && valid_tabpage(curtab_save)) goto_tabpage_tp(curtab_save, FALSE, FALSE); ! /* When the first completion is done and the preview ! * window is not resized, skip the preview window's ! * status line redrawing. */ if (ins_compl_active() && !resized) curwin->w_redr_status = FALSE; ! /* Return cursor to where we were */ validate_cursor(); redraw_later(SOME_VALID); ! /* When the preview window was resized we need to ! * update the view on the buffer. Only go back to ! * the window when needed, otherwise it will always be ! * redraw. */ if (resized && win_valid(curwin_save)) { ++no_u_sync; --- 886,905 ---- if (curtab != curtab_save && valid_tabpage(curtab_save)) goto_tabpage_tp(curtab_save, FALSE, FALSE); ! // When the first completion is done and the preview ! // window is not resized, skip the preview window's ! // status line redrawing. if (ins_compl_active() && !resized) curwin->w_redr_status = FALSE; ! // Return cursor to where we were validate_cursor(); redraw_later(SOME_VALID); ! // When the preview window was resized we need to ! // update the view on the buffer. Only go back to ! // the window when needed, otherwise it will always be ! // redraw. if (resized && win_valid(curwin_save)) { ++no_u_sync; *************** *** 908,915 **** update_topline(); } ! /* Update the screen before drawing the popup menu. ! * Enable updating the status lines. */ pum_do_redraw = TRUE; update_screen(0); pum_do_redraw = FALSE; --- 908,915 ---- update_topline(); } ! // Update the screen before drawing the popup menu. ! // Enable updating the status lines. pum_do_redraw = TRUE; update_screen(0); pum_do_redraw = FALSE; *************** *** 928,935 **** # endif } ! /* May need to update the screen again when there are ! * autocommands involved. */ pum_do_redraw = TRUE; update_screen(0); pum_do_redraw = FALSE; --- 928,935 ---- # endif } ! // May need to update the screen again when there are ! // autocommands involved. pum_do_redraw = TRUE; update_screen(0); pum_do_redraw = FALSE; *************** *** 1064,1077 **** { if (Rows - mouse_row > pum_size) { ! /* Enough space below the mouse row. */ pum_row = mouse_row + 1; if (pum_height > Rows - pum_row) pum_height = Rows - pum_row; } else { ! /* Show above the mouse row, reduce height if it does not fit. */ pum_row = mouse_row - pum_size; if (pum_row < 0) { --- 1064,1077 ---- { if (Rows - mouse_row > pum_size) { ! // Enough space below the mouse row. pum_row = mouse_row + 1; if (pum_height > Rows - pum_row) pum_height = Rows - pum_row; } else { ! // Show above the mouse row, reduce height if it does not fit. pum_row = mouse_row - pum_size; if (pum_row < 0) { *************** *** 1081,1090 **** } if (Columns - mouse_col >= pum_base_width || Columns - mouse_col > min_width) ! /* Enough space to show at mouse column. */ pum_col = mouse_col; else ! /* Not enough space, right align with window. */ pum_col = Columns - (pum_base_width > min_width ? min_width : pum_base_width); --- 1081,1090 ---- } if (Columns - mouse_col >= pum_base_width || Columns - mouse_col > min_width) ! // Enough space to show at mouse column. pum_col = mouse_col; else ! // Not enough space, right align with window. pum_col = Columns - (pum_base_width > min_width ? min_width : pum_base_width); *************** *** 1158,1164 **** { if ((*p == ',' && p[1] == ' ') || *p == '{' || *p == '}') { ! /* Looks like a good point to break. */ if (*p == '{') ++indent; else if (*p == '}' && indent > 0) --- 1158,1164 ---- { if ((*p == ',' && p[1] == ' ') || *p == '{' || *p == '}') { ! // Looks like a good point to break. if (*p == '{') ++indent; else if (*p == '}' && indent > 0) *************** *** 1181,1202 **** height = 2 + ga.ga_len; ! /* If there are long items and the height is below the limit: split lines */ if (long_item_count > 0 && height + long_item_count <= max_height) { split_long_items = TRUE; height += long_item_count; } ! /* Limit to half the window height, it has to fit above or below the mouse ! * position. */ if (height > max_height) height = max_height; *array = ALLOC_CLEAR_MULT(pumitem_T, height); if (*array == NULL) goto failed; ! /* Add an empty line above and below, looks better. */ (*array)->pum_text = vim_strsave((char_u *)""); (*array + height - 1)->pum_text = vim_strsave((char_u *)""); --- 1181,1202 ---- height = 2 + ga.ga_len; ! // If there are long items and the height is below the limit: split lines if (long_item_count > 0 && height + long_item_count <= max_height) { split_long_items = TRUE; height += long_item_count; } ! // Limit to half the window height, it has to fit above or below the mouse ! // position. if (height > max_height) height = max_height; *array = ALLOC_CLEAR_MULT(pumitem_T, height); if (*array == NULL) goto failed; ! // Add an empty line above and below, looks better. (*array)->pum_text = vim_strsave((char_u *)""); (*array + height - 1)->pum_text = vim_strsave((char_u *)""); *************** *** 1246,1252 **** vim_strncpy(p + ind, item->start + skip, copylen); (*array)[line].pum_text = p; ! item->indent = 0; /* wrapped line has no indent */ ++line; } } --- 1246,1252 ---- vim_strncpy(p + ind, item->start + skip, copylen); (*array)[line].pum_text = p; ! item->indent = 0; // wrapped line has no indent ++line; } } *************** *** 1415,1421 **** pum_selected = -1; pum_first = 0; # ifdef FEAT_BEVAL_TERM ! p_bevalterm = TRUE; /* track mouse movement */ mch_setmouse(TRUE); # endif --- 1415,1421 ---- pum_selected = -1; pum_first = 0; # ifdef FEAT_BEVAL_TERM ! p_bevalterm = TRUE; // track mouse movement mch_setmouse(TRUE); # endif *************** *** 1435,1447 **** break; else if (c == CAR || c == NL) { ! /* enter: select current item, if any, and close */ pum_execute_menu(menu, mode); break; } else if (c == 'k' || c == K_UP || c == K_MOUSEUP) { ! /* cursor up: select previous item */ while (pum_selected > 0) { --pum_selected; --- 1435,1447 ---- break; else if (c == CAR || c == NL) { ! // enter: select current item, if any, and close pum_execute_menu(menu, mode); break; } else if (c == 'k' || c == K_UP || c == K_MOUSEUP) { ! // cursor up: select previous item while (pum_selected > 0) { --pum_selected; *************** *** 1451,1457 **** } else if (c == 'j' || c == K_DOWN || c == K_MOUSEDOWN) { ! /* cursor down: select next item */ while (pum_selected < pum_size - 1) { ++pum_selected; --- 1451,1457 ---- } else if (c == 'j' || c == K_DOWN || c == K_MOUSEDOWN) { ! // cursor down: select next item while (pum_selected < pum_size - 1) { ++pum_selected; *************** *** 1461,1479 **** } else if (c == K_RIGHTMOUSE) { ! /* Right mouse down: reposition the menu. */ vungetc(c); break; } else if (c == K_LEFTDRAG || c == K_RIGHTDRAG || c == K_MOUSEMOVE) { ! /* mouse moved: select item in the mouse row */ pum_select_mouse_pos(); } else if (c == K_LEFTMOUSE || c == K_LEFTMOUSE_NM || c == K_RIGHTRELEASE) { ! /* left mouse click: select clicked item, if any, and close; ! * right mouse release: select clicked item, close if any */ pum_select_mouse_pos(); if (pum_selected >= 0) { --- 1461,1479 ---- } else if (c == K_RIGHTMOUSE) { ! // Right mouse down: reposition the menu. vungetc(c); break; } else if (c == K_LEFTDRAG || c == K_RIGHTDRAG || c == K_MOUSEMOVE) { ! // mouse moved: select item in the mouse row pum_select_mouse_pos(); } else if (c == K_LEFTMOUSE || c == K_LEFTMOUSE_NM || c == K_RIGHTRELEASE) { ! // left mouse click: select clicked item, if any, and close; ! // right mouse release: select clicked item, close if any pum_select_mouse_pos(); if (pum_selected >= 0) { *************** *** 1500,1507 **** if (!use_mouse_pos) { ! /* Hack: set mouse position at the cursor so that the menu pops up ! * around there. */ mouse_row = curwin->w_winrow + curwin->w_wrow; mouse_col = curwin->w_wincol + curwin->w_wcol; } --- 1500,1507 ---- if (!use_mouse_pos) { ! // Hack: set mouse position at the cursor so that the menu pops up ! // around there. mouse_row = curwin->w_winrow + curwin->w_wrow; mouse_col = curwin->w_wincol + curwin->w_wcol; } *** ../vim-8.1.2393/src/pty.c 2019-11-02 22:54:37.405188813 +0100 --- src/pty.c 2019-12-05 20:55:12.922786264 +0100 *************** *** 20,45 **** * copyright notice below. */ ! /* Copyright (c) 1993 ! * Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) ! * Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) ! * Copyright (c) 1987 Oliver Laumann ! * ! * This program is free software; you can redistribute it and/or modify ! * it under the terms of the GNU General Public License as published by ! * the Free Software Foundation; either version 2, or (at your option) ! * any later version. ! * ! * This program is distributed in the hope that it will be useful, ! * but WITHOUT ANY WARRANTY; without even the implied warranty of ! * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! * GNU General Public License for more details. ! * ! * You should have received a copy of the GNU General Public License ! * along with this program (see the file COPYING); if not, write to the ! * Free Software Foundation, Inc., ! * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA ! */ #include "vim.h" --- 20,44 ---- * copyright notice below. */ ! // Copyright (c) 1993 ! // Juergen Weigert (jnweiger@immd4.informatik.uni-erlangen.de) ! // Michael Schroeder (mlschroe@immd4.informatik.uni-erlangen.de) ! // Copyright (c) 1987 Oliver Laumann ! // ! // This program is free software; you can redistribute it and/or modify ! // it under the terms of the GNU General Public License as published by ! // the Free Software Foundation; either version 2, or (at your option) ! // any later version. ! // ! // This program is distributed in the hope that it will be useful, ! // but WITHOUT ANY WARRANTY; without even the implied warranty of ! // MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the ! // GNU General Public License for more details. ! // ! // You should have received a copy of the GNU General Public License ! // along with this program (see the file COPYING); if not, write to the ! // Free Software Foundation, Inc., ! // 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA #include "vim.h" *************** *** 124,130 **** # define PTYRANGE1 "0123456789abcdef" #endif ! /* SVR4 pseudo ttys don't seem to work with SCO-5 */ #ifdef M_UNIX # undef HAVE_SVR4_PTYS #endif --- 123,129 ---- # define PTYRANGE1 "0123456789abcdef" #endif ! // SVR4 pseudo ttys don't seem to work with SCO-5 #ifdef M_UNIX # undef HAVE_SVR4_PTYS #endif *************** *** 240,246 **** { char *m, *s; int f; ! /* used for opening a new pty-pair: */ static char PtyName[32]; static char TtyName[32]; --- 239,245 ---- { char *m, *s; int f; ! // used for opening a new pty-pair: static char PtyName[32]; static char TtyName[32]; *************** *** 289,295 **** { int f; stat_T buf; ! /* used for opening a new pty-pair: */ static char TtyName[32]; if ((f = open("/dev/ptc", O_RDWR | O_NOCTTY | O_NONBLOCK | O_EXTRA, 0)) < 0) --- 288,294 ---- { int f; stat_T buf; ! // used for opening a new pty-pair: static char TtyName[32]; if ((f = open("/dev/ptc", O_RDWR | O_NOCTTY | O_NONBLOCK | O_EXTRA, 0)) < 0) *************** *** 309,316 **** #if defined(HAVE_SVR4_PTYS) && !defined(PTY_DONE) && !defined(hpux) \ && !(defined(MACOS_X) && !defined(MAC_OS_X_VERSION_10_6)) ! /* NOTE: Even though HPUX can have /dev/ptmx, the code below doesn't work! ! * Same for Mac OS X Leopard (10.5). */ #define PTY_DONE int mch_openpty(char **ttyn) --- 308,315 ---- #if defined(HAVE_SVR4_PTYS) && !defined(PTY_DONE) && !defined(hpux) \ && !(defined(MACOS_X) && !defined(MAC_OS_X_VERSION_10_6)) ! // NOTE: Even though HPUX can have /dev/ptmx, the code below doesn't work! ! // Same for Mac OS X Leopard (10.5). #define PTY_DONE int mch_openpty(char **ttyn) *************** *** 318,324 **** int f; char *m; RETSIGTYPE (*sigcld) SIGPROTOARG; ! /* used for opening a new pty-pair: */ static char TtyName[32]; if ((f = open("/dev/ptmx", O_RDWR | O_NOCTTY | O_EXTRA, 0)) == -1) --- 317,323 ---- int f; char *m; RETSIGTYPE (*sigcld) SIGPROTOARG; ! // used for opening a new pty-pair: static char TtyName[32]; if ((f = open("/dev/ptmx", O_RDWR | O_NOCTTY | O_EXTRA, 0)) == -1) *************** *** 354,363 **** mch_openpty(char **ttyn) { int f; ! /* used for opening a new pty-pair: */ static char TtyName[32]; ! /* a dumb looking loop replaced by mycrofts code: */ if ((f = open("/dev/ptc", O_RDWR | O_NOCTTY | O_EXTRA)) < 0) return -1; vim_strncpy((char_u *)TtyName, (char_u *)ttyname(f), sizeof(TtyName) - 1); --- 353,362 ---- mch_openpty(char **ttyn) { int f; ! // used for opening a new pty-pair: static char TtyName[32]; ! // a dumb looking loop replaced by mycrofts code: if ((f = open("/dev/ptc", O_RDWR | O_NOCTTY | O_EXTRA)) < 0) return -1; vim_strncpy((char_u *)TtyName, (char_u *)ttyname(f), sizeof(TtyName) - 1); *************** *** 401,407 **** { char *p, *q, *l, *d; int f; ! /* used for opening a new pty-pair: */ static char PtyName[32]; static char TtyName[32]; --- 400,406 ---- { char *p, *q, *l, *d; int f; ! // used for opening a new pty-pair: static char PtyName[32]; static char TtyName[32]; *************** *** 425,437 **** continue; } #if defined(SUN_SYSTEM) && defined(TIOCGPGRP) && !defined(SUNOS3) ! /* Hack to ensure that the slave side of the pty is ! * unused. May not work in anything other than SunOS4.1 ! */ { int pgrp; ! /* tcgetpgrp does not work (uses TIOCGETPGRP)! */ if (ioctl(f, TIOCGPGRP, (char *)&pgrp) != -1 || errno != EIO) { close(f); --- 424,435 ---- continue; } #if defined(SUN_SYSTEM) && defined(TIOCGPGRP) && !defined(SUNOS3) ! // Hack to ensure that the slave side of the pty is ! // unused. May not work in anything other than SunOS4.1 { int pgrp; ! // tcgetpgrp does not work (uses TIOCGETPGRP)! if (ioctl(f, TIOCGPGRP, (char *)&pgrp) != -1 || errno != EIO) { close(f); *************** *** 474,477 **** return isatty(fd); } ! #endif /* FEAT_GUI || FEAT_JOB_CHANNEL */ --- 472,475 ---- return isatty(fd); } ! #endif // FEAT_GUI || FEAT_JOB_CHANNEL *** ../vim-8.1.2393/src/quickfix.c 2019-11-24 22:13:53.902251675 +0100 --- src/quickfix.c 2019-12-05 20:55:33.934710425 +0100 *************** *** 7880,7886 **** curwin->w_llist = qi; } } ! #endif /* FEAT_QUICKFIX */ #if defined(FEAT_EVAL) || defined(PROTO) # ifdef FEAT_QUICKFIX --- 7880,7886 ---- curwin->w_llist = qi; } } ! #endif // FEAT_QUICKFIX #if defined(FEAT_EVAL) || defined(PROTO) # ifdef FEAT_QUICKFIX *** ../vim-8.1.2393/src/regexp.c 2019-11-10 00:13:46.434916175 +0100 --- src/regexp.c 2019-12-05 21:09:56.631662972 +0100 *************** *** 12,20 **** #include "vim.h" #ifdef DEBUG ! /* show/save debugging data when BT engine is used */ # define BT_REGEXP_DUMP ! /* save the debugging data to a file instead of displaying it */ # define BT_REGEXP_LOG # define BT_REGEXP_DEBUG_LOG # define BT_REGEXP_DEBUG_LOG_NAME "bt_regexp_debug.log" --- 12,20 ---- #include "vim.h" #ifdef DEBUG ! // show/save debugging data when BT engine is used # define BT_REGEXP_DUMP ! // save the debugging data to a file instead of displaying it # define BT_REGEXP_LOG # define BT_REGEXP_DEBUG_LOG # define BT_REGEXP_DEBUG_LOG_NAME "bt_regexp_debug.log" *************** *** 58,65 **** */ #define UCHARAT(p) ((int)*(char_u *)(p)) ! /* Used for an error (down from) vim_regcomp(): give the error message, set ! * rc_did_emsg and return NULL */ #define EMSG_RET_NULL(m) return (emsg((m)), rc_did_emsg = TRUE, (void *)NULL) #define IEMSG_RET_NULL(m) return (iemsg((m)), rc_did_emsg = TRUE, (void *)NULL) #define EMSG_RET_FAIL(m) return (emsg((m)), rc_did_emsg = TRUE, FAIL) --- 58,65 ---- */ #define UCHARAT(p) ((int)*(char_u *)(p)) ! // Used for an error (down from) vim_regcomp(): give the error message, set ! // rc_did_emsg and return NULL #define EMSG_RET_NULL(m) return (emsg((m)), rc_did_emsg = TRUE, (void *)NULL) #define IEMSG_RET_NULL(m) return (iemsg((m)), rc_did_emsg = TRUE, (void *)NULL) #define EMSG_RET_FAIL(m) return (emsg((m)), rc_did_emsg = TRUE, FAIL) *************** *** 90,100 **** #define MULTI_MULT 2 // return values for regmatch() ! #define RA_FAIL 1 /* something failed, abort */ ! #define RA_CONT 2 /* continue in inner loop */ ! #define RA_BREAK 3 /* break inner loop */ ! #define RA_MATCH 4 /* successful match */ ! #define RA_NOMATCH 5 /* didn't match */ /* * Return NOT_MULTI if c is not a "multi" operator. --- 90,100 ---- #define MULTI_MULT 2 // return values for regmatch() ! #define RA_FAIL 1 // something failed, abort ! #define RA_CONT 2 // continue in inner loop ! #define RA_BREAK 3 // break inner loop ! #define RA_MATCH 4 // successful match ! #define RA_NOMATCH 5 // didn't match /* * Return NOT_MULTI if c is not a "multi" operator. *************** *** 281,317 **** #define ri_upper(c) (c < 0x100 && (class_tab[c] & RI_UPPER)) #define ri_white(c) (c < 0x100 && (class_tab[c] & RI_WHITE)) ! /* flags for regflags */ ! #define RF_ICASE 1 /* ignore case */ ! #define RF_NOICASE 2 /* don't ignore case */ ! #define RF_HASNL 4 /* can match a NL */ ! #define RF_ICOMBINE 8 /* ignore combining characters */ ! #define RF_LOOKBH 16 /* uses "\@<=" or "\@?@ACDFHIKLMOPSUVWX[_acdfhiklmnopsuvwxz{|~"; #else ! /* META[] is used often enough to justify turning it into a table. */ static char_u META_flags[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! /* % & ( ) * + . */ 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, ! /* 1 2 3 4 5 6 7 8 9 < = > ? */ 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, ! /* @ A C D F H I K L M O */ 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, ! /* P S U V W X Z [ _ */ 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, ! /* a c d f h i k l m n o */ 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, ! /* p s u v w x z { | ~ */ 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1 }; #endif ! static int curchr; /* currently parsed character */ ! /* Previous character. Note: prevchr is sometimes -1 when we are not at the ! * start, eg in /[ ^I]^ the pattern was never found even if it existed, ! * because ^ was taken to be magic -- webb */ static int prevchr; ! static int prevprevchr; /* previous-previous character */ ! static int nextchr; /* used for ungetchr() */ ! /* arguments for reg() */ ! #define REG_NOPAREN 0 /* toplevel reg() */ ! #define REG_PAREN 1 /* \(\) */ ! #define REG_ZPAREN 2 /* \z(\) */ ! #define REG_NPAREN 3 /* \%(\) */ typedef struct { --- 320,357 ---- #ifdef EBCDIC static char_u META[] = "%&()*+.123456789<=>?@ACDFHIKLMOPSUVWX[_acdfhiklmnopsuvwxz{|~"; #else ! // META[] is used often enough to justify turning it into a table. static char_u META_flags[] = { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, ! // % & ( ) * + . 0, 0, 0, 0, 0, 1, 1, 0, 1, 1, 1, 1, 0, 0, 1, 0, ! // 1 2 3 4 5 6 7 8 9 < = > ? 0, 1, 1, 1, 1, 1, 1, 1, 1, 1, 0, 0, 1, 1, 1, 1, ! // @ A C D F H I K L M O 1, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 0, 1, ! // P S U V W X Z [ _ 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 0, 0, 0, 1, ! // a c d f h i k l m n o 0, 1, 0, 1, 1, 0, 1, 0, 1, 1, 0, 1, 1, 1, 1, 1, ! // p s u v w x z { | ~ 1, 0, 0, 1, 0, 1, 1, 1, 1, 0, 1, 1, 1, 0, 1 }; #endif ! static int curchr; // currently parsed character ! // Previous character. Note: prevchr is sometimes -1 when we are not at the ! // start, eg in /[ ^I]^ the pattern was never found even if it existed, ! // because ^ was taken to be magic -- webb static int prevchr; ! static int prevprevchr; // previous-previous character ! static int nextchr; // used for ungetchr() ! // arguments for reg() ! #define REG_NOPAREN 0 // toplevel reg() ! #define REG_PAREN 1 // \(\) ! #define REG_ZPAREN 2 // \z(\) ! #define REG_NPAREN 3 // \%(\) typedef struct { *************** *** 477,484 **** return 0; } ! static int reg_cpo_lit; /* 'cpoptions' contains 'l' flag */ ! static int reg_cpo_bsl; /* 'cpoptions' contains '\' flag */ static void get_cpo_flags(void) --- 477,484 ---- return 0; } ! static int reg_cpo_lit; // 'cpoptions' contains 'l' flag ! static int reg_cpo_bsl; // 'cpoptions' contains '\' flag static void get_cpo_flags(void) *************** *** 497,503 **** { int l; ! if (*p == '^') /* Complement of range. */ ++p; if (*p == ']' || *p == '-') ++p; --- 497,503 ---- { int l; ! if (*p == '^') // Complement of range. ++p; if (*p == ']' || *p == '-') ++p; *************** *** 523,529 **** && get_equi_class(&p) == 0 && get_coll_element(&p) == 0 && *p != NUL) ! ++p; /* it is not a class name and not NUL */ } else ++p; --- 523,529 ---- && get_equi_class(&p) == 0 && get_coll_element(&p) == 0 && *p != NUL) ! ++p; // it is not a class name and not NUL } else ++p; *************** *** 559,565 **** for (; p[0] != NUL; MB_PTR_ADV(p)) { ! if (p[0] == dirc) /* found end of regexp */ break; if ((p[0] == '[' && mymagic >= MAGIC_ON) || (p[0] == '\\' && p[1] == '[' && mymagic <= MAGIC_OFF)) --- 559,565 ---- for (; p[0] != NUL; MB_PTR_ADV(p)) { ! if (p[0] == dirc) // found end of regexp break; if ((p[0] == '[' && mymagic >= MAGIC_ON) || (p[0] == '\\' && p[1] == '[' && mymagic <= MAGIC_OFF)) *************** *** 572,578 **** { if (dirc == '?' && newp != NULL && p[1] == '?') { ! /* change "\?" to "?", make a copy first. */ if (*newp == NULL) { *newp = vim_strsave(startp); --- 572,578 ---- { if (dirc == '?' && newp != NULL && p[1] == '?') { ! // change "\?" to "?", make a copy first. if (*newp == NULL) { *newp = vim_strsave(startp); *************** *** 585,591 **** ++p; } else ! ++p; /* skip next character */ if (*p == 'v') mymagic = MAGIC_ALL; else if (*p == 'V') --- 585,591 ---- ++p; } else ! ++p; // skip next character if (*p == 'v') mymagic = MAGIC_ALL; else if (*p == 'V') *************** *** 598,604 **** /* * Functions for getting characters from the regexp input. */ ! static int prevchr_len; /* byte length of previous char */ static int at_start; // True when on the first character static int prev_at_start; // True when on the second character --- 598,604 ---- /* * Functions for getting characters from the regexp input. */ ! static int prevchr_len; // byte length of previous char static int at_start; // True when on the first character static int prev_at_start; // True when on the second character *************** *** 666,672 **** case '.': case '[': case '~': ! /* magic when 'magic' is on */ if (reg_magic >= MAGIC_ON) curchr = Magic(curchr); break; --- 666,672 ---- case '.': case '[': case '~': ! // magic when 'magic' is on if (reg_magic >= MAGIC_ON) curchr = Magic(curchr); break; *************** *** 683,705 **** case '|': case '<': case '>': ! case '#': /* future ext. */ ! case '"': /* future ext. */ ! case '\'': /* future ext. */ ! case ',': /* future ext. */ ! case '-': /* future ext. */ ! case ':': /* future ext. */ ! case ';': /* future ext. */ ! case '`': /* future ext. */ ! case '/': /* Can't be used in / command */ ! /* magic only after "\v" */ if (reg_magic == MAGIC_ALL) curchr = Magic(curchr); break; case '*': ! /* * is not magic as the very first character, eg "?*ptr", when ! * after '^', eg "/^*ptr" and when after "\(", "\|", "\&". But ! * "\(\*" is not magic, thus must be magic if "after_slash" */ if (reg_magic >= MAGIC_ON && !at_start && !(prev_at_start && prevchr == Magic('^')) --- 683,705 ---- case '|': case '<': case '>': ! case '#': // future ext. ! case '"': // future ext. ! case '\'': // future ext. ! case ',': // future ext. ! case '-': // future ext. ! case ':': // future ext. ! case ';': // future ext. ! case '`': // future ext. ! case '/': // Can't be used in / command ! // magic only after "\v" if (reg_magic == MAGIC_ALL) curchr = Magic(curchr); break; case '*': ! // * is not magic as the very first character, eg "?*ptr", when ! // after '^', eg "/^*ptr" and when after "\(", "\|", "\&". But ! // "\(\*" is not magic, thus must be magic if "after_slash" if (reg_magic >= MAGIC_ON && !at_start && !(prev_at_start && prevchr == Magic('^')) *************** *** 710,717 **** curchr = Magic('*'); break; case '^': ! /* '^' is only magic as the very first character and if it's after ! * "\(", "\|", "\&' or "\n" */ if (reg_magic >= MAGIC_OFF && (at_start || reg_magic == MAGIC_ALL --- 710,717 ---- curchr = Magic('*'); break; case '^': ! // '^' is only magic as the very first character and if it's after ! // "\(", "\|", "\&' or "\n" if (reg_magic >= MAGIC_OFF && (at_start || reg_magic == MAGIC_ALL *************** *** 728,741 **** } break; case '$': ! /* '$' is only magic as the very last char and if it's in front of ! * either "\|", "\)", "\&", or "\n" */ if (reg_magic >= MAGIC_OFF) { char_u *p = regparse + 1; int is_magic_all = (reg_magic == MAGIC_ALL); ! /* ignore \c \C \m \M \v \V and \Z after '$' */ while (p[0] == '\\' && (p[1] == 'c' || p[1] == 'C' || p[1] == 'm' || p[1] == 'M' || p[1] == 'v' || p[1] == 'V' || p[1] == 'Z')) --- 728,741 ---- } break; case '$': ! // '$' is only magic as the very last char and if it's in front of ! // either "\|", "\)", "\&", or "\n" if (reg_magic >= MAGIC_OFF) { char_u *p = regparse + 1; int is_magic_all = (reg_magic == MAGIC_ALL); ! // ignore \c \C \m \M \v \V and \Z after '$' while (p[0] == '\\' && (p[1] == 'c' || p[1] == 'C' || p[1] == 'm' || p[1] == 'M' || p[1] == 'v' || p[1] == 'V' || p[1] == 'Z')) *************** *** 761,767 **** int c = regparse[1]; if (c == NUL) ! curchr = '\\'; /* trailing '\' */ else if ( #ifdef EBCDIC vim_strchr(META, c) --- 761,767 ---- int c = regparse[1]; if (c == NUL) ! curchr = '\\'; // trailing '\' else if ( #ifdef EBCDIC vim_strchr(META, c) *************** *** 779,785 **** */ curchr = -1; prev_at_start = at_start; ! at_start = FALSE; /* be able to say "/\*ptr" */ ++regparse; ++after_slash; peekchr(); --- 779,785 ---- */ curchr = -1; prev_at_start = at_start; ! at_start = FALSE; // be able to say "/\*ptr" ++regparse; ++after_slash; peekchr(); *************** *** 825,831 **** static void skipchr(void) { ! /* peekchr() eats a backslash, do the same here */ if (*regparse == '\\') prevchr_len = 1; else --- 825,831 ---- static void skipchr(void) { ! // peekchr() eats a backslash, do the same here if (*regparse == '\\') prevchr_len = 1; else *************** *** 833,839 **** if (regparse[prevchr_len] != NUL) { if (enc_utf8) ! /* exclude composing chars that mb_ptr2len does include */ prevchr_len += utf_ptr2len(regparse + prevchr_len); else if (has_mbyte) prevchr_len += (*mb_ptr2len)(regparse + prevchr_len); --- 833,839 ---- if (regparse[prevchr_len] != NUL) { if (enc_utf8) ! // exclude composing chars that mb_ptr2len does include prevchr_len += utf_ptr2len(regparse + prevchr_len); else if (has_mbyte) prevchr_len += (*mb_ptr2len)(regparse + prevchr_len); *************** *** 845,851 **** at_start = FALSE; prevprevchr = prevchr; prevchr = curchr; ! curchr = nextchr; /* use previously unget char, or -1 */ nextchr = -1; } --- 845,851 ---- at_start = FALSE; prevprevchr = prevchr; prevchr = curchr; ! curchr = nextchr; // use previously unget char, or -1 nextchr = -1; } *************** *** 891,898 **** at_start = prev_at_start; prev_at_start = FALSE; ! /* Backup regparse, so that it's at the same position as before the ! * getchr(). */ regparse -= prevchr_len; } --- 891,898 ---- at_start = prev_at_start; prev_at_start = FALSE; ! // Backup regparse, so that it's at the same position as before the ! // getchr(). regparse -= prevchr_len; } *************** *** 946,952 **** nr *= 10; nr += c - '0'; ++regparse; ! curchr = -1; /* no longer valid */ } if (i == 0) --- 946,952 ---- nr *= 10; nr += c - '0'; ++regparse; ! curchr = -1; // no longer valid } if (i == 0) *************** *** 999,1011 **** if (*regparse == '-') { ! /* Starts with '-', so reverse the range later */ regparse++; reverse = TRUE; } first_char = regparse; *minval = getdigits(®parse); ! if (*regparse == ',') /* There is a comma */ { if (vim_isdigit(*++regparse)) *maxval = getdigits(®parse); --- 999,1011 ---- if (*regparse == '-') { ! // Starts with '-', so reverse the range later regparse++; reverse = TRUE; } first_char = regparse; *minval = getdigits(®parse); ! if (*regparse == ',') // There is a comma { if (vim_isdigit(*++regparse)) *maxval = getdigits(®parse); *************** *** 1013,1023 **** *maxval = MAX_LIMIT; } else if (VIM_ISDIGIT(*first_char)) ! *maxval = *minval; /* It was \{n} or \{-n} */ else ! *maxval = MAX_LIMIT; /* It was \{} or \{-} */ if (*regparse == '\\') ! regparse++; /* Allow either \{...} or \{...\} */ if (*regparse != '}') EMSG2_RET_FAIL(_("E554: Syntax error in %s{...}"), reg_magic == MAGIC_ALL); --- 1013,1023 ---- *maxval = MAX_LIMIT; } else if (VIM_ISDIGIT(*first_char)) ! *maxval = *minval; // It was \{n} or \{-n} else ! *maxval = MAX_LIMIT; // It was \{} or \{-} if (*regparse == '\\') ! regparse++; // Allow either \{...} or \{...\} if (*regparse != '}') EMSG2_RET_FAIL(_("E554: Syntax error in %s{...}"), reg_magic == MAGIC_ALL); *************** *** 1032,1038 **** *minval = *maxval; *maxval = tmp; } ! skipchr(); /* let's be friends with the lexer again */ return OK; } --- 1032,1038 ---- *minval = *maxval; *maxval = tmp; } ! skipchr(); // let's be friends with the lexer again return OK; } *************** *** 1087,1093 **** buf_T *reg_buf; linenr_T reg_firstlnum; linenr_T reg_maxline; ! int reg_line_lbr; /* "\n" in string is line break */ // The current match-position is stord in these variables: linenr_T lnum; // line number, relative to first line --- 1087,1093 ---- buf_T *reg_buf; linenr_T reg_firstlnum; linenr_T reg_maxline; ! int reg_line_lbr; // "\n" in string is line break // The current match-position is stord in these variables: linenr_T lnum; // line number, relative to first line *************** *** 1100,1116 **** // cleared #endif ! /* Internal copy of 'ignorecase'. It is set at each call to vim_regexec(). ! * Normally it gets the value of "rm_ic" or "rmm_ic", but when the pattern ! * contains '\c' or '\C' the value is overruled. */ int reg_ic; ! /* Similar to "reg_ic", but only for 'combining' characters. Set with \Z ! * flag in the regexp. Defaults to false, always. */ int reg_icombine; ! /* Copy of "rmm_maxcol": maximum column to search for a match. Zero when ! * there is no maximum. */ colnr_T reg_maxcol; // State for the NFA engine regexec. --- 1100,1116 ---- // cleared #endif ! // Internal copy of 'ignorecase'. It is set at each call to vim_regexec(). ! // Normally it gets the value of "rm_ic" or "rmm_ic", but when the pattern ! // contains '\c' or '\C' the value is overruled. int reg_ic; ! // Similar to "reg_ic", but only for 'combining' characters. Set with \Z ! // flag in the regexp. Defaults to false, always. int reg_icombine; ! // Copy of "rmm_maxcol": maximum column to search for a match. Zero when ! // there is no maximum. colnr_T reg_maxcol; // State for the NFA engine regexec. *************** *** 1149,1172 **** static char_u * reg_getline(linenr_T lnum) { ! /* when looking behind for a match/no-match lnum is negative. But we ! * can't go before line 1 */ if (rex.reg_firstlnum + lnum < 1) return NULL; if (lnum > rex.reg_maxline) ! /* Must have matched the "\n" in the last line. */ return (char_u *)""; return ml_get_buf(rex.reg_buf, rex.reg_firstlnum + lnum, FALSE); } #ifdef FEAT_SYN_HL ! static char_u *reg_startzp[NSUBEXP]; /* Workspace to mark beginning */ ! static char_u *reg_endzp[NSUBEXP]; /* and end of \z(...\) matches */ ! static lpos_T reg_startzpos[NSUBEXP]; /* idem, beginning pos */ ! static lpos_T reg_endzpos[NSUBEXP]; /* idem, end pos */ #endif ! /* TRUE if using multi-line regexp. */ #define REG_MULTI (rex.reg_match == NULL) #ifdef FEAT_SYN_HL --- 1149,1172 ---- static char_u * reg_getline(linenr_T lnum) { ! // when looking behind for a match/no-match lnum is negative. But we ! // can't go before line 1 if (rex.reg_firstlnum + lnum < 1) return NULL; if (lnum > rex.reg_maxline) ! // Must have matched the "\n" in the last line. return (char_u *)""; return ml_get_buf(rex.reg_buf, rex.reg_firstlnum + lnum, FALSE); } #ifdef FEAT_SYN_HL ! static char_u *reg_startzp[NSUBEXP]; // Workspace to mark beginning ! static char_u *reg_endzp[NSUBEXP]; // and end of \z(...\) matches ! static lpos_T reg_startzpos[NSUBEXP]; // idem, beginning pos ! static lpos_T reg_endzpos[NSUBEXP]; // idem, end pos #endif ! // TRUE if using multi-line regexp. #define REG_MULTI (rex.reg_match == NULL) #ifdef FEAT_SYN_HL *************** *** 1240,1246 **** colnr_T start2, end2; colnr_T cols; ! /* Check if the buffer is the current buffer. */ if (rex.reg_buf != curbuf || VIsual.lnum == 0) return FALSE; --- 1240,1246 ---- colnr_T start2, end2; colnr_T cols; ! // Check if the buffer is the current buffer. if (rex.reg_buf != curbuf || VIsual.lnum == 0) return FALSE; *************** *** 1311,1317 **** prog = REG_MULTI ? rex.reg_mmatch->regprog : rex.reg_match->regprog; if (prog->engine == &nfa_regengine) ! /* For NFA matcher we don't check the magic */ return FALSE; if (UCHARAT(((bt_regprog_T *)prog)->program) != REGMAGIC) --- 1311,1317 ---- prog = REG_MULTI ? rex.reg_mmatch->regprog : rex.reg_match->regprog; if (prog->engine == &nfa_regengine) ! // For NFA matcher we don't check the magic return FALSE; if (UCHARAT(((bt_regprog_T *)prog)->program) != REGMAGIC) *************** *** 1334,1340 **** { if (REG_MULTI) { ! /* Use 0xff to set lnum to -1 */ vim_memset(rex.reg_startpos, 0xff, sizeof(lpos_T) * NSUBEXP); vim_memset(rex.reg_endpos, 0xff, sizeof(lpos_T) * NSUBEXP); } --- 1334,1340 ---- { if (REG_MULTI) { ! // Use 0xff to set lnum to -1 vim_memset(rex.reg_startpos, 0xff, sizeof(lpos_T) * NSUBEXP); vim_memset(rex.reg_endpos, 0xff, sizeof(lpos_T) * NSUBEXP); } *************** *** 1355,1361 **** { if (REG_MULTI) { ! /* Use 0xff to set lnum to -1 */ vim_memset(reg_startzpos, 0xff, sizeof(lpos_T) * NSUBEXP); vim_memset(reg_endzpos, 0xff, sizeof(lpos_T) * NSUBEXP); } --- 1355,1361 ---- { if (REG_MULTI) { ! // Use 0xff to set lnum to -1 vim_memset(reg_startzpos, 0xff, sizeof(lpos_T) * NSUBEXP); vim_memset(reg_endzpos, 0xff, sizeof(lpos_T) * NSUBEXP); } *************** *** 1403,1420 **** *bytelen = 0; for (;;) { ! /* Since getting one line may invalidate the other, need to make copy. ! * Slow! */ if (rex.line != reg_tofree) { len = (int)STRLEN(rex.line); if (reg_tofree == NULL || len >= (int)reg_tofreelen) { ! len += 50; /* get some extra */ vim_free(reg_tofree); reg_tofree = alloc(len); if (reg_tofree == NULL) ! return RA_FAIL; /* out of memory!*/ reg_tofreelen = len; } STRCPY(reg_tofree, rex.line); --- 1403,1420 ---- *bytelen = 0; for (;;) { ! // Since getting one line may invalidate the other, need to make copy. ! // Slow! if (rex.line != reg_tofree) { len = (int)STRLEN(rex.line); if (reg_tofree == NULL || len >= (int)reg_tofreelen) { ! len += 50; // get some extra vim_free(reg_tofree); reg_tofree = alloc(len); if (reg_tofree == NULL) ! return RA_FAIL; // out of memory! reg_tofreelen = len; } STRCPY(reg_tofree, rex.line); *************** *** 1422,1428 **** rex.line = reg_tofree; } ! /* Get the line to compare with. */ p = reg_getline(clnum); if (clnum == end_lnum) len = end_col - ccol; --- 1422,1428 ---- rex.line = reg_tofree; } ! // Get the line to compare with. p = reg_getline(clnum); if (clnum == end_lnum) len = end_col - ccol; *************** *** 1430,1444 **** len = (int)STRLEN(p + ccol); if (cstrncmp(p + ccol, rex.input, &len) != 0) ! return RA_NOMATCH; /* doesn't match */ if (bytelen != NULL) *bytelen += len; if (clnum == end_lnum) ! break; /* match and at end! */ if (rex.lnum >= rex.reg_maxline) ! return RA_NOMATCH; /* text too short */ ! /* Advance to next line. */ reg_nextline(); if (bytelen != NULL) *bytelen = 0; --- 1430,1444 ---- len = (int)STRLEN(p + ccol); if (cstrncmp(p + ccol, rex.input, &len) != 0) ! return RA_NOMATCH; // doesn't match if (bytelen != NULL) *bytelen += len; if (clnum == end_lnum) ! break; // match and at end! if (rex.lnum >= rex.reg_maxline) ! return RA_NOMATCH; // text too short ! // Advance to next line. reg_nextline(); if (bytelen != NULL) *bytelen = 0; *************** *** 1448,1455 **** return RA_FAIL; } ! /* found a match! Note that rex.line may now point to a copy of the line, ! * that should not matter. */ return RA_MATCH; } --- 1448,1455 ---- return RA_FAIL; } ! // found a match! Note that rex.line may now point to a copy of the line, ! // that should not matter. return RA_MATCH; } *************** *** 1474,1530 **** } decomp_T; ! /* 0xfb20 - 0xfb4f */ static decomp_T decomp_table[0xfb4f-0xfb20+1] = { ! {0x5e2,0,0}, /* 0xfb20 alt ayin */ ! {0x5d0,0,0}, /* 0xfb21 alt alef */ ! {0x5d3,0,0}, /* 0xfb22 alt dalet */ ! {0x5d4,0,0}, /* 0xfb23 alt he */ ! {0x5db,0,0}, /* 0xfb24 alt kaf */ ! {0x5dc,0,0}, /* 0xfb25 alt lamed */ ! {0x5dd,0,0}, /* 0xfb26 alt mem-sofit */ ! {0x5e8,0,0}, /* 0xfb27 alt resh */ ! {0x5ea,0,0}, /* 0xfb28 alt tav */ ! {'+', 0, 0}, /* 0xfb29 alt plus */ ! {0x5e9, 0x5c1, 0}, /* 0xfb2a shin+shin-dot */ ! {0x5e9, 0x5c2, 0}, /* 0xfb2b shin+sin-dot */ ! {0x5e9, 0x5c1, 0x5bc}, /* 0xfb2c shin+shin-dot+dagesh */ ! {0x5e9, 0x5c2, 0x5bc}, /* 0xfb2d shin+sin-dot+dagesh */ ! {0x5d0, 0x5b7, 0}, /* 0xfb2e alef+patah */ ! {0x5d0, 0x5b8, 0}, /* 0xfb2f alef+qamats */ ! {0x5d0, 0x5b4, 0}, /* 0xfb30 alef+hiriq */ ! {0x5d1, 0x5bc, 0}, /* 0xfb31 bet+dagesh */ ! {0x5d2, 0x5bc, 0}, /* 0xfb32 gimel+dagesh */ ! {0x5d3, 0x5bc, 0}, /* 0xfb33 dalet+dagesh */ ! {0x5d4, 0x5bc, 0}, /* 0xfb34 he+dagesh */ ! {0x5d5, 0x5bc, 0}, /* 0xfb35 vav+dagesh */ ! {0x5d6, 0x5bc, 0}, /* 0xfb36 zayin+dagesh */ ! {0xfb37, 0, 0}, /* 0xfb37 -- UNUSED */ ! {0x5d8, 0x5bc, 0}, /* 0xfb38 tet+dagesh */ ! {0x5d9, 0x5bc, 0}, /* 0xfb39 yud+dagesh */ ! {0x5da, 0x5bc, 0}, /* 0xfb3a kaf sofit+dagesh */ ! {0x5db, 0x5bc, 0}, /* 0xfb3b kaf+dagesh */ ! {0x5dc, 0x5bc, 0}, /* 0xfb3c lamed+dagesh */ ! {0xfb3d, 0, 0}, /* 0xfb3d -- UNUSED */ ! {0x5de, 0x5bc, 0}, /* 0xfb3e mem+dagesh */ ! {0xfb3f, 0, 0}, /* 0xfb3f -- UNUSED */ ! {0x5e0, 0x5bc, 0}, /* 0xfb40 nun+dagesh */ ! {0x5e1, 0x5bc, 0}, /* 0xfb41 samech+dagesh */ ! {0xfb42, 0, 0}, /* 0xfb42 -- UNUSED */ ! {0x5e3, 0x5bc, 0}, /* 0xfb43 pe sofit+dagesh */ ! {0x5e4, 0x5bc,0}, /* 0xfb44 pe+dagesh */ ! {0xfb45, 0, 0}, /* 0xfb45 -- UNUSED */ ! {0x5e6, 0x5bc, 0}, /* 0xfb46 tsadi+dagesh */ ! {0x5e7, 0x5bc, 0}, /* 0xfb47 qof+dagesh */ ! {0x5e8, 0x5bc, 0}, /* 0xfb48 resh+dagesh */ ! {0x5e9, 0x5bc, 0}, /* 0xfb49 shin+dagesh */ ! {0x5ea, 0x5bc, 0}, /* 0xfb4a tav+dagesh */ ! {0x5d5, 0x5b9, 0}, /* 0xfb4b vav+holam */ ! {0x5d1, 0x5bf, 0}, /* 0xfb4c bet+rafe */ ! {0x5db, 0x5bf, 0}, /* 0xfb4d kaf+rafe */ ! {0x5e4, 0x5bf, 0}, /* 0xfb4e pe+rafe */ ! {0x5d0, 0x5dc, 0} /* 0xfb4f alef-lamed */ }; static void --- 1474,1530 ---- } decomp_T; ! // 0xfb20 - 0xfb4f static decomp_T decomp_table[0xfb4f-0xfb20+1] = { ! {0x5e2,0,0}, // 0xfb20 alt ayin ! {0x5d0,0,0}, // 0xfb21 alt alef ! {0x5d3,0,0}, // 0xfb22 alt dalet ! {0x5d4,0,0}, // 0xfb23 alt he ! {0x5db,0,0}, // 0xfb24 alt kaf ! {0x5dc,0,0}, // 0xfb25 alt lamed ! {0x5dd,0,0}, // 0xfb26 alt mem-sofit ! {0x5e8,0,0}, // 0xfb27 alt resh ! {0x5ea,0,0}, // 0xfb28 alt tav ! {'+', 0, 0}, // 0xfb29 alt plus ! {0x5e9, 0x5c1, 0}, // 0xfb2a shin+shin-dot ! {0x5e9, 0x5c2, 0}, // 0xfb2b shin+sin-dot ! {0x5e9, 0x5c1, 0x5bc}, // 0xfb2c shin+shin-dot+dagesh ! {0x5e9, 0x5c2, 0x5bc}, // 0xfb2d shin+sin-dot+dagesh ! {0x5d0, 0x5b7, 0}, // 0xfb2e alef+patah ! {0x5d0, 0x5b8, 0}, // 0xfb2f alef+qamats ! {0x5d0, 0x5b4, 0}, // 0xfb30 alef+hiriq ! {0x5d1, 0x5bc, 0}, // 0xfb31 bet+dagesh ! {0x5d2, 0x5bc, 0}, // 0xfb32 gimel+dagesh ! {0x5d3, 0x5bc, 0}, // 0xfb33 dalet+dagesh ! {0x5d4, 0x5bc, 0}, // 0xfb34 he+dagesh ! {0x5d5, 0x5bc, 0}, // 0xfb35 vav+dagesh ! {0x5d6, 0x5bc, 0}, // 0xfb36 zayin+dagesh ! {0xfb37, 0, 0}, // 0xfb37 -- UNUSED ! {0x5d8, 0x5bc, 0}, // 0xfb38 tet+dagesh ! {0x5d9, 0x5bc, 0}, // 0xfb39 yud+dagesh ! {0x5da, 0x5bc, 0}, // 0xfb3a kaf sofit+dagesh ! {0x5db, 0x5bc, 0}, // 0xfb3b kaf+dagesh ! {0x5dc, 0x5bc, 0}, // 0xfb3c lamed+dagesh ! {0xfb3d, 0, 0}, // 0xfb3d -- UNUSED ! {0x5de, 0x5bc, 0}, // 0xfb3e mem+dagesh ! {0xfb3f, 0, 0}, // 0xfb3f -- UNUSED ! {0x5e0, 0x5bc, 0}, // 0xfb40 nun+dagesh ! {0x5e1, 0x5bc, 0}, // 0xfb41 samech+dagesh ! {0xfb42, 0, 0}, // 0xfb42 -- UNUSED ! {0x5e3, 0x5bc, 0}, // 0xfb43 pe sofit+dagesh ! {0x5e4, 0x5bc,0}, // 0xfb44 pe+dagesh ! {0xfb45, 0, 0}, // 0xfb45 -- UNUSED ! {0x5e6, 0x5bc, 0}, // 0xfb46 tsadi+dagesh ! {0x5e7, 0x5bc, 0}, // 0xfb47 qof+dagesh ! {0x5e8, 0x5bc, 0}, // 0xfb48 resh+dagesh ! {0x5e9, 0x5bc, 0}, // 0xfb49 shin+dagesh ! {0x5ea, 0x5bc, 0}, // 0xfb4a tav+dagesh ! {0x5d5, 0x5b9, 0}, // 0xfb4b vav+holam ! {0x5d1, 0x5bf, 0}, // 0xfb4c bet+rafe ! {0x5db, 0x5bf, 0}, // 0xfb4d kaf+rafe ! {0x5e4, 0x5bf, 0}, // 0xfb4e pe+rafe ! {0x5d0, 0x5dc, 0} // 0xfb4f alef-lamed }; static void *************** *** 1561,1575 **** else result = MB_STRNICMP(s1, s2, *n); ! /* if it failed and it's utf8 and we want to combineignore: */ if (result != 0 && enc_utf8 && rex.reg_icombine) { char_u *str1, *str2; int c1, c2, c11, c12; int junk; ! /* we have to handle the strcmp ourselves, since it is necessary to ! * deal with the composing characters by ignoring them: */ str1 = s1; str2 = s2; c1 = c2 = 0; --- 1561,1575 ---- else result = MB_STRNICMP(s1, s2, *n); ! // if it failed and it's utf8 and we want to combineignore: if (result != 0 && enc_utf8 && rex.reg_icombine) { char_u *str1, *str2; int c1, c2, c11, c12; int junk; ! // we have to handle the strcmp ourselves, since it is necessary to ! // deal with the composing characters by ignoring them: str1 = s1; str2 = s2; c1 = c2 = 0; *************** *** 1612,1620 **** if (!rex.reg_ic || (!enc_utf8 && mb_char2len(c) > 1)) return vim_strchr(s, c); ! /* tolower() and toupper() can be slow, comparing twice should be a lot ! * faster (esp. when using MS Visual C++!). ! * For UTF-8 need to use folded case. */ if (enc_utf8 && c > 0x80) cc = utf_fold(c); else --- 1612,1620 ---- if (!rex.reg_ic || (!enc_utf8 && mb_char2len(c) > 1)) return vim_strchr(s, c); ! // tolower() and toupper() can be slow, comparing twice should be a lot ! // faster (esp. when using MS Visual C++!). ! // For UTF-8 need to use folded case. if (enc_utf8 && c > 0x80) cc = utf_fold(c); else *************** *** 1639,1645 **** } } else ! /* Faster version for when there are no multi-byte characters. */ for (p = s; *p != NUL; ++p) if (*p == c || *p == cc) return p; --- 1639,1645 ---- } } else ! // Faster version for when there are no multi-byte characters. for (p = s; *p != NUL; ++p) if (*p == c || *p == cc) return p; *************** *** 1647,1655 **** return NULL; } ! /*************************************************************** ! * regsub stuff * ! ***************************************************************/ /* * We should define ftpr as a pointer to a function returning a pointer to --- 1647,1655 ---- return NULL; } ! //////////////////////////////////////////////////////////////// ! // regsub stuff // ! //////////////////////////////////////////////////////////////// /* * We should define ftpr as a pointer to a function returning a pointer to *************** *** 1720,1755 **** { if (reg_prev_sub != NULL) { ! /* length = len(newsub) - 1 + len(prev_sub) + 1 */ prevlen = (int)STRLEN(reg_prev_sub); tmpsub = alloc(STRLEN(newsub) + prevlen); if (tmpsub != NULL) { ! /* copy prefix */ ! len = (int)(p - newsub); /* not including ~ */ mch_memmove(tmpsub, newsub, (size_t)len); ! /* interpret tilde */ mch_memmove(tmpsub + len, reg_prev_sub, (size_t)prevlen); ! /* copy postfix */ if (!magic) ! ++p; /* back off \ */ STRCPY(tmpsub + len + prevlen, p + 1); ! if (newsub != source) /* already allocated newsub */ vim_free(newsub); newsub = tmpsub; p = newsub + len + prevlen; } } else if (magic) ! STRMOVE(p, p + 1); /* remove '~' */ else ! STRMOVE(p, p + 2); /* remove '\~' */ --p; } else { ! if (*p == '\\' && p[1]) /* skip escaped characters */ ++p; if (has_mbyte) p += (*mb_ptr2len)(p) - 1; --- 1720,1755 ---- { if (reg_prev_sub != NULL) { ! // length = len(newsub) - 1 + len(prev_sub) + 1 prevlen = (int)STRLEN(reg_prev_sub); tmpsub = alloc(STRLEN(newsub) + prevlen); if (tmpsub != NULL) { ! // copy prefix ! len = (int)(p - newsub); // not including ~ mch_memmove(tmpsub, newsub, (size_t)len); ! // interpret tilde mch_memmove(tmpsub + len, reg_prev_sub, (size_t)prevlen); ! // copy postfix if (!magic) ! ++p; // back off backslash STRCPY(tmpsub + len + prevlen, p + 1); ! if (newsub != source) // already allocated newsub vim_free(newsub); newsub = tmpsub; p = newsub + len + prevlen; } } else if (magic) ! STRMOVE(p, p + 1); // remove '~' else ! STRMOVE(p, p + 2); // remove '\~' --p; } else { ! if (*p == '\\' && p[1]) // skip escaped characters ++p; if (has_mbyte) p += (*mb_ptr2len)(p) - 1; *************** *** 1757,1775 **** } vim_free(reg_prev_sub); ! if (newsub != source) /* newsub was allocated, just keep it */ reg_prev_sub = newsub; ! else /* no ~ found, need to save newsub */ reg_prev_sub = vim_strsave(newsub); return newsub; } #ifdef FEAT_EVAL ! static int can_f_submatch = FALSE; /* TRUE when submatch() can be used */ ! /* These pointers are used for reg_submatch(). Needed for when the ! * substitution string is an expression that contains a call to substitute() ! * and submatch(). */ typedef struct { regmatch_T *sm_match; regmmatch_T *sm_mmatch; --- 1757,1775 ---- } vim_free(reg_prev_sub); ! if (newsub != source) // newsub was allocated, just keep it reg_prev_sub = newsub; ! else // no ~ found, need to save newsub reg_prev_sub = vim_strsave(newsub); return newsub; } #ifdef FEAT_EVAL ! static int can_f_submatch = FALSE; // TRUE when submatch() can be used ! // These pointers are used for reg_submatch(). Needed for when the ! // substitution string is an expression that contains a call to substitute() ! // and submatch(). typedef struct { regmatch_T *sm_match; regmmatch_T *sm_mmatch; *************** *** 1778,1784 **** int sm_line_lbr; } regsubmatch_T; ! static regsubmatch_T rsm; /* can only be used when can_f_submatch is TRUE */ #endif #ifdef FEAT_EVAL --- 1778,1784 ---- int sm_line_lbr; } regsubmatch_T; ! static regsubmatch_T rsm; // can only be used when can_f_submatch is TRUE #endif #ifdef FEAT_EVAL *************** *** 1861,1867 **** int rex_in_use_save = rex_in_use; if (rex_in_use) ! /* Being called recursively, save the state. */ rex_save = rex; rex_in_use = TRUE; --- 1861,1867 ---- int rex_in_use_save = rex_in_use; if (rex_in_use) ! // Being called recursively, save the state. rex_save = rex; rex_in_use = TRUE; *************** *** 1894,1906 **** int rex_in_use_save = rex_in_use; if (rex_in_use) ! /* Being called recursively, save the state. */ rex_save = rex; rex_in_use = TRUE; rex.reg_match = NULL; rex.reg_mmatch = rmp; ! rex.reg_buf = curbuf; /* always works on the current buffer! */ rex.reg_firstlnum = lnum; rex.reg_maxline = curbuf->b_ml.ml_line_count - lnum; rex.reg_line_lbr = FALSE; --- 1894,1906 ---- int rex_in_use_save = rex_in_use; if (rex_in_use) ! // Being called recursively, save the state. rex_save = rex; rex_in_use = TRUE; rex.reg_match = NULL; rex.reg_mmatch = rmp; ! rex.reg_buf = curbuf; // always works on the current buffer! rex.reg_firstlnum = lnum; rex.reg_maxline = curbuf->b_ml.ml_line_count - lnum; rex.reg_line_lbr = FALSE; *************** *** 1930,1942 **** int no = -1; fptr_T func_all = (fptr_T)NULL; fptr_T func_one = (fptr_T)NULL; ! linenr_T clnum = 0; /* init for GCC */ ! int len = 0; /* init for GCC */ #ifdef FEAT_EVAL static char_u *eval_result = NULL; #endif ! /* Be paranoid... */ if ((source == NULL && expr == NULL) || dest == NULL) { emsg(_(e_null)); --- 1930,1942 ---- int no = -1; fptr_T func_all = (fptr_T)NULL; fptr_T func_one = (fptr_T)NULL; ! linenr_T clnum = 0; // init for GCC ! int len = 0; // init for GCC #ifdef FEAT_EVAL static char_u *eval_result = NULL; #endif ! // Be paranoid... if ((source == NULL && expr == NULL) || dest == NULL) { emsg(_(e_null)); *************** *** 1953,1962 **** if (expr != NULL || (source[0] == '\\' && source[1] == '=')) { #ifdef FEAT_EVAL ! /* To make sure that the length doesn't change between checking the ! * length and copying the string, and to speed up things, the ! * resulting string is saved from the call with "copy" == FALSE to the ! * call with "copy" == TRUE. */ if (copy) { if (eval_result != NULL) --- 1953,1962 ---- if (expr != NULL || (source[0] == '\\' && source[1] == '=')) { #ifdef FEAT_EVAL ! // To make sure that the length doesn't change between checking the ! // length and copying the string, and to speed up things, the ! // resulting string is saved from the call with "copy" == FALSE to the ! // call with "copy" == TRUE. if (copy) { if (eval_result != NULL) *************** *** 1973,1981 **** vim_free(eval_result); ! /* The expression may contain substitute(), which calls us ! * recursively. Make sure submatch() gets the text from the first ! * level. */ if (can_f_submatch) rsm_save = rsm; can_f_submatch = TRUE; --- 1973,1981 ---- vim_free(eval_result); ! // The expression may contain substitute(), which calls us ! // recursively. Make sure submatch() gets the text from the first ! // level. if (can_f_submatch) rsm_save = rsm; can_f_submatch = TRUE; *************** *** 2038,2046 **** for (s = eval_result; *s != NUL; MB_PTR_ADV(s)) { ! /* Change NL to CR, so that it becomes a line break, ! * unless called from vim_regexec_nl(). ! * Skip over a backslashed character. */ if (*s == NL && !rsm.sm_line_lbr) *s = CAR; else if (*s == '\\' && s[1] != NUL) --- 2038,2046 ---- for (s = eval_result; *s != NUL; MB_PTR_ADV(s)) { ! // Change NL to CR, so that it becomes a line break, ! // unless called from vim_regexec_nl(). ! // Skip over a backslashed character. if (*s == NL && !rsm.sm_line_lbr) *s = CAR; else if (*s == '\\' && s[1] != NUL) *************** *** 2059,2065 **** } if (had_backslash && backslash) { ! /* Backslashes will be consumed, need to double them. */ s = vim_strsave_escaped(eval_result, (char_u *)"\\"); if (s != NULL) { --- 2059,2065 ---- } if (had_backslash && backslash) { ! // Backslashes will be consumed, need to double them. s = vim_strsave_escaped(eval_result, (char_u *)"\\"); if (s != NULL) { *************** *** 2111,2121 **** } } } ! if (no < 0) /* Ordinary character. */ { if (c == K_SPECIAL && src[0] != NUL && src[1] != NUL) { ! /* Copy a special key as-is. */ if (copy) { *dst++ = c; --- 2111,2121 ---- } } } ! if (no < 0) // Ordinary character. { if (c == K_SPECIAL && src[0] != NUL && src[1] != NUL) { ! // Copy a special key as-is. if (copy) { *dst++ = c; *************** *** 2132,2149 **** if (c == '\\' && *src != NUL) { ! /* Check for abbreviations -- webb */ switch (*src) { case 'r': c = CAR; ++src; break; case 'n': c = NL; ++src; break; case 't': c = TAB; ++src; break; ! /* Oh no! \e already has meaning in subst pat :-( */ ! /* case 'e': c = ESC; ++src; break; */ case 'b': c = Ctrl_H; ++src; break; ! /* If "backslash" is TRUE the backslash will be removed ! * later. Used to insert a literal CR. */ default: if (backslash) { if (copy) --- 2132,2149 ---- if (c == '\\' && *src != NUL) { ! // Check for abbreviations -- webb switch (*src) { case 'r': c = CAR; ++src; break; case 'n': c = NL; ++src; break; case 't': c = TAB; ++src; break; ! // Oh no! \e already has meaning in subst pat :-( ! // case 'e': c = ESC; ++src; break; case 'b': c = Ctrl_H; ++src; break; ! // If "backslash" is TRUE the backslash will be removed ! // later. Used to insert a literal CR. default: if (backslash) { if (copy) *************** *** 2156,2169 **** else if (has_mbyte) c = mb_ptr2char(src - 1); ! /* Write to buffer, if copy is set. */ if (func_one != (fptr_T)NULL) ! /* Turbo C complains without the typecast */ func_one = (fptr_T)(func_one(&cc, c)); else if (func_all != (fptr_T)NULL) ! /* Turbo C complains without the typecast */ func_all = (fptr_T)(func_all(&cc, c)); ! else /* just copy */ cc = c; if (has_mbyte) --- 2156,2169 ---- else if (has_mbyte) c = mb_ptr2char(src - 1); ! // Write to buffer, if copy is set. if (func_one != (fptr_T)NULL) ! // Turbo C complains without the typecast func_one = (fptr_T)(func_one(&cc, c)); else if (func_all != (fptr_T)NULL) ! // Turbo C complains without the typecast func_all = (fptr_T)(func_all(&cc, c)); ! else // just copy cc = c; if (has_mbyte) *************** *** 2177,2184 **** { int clen = utf_ptr2len(src - 1); ! /* If the character length is shorter than "totlen", there ! * are composing characters; copy them as-is. */ if (clen < totlen) { if (copy) --- 2177,2184 ---- { int clen = utf_ptr2len(src - 1); ! // If the character length is shorter than "totlen", there ! // are composing characters; copy them as-is. if (clen < totlen) { if (copy) *************** *** 2240,2246 **** else break; } ! else if (*s == NUL) /* we hit NUL. */ { if (copy) emsg(_(e_re_damg)); --- 2240,2246 ---- else break; } ! else if (*s == NUL) // we hit NUL. { if (copy) emsg(_(e_re_damg)); *************** *** 2271,2290 **** c = *s; if (func_one != (fptr_T)NULL) ! /* Turbo C complains without the typecast */ func_one = (fptr_T)(func_one(&cc, c)); else if (func_all != (fptr_T)NULL) ! /* Turbo C complains without the typecast */ func_all = (fptr_T)(func_all(&cc, c)); ! else /* just copy */ cc = c; if (has_mbyte) { int l; ! /* Copy composing characters separately, one ! * at a time. */ if (enc_utf8) l = utf_ptr2len(s) - 1; else --- 2271,2290 ---- c = *s; if (func_one != (fptr_T)NULL) ! // Turbo C complains without the typecast func_one = (fptr_T)(func_one(&cc, c)); else if (func_all != (fptr_T)NULL) ! // Turbo C complains without the typecast func_all = (fptr_T)(func_all(&cc, c)); ! else // just copy cc = c; if (has_mbyte) { int l; ! // Copy composing characters separately, one ! // at a time. if (enc_utf8) l = utf_ptr2len(s) - 1; else *************** *** 2374,2380 **** s += rsm.sm_mmatch->startpos[no].col; if (rsm.sm_mmatch->endpos[no].lnum == lnum) { ! /* Within one line: take form start to end col. */ len = rsm.sm_mmatch->endpos[no].col - rsm.sm_mmatch->startpos[no].col; if (round == 2) --- 2374,2380 ---- s += rsm.sm_mmatch->startpos[no].col; if (rsm.sm_mmatch->endpos[no].lnum == lnum) { ! // Within one line: take form start to end col. len = rsm.sm_mmatch->endpos[no].col - rsm.sm_mmatch->startpos[no].col; if (round == 2) *************** *** 2383,2390 **** } else { ! /* Multiple lines: take start line from start col, middle ! * lines completely and end line up to end col. */ len = (int)STRLEN(s); if (round == 2) { --- 2383,2390 ---- } else { ! // Multiple lines: take start line from start col, middle ! // lines completely and end line up to end col. len = (int)STRLEN(s); if (round == 2) { *************** *** 2533,2540 **** (char_u *)"" }; ! /* Which regexp engine to use? Needed for vim_regcomp(). ! * Must match with 'regexpengine'. */ static int regexp_engine = 0; #ifdef DEBUG --- 2533,2540 ---- (char_u *)"" }; ! // Which regexp engine to use? Needed for vim_regcomp(). ! // Must match with 'regexpengine'. static int regexp_engine = 0; #ifdef DEBUG *************** *** 2560,2566 **** regexp_engine = p_re; ! /* Check for prefix "\%#=", that sets the regexp engine */ if (STRNCMP(expr, "\\%#=", 4) == 0) { int newengine = expr[4] - '0'; --- 2560,2566 ---- regexp_engine = p_re; ! // Check for prefix "\%#=", that sets the regexp engine if (STRNCMP(expr, "\\%#=", 4) == 0) { int newengine = expr[4] - '0'; *************** *** 2600,2610 **** else prog = bt_regengine.regcomp(expr, re_flags); ! /* Check for error compiling regexp with initial engine. */ if (prog == NULL) { #ifdef BT_REGEXP_DEBUG_LOG ! if (regexp_engine != BACKTRACKING_ENGINE) /* debugging log for NFA */ { FILE *f; f = fopen(BT_REGEXP_DEBUG_LOG_NAME, "a"); --- 2600,2610 ---- else prog = bt_regengine.regcomp(expr, re_flags); ! // Check for error compiling regexp with initial engine. if (prog == NULL) { #ifdef BT_REGEXP_DEBUG_LOG ! if (regexp_engine != BACKTRACKING_ENGINE) // debugging log for NFA { FILE *f; f = fopen(BT_REGEXP_DEBUG_LOG_NAME, "a"); *************** *** 2634,2641 **** if (prog != NULL) { ! /* Store the info needed to call regcomp() again when the engine turns ! * out to be very slow when executing it. */ prog->re_engine = regexp_engine; prog->re_flags = re_flags; } --- 2634,2641 ---- if (prog != NULL) { ! // Store the info needed to call regcomp() again when the engine turns ! // out to be very slow when executing it. prog->re_engine = regexp_engine; prog->re_flags = re_flags; } *************** *** 2702,2709 **** static int vim_regexec_string( regmatch_T *rmp, ! char_u *line, /* string to match against */ ! colnr_T col, /* column to start looking for match */ int nl) { int result; --- 2702,2709 ---- static int vim_regexec_string( regmatch_T *rmp, ! char_u *line, // string to match against ! colnr_T col, // column to start looking for match int nl) { int result; *************** *** 2731,2737 **** result = rmp->regprog->engine->regexec_nl(rmp, line, col, nl); rmp->regprog->re_in_use = FALSE; ! /* NFA engine aborted because it's very slow. */ if (rmp->regprog->re_engine == AUTOMATIC_ENGINE && result == NFA_TOO_EXPENSIVE) { --- 2731,2737 ---- result = rmp->regprog->engine->regexec_nl(rmp, line, col, nl); rmp->regprog->re_in_use = FALSE; ! // NFA engine aborted because it's very slow. if (rmp->regprog->re_engine == AUTOMATIC_ENGINE && result == NFA_TOO_EXPENSIVE) { *************** *** 2820,2831 **** long vim_regexec_multi( regmmatch_T *rmp, ! win_T *win, /* window in which to search or NULL */ ! buf_T *buf, /* buffer in which to search */ ! linenr_T lnum, /* nr of line to start looking for match */ ! colnr_T col, /* column to start looking for match */ ! proftime_T *tm, /* timeout limit or NULL */ ! int *timed_out) /* flag is set when timeout limit reached */ { int result; regexec_T rex_save; --- 2820,2831 ---- long vim_regexec_multi( regmmatch_T *rmp, ! win_T *win, // window in which to search or NULL ! buf_T *buf, // buffer in which to search ! linenr_T lnum, // nr of line to start looking for match ! colnr_T col, // column to start looking for match ! proftime_T *tm, // timeout limit or NULL ! int *timed_out) // flag is set when timeout limit reached { int result; regexec_T rex_save; *************** *** 2840,2846 **** rmp->regprog->re_in_use = TRUE; if (rex_in_use) ! /* Being called recursively, save the state. */ rex_save = rex; rex_in_use = TRUE; --- 2840,2846 ---- rmp->regprog->re_in_use = TRUE; if (rex_in_use) ! // Being called recursively, save the state. rex_save = rex; rex_in_use = TRUE; *************** *** 2848,2854 **** rmp, win, buf, lnum, col, tm, timed_out); rmp->regprog->re_in_use = FALSE; ! /* NFA engine aborted because it's very slow. */ if (rmp->regprog->re_engine == AUTOMATIC_ENGINE && result == NFA_TOO_EXPENSIVE) { --- 2848,2854 ---- rmp, win, buf, lnum, col, tm, timed_out); rmp->regprog->re_in_use = FALSE; ! // NFA engine aborted because it's very slow. if (rmp->regprog->re_engine == AUTOMATIC_ENGINE && result == NFA_TOO_EXPENSIVE) { *** ../vim-8.1.2393/src/regexp_nfa.c 2019-11-02 22:54:37.409188799 +0100 --- src/regexp_nfa.c 2019-12-05 21:01:38.965408740 +0100 *************** *** 29,71 **** # define NFA_REGEXP_DEBUG_LOG "nfa_regexp_debug.log" #endif ! /* Added to NFA_ANY - NFA_NUPPER_IC to include a NL. */ #define NFA_ADD_NL 31 enum { NFA_SPLIT = -1024, NFA_MATCH, ! NFA_EMPTY, /* matches 0-length */ ! NFA_START_COLL, /* [abc] start */ ! NFA_END_COLL, /* [abc] end */ ! NFA_START_NEG_COLL, /* [^abc] start */ ! NFA_END_NEG_COLL, /* [^abc] end (postfix only) */ ! NFA_RANGE, /* range of the two previous items ! * (postfix only) */ ! NFA_RANGE_MIN, /* low end of a range */ ! NFA_RANGE_MAX, /* high end of a range */ ! ! NFA_CONCAT, /* concatenate two previous items (postfix ! * only) */ ! NFA_OR, /* \| (postfix only) */ ! NFA_STAR, /* greedy * (postfix only) */ ! NFA_STAR_NONGREEDY, /* non-greedy * (postfix only) */ ! NFA_QUEST, /* greedy \? (postfix only) */ ! NFA_QUEST_NONGREEDY, /* non-greedy \? (postfix only) */ ! ! NFA_BOL, /* ^ Begin line */ ! NFA_EOL, /* $ End line */ ! NFA_BOW, /* \< Begin word */ ! NFA_EOW, /* \> End word */ ! NFA_BOF, /* \%^ Begin file */ ! NFA_EOF, /* \%$ End file */ NFA_NEWL, ! NFA_ZSTART, /* Used for \zs */ ! NFA_ZEND, /* Used for \ze */ ! NFA_NOPEN, /* Start of subexpression marked with \%( */ ! NFA_NCLOSE, /* End of subexpr. marked with \%( ... \) */ NFA_START_INVISIBLE, NFA_START_INVISIBLE_FIRST, NFA_START_INVISIBLE_NEG, --- 29,71 ---- # define NFA_REGEXP_DEBUG_LOG "nfa_regexp_debug.log" #endif ! // Added to NFA_ANY - NFA_NUPPER_IC to include a NL. #define NFA_ADD_NL 31 enum { NFA_SPLIT = -1024, NFA_MATCH, ! NFA_EMPTY, // matches 0-length ! NFA_START_COLL, // [abc] start ! NFA_END_COLL, // [abc] end ! NFA_START_NEG_COLL, // [^abc] start ! NFA_END_NEG_COLL, // [^abc] end (postfix only) ! NFA_RANGE, // range of the two previous items ! // (postfix only) ! NFA_RANGE_MIN, // low end of a range ! NFA_RANGE_MAX, // high end of a range ! ! NFA_CONCAT, // concatenate two previous items (postfix ! // only) ! NFA_OR, // \| (postfix only) ! NFA_STAR, // greedy * (postfix only) ! NFA_STAR_NONGREEDY, // non-greedy * (postfix only) ! NFA_QUEST, // greedy \? (postfix only) ! NFA_QUEST_NONGREEDY, // non-greedy \? (postfix only) ! ! NFA_BOL, // ^ Begin line ! NFA_EOL, // $ End line ! NFA_BOW, // \< Begin word ! NFA_EOW, // \> End word ! NFA_BOF, // \%^ Begin file ! NFA_EOF, // \%$ End file NFA_NEWL, ! NFA_ZSTART, // Used for \zs ! NFA_ZEND, // Used for \ze ! NFA_NOPEN, // Start of subexpression marked with \%( ! NFA_NCLOSE, // End of subexpr. marked with \%( ... \) NFA_START_INVISIBLE, NFA_START_INVISIBLE_FIRST, NFA_START_INVISIBLE_NEG, *************** *** 78,117 **** NFA_END_INVISIBLE, NFA_END_INVISIBLE_NEG, NFA_END_PATTERN, ! NFA_COMPOSING, /* Next nodes in NFA are part of the ! composing multibyte char */ ! NFA_END_COMPOSING, /* End of a composing char in the NFA */ ! NFA_ANY_COMPOSING, /* \%C: Any composing characters. */ ! NFA_OPT_CHARS, /* \%[abc] */ ! ! /* The following are used only in the postfix form, not in the NFA */ ! NFA_PREV_ATOM_NO_WIDTH, /* Used for \@= */ ! NFA_PREV_ATOM_NO_WIDTH_NEG, /* Used for \@! */ ! NFA_PREV_ATOM_JUST_BEFORE, /* Used for \@<= */ ! NFA_PREV_ATOM_JUST_BEFORE_NEG, /* Used for \@ */ ! ! NFA_BACKREF1, /* \1 */ ! NFA_BACKREF2, /* \2 */ ! NFA_BACKREF3, /* \3 */ ! NFA_BACKREF4, /* \4 */ ! NFA_BACKREF5, /* \5 */ ! NFA_BACKREF6, /* \6 */ ! NFA_BACKREF7, /* \7 */ ! NFA_BACKREF8, /* \8 */ ! NFA_BACKREF9, /* \9 */ ! #ifdef FEAT_SYN_HL ! NFA_ZREF1, /* \z1 */ ! NFA_ZREF2, /* \z2 */ ! NFA_ZREF3, /* \z3 */ ! NFA_ZREF4, /* \z4 */ ! NFA_ZREF5, /* \z5 */ ! NFA_ZREF6, /* \z6 */ ! NFA_ZREF7, /* \z7 */ ! NFA_ZREF8, /* \z8 */ ! NFA_ZREF9, /* \z9 */ #endif ! NFA_SKIP, /* Skip characters */ NFA_MOPEN, NFA_MOPEN1, --- 78,117 ---- NFA_END_INVISIBLE, NFA_END_INVISIBLE_NEG, NFA_END_PATTERN, ! NFA_COMPOSING, // Next nodes in NFA are part of the ! // composing multibyte char ! NFA_END_COMPOSING, // End of a composing char in the NFA ! NFA_ANY_COMPOSING, // \%C: Any composing characters. ! NFA_OPT_CHARS, // \%[abc] ! ! // The following are used only in the postfix form, not in the NFA ! NFA_PREV_ATOM_NO_WIDTH, // Used for \@= ! NFA_PREV_ATOM_NO_WIDTH_NEG, // Used for \@! ! NFA_PREV_ATOM_JUST_BEFORE, // Used for \@<= ! NFA_PREV_ATOM_JUST_BEFORE_NEG, // Used for \@ ! ! NFA_BACKREF1, // \1 ! NFA_BACKREF2, // \2 ! NFA_BACKREF3, // \3 ! NFA_BACKREF4, // \4 ! NFA_BACKREF5, // \5 ! NFA_BACKREF6, // \6 ! NFA_BACKREF7, // \7 ! NFA_BACKREF8, // \8 ! NFA_BACKREF9, // \9 ! #ifdef FEAT_SYN_HL ! NFA_ZREF1, // \z1 ! NFA_ZREF2, // \z2 ! NFA_ZREF3, // \z3 ! NFA_ZREF4, // \z4 ! NFA_ZREF5, // \z5 ! NFA_ZREF6, // \z6 ! NFA_ZREF7, // \z7 ! NFA_ZREF8, // \z8 ! NFA_ZREF9, // \z9 #endif ! NFA_SKIP, // Skip characters NFA_MOPEN, NFA_MOPEN1, *************** *** 159,216 **** NFA_ZCLOSE9, #endif ! /* NFA_FIRST_NL */ ! NFA_ANY, /* Match any one character. */ ! NFA_IDENT, /* Match identifier char */ ! NFA_SIDENT, /* Match identifier char but no digit */ ! NFA_KWORD, /* Match keyword char */ ! NFA_SKWORD, /* Match word char but no digit */ ! NFA_FNAME, /* Match file name char */ ! NFA_SFNAME, /* Match file name char but no digit */ ! NFA_PRINT, /* Match printable char */ ! NFA_SPRINT, /* Match printable char but no digit */ ! NFA_WHITE, /* Match whitespace char */ ! NFA_NWHITE, /* Match non-whitespace char */ ! NFA_DIGIT, /* Match digit char */ ! NFA_NDIGIT, /* Match non-digit char */ ! NFA_HEX, /* Match hex char */ ! NFA_NHEX, /* Match non-hex char */ ! NFA_OCTAL, /* Match octal char */ ! NFA_NOCTAL, /* Match non-octal char */ ! NFA_WORD, /* Match word char */ ! NFA_NWORD, /* Match non-word char */ ! NFA_HEAD, /* Match head char */ ! NFA_NHEAD, /* Match non-head char */ ! NFA_ALPHA, /* Match alpha char */ ! NFA_NALPHA, /* Match non-alpha char */ ! NFA_LOWER, /* Match lowercase char */ ! NFA_NLOWER, /* Match non-lowercase char */ ! NFA_UPPER, /* Match uppercase char */ ! NFA_NUPPER, /* Match non-uppercase char */ ! NFA_LOWER_IC, /* Match [a-z] */ ! NFA_NLOWER_IC, /* Match [^a-z] */ ! NFA_UPPER_IC, /* Match [A-Z] */ ! NFA_NUPPER_IC, /* Match [^A-Z] */ NFA_FIRST_NL = NFA_ANY + NFA_ADD_NL, NFA_LAST_NL = NFA_NUPPER_IC + NFA_ADD_NL, ! NFA_CURSOR, /* Match cursor pos */ ! NFA_LNUM, /* Match line number */ ! NFA_LNUM_GT, /* Match > line number */ ! NFA_LNUM_LT, /* Match < line number */ ! NFA_COL, /* Match cursor column */ ! NFA_COL_GT, /* Match > cursor column */ ! NFA_COL_LT, /* Match < cursor column */ ! NFA_VCOL, /* Match cursor virtual column */ ! NFA_VCOL_GT, /* Match > cursor virtual column */ ! NFA_VCOL_LT, /* Match < cursor virtual column */ ! NFA_MARK, /* Match mark */ ! NFA_MARK_GT, /* Match > mark */ ! NFA_MARK_LT, /* Match < mark */ ! NFA_VISUAL, /* Match Visual area */ ! /* Character classes [:alnum:] etc */ NFA_CLASS_ALNUM, NFA_CLASS_ALPHA, NFA_CLASS_BLANK, --- 159,216 ---- NFA_ZCLOSE9, #endif ! // NFA_FIRST_NL ! NFA_ANY, // Match any one character. ! NFA_IDENT, // Match identifier char ! NFA_SIDENT, // Match identifier char but no digit ! NFA_KWORD, // Match keyword char ! NFA_SKWORD, // Match word char but no digit ! NFA_FNAME, // Match file name char ! NFA_SFNAME, // Match file name char but no digit ! NFA_PRINT, // Match printable char ! NFA_SPRINT, // Match printable char but no digit ! NFA_WHITE, // Match whitespace char ! NFA_NWHITE, // Match non-whitespace char ! NFA_DIGIT, // Match digit char ! NFA_NDIGIT, // Match non-digit char ! NFA_HEX, // Match hex char ! NFA_NHEX, // Match non-hex char ! NFA_OCTAL, // Match octal char ! NFA_NOCTAL, // Match non-octal char ! NFA_WORD, // Match word char ! NFA_NWORD, // Match non-word char ! NFA_HEAD, // Match head char ! NFA_NHEAD, // Match non-head char ! NFA_ALPHA, // Match alpha char ! NFA_NALPHA, // Match non-alpha char ! NFA_LOWER, // Match lowercase char ! NFA_NLOWER, // Match non-lowercase char ! NFA_UPPER, // Match uppercase char ! NFA_NUPPER, // Match non-uppercase char ! NFA_LOWER_IC, // Match [a-z] ! NFA_NLOWER_IC, // Match [^a-z] ! NFA_UPPER_IC, // Match [A-Z] ! NFA_NUPPER_IC, // Match [^A-Z] NFA_FIRST_NL = NFA_ANY + NFA_ADD_NL, NFA_LAST_NL = NFA_NUPPER_IC + NFA_ADD_NL, ! NFA_CURSOR, // Match cursor pos ! NFA_LNUM, // Match line number ! NFA_LNUM_GT, // Match > line number ! NFA_LNUM_LT, // Match < line number ! NFA_COL, // Match cursor column ! NFA_COL_GT, // Match > cursor column ! NFA_COL_LT, // Match < cursor column ! NFA_VCOL, // Match cursor virtual column ! NFA_VCOL_GT, // Match > cursor virtual column ! NFA_VCOL_LT, // Match < cursor virtual column ! NFA_MARK, // Match mark ! NFA_MARK_GT, // Match > mark ! NFA_MARK_LT, // Match < mark ! NFA_VISUAL, // Match Visual area ! // Character classes [:alnum:] etc NFA_CLASS_ALNUM, NFA_CLASS_ALPHA, NFA_CLASS_BLANK, *************** *** 232,238 **** NFA_CLASS_FNAME }; ! /* Keep in sync with classchars. */ static int nfa_classcodes[] = { NFA_ANY, NFA_IDENT, NFA_SIDENT, NFA_KWORD,NFA_SKWORD, NFA_FNAME, NFA_SFNAME, NFA_PRINT, NFA_SPRINT, --- 232,238 ---- NFA_CLASS_FNAME }; ! // Keep in sync with classchars. static int nfa_classcodes[] = { NFA_ANY, NFA_IDENT, NFA_SIDENT, NFA_KWORD,NFA_SKWORD, NFA_FNAME, NFA_SFNAME, NFA_PRINT, NFA_SPRINT, *************** *** 255,264 **** static int nstate; // Number of states in the NFA. static int istate; // Index in the state vector, used in alloc_state() ! /* If not NULL match must end at this position */ static save_se_T *nfa_endp = NULL; ! /* 0 for first call to nfa_regmatch(), 1 for recursive call. */ static int nfa_ll_index = 0; static int realloc_post_list(void); --- 255,264 ---- static int nstate; // Number of states in the NFA. static int istate; // Index in the state vector, used in alloc_state() ! // If not NULL match must end at this position static save_se_T *nfa_endp = NULL; ! // 0 for first call to nfa_regmatch(), 1 for recursive call. static int nfa_ll_index = 0; static int realloc_post_list(void); *************** *** 269,275 **** static int match_follows(nfa_state_T *startstate, int depth); static int failure_chance(nfa_state_T *state, int depth); ! /* helper functions used when doing re2post() ... regatom() parsing */ #define EMIT(c) do { \ if (post_ptr >= post_end && realloc_post_list() == FAIL) \ return FAIL; \ --- 269,275 ---- static int match_follows(nfa_state_T *startstate, int depth); static int failure_chance(nfa_state_T *state, int depth); ! // helper functions used when doing re2post() ... regatom() parsing #define EMIT(c) do { \ if (post_ptr >= post_end && realloc_post_list() == FAIL) \ return FAIL; \ *************** *** 283,303 **** static int nfa_regcomp_start( char_u *expr, ! int re_flags) /* see vim_regcomp() */ { size_t postfix_size; int nstate_max; nstate = 0; istate = 0; ! /* A reasonable estimation for maximum size */ nstate_max = (int)(STRLEN(expr) + 1) * 25; ! /* Some items blow up in size, such as [A-z]. Add more space for that. ! * When it is still not enough realloc_post_list() will be used. */ nstate_max += 1000; ! /* Size for postfix representation of expr. */ postfix_size = sizeof(int) * nstate_max; post_start = alloc(postfix_size); --- 283,303 ---- static int nfa_regcomp_start( char_u *expr, ! int re_flags) // see vim_regcomp() { size_t postfix_size; int nstate_max; nstate = 0; istate = 0; ! // A reasonable estimation for maximum size nstate_max = (int)(STRLEN(expr) + 1) * 25; ! // Some items blow up in size, such as [A-z]. Add more space for that. ! // When it is still not enough realloc_post_list() will be used. nstate_max += 1000; ! // Size for postfix representation of expr. postfix_size = sizeof(int) * nstate_max; post_start = alloc(postfix_size); *************** *** 308,314 **** rex.nfa_has_zend = FALSE; rex.nfa_has_backref = FALSE; ! /* shared with BT engine */ regcomp_start(expr, re_flags); return OK; --- 308,314 ---- rex.nfa_has_zend = FALSE; rex.nfa_has_backref = FALSE; ! // shared with BT engine regcomp_start(expr, re_flags); return OK; *************** *** 332,338 **** { case NFA_BOL: case NFA_BOF: ! return 1; /* yes! */ case NFA_ZSTART: case NFA_ZEND: --- 332,338 ---- { case NFA_BOL: case NFA_BOF: ! return 1; // yes! case NFA_ZSTART: case NFA_ZEND: *************** *** 370,376 **** && nfa_get_reganch(p->out1, depth + 1); default: ! return 0; /* noooo */ } } return 0; --- 370,376 ---- && nfa_get_reganch(p->out1, depth + 1); default: ! return 0; // noooo } } return 0; *************** *** 392,398 **** { switch (p->c) { ! /* all kinds of zero-width matches */ case NFA_BOL: case NFA_BOF: case NFA_BOW: --- 392,398 ---- { switch (p->c) { ! // all kinds of zero-width matches case NFA_BOL: case NFA_BOF: case NFA_BOW: *************** *** 446,458 **** int c2 = nfa_get_regstart(p->out1, depth + 1); if (c1 == c2) ! return c1; /* yes! */ return 0; } default: if (p->c > 0) ! return p->c; /* yes! */ return 0; } } --- 446,458 ---- int c2 = nfa_get_regstart(p->out1, depth + 1); if (c1 == c2) ! return c1; // yes! return 0; } default: if (p->c > 0) ! return p->c; // yes! return 0; } } *************** *** 473,479 **** char_u *s; if (p->c != NFA_MOPEN) ! return NULL; /* just in case */ p = p->out; while (p->c > 0) { --- 473,479 ---- char_u *s; if (p->c != NFA_MOPEN) ! return NULL; // just in case p = p->out; while (p->c > 0) { *************** *** 486,492 **** ret = alloc(len); if (ret != NULL) { ! p = start->out->out; /* skip first char, it goes into regstart */ s = ret; while (p->c > 0) { --- 486,492 ---- ret = alloc(len); if (ret != NULL) { ! p = start->out->out; // skip first char, it goes into regstart s = ret; while (p->c > 0) { *************** *** 633,639 **** } else return FAIL; ! } /* while (p < end) */ if (p != end) return FAIL; --- 633,639 ---- } else return FAIL; ! } // while (p < end) if (p != end) return FAIL; *************** *** 1161,1167 **** EMITMBC(0x1b6) EMITMBC(0x1e91) EMITMBC(0x1e95) return OK; ! /* default: character itself */ } } --- 1161,1167 ---- EMITMBC(0x1b6) EMITMBC(0x1e91) EMITMBC(0x1e95) return OK; ! // default: character itself } } *************** *** 1241,1252 **** if (c == NUL) EMSG_RET_FAIL(_(e_nul_found)); ! if (c == '^') /* "\_^" is start-of-line */ { EMIT(NFA_BOL); break; } ! if (c == '$') /* "\_$" is end-of-line */ { EMIT(NFA_EOL); #if defined(FEAT_SYN_HL) || defined(PROTO) --- 1241,1252 ---- if (c == NUL) EMSG_RET_FAIL(_(e_nul_found)); ! if (c == '^') // "\_^" is start-of-line { EMIT(NFA_BOL); break; } ! if (c == '$') // "\_$" is end-of-line { EMIT(NFA_EOL); #if defined(FEAT_SYN_HL) || defined(PROTO) *************** *** 1257,1268 **** extra = NFA_ADD_NL; ! /* "\_[" is collection plus newline */ if (c == '[') goto collection; ! /* "\_x" is character class plus newline */ ! /* FALLTHROUGH */ /* * Character classes. --- 1257,1268 ---- extra = NFA_ADD_NL; ! // "\_[" is collection plus newline if (c == '[') goto collection; ! // "\_x" is character class plus newline ! // FALLTHROUGH /* * Character classes. *************** *** 1307,1314 **** return FAIL; } ! /* When '.' is followed by a composing char ignore the dot, so that ! * the composing char is matched here. */ if (enc_utf8 && c == Magic('.') && utf_iscomposing(peekchr())) { old_regparse = regparse; --- 1307,1314 ---- return FAIL; } ! // When '.' is followed by a composing char ignore the dot, so that ! // the composing char is matched here. if (enc_utf8 && c == Magic('.') && utf_iscomposing(peekchr())) { old_regparse = regparse; *************** *** 1326,1336 **** case Magic('n'): if (reg_string) ! /* In a string "\n" matches a newline character. */ EMIT(NL); else { ! /* In buffer text "\n" matches the end of a line. */ EMIT(NFA_NEWL); regflags |= RF_HASNL; } --- 1326,1336 ---- case Magic('n'): if (reg_string) ! // In a string "\n" matches a newline character. EMIT(NL); else { ! // In buffer text "\n" matches the end of a line. EMIT(NFA_NEWL); regflags |= RF_HASNL; } *************** *** 1338,1344 **** case Magic('('): if (nfa_reg(REG_PAREN) == FAIL) ! return FAIL; /* cascaded error */ break; case Magic('|'): --- 1338,1344 ---- case Magic('('): if (nfa_reg(REG_PAREN) == FAIL) ! return FAIL; // cascaded error break; case Magic('|'): *************** *** 1353,1359 **** case Magic('@'): case Magic('*'): case Magic('{'): ! /* these should follow an atom, not form an atom */ semsg(_(e_misplaced), no_Magic(c)); return FAIL; --- 1353,1359 ---- case Magic('@'): case Magic('*'): case Magic('{'): ! // these should follow an atom, not form an atom semsg(_(e_misplaced), no_Magic(c)); return FAIL; *************** *** 1361,1368 **** { char_u *lp; ! /* Previous substitute pattern. ! * Generated as "\%(pattern\)". */ if (reg_prev_sub == NULL) { emsg(_(e_nopresub)); --- 1361,1368 ---- { char_u *lp; ! // Previous substitute pattern. ! // Generated as "\%(pattern\)". if (reg_prev_sub == NULL) { emsg(_(e_nopresub)); *************** *** 1422,1441 **** case '7': case '8': case '9': ! /* \z1...\z9 */ if ((reg_do_extmatch & REX_USE) == 0) EMSG_RET_FAIL(_(e_z1_not_allowed)); EMIT(NFA_ZREF1 + (no_Magic(c) - '1')); ! /* No need to set rex.nfa_has_backref, the sub-matches don't ! * change when \z1 .. \z9 matches or not. */ re_has_z = REX_USE; break; case '(': ! /* \z( */ if ((reg_do_extmatch & REX_SET) == 0) EMSG_RET_FAIL(_(e_z_not_allowed)); if (nfa_reg(REG_ZPAREN) == FAIL) ! return FAIL; /* cascaded error */ re_has_z = REX_SET; break; #endif --- 1422,1441 ---- case '7': case '8': case '9': ! // \z1...\z9 if ((reg_do_extmatch & REX_USE) == 0) EMSG_RET_FAIL(_(e_z1_not_allowed)); EMIT(NFA_ZREF1 + (no_Magic(c) - '1')); ! // No need to set rex.nfa_has_backref, the sub-matches don't ! // change when \z1 .. \z9 matches or not. re_has_z = REX_USE; break; case '(': ! // \z( if ((reg_do_extmatch & REX_SET) == 0) EMSG_RET_FAIL(_(e_z_not_allowed)); if (nfa_reg(REG_ZPAREN) == FAIL) ! return FAIL; // cascaded error re_has_z = REX_SET; break; #endif *************** *** 1450,1467 **** c = no_Magic(getchr()); switch (c) { ! /* () without a back reference */ case '(': if (nfa_reg(REG_NPAREN) == FAIL) return FAIL; EMIT(NFA_NOPEN); break; ! case 'd': /* %d123 decimal */ ! case 'o': /* %o123 octal */ ! case 'x': /* %xab hex 2 */ ! case 'u': /* %uabcd hex 4 */ ! case 'U': /* %U1234abcd hex 8 */ { long nr; --- 1450,1467 ---- c = no_Magic(getchr()); switch (c) { ! // () without a back reference case '(': if (nfa_reg(REG_NPAREN) == FAIL) return FAIL; EMIT(NFA_NOPEN); break; ! case 'd': // %d123 decimal ! case 'o': // %o123 octal ! case 'x': // %xab hex 2 ! case 'u': // %uabcd hex 4 ! case 'U': // %U1234abcd hex 8 { long nr; *************** *** 1479,1492 **** EMSG2_RET_FAIL( _("E678: Invalid character after %s%%[dxouU]"), reg_magic == MAGIC_ALL); ! /* A NUL is stored in the text as NL */ ! /* TODO: what if a composing character follows? */ EMIT(nr == 0 ? 0x0a : nr); } break; ! /* Catch \%^ and \%$ regardless of where they appear in the ! * pattern -- regardless of whether or not it makes sense. */ case '^': EMIT(NFA_BOF); break; --- 1479,1492 ---- EMSG2_RET_FAIL( _("E678: Invalid character after %s%%[dxouU]"), reg_magic == MAGIC_ALL); ! // A NUL is stored in the text as NL ! // TODO: what if a composing character follows? EMIT(nr == 0 ? 0x0a : nr); } break; ! // Catch \%^ and \%$ regardless of where they appear in the ! // pattern -- regardless of whether or not it makes sense. case '^': EMIT(NFA_BOF); break; *************** *** 1511,1540 **** { int n; ! /* \%[abc] */ for (n = 0; (c = peekchr()) != ']'; ++n) { if (c == NUL) EMSG2_RET_FAIL(_(e_missing_sb), reg_magic == MAGIC_ALL); ! /* recursive call! */ if (nfa_regatom() == FAIL) return FAIL; } ! getchr(); /* get the ] */ if (n == 0) EMSG2_RET_FAIL(_(e_empty_sb), reg_magic == MAGIC_ALL); EMIT(NFA_OPT_CHARS); EMIT(n); ! /* Emit as "\%(\%[abc]\)" to be able to handle ! * "\%[abc]*" which would cause the empty string to be ! * matched an unlimited number of times. NFA_NOPEN is ! * added only once at a position, while NFA_SPLIT is ! * added multiple times. This is more efficient than ! * not allowing NFA_SPLIT multiple times, it is used ! * a lot. */ EMIT(NFA_NOPEN); break; } --- 1511,1540 ---- { int n; ! // \%[abc] for (n = 0; (c = peekchr()) != ']'; ++n) { if (c == NUL) EMSG2_RET_FAIL(_(e_missing_sb), reg_magic == MAGIC_ALL); ! // recursive call! if (nfa_regatom() == FAIL) return FAIL; } ! getchr(); // get the ] if (n == 0) EMSG2_RET_FAIL(_(e_empty_sb), reg_magic == MAGIC_ALL); EMIT(NFA_OPT_CHARS); EMIT(n); ! // Emit as "\%(\%[abc]\)" to be able to handle ! // "\%[abc]*" which would cause the empty string to be ! // matched an unlimited number of times. NFA_NOPEN is ! // added only once at a position, while NFA_SPLIT is ! // added multiple times. This is more efficient than ! // not allowing NFA_SPLIT multiple times, it is used ! // a lot. EMIT(NFA_NOPEN); break; } *************** *** 1557,1575 **** if (c == 'l') { ! /* \%{n}l \%{n}l */ EMIT(cmp == '<' ? NFA_LNUM_LT : cmp == '>' ? NFA_LNUM_GT : NFA_LNUM); if (save_prev_at_start) at_start = TRUE; } else if (c == 'c') ! /* \%{n}c \%{n}c */ EMIT(cmp == '<' ? NFA_COL_LT : cmp == '>' ? NFA_COL_GT : NFA_COL); else { ! /* \%{n}v \%{n}v */ EMIT(cmp == '<' ? NFA_VCOL_LT : cmp == '>' ? NFA_VCOL_GT : NFA_VCOL); limit = INT_MAX / MB_MAXBYTES; --- 1557,1575 ---- if (c == 'l') { ! // \%{n}l \%{n}l EMIT(cmp == '<' ? NFA_LNUM_LT : cmp == '>' ? NFA_LNUM_GT : NFA_LNUM); if (save_prev_at_start) at_start = TRUE; } else if (c == 'c') ! // \%{n}c \%{n}c EMIT(cmp == '<' ? NFA_COL_LT : cmp == '>' ? NFA_COL_GT : NFA_COL); else { ! // \%{n}v \%{n}v EMIT(cmp == '<' ? NFA_VCOL_LT : cmp == '>' ? NFA_VCOL_GT : NFA_VCOL); limit = INT_MAX / MB_MAXBYTES; *************** *** 1584,1590 **** } else if (c == '\'' && n == 0) { ! /* \%'m \%<'m \%>'m */ EMIT(cmp == '<' ? NFA_MARK_LT : cmp == '>' ? NFA_MARK_GT : NFA_MARK); EMIT(getchr()); --- 1584,1590 ---- } else if (c == '\'' && n == 0) { ! // \%'m \%<'m \%>'m EMIT(cmp == '<' ? NFA_MARK_LT : cmp == '>' ? NFA_MARK_GT : NFA_MARK); EMIT(getchr()); *************** *** 1640,1646 **** */ startc = endc = oldstartc = -1; negated = FALSE; ! if (*regparse == '^') /* negated range */ { negated = TRUE; MB_PTR_ADV(regparse); --- 1640,1646 ---- */ startc = endc = oldstartc = -1; negated = FALSE; ! if (*regparse == '^') // negated range { negated = TRUE; MB_PTR_ADV(regparse); *************** *** 1655,1661 **** EMIT(NFA_CONCAT); MB_PTR_ADV(regparse); } ! /* Emit the OR branches for each character in the [] */ emit_range = FALSE; while (regparse < endp) { --- 1655,1661 ---- EMIT(NFA_CONCAT); MB_PTR_ADV(regparse); } ! // Emit the OR branches for each character in the [] emit_range = FALSE; while (regparse < endp) { *************** *** 1664,1670 **** got_coll_char = FALSE; if (*regparse == '[') { ! /* Check for [: :], [= =], [. .] */ equiclass = collclass = 0; charclass = get_char_class(®parse); if (charclass == CLASS_NONE) --- 1664,1670 ---- got_coll_char = FALSE; if (*regparse == '[') { ! // Check for [: :], [= =], [. .] equiclass = collclass = 0; charclass = get_char_class(®parse); if (charclass == CLASS_NONE) *************** *** 1674,1680 **** collclass = get_coll_element(®parse); } ! /* Character class like [:alpha:] */ if (charclass != CLASS_NONE) { switch (charclass) --- 1674,1680 ---- collclass = get_coll_element(®parse); } ! // Character class like [:alpha:] if (charclass != CLASS_NONE) { switch (charclass) *************** *** 1740,1780 **** EMIT(NFA_CONCAT); continue; } ! /* Try equivalence class [=a=] and the like */ if (equiclass != 0) { result = nfa_emit_equi_class(equiclass); if (result == FAIL) { ! /* should never happen */ EMSG_RET_FAIL(_("E868: Error building NFA with equivalence class!")); } continue; } ! /* Try collating class like [. .] */ if (collclass != 0) { ! startc = collclass; /* allow [.a.]-x as a range */ ! /* Will emit the proper atom at the end of the ! * while loop. */ } } ! /* Try a range like 'a-x' or '\t-z'. Also allows '-' as a ! * start character. */ if (*regparse == '-' && oldstartc != -1) { emit_range = TRUE; startc = oldstartc; MB_PTR_ADV(regparse); ! continue; /* reading the end of the range */ } ! /* Now handle simple and escaped characters. ! * Only "\]", "\^", "\]" and "\\" are special in Vi. Vim ! * accepts "\t", "\e", etc., but only when the 'l' flag in ! * 'cpoptions' is not included. ! * Posix doesn't recognize backslash at all. ! */ if (*regparse == '\\' && !reg_cpo_bsl && regparse + 1 <= endp --- 1740,1779 ---- EMIT(NFA_CONCAT); continue; } ! // Try equivalence class [=a=] and the like if (equiclass != 0) { result = nfa_emit_equi_class(equiclass); if (result == FAIL) { ! // should never happen EMSG_RET_FAIL(_("E868: Error building NFA with equivalence class!")); } continue; } ! // Try collating class like [. .] if (collclass != 0) { ! startc = collclass; // allow [.a.]-x as a range ! // Will emit the proper atom at the end of the ! // while loop. } } ! // Try a range like 'a-x' or '\t-z'. Also allows '-' as a ! // start character. if (*regparse == '-' && oldstartc != -1) { emit_range = TRUE; startc = oldstartc; MB_PTR_ADV(regparse); ! continue; // reading the end of the range } ! // Now handle simple and escaped characters. ! // Only "\]", "\^", "\]" and "\\" are special in Vi. Vim ! // accepts "\t", "\e", etc., but only when the 'l' flag in ! // 'cpoptions' is not included. ! // Posix doesn't recognize backslash at all. if (*regparse == '\\' && !reg_cpo_bsl && regparse + 1 <= endp *************** *** 1797,1819 **** || *regparse == 'U' ) { ! /* TODO(RE) This needs more testing */ startc = coll_get_char(); got_coll_char = TRUE; MB_PTR_BACK(old_regparse, regparse); } else { ! /* \r,\t,\e,\b */ startc = backslash_trans(*regparse); } } ! /* Normal printable char */ if (startc == -1) startc = PTR2CHAR(regparse); ! /* Previous char was '-', so this char is end of range. */ if (emit_range) { endc = startc; --- 1796,1818 ---- || *regparse == 'U' ) { ! // TODO(RE) This needs more testing startc = coll_get_char(); got_coll_char = TRUE; MB_PTR_BACK(old_regparse, regparse); } else { ! // \r,\t,\e,\b startc = backslash_trans(*regparse); } } ! // Normal printable char if (startc == -1) startc = PTR2CHAR(regparse); ! // Previous char was '-', so this char is end of range. if (emit_range) { endc = startc; *************** *** 1823,1835 **** if (endc > startc + 2) { ! /* Emit a range instead of the sequence of ! * individual characters. */ if (startc == 0) ! /* \x00 is translated to \x0a, start at \x01. */ EMIT(1); else ! --post_ptr; /* remove NFA_CONCAT */ EMIT(endc); EMIT(NFA_RANGE); EMIT(NFA_CONCAT); --- 1822,1834 ---- if (endc > startc + 2) { ! // Emit a range instead of the sequence of ! // individual characters. if (startc == 0) ! // \x00 is translated to \x0a, start at \x01. EMIT(1); else ! --post_ptr; // remove NFA_CONCAT EMIT(endc); EMIT(NFA_RANGE); EMIT(NFA_CONCAT); *************** *** 1837,1845 **** else if (has_mbyte && ((*mb_char2len)(startc) > 1 || (*mb_char2len)(endc) > 1)) { ! /* Emit the characters in the range. ! * "startc" was already emitted, so skip it. ! * */ for (c = startc + 1; c <= endc; c++) { EMIT(c); --- 1836,1844 ---- else if (has_mbyte && ((*mb_char2len)(startc) > 1 || (*mb_char2len)(endc) > 1)) { ! // Emit the characters in the range. ! // "startc" was already emitted, so skip it. ! // for (c = startc + 1; c <= endc; c++) { EMIT(c); *************** *** 1851,1863 **** #ifdef EBCDIC int alpha_only = FALSE; ! /* for alphabetical range skip the gaps ! * 'i'-'j', 'r'-'s', 'I'-'J' and 'R'-'S'. */ if (isalpha(startc) && isalpha(endc)) alpha_only = TRUE; #endif ! /* Emit the range. "startc" was already emitted, so ! * skip it. */ for (c = startc + 1; c <= endc; c++) #ifdef EBCDIC if (!alpha_only || isalpha(startc)) --- 1850,1862 ---- #ifdef EBCDIC int alpha_only = FALSE; ! // for alphabetical range skip the gaps ! // 'i'-'j', 'r'-'s', 'I'-'J' and 'R'-'S'. if (isalpha(startc) && isalpha(endc)) alpha_only = TRUE; #endif ! // Emit the range. "startc" was already emitted, so ! // skip it. for (c = startc + 1; c <= endc; c++) #ifdef EBCDIC if (!alpha_only || isalpha(startc)) *************** *** 1872,1889 **** } else { ! /* This char (startc) is not part of a range. Just ! * emit it. ! * Normally, simply emit startc. But if we get char ! * code=0 from a collating char, then replace it with ! * 0x0a. ! * This is needed to completely mimic the behaviour of ! * the backtracking engine. */ if (startc == NFA_NEWL) { ! /* Line break can't be matched as part of the ! * collection, add an OR below. But not for negated ! * range. */ if (!negated) extra = NFA_ADD_NL; } --- 1871,1888 ---- } else { ! // This char (startc) is not part of a range. Just ! // emit it. ! // Normally, simply emit startc. But if we get char ! // code=0 from a collating char, then replace it with ! // 0x0a. ! // This is needed to completely mimic the behaviour of ! // the backtracking engine. if (startc == NFA_NEWL) { ! // Line break can't be matched as part of the ! // collection, add an OR below. But not for negated ! // range. if (!negated) extra = NFA_ADD_NL; } *************** *** 1898,1923 **** } MB_PTR_ADV(regparse); ! } /* while (p < endp) */ MB_PTR_BACK(old_regparse, regparse); ! if (*regparse == '-') /* if last, '-' is just a char */ { EMIT('-'); EMIT(NFA_CONCAT); } ! /* skip the trailing ] */ regparse = endp; MB_PTR_ADV(regparse); ! /* Mark end of the collection. */ if (negated == TRUE) EMIT(NFA_END_NEG_COLL); else EMIT(NFA_END_COLL); ! /* \_[] also matches \n but it's not negated */ if (extra == NFA_ADD_NL) { EMIT(reg_string ? NL : NFA_NEWL); --- 1897,1922 ---- } MB_PTR_ADV(regparse); ! } // while (p < endp) MB_PTR_BACK(old_regparse, regparse); ! if (*regparse == '-') // if last, '-' is just a char { EMIT('-'); EMIT(NFA_CONCAT); } ! // skip the trailing ] regparse = endp; MB_PTR_ADV(regparse); ! // Mark end of the collection. if (negated == TRUE) EMIT(NFA_END_NEG_COLL); else EMIT(NFA_END_COLL); ! // \_[] also matches \n but it's not negated if (extra == NFA_ADD_NL) { EMIT(reg_string ? NL : NFA_NEWL); *************** *** 1925,1956 **** } return OK; ! } /* if exists closing ] */ if (reg_strict) EMSG_RET_FAIL(_(e_missingbracket)); ! /* FALLTHROUGH */ default: { int plen; nfa_do_multibyte: ! /* plen is length of current char with composing chars */ if (enc_utf8 && ((*mb_char2len)(c) != (plen = utfc_ptr2len(old_regparse)) || utf_iscomposing(c))) { int i = 0; ! /* A base character plus composing characters, or just one ! * or more composing characters. ! * This requires creating a separate atom as if enclosing ! * the characters in (), where NFA_COMPOSING is the ( and ! * NFA_END_COMPOSING is the ). Note that right now we are ! * building the postfix form, not the NFA itself; ! * a composing char could be: a, b, c, NFA_COMPOSING ! * where 'b' and 'c' are chars with codes > 256. */ for (;;) { EMIT(c); --- 1924,1955 ---- } return OK; ! } // if exists closing ] if (reg_strict) EMSG_RET_FAIL(_(e_missingbracket)); ! // FALLTHROUGH default: { int plen; nfa_do_multibyte: ! // plen is length of current char with composing chars if (enc_utf8 && ((*mb_char2len)(c) != (plen = utfc_ptr2len(old_regparse)) || utf_iscomposing(c))) { int i = 0; ! // A base character plus composing characters, or just one ! // or more composing characters. ! // This requires creating a separate atom as if enclosing ! // the characters in (), where NFA_COMPOSING is the ( and ! // NFA_END_COMPOSING is the ). Note that right now we are ! // building the postfix form, not the NFA itself; ! // a composing char could be: a, b, c, NFA_COMPOSING ! // where 'b' and 'c' are chars with codes > 256. for (;;) { EMIT(c); *************** *** 1992,1998 **** int op; int ret; long minval, maxval; ! int greedy = TRUE; /* Braces are prefixed with '-' ? */ parse_state_T old_state; parse_state_T new_state; long c2; --- 1991,1997 ---- int op; int ret; long minval, maxval; ! int greedy = TRUE; // Braces are prefixed with '-' ? parse_state_T old_state; parse_state_T new_state; long c2; *************** *** 2000,2015 **** int my_post_start; int quest; ! /* Save the current parse state, so that we can use it if {m,n} is ! * next. */ save_parse_state(&old_state); ! /* store current pos in the postfix form, for \{m,n} involving 0s */ my_post_start = (int)(post_ptr - post_start); ret = nfa_regatom(); if (ret == FAIL) ! return FAIL; /* cascaded error */ op = peekchr(); if (re_multi_type(op) == NOT_MULTI) --- 1999,2014 ---- int my_post_start; int quest; ! // Save the current parse state, so that we can use it if {m,n} is ! // next. save_parse_state(&old_state); ! // store current pos in the postfix form, for \{m,n} involving 0s my_post_start = (int)(post_ptr - post_start); ret = nfa_regatom(); if (ret == FAIL) ! return FAIL; // cascaded error op = peekchr(); if (re_multi_type(op) == NOT_MULTI) *************** *** 2040,2046 **** return FAIL; EMIT(NFA_STAR); EMIT(NFA_CONCAT); ! skipchr(); /* skip the \+ */ break; case Magic('@'): --- 2039,2045 ---- return FAIL; EMIT(NFA_STAR); EMIT(NFA_CONCAT); ! skipchr(); // skip the \+ break; case Magic('@'): *************** *** 2050,2073 **** switch(op) { case '=': ! /* \@= */ i = NFA_PREV_ATOM_NO_WIDTH; break; case '!': ! /* \@! */ i = NFA_PREV_ATOM_NO_WIDTH_NEG; break; case '<': op = no_Magic(getchr()); if (op == '=') ! /* \@<= */ i = NFA_PREV_ATOM_JUST_BEFORE; else if (op == '!') ! /* \@': ! /* \@> */ i = NFA_PREV_ATOM_LIKE_PATTERN; break; } --- 2049,2072 ---- switch(op) { case '=': ! // \@= i = NFA_PREV_ATOM_NO_WIDTH; break; case '!': ! // \@! i = NFA_PREV_ATOM_NO_WIDTH_NEG; break; case '<': op = no_Magic(getchr()); if (op == '=') ! // \@<= i = NFA_PREV_ATOM_JUST_BEFORE; else if (op == '!') ! // \@': ! // \@> i = NFA_PREV_ATOM_LIKE_PATTERN; break; } *************** *** 2088,2099 **** break; case Magic('{'): ! /* a{2,5} will expand to 'aaa?a?a?' ! * a{-1,3} will expand to 'aa??a??', where ?? is the nongreedy ! * version of '?' ! * \v(ab){2,3} will expand to '(ab)(ab)(ab)?', where all the ! * parenthesis have the same id ! */ greedy = TRUE; c2 = peekchr(); --- 2087,2097 ---- break; case Magic('{'): ! // a{2,5} will expand to 'aaa?a?a?' ! // a{-1,3} will expand to 'aa??a??', where ?? is the nongreedy ! // version of '?' ! // \v(ab){2,3} will expand to '(ab)(ab)(ab)?', where all the ! // parenthesis have the same id greedy = TRUE; c2 = peekchr(); *************** *** 2105,2154 **** if (!read_limits(&minval, &maxval)) EMSG_RET_FAIL(_("E870: (NFA regexp) Error reading repetition limits")); ! /* {0,inf}, {0,} and {} are equivalent to ! * * */ if (minval == 0 && maxval == MAX_LIMIT) { ! if (greedy) /* { { (match the braces) */ ! /* \{}, \{0,} */ EMIT(NFA_STAR); ! else /* { { (match the braces) */ ! /* \{-}, \{-0,} */ EMIT(NFA_STAR_NONGREEDY); break; } ! /* Special case: x{0} or x{-0} */ if (maxval == 0) { ! /* Ignore result of previous call to nfa_regatom() */ post_ptr = post_start + my_post_start; ! /* NFA_EMPTY is 0-length and works everywhere */ EMIT(NFA_EMPTY); return OK; } ! /* The engine is very inefficient (uses too many states) when the ! * maximum is much larger than the minimum and when the maximum is ! * large. Bail out if we can use the other engine. */ if ((nfa_re_flags & RE_AUTO) && (maxval > 500 || maxval > minval + 200)) return FAIL; ! /* Ignore previous call to nfa_regatom() */ post_ptr = post_start + my_post_start; ! /* Save parse state after the repeated atom and the \{} */ save_parse_state(&new_state); quest = (greedy == TRUE? NFA_QUEST : NFA_QUEST_NONGREEDY); for (i = 0; i < maxval; i++) { ! /* Goto beginning of the repeated atom */ restore_parse_state(&old_state); old_post_pos = (int)(post_ptr - post_start); if (nfa_regatom() == FAIL) return FAIL; ! /* after "minval" times, atoms are optional */ if (i + 1 > minval) { if (maxval == MAX_LIMIT) --- 2103,2152 ---- if (!read_limits(&minval, &maxval)) EMSG_RET_FAIL(_("E870: (NFA regexp) Error reading repetition limits")); ! // {0,inf}, {0,} and {} are equivalent to ! // * if (minval == 0 && maxval == MAX_LIMIT) { ! if (greedy) // { { (match the braces) ! // \{}, \{0,} EMIT(NFA_STAR); ! else // { { (match the braces) ! // \{-}, \{-0,} EMIT(NFA_STAR_NONGREEDY); break; } ! // Special case: x{0} or x{-0} if (maxval == 0) { ! // Ignore result of previous call to nfa_regatom() post_ptr = post_start + my_post_start; ! // NFA_EMPTY is 0-length and works everywhere EMIT(NFA_EMPTY); return OK; } ! // The engine is very inefficient (uses too many states) when the ! // maximum is much larger than the minimum and when the maximum is ! // large. Bail out if we can use the other engine. if ((nfa_re_flags & RE_AUTO) && (maxval > 500 || maxval > minval + 200)) return FAIL; ! // Ignore previous call to nfa_regatom() post_ptr = post_start + my_post_start; ! // Save parse state after the repeated atom and the \{} save_parse_state(&new_state); quest = (greedy == TRUE? NFA_QUEST : NFA_QUEST_NONGREEDY); for (i = 0; i < maxval; i++) { ! // Goto beginning of the repeated atom restore_parse_state(&old_state); old_post_pos = (int)(post_ptr - post_start); if (nfa_regatom() == FAIL) return FAIL; ! // after "minval" times, atoms are optional if (i + 1 > minval) { if (maxval == MAX_LIMIT) *************** *** 2167,2173 **** break; } ! /* Go to just after the repeated atom and the \{} */ restore_parse_state(&new_state); curchr = -1; --- 2165,2171 ---- break; } ! // Go to just after the repeated atom and the \{} restore_parse_state(&new_state); curchr = -1; *************** *** 2176,2185 **** default: break; ! } /* end switch */ if (re_multi_type(peekchr()) != NOT_MULTI) ! /* Can't have a multi follow a multi. */ EMSG_RET_FAIL(_("E871: (NFA regexp) Can't have a multi follow a multi")); return OK; --- 2174,2183 ---- default: break; ! } // end switch if (re_multi_type(peekchr()) != NOT_MULTI) ! // Can't have a multi follow a multi. EMSG_RET_FAIL(_("E871: (NFA regexp) Can't have a multi follow a multi")); return OK; *************** *** 2278,2292 **** old_post_pos = (int)(post_ptr - post_start); ! /* First branch, possibly the only one */ if (nfa_regconcat() == FAIL) return FAIL; ! /* Try next concats */ while (peekchr() == Magic('&')) { skipchr(); ! /* if concat is empty do emit a node */ if (old_post_pos == (int)(post_ptr - post_start)) EMIT(NFA_EMPTY); EMIT(NFA_NOPEN); --- 2276,2290 ---- old_post_pos = (int)(post_ptr - post_start); ! // First branch, possibly the only one if (nfa_regconcat() == FAIL) return FAIL; ! // Try next concats while (peekchr() == Magic('&')) { skipchr(); ! // if concat is empty do emit a node if (old_post_pos == (int)(post_ptr - post_start)) EMIT(NFA_EMPTY); EMIT(NFA_NOPEN); *************** *** 2294,2306 **** old_post_pos = (int)(post_ptr - post_start); if (nfa_regconcat() == FAIL) return FAIL; ! /* if concat is empty do emit a node */ if (old_post_pos == (int)(post_ptr - post_start)) EMIT(NFA_EMPTY); EMIT(NFA_CONCAT); } ! /* if a branch is empty, emit one node for it */ if (old_post_pos == (int)(post_ptr - post_start)) EMIT(NFA_EMPTY); --- 2292,2304 ---- old_post_pos = (int)(post_ptr - post_start); if (nfa_regconcat() == FAIL) return FAIL; ! // if concat is empty do emit a node if (old_post_pos == (int)(post_ptr - post_start)) EMIT(NFA_EMPTY); EMIT(NFA_CONCAT); } ! // if a branch is empty, emit one node for it if (old_post_pos == (int)(post_ptr - post_start)) EMIT(NFA_EMPTY); *************** *** 2320,2339 **** */ static int nfa_reg( ! int paren) /* REG_NOPAREN, REG_PAREN, REG_NPAREN or REG_ZPAREN */ { int parno = 0; if (paren == REG_PAREN) { ! if (regnpar >= NSUBEXP) /* Too many `(' */ EMSG_RET_FAIL(_("E872: (NFA regexp) Too many '('")); parno = regnpar++; } #ifdef FEAT_SYN_HL else if (paren == REG_ZPAREN) { ! /* Make a ZOPEN node. */ if (regnzpar >= NSUBEXP) EMSG_RET_FAIL(_("E879: (NFA regexp) Too many \\z(")); parno = regnzpar++; --- 2318,2337 ---- */ static int nfa_reg( ! int paren) // REG_NOPAREN, REG_PAREN, REG_NPAREN or REG_ZPAREN { int parno = 0; if (paren == REG_PAREN) { ! if (regnpar >= NSUBEXP) // Too many `(' EMSG_RET_FAIL(_("E872: (NFA regexp) Too many '('")); parno = regnpar++; } #ifdef FEAT_SYN_HL else if (paren == REG_ZPAREN) { ! // Make a ZOPEN node. if (regnzpar >= NSUBEXP) EMSG_RET_FAIL(_("E879: (NFA regexp) Too many \\z(")); parno = regnzpar++; *************** *** 2341,2357 **** #endif if (nfa_regbranch() == FAIL) ! return FAIL; /* cascaded error */ while (peekchr() == Magic('|')) { skipchr(); if (nfa_regbranch() == FAIL) ! return FAIL; /* cascaded error */ EMIT(NFA_OR); } ! /* Check for proper termination. */ if (paren != REG_NOPAREN && getchr() != Magic(')')) { if (paren == REG_NPAREN) --- 2339,2355 ---- #endif if (nfa_regbranch() == FAIL) ! return FAIL; // cascaded error while (peekchr() == Magic('|')) { skipchr(); if (nfa_regbranch() == FAIL) ! return FAIL; // cascaded error EMIT(NFA_OR); } ! // Check for proper termination. if (paren != REG_NOPAREN && getchr() != Magic(')')) { if (paren == REG_NPAREN) *************** *** 2372,2378 **** */ if (paren == REG_PAREN) { ! had_endbrace[parno] = TRUE; /* have seen the close paren */ EMIT(NFA_MOPEN + parno); } #ifdef FEAT_SYN_HL --- 2370,2376 ---- */ if (paren == REG_PAREN) { ! had_endbrace[parno] = TRUE; // have seen the close paren EMIT(NFA_MOPEN + parno); } #ifdef FEAT_SYN_HL *************** *** 2678,2684 **** fprintf(debugf, "(%2d)", abs(state->id)); ! /* Output indent */ p = (char_u *)indent->ga_data; if (indent->ga_len >= 3) { --- 2676,2682 ---- fprintf(debugf, "(%2d)", abs(state->id)); ! // Output indent p = (char_u *)indent->ga_data; if (indent->ga_len >= 3) { *************** *** 2704,2710 **** state->id = abs(state->id) * -1; ! /* grow indent for state->out */ indent->ga_len -= 1; if (state->out1) ga_concat(indent, (char_u *)"| "); --- 2702,2708 ---- state->id = abs(state->id) * -1; ! // grow indent for state->out indent->ga_len -= 1; if (state->out1) ga_concat(indent, (char_u *)"| "); *************** *** 2714,2727 **** nfa_print_state2(debugf, state->out, indent); ! /* replace last part of indent for state->out1 */ indent->ga_len -= 3; ga_concat(indent, (char_u *)" "); ga_append(indent, '\0'); nfa_print_state2(debugf, state->out1, indent); ! /* shrink indent */ indent->ga_len -= 3; ga_append(indent, '\0'); } --- 2712,2725 ---- nfa_print_state2(debugf, state->out, indent); ! // replace last part of indent for state->out1 indent->ga_len -= 3; ga_concat(indent, (char_u *)" "); ga_append(indent, '\0'); nfa_print_state2(debugf, state->out1, indent); ! // shrink indent indent->ga_len -= 3; ga_append(indent, '\0'); } *************** *** 2749,2756 **** fclose(debugf); } } ! #endif /* ENABLE_LOG */ ! #endif /* DEBUG */ /* * Parse r.e. @expr and convert it into postfix form. --- 2747,2754 ---- fclose(debugf); } } ! #endif // ENABLE_LOG ! #endif // DEBUG /* * Parse r.e. @expr and convert it into postfix form. *************** *** 2765,2771 **** return post_start; } ! /* NB. Some of the code below is inspired by Russ's. */ /* * Represents an NFA state plus zero or one or two arrows exiting. --- 2763,2769 ---- return post_start; } ! // NB. Some of the code below is inspired by Russ's. /* * Represents an NFA state plus zero or one or two arrows exiting. *************** *** 2774,2780 **** * If c < 256, labeled arrow with character c to out. */ ! static nfa_state_T *state_ptr; /* points to nfa_prog->state */ /* * Allocate and initialize nfa_state_T. --- 2772,2778 ---- * If c < 256, labeled arrow with character c to out. */ ! static nfa_state_T *state_ptr; // points to nfa_prog->state /* * Allocate and initialize nfa_state_T. *************** *** 2808,2816 **** * next state for this fragment. */ ! /* Since the out pointers in the list are always ! * uninitialized, we use the pointers themselves ! * as storage for the Ptrlists. */ typedef union Ptrlist Ptrlist; union Ptrlist { --- 2806,2814 ---- * next state for this fragment. */ ! // Since the out pointers in the list are always ! // uninitialized, we use the pointers themselves ! // as storage for the Ptrlists. typedef union Ptrlist Ptrlist; union Ptrlist { *************** *** 2970,2976 **** nfa_state_T *state = startstate; int len = 0; ! /* detect looping in a NFA_SPLIT */ if (depth > 4) return -1; --- 2968,2974 ---- nfa_state_T *state = startstate; int len = 0; ! // detect looping in a NFA_SPLIT if (depth > 4) return -1; *************** *** 2980,2990 **** { case NFA_END_INVISIBLE: case NFA_END_INVISIBLE_NEG: ! /* the end, return what we have */ return len; case NFA_SPLIT: ! /* two alternatives, use the maximum */ l = nfa_max_width(state->out, depth + 1); r = nfa_max_width(state->out1, depth + 1); if (l < 0 || r < 0) --- 2978,2988 ---- { case NFA_END_INVISIBLE: case NFA_END_INVISIBLE_NEG: ! // the end, return what we have return len; case NFA_SPLIT: ! // two alternatives, use the maximum l = nfa_max_width(state->out, depth + 1); r = nfa_max_width(state->out1, depth + 1); if (l < 0 || r < 0) *************** *** 2994,3000 **** case NFA_ANY: case NFA_START_COLL: case NFA_START_NEG_COLL: ! /* matches some character, including composing chars */ if (enc_utf8) len += MB_MAXBYTES; else if (has_mbyte) --- 2992,2998 ---- case NFA_ANY: case NFA_START_COLL: case NFA_START_NEG_COLL: ! // matches some character, including composing chars if (enc_utf8) len += MB_MAXBYTES; else if (has_mbyte) *************** *** 3003,3009 **** ++len; if (state->c != NFA_ANY) { ! /* skip over the characters */ state = state->out1->out; continue; } --- 3001,3007 ---- ++len; if (state->c != NFA_ANY) { ! // skip over the characters state = state->out1->out; continue; } *************** *** 3013,3019 **** case NFA_WHITE: case NFA_HEX: case NFA_OCTAL: ! /* ascii */ ++len; break; --- 3011,3017 ---- case NFA_WHITE: case NFA_HEX: case NFA_OCTAL: ! // ascii ++len; break; *************** *** 3044,3050 **** case NFA_UPPER_IC: case NFA_NUPPER_IC: case NFA_ANY_COMPOSING: ! /* possibly non-ascii */ if (has_mbyte) len += 3; else --- 3042,3048 ---- case NFA_UPPER_IC: case NFA_NUPPER_IC: case NFA_ANY_COMPOSING: ! // possibly non-ascii if (has_mbyte) len += 3; else *************** *** 3055,3061 **** case NFA_START_INVISIBLE_NEG: case NFA_START_INVISIBLE_BEFORE: case NFA_START_INVISIBLE_BEFORE_NEG: ! /* zero-width, out1 points to the END state */ state = state->out1->out; continue; --- 3053,3059 ---- case NFA_START_INVISIBLE_NEG: case NFA_START_INVISIBLE_BEFORE: case NFA_START_INVISIBLE_BEFORE_NEG: ! // zero-width, out1 points to the END state state = state->out1->out; continue; *************** *** 3081,3087 **** #endif case NFA_NEWL: case NFA_SKIP: ! /* unknown width */ return -1; case NFA_BOL: --- 3079,3085 ---- #endif case NFA_NEWL: case NFA_SKIP: ! // unknown width return -1; case NFA_BOL: *************** *** 3158,3180 **** case NFA_END_PATTERN: case NFA_COMPOSING: case NFA_END_COMPOSING: ! /* zero-width */ break; default: if (state->c < 0) ! /* don't know what this is */ return -1; ! /* normal character */ len += MB_CHAR2LEN(state->c); break; } ! /* normal way to continue */ state = state->out; } ! /* unrecognized, "cannot happen" */ return -1; } --- 3156,3178 ---- case NFA_END_PATTERN: case NFA_COMPOSING: case NFA_END_COMPOSING: ! // zero-width break; default: if (state->c < 0) ! // don't know what this is return -1; ! // normal character len += MB_CHAR2LEN(state->c); break; } ! // normal way to continue state = state->out; } ! // unrecognized, "cannot happen" return -1; } *************** *** 3226,3238 **** switch (*p) { case NFA_CONCAT: ! /* Concatenation. ! * Pay attention: this operator does not exist in the r.e. itself ! * (it is implicit, really). It is added when r.e. is translated ! * to postfix form in re2post(). */ if (nfa_calc_size == TRUE) { ! /* nstate += 0; */ break; } e2 = POP(); --- 3224,3236 ---- switch (*p) { case NFA_CONCAT: ! // Concatenation. ! // Pay attention: this operator does not exist in the r.e. itself ! // (it is implicit, really). It is added when r.e. is translated ! // to postfix form in re2post(). if (nfa_calc_size == TRUE) { ! // nstate += 0; break; } e2 = POP(); *************** *** 3242,3248 **** break; case NFA_OR: ! /* Alternation */ if (nfa_calc_size == TRUE) { nstate++; --- 3240,3246 ---- break; case NFA_OR: ! // Alternation if (nfa_calc_size == TRUE) { nstate++; *************** *** 3257,3263 **** break; case NFA_STAR: ! /* Zero or more, prefer more */ if (nfa_calc_size == TRUE) { nstate++; --- 3255,3261 ---- break; case NFA_STAR: ! // Zero or more, prefer more if (nfa_calc_size == TRUE) { nstate++; *************** *** 3272,3278 **** break; case NFA_STAR_NONGREEDY: ! /* Zero or more, prefer zero */ if (nfa_calc_size == TRUE) { nstate++; --- 3270,3276 ---- break; case NFA_STAR_NONGREEDY: ! // Zero or more, prefer zero if (nfa_calc_size == TRUE) { nstate++; *************** *** 3287,3293 **** break; case NFA_QUEST: ! /* one or zero atoms=> greedy match */ if (nfa_calc_size == TRUE) { nstate++; --- 3285,3291 ---- break; case NFA_QUEST: ! // one or zero atoms=> greedy match if (nfa_calc_size == TRUE) { nstate++; *************** *** 3301,3307 **** break; case NFA_QUEST_NONGREEDY: ! /* zero or one atoms => non-greedy match */ if (nfa_calc_size == TRUE) { nstate++; --- 3299,3305 ---- break; case NFA_QUEST_NONGREEDY: ! // zero or one atoms => non-greedy match if (nfa_calc_size == TRUE) { nstate++; *************** *** 3316,3324 **** case NFA_END_COLL: case NFA_END_NEG_COLL: ! /* On the stack is the sequence starting with NFA_START_COLL or ! * NFA_START_NEG_COLL and all possible characters. Patch it to ! * add the output to the start. */ if (nfa_calc_size == TRUE) { nstate++; --- 3314,3322 ---- case NFA_END_COLL: case NFA_END_NEG_COLL: ! // On the stack is the sequence starting with NFA_START_COLL or ! // NFA_START_NEG_COLL and all possible characters. Patch it to ! // add the output to the start. if (nfa_calc_size == TRUE) { nstate++; *************** *** 3334,3344 **** break; case NFA_RANGE: ! /* Before this are two characters, the low and high end of a ! * range. Turn them into two states with MIN and MAX. */ if (nfa_calc_size == TRUE) { ! /* nstate += 0; */ break; } e2 = POP(); --- 3332,3342 ---- break; case NFA_RANGE: ! // Before this are two characters, the low and high end of a ! // range. Turn them into two states with MIN and MAX. if (nfa_calc_size == TRUE) { ! // nstate += 0; break; } e2 = POP(); *************** *** 3352,3358 **** break; case NFA_EMPTY: ! /* 0-length, used in a repetition with max/min count of 0 */ if (nfa_calc_size == TRUE) { nstate++; --- 3350,3356 ---- break; case NFA_EMPTY: ! // 0-length, used in a repetition with max/min count of 0 if (nfa_calc_size == TRUE) { nstate++; *************** *** 3368,3397 **** { int n; ! /* \%[abc] implemented as: ! * NFA_SPLIT ! * +-CHAR(a) ! * | +-NFA_SPLIT ! * | +-CHAR(b) ! * | | +-NFA_SPLIT ! * | | +-CHAR(c) ! * | | | +-next ! * | | +- next ! * | +- next ! * +- next ! */ ! n = *++p; /* get number of characters */ if (nfa_calc_size == TRUE) { nstate += n; break; } ! s = NULL; /* avoid compiler warning */ ! e1.out = NULL; /* stores list with out1's */ ! s1 = NULL; /* previous NFA_SPLIT to connect to */ while (n-- > 0) { ! e = POP(); /* get character */ s = alloc_state(NFA_SPLIT, e.start, NULL); if (s == NULL) goto theend; --- 3366,3394 ---- { int n; ! // \%[abc] implemented as: ! // NFA_SPLIT ! // +-CHAR(a) ! // | +-NFA_SPLIT ! // | +-CHAR(b) ! // | | +-NFA_SPLIT ! // | | +-CHAR(c) ! // | | | +-next ! // | | +- next ! // | +- next ! // +- next ! n = *++p; // get number of characters if (nfa_calc_size == TRUE) { nstate += n; break; } ! s = NULL; // avoid compiler warning ! e1.out = NULL; // stores list with out1's ! s1 = NULL; // previous NFA_SPLIT to connect to while (n-- > 0) { ! e = POP(); // get character s = alloc_state(NFA_SPLIT, e.start, NULL); if (s == NULL) goto theend; *************** *** 3438,3458 **** start_state = NFA_START_INVISIBLE_BEFORE_NEG; end_state = NFA_END_INVISIBLE_NEG; break; ! default: /* NFA_PREV_ATOM_LIKE_PATTERN: */ start_state = NFA_START_PATTERN; end_state = NFA_END_PATTERN; break; } if (before) ! n = *++p; /* get the count */ ! /* The \@= operator: match the preceding atom with zero width. ! * The \@! operator: no match for the preceding atom. ! * The \@<= operator: match for the preceding atom. ! * The \@ NFA_END_PATTERN -> NFA_SKIP -> what follows. */ skip = alloc_state(NFA_SKIP, NULL, NULL); if (skip == NULL) goto theend; --- 3466,3472 ---- goto theend; if (pattern) { ! // NFA_ZEND -> NFA_END_PATTERN -> NFA_SKIP -> what follows. skip = alloc_state(NFA_SKIP, NULL, NULL); if (skip == NULL) goto theend; *************** *** 3487,3512 **** if (before) { if (n <= 0) ! /* See if we can guess the maximum width, it avoids a ! * lot of pointless tries. */ n = nfa_max_width(e.start, 0); ! s->val = n; /* store the count */ } } break; } ! case NFA_COMPOSING: /* char with composing char */ #if 0 ! /* TODO */ if (regflags & RF_ICOMBINE) { ! /* use the base character only */ } #endif ! /* FALLTHROUGH */ ! case NFA_MOPEN: /* \( \) Submatch */ case NFA_MOPEN1: case NFA_MOPEN2: case NFA_MOPEN3: --- 3484,3509 ---- if (before) { if (n <= 0) ! // See if we can guess the maximum width, it avoids a ! // lot of pointless tries. n = nfa_max_width(e.start, 0); ! s->val = n; // store the count } } break; } ! case NFA_COMPOSING: // char with composing char #if 0 ! // TODO if (regflags & RF_ICOMBINE) { ! // use the base character only } #endif ! // FALLTHROUGH ! case NFA_MOPEN: // \( \) Submatch case NFA_MOPEN1: case NFA_MOPEN2: case NFA_MOPEN3: *************** *** 3517,3523 **** case NFA_MOPEN8: case NFA_MOPEN9: #ifdef FEAT_SYN_HL ! case NFA_ZOPEN: /* \z( \) Submatch */ case NFA_ZOPEN1: case NFA_ZOPEN2: case NFA_ZOPEN3: --- 3514,3520 ---- case NFA_MOPEN8: case NFA_MOPEN9: #ifdef FEAT_SYN_HL ! case NFA_ZOPEN: // \z( \) Submatch case NFA_ZOPEN1: case NFA_ZOPEN2: case NFA_ZOPEN3: *************** *** 3528,3534 **** case NFA_ZOPEN8: case NFA_ZOPEN9: #endif ! case NFA_NOPEN: /* \%( \) "Invisible Submatch" */ if (nfa_calc_size == TRUE) { nstate += 2; --- 3525,3531 ---- case NFA_ZOPEN8: case NFA_ZOPEN9: #endif ! case NFA_NOPEN: // \%( \) "Invisible Submatch" if (nfa_calc_size == TRUE) { nstate += 2; *************** *** 3553,3567 **** #endif case NFA_COMPOSING: mclose = NFA_END_COMPOSING; break; default: ! /* NFA_MOPEN, NFA_MOPEN1 .. NFA_MOPEN9 */ mclose = *p + NSUBEXP; break; } ! /* Allow "NFA_MOPEN" as a valid postfix representation for ! * the empty regexp "". In this case, the NFA will be ! * NFA_MOPEN -> NFA_MCLOSE. Note that this also allows ! * empty groups of parenthesis, and empty mbyte chars */ if (stackp == stack) { s = alloc_state(mopen, NULL, NULL); --- 3550,3564 ---- #endif case NFA_COMPOSING: mclose = NFA_END_COMPOSING; break; default: ! // NFA_MOPEN, NFA_MOPEN1 .. NFA_MOPEN9 mclose = *p + NSUBEXP; break; } ! // Allow "NFA_MOPEN" as a valid postfix representation for ! // the empty regexp "". In this case, the NFA will be ! // NFA_MOPEN -> NFA_MCLOSE. Note that this also allows ! // empty groups of parenthesis, and empty mbyte chars if (stackp == stack) { s = alloc_state(mopen, NULL, NULL); *************** *** 3575,3594 **** break; } ! /* At least one node was emitted before NFA_MOPEN, so ! * at least one node will be between NFA_MOPEN and NFA_MCLOSE */ e = POP(); ! s = alloc_state(mopen, e.start, NULL); /* `(' */ if (s == NULL) goto theend; ! s1 = alloc_state(mclose, NULL, NULL); /* `)' */ if (s1 == NULL) goto theend; patch(e.out, s1); if (mopen == NFA_COMPOSING) ! /* COMPOSING->out1 = END_COMPOSING */ patch(list1(&s->out1), s1); PUSH(frag(s, list1(&s1->out))); --- 3572,3591 ---- break; } ! // At least one node was emitted before NFA_MOPEN, so ! // at least one node will be between NFA_MOPEN and NFA_MCLOSE e = POP(); ! s = alloc_state(mopen, e.start, NULL); // `(' if (s == NULL) goto theend; ! s1 = alloc_state(mclose, NULL, NULL); // `)' if (s1 == NULL) goto theend; patch(e.out, s1); if (mopen == NFA_COMPOSING) ! // COMPOSING->out1 = END_COMPOSING patch(list1(&s->out1), s1); PUSH(frag(s, list1(&s1->out))); *************** *** 3642,3648 **** case NFA_MARK_GT: case NFA_MARK_LT: { ! int n = *++p; /* lnum, col or mark name */ if (nfa_calc_size == TRUE) { --- 3639,3645 ---- case NFA_MARK_GT: case NFA_MARK_LT: { ! int n = *++p; // lnum, col or mark name if (nfa_calc_size == TRUE) { *************** *** 3660,3666 **** case NFA_ZSTART: case NFA_ZEND: default: ! /* Operands */ if (nfa_calc_size == TRUE) { nstate++; --- 3657,3663 ---- case NFA_ZSTART: case NFA_ZEND: default: ! // Operands if (nfa_calc_size == TRUE) { nstate++; *************** *** 3672,3685 **** PUSH(frag(s, list1(&s->out))); break; ! } /* switch(*p) */ ! } /* for(p = postfix; *p; ++p) */ if (nfa_calc_size == TRUE) { nstate++; ! goto theend; /* Return value when counting size is ignored anyway */ } e = POP(); --- 3669,3682 ---- PUSH(frag(s, list1(&s->out))); break; ! } // switch(*p) ! } // for(p = postfix; *p; ++p) if (nfa_calc_size == TRUE) { nstate++; ! goto theend; // Return value when counting size is ignored anyway } e = POP(); *************** *** 3695,3701 **** EMSG_RET_NULL(_("E876: (NFA regexp) Not enough space to store the whole NFA ")); } ! matchstate = &state_ptr[istate++]; /* the match state */ matchstate->c = NFA_MATCH; matchstate->out = matchstate->out1 = NULL; matchstate->id = 0; --- 3692,3698 ---- EMSG_RET_NULL(_("E876: (NFA regexp) Not enough space to store the whole NFA ")); } ! matchstate = &state_ptr[istate++]; // the match state matchstate->c = NFA_MATCH; matchstate->out = matchstate->out1 = NULL; matchstate->id = 0; *************** *** 3734,3741 **** { int directly; ! /* Do it directly when what follows is possibly the end of the ! * match. */ if (match_follows(prog->state[i].out1->out, 0)) directly = TRUE; else --- 3731,3738 ---- { int directly; ! // Do it directly when what follows is possibly the end of the ! // match. if (match_follows(prog->state[i].out1->out, 0)) directly = TRUE; else *************** *** 3743,3757 **** int ch_invisible = failure_chance(prog->state[i].out, 0); int ch_follows = failure_chance(prog->state[i].out1->out, 0); ! /* Postpone when the invisible match is expensive or has a ! * lower chance of failing. */ if (c == NFA_START_INVISIBLE_BEFORE || c == NFA_START_INVISIBLE_BEFORE_NEG) { ! /* "before" matches are very expensive when ! * unbounded, always prefer what follows then, ! * unless what follows will always match. ! * Otherwise strongly prefer what follows. */ if (prog->state[i].val <= 0 && ch_follows > 0) directly = FALSE; else --- 3740,3754 ---- int ch_invisible = failure_chance(prog->state[i].out, 0); int ch_follows = failure_chance(prog->state[i].out1->out, 0); ! // Postpone when the invisible match is expensive or has a ! // lower chance of failing. if (c == NFA_START_INVISIBLE_BEFORE || c == NFA_START_INVISIBLE_BEFORE_NEG) { ! // "before" matches are very expensive when ! // unbounded, always prefer what follows then, ! // unless what follows will always match. ! // Otherwise strongly prefer what follows. if (prog->state[i].val <= 0 && ch_follows > 0) directly = FALSE; else *************** *** 3759,3785 **** } else { ! /* normal invisible, first do the one with the ! * highest failure chance */ directly = ch_follows < ch_invisible; } } if (directly) ! /* switch to the _FIRST state */ ++prog->state[i].c; } } } ! /**************************************************************** ! * NFA execution code. ! ****************************************************************/ typedef struct { ! int in_use; /* number of subexpr with useful info */ ! /* When REG_MULTI is TRUE list.multi is used, otherwise list.line. */ union { struct multipos --- 3756,3782 ---- } else { ! // normal invisible, first do the one with the ! // highest failure chance directly = ch_follows < ch_invisible; } } if (directly) ! // switch to the _FIRST state ++prog->state[i].c; } } } ! ///////////////////////////////////////////////////////////////// ! // NFA execution code. ! ///////////////////////////////////////////////////////////////// typedef struct { ! int in_use; // number of subexpr with useful info ! // When REG_MULTI is TRUE list.multi is used, otherwise list.line. union { struct multipos *************** *** 3799,3849 **** typedef struct { ! regsub_T norm; /* \( .. \) matches */ #ifdef FEAT_SYN_HL ! regsub_T synt; /* \z( .. \) matches */ #endif } regsubs_T; ! /* nfa_pim_T stores a Postponed Invisible Match. */ typedef struct nfa_pim_S nfa_pim_T; struct nfa_pim_S { ! int result; /* NFA_PIM_*, see below */ ! nfa_state_T *state; /* the invisible match start state */ ! regsubs_T subs; /* submatch info, only party used */ union { lpos_T pos; char_u *ptr; ! } end; /* where the match must end */ }; ! /* Values for done in nfa_pim_T. */ ! #define NFA_PIM_UNUSED 0 /* pim not used */ ! #define NFA_PIM_TODO 1 /* pim not done yet */ ! #define NFA_PIM_MATCH 2 /* pim executed, matches */ ! #define NFA_PIM_NOMATCH 3 /* pim executed, no match */ ! /* nfa_thread_T contains execution information of a NFA state */ typedef struct { nfa_state_T *state; int count; ! nfa_pim_T pim; /* if pim.result != NFA_PIM_UNUSED: postponed ! * invisible match */ ! regsubs_T subs; /* submatch info, only party used */ } nfa_thread_T; ! /* nfa_list_T contains the alternative NFA execution states. */ typedef struct { ! nfa_thread_T *t; /* allocated array of states */ ! int n; /* nr of states currently in "t" */ ! int len; /* max nr of states in "t" */ ! int id; /* ID of the list */ ! int has_pim; /* TRUE when any state has a PIM */ } nfa_list_T; #ifdef ENABLE_LOG --- 3796,3846 ---- typedef struct { ! regsub_T norm; // \( .. \) matches #ifdef FEAT_SYN_HL ! regsub_T synt; // \z( .. \) matches #endif } regsubs_T; ! // nfa_pim_T stores a Postponed Invisible Match. typedef struct nfa_pim_S nfa_pim_T; struct nfa_pim_S { ! int result; // NFA_PIM_*, see below ! nfa_state_T *state; // the invisible match start state ! regsubs_T subs; // submatch info, only party used union { lpos_T pos; char_u *ptr; ! } end; // where the match must end }; ! // Values for done in nfa_pim_T. ! #define NFA_PIM_UNUSED 0 // pim not used ! #define NFA_PIM_TODO 1 // pim not done yet ! #define NFA_PIM_MATCH 2 // pim executed, matches ! #define NFA_PIM_NOMATCH 3 // pim executed, no match ! // nfa_thread_T contains execution information of a NFA state typedef struct { nfa_state_T *state; int count; ! nfa_pim_T pim; // if pim.result != NFA_PIM_UNUSED: postponed ! // invisible match ! regsubs_T subs; // submatch info, only party used } nfa_thread_T; ! // nfa_list_T contains the alternative NFA execution states. typedef struct { ! nfa_thread_T *t; // allocated array of states ! int n; // nr of states currently in "t" ! int len; // max nr of states in "t" ! int id; // ID of the list ! int has_pim; // TRUE when any state has a PIM } nfa_list_T; #ifdef ENABLE_LOG *************** *** 3901,3907 **** #endif ! /* Used during execution: whether a match has been found. */ static int nfa_match; #ifdef FEAT_RELTIME static proftime_T *nfa_time_limit; --- 3898,3904 ---- #endif ! // Used during execution: whether a match has been found. static int nfa_match; #ifdef FEAT_RELTIME static proftime_T *nfa_time_limit; *************** *** 3932,3938 **** clear_sub(regsub_T *sub) { if (REG_MULTI) ! /* Use 0xff to set lnum to -1 */ vim_memset(sub->list.multi, 0xff, sizeof(struct multipos) * rex.nfa_nsubexpr); else --- 3929,3935 ---- clear_sub(regsub_T *sub) { if (REG_MULTI) ! // Use 0xff to set lnum to -1 vim_memset(sub->list.multi, 0xff, sizeof(struct multipos) * rex.nfa_nsubexpr); else *************** *** 3950,3956 **** to->in_use = from->in_use; if (from->in_use > 0) { ! /* Copy the match start and end positions. */ if (REG_MULTI) mch_memmove(&to->list.multi[0], &from->list.multi[0], --- 3947,3953 ---- to->in_use = from->in_use; if (from->in_use > 0) { ! // Copy the match start and end positions. if (REG_MULTI) mch_memmove(&to->list.multi[0], &from->list.multi[0], *************** *** 3972,3978 **** to->in_use = from->in_use; if (from->in_use > 1) { ! /* Copy the match start and end positions. */ if (REG_MULTI) mch_memmove(&to->list.multi[1], &from->list.multi[1], --- 3969,3975 ---- to->in_use = from->in_use; if (from->in_use > 1) { ! // Copy the match start and end positions. if (REG_MULTI) mch_memmove(&to->list.multi[1], &from->list.multi[1], *************** *** 4121,4130 **** */ static int has_state_with_pos( ! nfa_list_T *l, /* runtime state list */ ! nfa_state_T *state, /* state to update */ ! regsubs_T *subs, /* pointers to subexpressions */ ! nfa_pim_T *pim) /* postponed match or NULL */ { nfa_thread_T *thread; int i; --- 4118,4127 ---- */ static int has_state_with_pos( ! nfa_list_T *l, // runtime state list ! nfa_state_T *state, // state to update ! regsubs_T *subs, // pointers to subexpressions ! nfa_pim_T *pim) // postponed match or NULL { nfa_thread_T *thread; int i; *************** *** 4155,4169 **** int two_unused = (two == NULL || two->result == NFA_PIM_UNUSED); if (one_unused) ! /* one is unused: equal when two is also unused */ return two_unused; if (two_unused) ! /* one is used and two is not: not equal */ return FALSE; ! /* compare the state id */ if (one->state->id != two->state->id) return FALSE; ! /* compare the position */ if (REG_MULTI) return one->end.pos.lnum == two->end.pos.lnum && one->end.pos.col == two->end.pos.col; --- 4152,4166 ---- int two_unused = (two == NULL || two->result == NFA_PIM_UNUSED); if (one_unused) ! // one is unused: equal when two is also unused return two_unused; if (two_unused) ! // one is used and two is not: not equal return FALSE; ! // compare the state id if (one->state->id != two->state->id) return FALSE; ! // compare the position if (REG_MULTI) return one->end.pos.lnum == two->end.pos.lnum && one->end.pos.col == two->end.pos.col; *************** *** 4178,4184 **** { nfa_state_T *state = startstate; ! /* avoid too much recursion */ if (depth > 10) return FALSE; --- 4175,4181 ---- { nfa_state_T *state = startstate; ! // avoid too much recursion if (depth > 10) return FALSE; *************** *** 4206,4212 **** case NFA_START_INVISIBLE_BEFORE_NEG: case NFA_START_INVISIBLE_BEFORE_NEG_FIRST: case NFA_COMPOSING: ! /* skip ahead to next state */ state = state->out1->out; continue; --- 4203,4209 ---- case NFA_START_INVISIBLE_BEFORE_NEG: case NFA_START_INVISIBLE_BEFORE_NEG_FIRST: case NFA_COMPOSING: ! // skip ahead to next state state = state->out1->out; continue; *************** *** 4245,4260 **** case NFA_START_COLL: case NFA_START_NEG_COLL: case NFA_NEWL: ! /* state will advance input */ return FALSE; default: if (state->c > 0) ! /* state will advance input */ return FALSE; ! /* Others: zero-width or possibly zero-width, might still find ! * a match at the same position, keep looking. */ break; } state = state->out; --- 4242,4257 ---- case NFA_START_COLL: case NFA_START_NEG_COLL: case NFA_NEWL: ! // state will advance input return FALSE; default: if (state->c > 0) ! // state will advance input return FALSE; ! // Others: zero-width or possibly zero-width, might still find ! // a match at the same position, keep looking. break; } state = state->out; *************** *** 4268,4276 **** */ static int state_in_list( ! nfa_list_T *l, /* runtime state list */ ! nfa_state_T *state, /* state to update */ ! regsubs_T *subs) /* pointers to subexpressions */ { if (state->lastlist[nfa_ll_index] == l->id) { --- 4265,4273 ---- */ static int state_in_list( ! nfa_list_T *l, // runtime state list ! nfa_state_T *state, // state to update ! regsubs_T *subs) // pointers to subexpressions { if (state->lastlist[nfa_ll_index] == l->id) { *************** *** 4280,4286 **** return FALSE; } ! /* Offset used for "off" by addstate_here(). */ #define ADDSTATE_HERE_OFFSET 10 /* --- 4277,4283 ---- return FALSE; } ! // Offset used for "off" by addstate_here(). #define ADDSTATE_HERE_OFFSET 10 /* *************** *** 4290,4300 **** */ static regsubs_T * addstate( ! nfa_list_T *l, /* runtime state list */ ! nfa_state_T *state, /* state to update */ ! regsubs_T *subs_arg, /* pointers to subexpressions */ ! nfa_pim_T *pim, /* postponed look-behind match */ ! int off_arg) /* byte offset, when -1 go to next line */ { int subidx; int off = off_arg; --- 4287,4297 ---- */ static regsubs_T * addstate( ! nfa_list_T *l, // runtime state list ! nfa_state_T *state, // state to update ! regsubs_T *subs_arg, // pointers to subexpressions ! nfa_pim_T *pim, // postponed look-behind match ! int off_arg) // byte offset, when -1 go to next line { int subidx; int off = off_arg; *************** *** 4359,4380 **** case NFA_ZEND: case NFA_SPLIT: case NFA_EMPTY: ! /* These nodes are not added themselves but their "out" and/or ! * "out1" may be added below. */ break; case NFA_BOL: case NFA_BOF: ! /* "^" won't match past end-of-line, don't bother trying. ! * Except when at the end of the line, or when we are going to the ! * next line for a look-behind match. */ if (rex.input > rex.line && *rex.input != NUL && (nfa_endp == NULL || !REG_MULTI || rex.lnum == nfa_endp->se_u.pos.lnum)) goto skip_add; ! /* FALLTHROUGH */ case NFA_MOPEN1: case NFA_MOPEN2: --- 4356,4377 ---- case NFA_ZEND: case NFA_SPLIT: case NFA_EMPTY: ! // These nodes are not added themselves but their "out" and/or ! // "out1" may be added below. break; case NFA_BOL: case NFA_BOF: ! // "^" won't match past end-of-line, don't bother trying. ! // Except when at the end of the line, or when we are going to the ! // next line for a look-behind match. if (rex.input > rex.line && *rex.input != NUL && (nfa_endp == NULL || !REG_MULTI || rex.lnum == nfa_endp->se_u.pos.lnum)) goto skip_add; ! // FALLTHROUGH case NFA_MOPEN1: case NFA_MOPEN2: *************** *** 4399,4420 **** #endif case NFA_NOPEN: case NFA_ZSTART: ! /* These nodes need to be added so that we can bail out when it ! * was added to this list before at the same position to avoid an ! * endless loop for "\(\)*" */ default: if (state->lastlist[nfa_ll_index] == l->id && state->c != NFA_SKIP) { ! /* This state is already in the list, don't add it again, ! * unless it is an MOPEN that is used for a backreference or ! * when there is a PIM. For NFA_MATCH check the position, ! * lower position is preferred. */ if (!rex.nfa_has_backref && pim == NULL && !l->has_pim && state->c != NFA_MATCH) { ! /* When called from addstate_here() do insert before ! * existing states. */ if (add_here) { for (k = 0; k < l->n && k < listindex; ++k) --- 4396,4417 ---- #endif case NFA_NOPEN: case NFA_ZSTART: ! // These nodes need to be added so that we can bail out when it ! // was added to this list before at the same position to avoid an ! // endless loop for "\(\)*" default: if (state->lastlist[nfa_ll_index] == l->id && state->c != NFA_SKIP) { ! // This state is already in the list, don't add it again, ! // unless it is an MOPEN that is used for a backreference or ! // when there is a PIM. For NFA_MATCH check the position, ! // lower position is preferred. if (!rex.nfa_has_backref && pim == NULL && !l->has_pim && state->c != NFA_MATCH) { ! // When called from addstate_here() do insert before ! // existing states. if (add_here) { for (k = 0; k < l->n && k < listindex; ++k) *************** *** 4438,4445 **** } } ! /* Do not add the state again when it exists with the same ! * positions. */ if (has_state_with_pos(l, state, subs, pim)) goto skip_add; } --- 4435,4442 ---- } } ! // Do not add the state again when it exists with the same ! // positions. if (has_state_with_pos(l, state, subs, pim)) goto skip_add; } *************** *** 4460,4467 **** } if (subs != &temp_subs) { ! /* "subs" may point into the current array, need to make a ! * copy before it becomes invalid. */ copy_sub(&temp_subs.norm, &subs->norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) --- 4457,4464 ---- } if (subs != &temp_subs) { ! // "subs" may point into the current array, need to make a ! // copy before it becomes invalid. copy_sub(&temp_subs.norm, &subs->norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) *************** *** 4481,4487 **** l->len = newlen; } ! /* add the state to the list */ state->lastlist[nfa_ll_index] = l->id; thread = &l->t[l->n++]; thread->state = state; --- 4478,4484 ---- l->len = newlen; } ! // add the state to the list state->lastlist[nfa_ll_index] = l->id; thread = &l->t[l->n++]; thread->state = state; *************** *** 4513,4519 **** break; case NFA_SPLIT: ! /* order matters here */ subs = addstate(l, state->out, subs, pim, off_arg); subs = addstate(l, state->out1, subs, pim, off_arg); break; --- 4510,4516 ---- break; case NFA_SPLIT: ! // order matters here subs = addstate(l, state->out, subs, pim, off_arg); subs = addstate(l, state->out1, subs, pim, off_arg); break; *************** *** 4565,4576 **** sub = &subs->norm; } ! /* avoid compiler warnings */ save_ptr = NULL; vim_memset(&save_multipos, 0, sizeof(save_multipos)); ! /* Set the position (with "off" added) in the subexpression. Save ! * and restore it when it was in use. Otherwise fill any gap. */ if (REG_MULTI) { if (subidx < sub->in_use) --- 4562,4573 ---- sub = &subs->norm; } ! // avoid compiler warnings save_ptr = NULL; vim_memset(&save_multipos, 0, sizeof(save_multipos)); ! // Set the position (with "off" added) in the subexpression. Save ! // and restore it when it was in use. Otherwise fill any gap. if (REG_MULTI) { if (subidx < sub->in_use) *************** *** 4652,4658 **** subs = addstate(l, state->out, subs, pim, off_arg); break; } ! /* FALLTHROUGH */ case NFA_MCLOSE1: case NFA_MCLOSE2: case NFA_MCLOSE3: --- 4649,4655 ---- subs = addstate(l, state->out, subs, pim, off_arg); break; } ! // FALLTHROUGH case NFA_MCLOSE1: case NFA_MCLOSE2: case NFA_MCLOSE3: *************** *** 4693,4700 **** sub = &subs->norm; } ! /* We don't fill in gaps here, there must have been an MOPEN that ! * has done that. */ save_in_use = sub->in_use; if (sub->in_use <= subidx) sub->in_use = subidx + 1; --- 4690,4697 ---- sub = &subs->norm; } ! // We don't fill in gaps here, there must have been an MOPEN that ! // has done that. save_in_use = sub->in_use; if (sub->in_use <= subidx) sub->in_use = subidx + 1; *************** *** 4712,4732 **** sub->list.multi[subidx].end_col = (colnr_T)(rex.input - rex.line + off); } ! /* avoid compiler warnings */ save_ptr = NULL; } else { save_ptr = sub->list.line[subidx].end; sub->list.line[subidx].end = rex.input + off; ! /* avoid compiler warnings */ vim_memset(&save_multipos, 0, sizeof(save_multipos)); } subs = addstate(l, state->out, subs, pim, off_arg); if (subs == NULL) break; ! /* "subs" may have changed, need to set "sub" again */ #ifdef FEAT_SYN_HL if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) sub = &subs->synt; --- 4709,4729 ---- sub->list.multi[subidx].end_col = (colnr_T)(rex.input - rex.line + off); } ! // avoid compiler warnings save_ptr = NULL; } else { save_ptr = sub->list.line[subidx].end; sub->list.line[subidx].end = rex.input + off; ! // avoid compiler warnings vim_memset(&save_multipos, 0, sizeof(save_multipos)); } subs = addstate(l, state->out, subs, pim, off_arg); if (subs == NULL) break; ! // "subs" may have changed, need to set "sub" again #ifdef FEAT_SYN_HL if (state->c >= NFA_ZCLOSE && state->c <= NFA_ZCLOSE9) sub = &subs->synt; *************** *** 4753,4762 **** */ static regsubs_T * addstate_here( ! nfa_list_T *l, /* runtime state list */ ! nfa_state_T *state, /* state to update */ ! regsubs_T *subs, /* pointers to subexpressions */ ! nfa_pim_T *pim, /* postponed look-behind match */ int *ip) { int tlen = l->n; --- 4750,4759 ---- */ static regsubs_T * addstate_here( ! nfa_list_T *l, // runtime state list ! nfa_state_T *state, // state to update ! regsubs_T *subs, // pointers to subexpressions ! nfa_pim_T *pim, // postponed look-behind match int *ip) { int tlen = l->n; *************** *** 4764,4772 **** int listidx = *ip; regsubs_T *r; ! /* First add the state(s) at the end, so that we know how many there are. ! * Pass the listidx as offset (avoids adding another argument to ! * addstate(). */ r = addstate(l, state, subs, pim, -listidx - ADDSTATE_HERE_OFFSET); if (r == NULL) return NULL; --- 4761,4769 ---- int listidx = *ip; regsubs_T *r; ! // First add the state(s) at the end, so that we know how many there are. ! // Pass the listidx as offset (avoids adding another argument to ! // addstate(). r = addstate(l, state, subs, pim, -listidx - ADDSTATE_HERE_OFFSET); if (r == NULL) return NULL; *************** *** 4788,4795 **** { if (l->n + count - 1 >= l->len) { ! /* not enough space to move the new states, reallocate the list ! * and move the states to the right position */ int newlen = l->len * 3 / 2 + 50; size_t newsize = newlen * sizeof(nfa_thread_T); nfa_thread_T *newl; --- 4785,4792 ---- { if (l->n + count - 1 >= l->len) { ! // not enough space to move the new states, reallocate the list ! // and move the states to the right position int newlen = l->len * 3 / 2 + 50; size_t newsize = newlen * sizeof(nfa_thread_T); nfa_thread_T *newl; *************** *** 4817,4824 **** } else { ! /* make space for new states, then move them from the ! * end to the current position */ mch_memmove(&(l->t[listidx + count]), &(l->t[listidx + 1]), sizeof(nfa_thread_T) * (l->n - listidx - 1)); --- 4814,4821 ---- } else { ! // make space for new states, then move them from the ! // end to the current position mch_memmove(&(l->t[listidx + count]), &(l->t[listidx + 1]), sizeof(nfa_thread_T) * (l->n - listidx - 1)); *************** *** 4919,4925 **** break; default: ! /* should not be here :P */ siemsg(_(e_ill_char_class), class); return FAIL; } --- 4916,4922 ---- break; default: ! // should not be here :P siemsg(_(e_ill_char_class), class); return FAIL; } *************** *** 4932,4947 **** */ static int match_backref( ! regsub_T *sub, /* pointers to subexpressions */ int subidx, ! int *bytelen) /* out: length of match in bytes */ { int len; if (sub->in_use <= subidx) { retempty: ! /* backref was not set, match an empty string */ *bytelen = 0; return TRUE; } --- 4929,4944 ---- */ static int match_backref( ! regsub_T *sub, // pointers to subexpressions int subidx, ! int *bytelen) // out: length of match in bytes { int len; if (sub->in_use <= subidx) { retempty: ! // backref was not set, match an empty string *bytelen = 0; return TRUE; } *************** *** 4998,5011 **** static int match_zref( int subidx, ! int *bytelen) /* out: length of match in bytes */ { int len; cleanup_zsubexpr(); if (re_extmatch_in == NULL || re_extmatch_in->matches[subidx] == NULL) { ! /* backref was not set, match an empty string */ *bytelen = 0; return TRUE; } --- 4995,5008 ---- static int match_zref( int subidx, ! int *bytelen) // out: length of match in bytes { int len; cleanup_zsubexpr(); if (re_extmatch_in == NULL || re_extmatch_in->matches[subidx] == NULL) { ! // backref was not set, match an empty string *bytelen = 0; return TRUE; } *************** *** 5031,5037 **** int i; nfa_state_T *p; ! /* Order in the list is reverse, it's a bit faster that way. */ p = &prog->state[0]; for (i = prog->nstate; --i >= 0; ) { --- 5028,5034 ---- int i; nfa_state_T *p; ! // Order in the list is reverse, it's a bit faster that way. p = &prog->state[0]; for (i = prog->nstate; --i >= 0; ) { *************** *** 5095,5101 **** if (pim != NULL) { ! /* start at the position where the postponed match was */ if (REG_MULTI) rex.input = rex.line + pim->end.pos.col; else --- 5092,5098 ---- if (pim != NULL) { ! // start at the position where the postponed match was if (REG_MULTI) rex.input = rex.line + pim->end.pos.col; else *************** *** 5107,5114 **** || state->c == NFA_START_INVISIBLE_BEFORE_NEG || state->c == NFA_START_INVISIBLE_BEFORE_NEG_FIRST) { ! /* The recursive match must end at the current position. When "pim" is ! * not NULL it specifies the current position. */ endposp = &endpos; if (REG_MULTI) { --- 5104,5111 ---- || state->c == NFA_START_INVISIBLE_BEFORE_NEG || state->c == NFA_START_INVISIBLE_BEFORE_NEG_FIRST) { ! // The recursive match must end at the current position. When "pim" is ! // not NULL it specifies the current position. endposp = &endpos; if (REG_MULTI) { *************** *** 5128,5144 **** endpos.se_u.ptr = pim->end.ptr; } ! /* Go back the specified number of bytes, or as far as the ! * start of the previous line, to try matching "\@<=" or ! * not matching "\@val <= 0) { if (REG_MULTI) { rex.line = reg_getline(--rex.lnum); if (rex.line == NULL) ! /* can't go before the first line */ rex.line = reg_getline(++rex.lnum); } rex.input = rex.line; --- 5125,5141 ---- endpos.se_u.ptr = pim->end.ptr; } ! // Go back the specified number of bytes, or as far as the ! // start of the previous line, to try matching "\@<=" or ! // not matching "\@val <= 0) { if (REG_MULTI) { rex.line = reg_getline(--rex.lnum); if (rex.line == NULL) ! // can't go before the first line rex.line = reg_getline(++rex.lnum); } rex.input = rex.line; *************** *** 5147,5158 **** { if (REG_MULTI && (int)(rex.input - rex.line) < state->val) { ! /* Not enough bytes in this line, go to end of ! * previous line. */ rex.line = reg_getline(--rex.lnum); if (rex.line == NULL) { ! /* can't go before the first line */ rex.line = reg_getline(++rex.lnum); rex.input = rex.line; } --- 5144,5155 ---- { if (REG_MULTI && (int)(rex.input - rex.line) < state->val) { ! // Not enough bytes in this line, go to end of ! // previous line. rex.line = reg_getline(--rex.lnum); if (rex.line == NULL) { ! // can't go before the first line rex.line = reg_getline(++rex.lnum); rex.input = rex.line; } *************** *** 5175,5186 **** fclose(log_fd); log_fd = NULL; #endif ! /* Have to clear the lastlist field of the NFA nodes, so that ! * nfa_regmatch() and addstate() can run properly after recursion. */ if (nfa_ll_index == 1) { ! /* Already calling nfa_regmatch() recursively. Save the lastlist[1] ! * values and clear them. */ if (*listids == NULL || *listids_len < prog->nstate) { vim_free(*listids); --- 5172,5183 ---- fclose(log_fd); log_fd = NULL; #endif ! // Have to clear the lastlist field of the NFA nodes, so that ! // nfa_regmatch() and addstate() can run properly after recursion. if (nfa_ll_index == 1) { ! // Already calling nfa_regmatch() recursively. Save the lastlist[1] ! // values and clear them. if (*listids == NULL || *listids_len < prog->nstate) { vim_free(*listids); *************** *** 5194,5213 **** } nfa_save_listids(prog, *listids); need_restore = TRUE; ! /* any value of rex.nfa_listid will do */ } else { ! /* First recursive nfa_regmatch() call, switch to the second lastlist ! * entry. Make sure rex.nfa_listid is different from a previous ! * recursive call, because some states may still have this ID. */ ++nfa_ll_index; if (rex.nfa_listid <= rex.nfa_alt_listid) rex.nfa_listid = rex.nfa_alt_listid; } ! /* Call nfa_regmatch() to check if the current concat matches at this ! * position. The concat ends with the node NFA_END_INVISIBLE */ nfa_endp = endposp; result = nfa_regmatch(prog, state->out, submatch, m); --- 5191,5210 ---- } nfa_save_listids(prog, *listids); need_restore = TRUE; ! // any value of rex.nfa_listid will do } else { ! // First recursive nfa_regmatch() call, switch to the second lastlist ! // entry. Make sure rex.nfa_listid is different from a previous ! // recursive call, because some states may still have this ID. ++nfa_ll_index; if (rex.nfa_listid <= rex.nfa_alt_listid) rex.nfa_listid = rex.nfa_alt_listid; } ! // Call nfa_regmatch() to check if the current concat matches at this ! // position. The concat ends with the node NFA_END_INVISIBLE nfa_endp = endposp; result = nfa_regmatch(prog, state->out, submatch, m); *************** *** 5219,5225 **** rex.nfa_alt_listid = rex.nfa_listid; } ! /* restore position in input text */ rex.lnum = save_reglnum; if (REG_MULTI) rex.line = reg_getline(rex.lnum); --- 5216,5222 ---- rex.nfa_alt_listid = rex.nfa_listid; } ! // restore position in input text rex.lnum = save_reglnum; if (REG_MULTI) rex.line = reg_getline(rex.lnum); *************** *** 5262,5268 **** int c = state->c; int l, r; ! /* detect looping */ if (depth > 4) return 1; --- 5259,5265 ---- int c = state->c; int l, r; ! // detect looping if (depth > 4) return 1; *************** *** 5270,5290 **** { case NFA_SPLIT: if (state->out->c == NFA_SPLIT || state->out1->c == NFA_SPLIT) ! /* avoid recursive stuff */ return 1; ! /* two alternatives, use the lowest failure chance */ l = failure_chance(state->out, depth + 1); r = failure_chance(state->out1, depth + 1); return l < r ? l : r; case NFA_ANY: ! /* matches anything, unlikely to fail */ return 1; case NFA_MATCH: case NFA_MCLOSE: case NFA_ANY_COMPOSING: ! /* empty match works always */ return 0; case NFA_START_INVISIBLE: --- 5267,5287 ---- { case NFA_SPLIT: if (state->out->c == NFA_SPLIT || state->out1->c == NFA_SPLIT) ! // avoid recursive stuff return 1; ! // two alternatives, use the lowest failure chance l = failure_chance(state->out, depth + 1); r = failure_chance(state->out1, depth + 1); return l < r ? l : r; case NFA_ANY: ! // matches anything, unlikely to fail return 1; case NFA_MATCH: case NFA_MCLOSE: case NFA_ANY_COMPOSING: ! // empty match works always return 0; case NFA_START_INVISIBLE: *************** *** 5296,5302 **** case NFA_START_INVISIBLE_BEFORE_NEG: case NFA_START_INVISIBLE_BEFORE_NEG_FIRST: case NFA_START_PATTERN: ! /* recursive regmatch is expensive, use low failure chance */ return 5; case NFA_BOL: --- 5293,5299 ---- case NFA_START_INVISIBLE_BEFORE_NEG: case NFA_START_INVISIBLE_BEFORE_NEG_FIRST: case NFA_START_PATTERN: ! // recursive regmatch is expensive, use low failure chance return 5; case NFA_BOL: *************** *** 5375,5381 **** case NFA_ZREF8: case NFA_ZREF9: #endif ! /* backreferences don't match in many places */ return 94; case NFA_LNUM_GT: --- 5372,5378 ---- case NFA_ZREF8: case NFA_ZREF9: #endif ! // backreferences don't match in many places return 94; case NFA_LNUM_GT: *************** *** 5387,5393 **** case NFA_MARK_GT: case NFA_MARK_LT: case NFA_VISUAL: ! /* before/after positions don't match very often */ return 85; case NFA_LNUM: --- 5384,5390 ---- case NFA_MARK_GT: case NFA_MARK_LT: case NFA_VISUAL: ! // before/after positions don't match very often return 85; case NFA_LNUM: *************** *** 5397,5403 **** case NFA_COL: case NFA_VCOL: case NFA_MARK: ! /* specific positions rarely match */ return 98; case NFA_COMPOSING: --- 5394,5400 ---- case NFA_COL: case NFA_VCOL: case NFA_MARK: ! // specific positions rarely match return 98; case NFA_COMPOSING: *************** *** 5405,5415 **** default: if (c > 0) ! /* character match fails often */ return 95; } ! /* something else, includes character classes */ return 50; } --- 5402,5412 ---- default: if (c > 0) ! // character match fails often return 95; } ! // something else, includes character classes return 50; } *************** *** 5421,5427 **** { char_u *s; ! /* Used often, do some work to avoid call overhead. */ if (!rex.reg_ic && !has_mbyte) s = vim_strbyte(rex.line + *colp, c); else --- 5418,5424 ---- { char_u *s; ! // Used often, do some work to avoid call overhead. if (!rex.reg_ic && !has_mbyte) s = vim_strbyte(rex.line + *colp, c); else *************** *** 5448,5454 **** for (;;) { match = TRUE; ! len2 = MB_CHAR2LEN(regstart); /* skip regstart */ for (len1 = 0; match_text[len1] != NUL; len1 += MB_CHAR2LEN(c1)) { c1 = PTR2CHAR(match_text + len1); --- 5445,5451 ---- for (;;) { match = TRUE; ! len2 = MB_CHAR2LEN(regstart); // skip regstart for (len1 = 0; match_text[len1] != NUL; len1 += MB_CHAR2LEN(c1)) { c1 = PTR2CHAR(match_text + len1); *************** *** 5461,5467 **** len2 += MB_CHAR2LEN(c2); } if (match ! /* check that no composing char follows */ && !(enc_utf8 && utf_iscomposing(PTR2CHAR(rex.line + col + len2)))) { --- 5458,5464 ---- len2 += MB_CHAR2LEN(c2); } if (match ! // check that no composing char follows && !(enc_utf8 && utf_iscomposing(PTR2CHAR(rex.line + col + len2)))) { *************** *** 5481,5488 **** return 1L; } ! /* Try finding regstart after the current match. */ ! col += MB_CHAR2LEN(regstart); /* skip regstart */ if (skip_to_start(regstart, &col) == FAIL) break; } --- 5478,5485 ---- return 1L; } ! // Try finding regstart after the current match. ! col += MB_CHAR2LEN(regstart); // skip regstart if (skip_to_start(regstart, &col) == FAIL) break; } *************** *** 5544,5551 **** FILE *debug; #endif ! /* Some patterns may take a long time to match, especially when using ! * recursive_regmatch(). Allow interrupting them with CTRL-C. */ fast_breakcheck(); if (got_int) return FALSE; --- 5541,5548 ---- FILE *debug; #endif ! // Some patterns may take a long time to match, especially when using ! // recursive_regmatch(). Allow interrupting them with CTRL-C. fast_breakcheck(); if (got_int) return FALSE; *************** *** 5564,5570 **** #endif nfa_match = FALSE; ! /* Allocate memory for the lists of nodes. */ size = (prog->nstate + 1) * sizeof(nfa_thread_T); list[0].t = alloc(size); --- 5561,5567 ---- #endif nfa_match = FALSE; ! // Allocate memory for the lists of nodes. size = (prog->nstate + 1) * sizeof(nfa_thread_T); list[0].t = alloc(size); *************** *** 5602,5609 **** #endif thislist->id = rex.nfa_listid + 1; ! /* Inline optimized code for addstate(thislist, start, m, 0) if we know ! * it's the first MOPEN. */ if (toplevel) { if (REG_MULTI) --- 5599,5606 ---- #endif thislist->id = rex.nfa_listid + 1; ! // Inline optimized code for addstate(thislist, start, m, 0) if we know ! // it's the first MOPEN. if (toplevel) { if (REG_MULTI) *************** *** 5654,5663 **** go_to_nextline = FALSE; } ! /* swap lists */ thislist = &list[flag]; nextlist = &list[flag ^= 1]; ! nextlist->n = 0; /* clear nextlist */ nextlist->has_pim = FALSE; ++rex.nfa_listid; if (prog->re_engine == AUTOMATIC_ENGINE --- 5651,5660 ---- go_to_nextline = FALSE; } ! // swap lists thislist = &list[flag]; nextlist = &list[flag ^= 1]; ! nextlist->n = 0; // clear nextlist nextlist->has_pim = FALSE; ++rex.nfa_listid; if (prog->re_engine == AUTOMATIC_ENGINE *************** *** 5667,5673 **** # endif )) { ! /* too many states, retry with old engine */ nfa_match = NFA_TOO_EXPENSIVE; goto theend; } --- 5664,5670 ---- # endif )) { ! // too many states, retry with old engine nfa_match = NFA_TOO_EXPENSIVE; goto theend; } *************** *** 5698,5708 **** if (thislist->n == 0) break; ! /* compute nextlist */ for (listidx = 0; listidx < thislist->n; ++listidx) { ! /* If the list gets very long there probably is something wrong. ! * At least allow interrupting with CTRL-C. */ fast_breakcheck(); if (got_int) break; --- 5695,5705 ---- if (thislist->n == 0) break; ! // compute nextlist for (listidx = 0; listidx < thislist->n; ++listidx) { ! // If the list gets very long there probably is something wrong. ! // At least allow interrupting with CTRL-C. fast_breakcheck(); if (got_int) break; *************** *** 5748,5755 **** { case NFA_MATCH: { ! /* If the match ends before a composing characters and ! * rex.reg_icombine is not set, that is not really a match. */ if (enc_utf8 && !rex.reg_icombine && utf_iscomposing(curc)) break; --- 5745,5752 ---- { case NFA_MATCH: { ! // If the match ends before a composing characters and ! // rex.reg_icombine is not set, that is not really a match. if (enc_utf8 && !rex.reg_icombine && utf_iscomposing(curc)) break; *************** *** 5762,5771 **** #ifdef ENABLE_LOG log_subsexpr(&t->subs); #endif ! /* Found the left-most longest match, do not look at any other ! * states at this position. When the list of states is going ! * to be empty quit without advancing, so that "rex.input" is ! * correct. */ if (nextlist->n == 0) clen = 0; goto nextchar; --- 5759,5768 ---- #ifdef ENABLE_LOG log_subsexpr(&t->subs); #endif ! // Found the left-most longest match, do not look at any other ! // states at this position. When the list of states is going ! // to be empty quit without advancing, so that "rex.input" is ! // correct. if (nextlist->n == 0) clen = 0; goto nextchar; *************** *** 5800,5807 **** (int)(nfa_endp->se_u.ptr - rex.input)); } #endif ! /* If "nfa_endp" is set it's only a match if it ends at ! * "nfa_endp" */ if (nfa_endp != NULL && (REG_MULTI ? (rex.lnum != nfa_endp->se_u.pos.lnum || (int)(rex.input - rex.line) --- 5797,5804 ---- (int)(nfa_endp->se_u.ptr - rex.input)); } #endif ! // If "nfa_endp" is set it's only a match if it ends at ! // "nfa_endp" if (nfa_endp != NULL && (REG_MULTI ? (rex.lnum != nfa_endp->se_u.pos.lnum || (int)(rex.input - rex.line) *************** *** 5809,5815 **** : rex.input != nfa_endp->se_u.ptr)) break; ! /* do not set submatches for \@! */ if (t->state->c != NFA_END_INVISIBLE_NEG) { copy_sub(&m->norm, &t->subs.norm); --- 5806,5812 ---- : rex.input != nfa_endp->se_u.ptr)) break; ! // do not set submatches for \@! if (t->state->c != NFA_END_INVISIBLE_NEG) { copy_sub(&m->norm, &t->subs.norm); *************** *** 5823,5829 **** log_subsexpr(m); #endif nfa_match = TRUE; ! /* See comment above at "goto nextchar". */ if (nextlist->n == 0) clen = 0; goto nextchar; --- 5820,5826 ---- log_subsexpr(m); #endif nfa_match = TRUE; ! // See comment above at "goto nextchar". if (nextlist->n == 0) clen = 0; goto nextchar; *************** *** 5842,5849 **** failure_chance(t->state->out, 0), failure_chance(t->state->out1->out, 0)); #endif ! /* Do it directly if there already is a PIM or when ! * nfa_postprocess() detected it will work better. */ if (t->pim.result != NFA_PIM_UNUSED || t->state->c == NFA_START_INVISIBLE_FIRST || t->state->c == NFA_START_INVISIBLE_NEG_FIRST --- 5839,5846 ---- failure_chance(t->state->out, 0), failure_chance(t->state->out1->out, 0)); #endif ! // Do it directly if there already is a PIM or when ! // nfa_postprocess() detected it will work better. if (t->pim.result != NFA_PIM_UNUSED || t->state->c == NFA_START_INVISIBLE_FIRST || t->state->c == NFA_START_INVISIBLE_NEG_FIRST *************** *** 5852,5859 **** { int in_use = m->norm.in_use; ! /* Copy submatch info for the recursive call, opposite ! * of what happens on success below. */ copy_sub_off(&m->norm, &t->subs.norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) --- 5849,5856 ---- { int in_use = m->norm.in_use; ! // Copy submatch info for the recursive call, opposite ! // of what happens on success below. copy_sub_off(&m->norm, &t->subs.norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) *************** *** 5872,5879 **** goto theend; } ! /* for \@! and \@state->c == NFA_START_INVISIBLE_NEG || t->state->c == NFA_START_INVISIBLE_NEG_FIRST || t->state->c --- 5869,5876 ---- goto theend; } ! // for \@! and \@state->c == NFA_START_INVISIBLE_NEG || t->state->c == NFA_START_INVISIBLE_NEG_FIRST || t->state->c *************** *** 5881,5899 **** || t->state->c == NFA_START_INVISIBLE_BEFORE_NEG_FIRST)) { ! /* Copy submatch info from the recursive call */ copy_sub_off(&t->subs.norm, &m->norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) copy_sub_off(&t->subs.synt, &m->synt); #endif ! /* If the pattern has \ze and it matched in the ! * sub pattern, use it. */ copy_ze_off(&t->subs.norm, &m->norm); ! /* t->state->out1 is the corresponding ! * END_INVISIBLE node; Add its out to the current ! * list (zero-width match). */ add_here = TRUE; add_state = t->state->out1->out; } --- 5878,5896 ---- || t->state->c == NFA_START_INVISIBLE_BEFORE_NEG_FIRST)) { ! // Copy submatch info from the recursive call copy_sub_off(&t->subs.norm, &m->norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) copy_sub_off(&t->subs.synt, &m->synt); #endif ! // If the pattern has \ze and it matched in the ! // sub pattern, use it. copy_ze_off(&t->subs.norm, &m->norm); ! // t->state->out1 is the corresponding ! // END_INVISIBLE node; Add its out to the current ! // list (zero-width match). add_here = TRUE; add_state = t->state->out1->out; } *************** *** 5923,5931 **** else pim.end.ptr = rex.input; ! /* t->state->out1 is the corresponding END_INVISIBLE ! * node; Add its out to the current list (zero-width ! * match). */ if (addstate_here(thislist, t->state->out1->out, &t->subs, &pim, &listidx) == NULL) { --- 5920,5928 ---- else pim.end.ptr = rex.input; ! // t->state->out1 is the corresponding END_INVISIBLE ! // node; Add its out to the current list (zero-width ! // match). if (addstate_here(thislist, t->state->out1->out, &t->subs, &pim, &listidx) == NULL) { *************** *** 5943,5950 **** int skip_lid = 0; #endif ! /* There is no point in trying to match the pattern if the ! * output state is not going to be added to the list. */ if (state_in_list(nextlist, t->state->out1->out, &t->subs)) { skip = t->state->out1->out; --- 5940,5947 ---- int skip_lid = 0; #endif ! // There is no point in trying to match the pattern if the ! // output state is not going to be added to the list. if (state_in_list(nextlist, t->state->out1->out, &t->subs)) { skip = t->state->out1->out; *************** *** 5977,5991 **** #endif break; } ! /* Copy submatch info to the recursive call, opposite of what ! * happens afterwards. */ copy_sub_off(&m->norm, &t->subs.norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) copy_sub_off(&m->synt, &t->subs.synt); #endif ! /* First try matching the pattern. */ result = recursive_regmatch(t->state, NULL, prog, submatch, m, &listids, &listids_len); if (result == NFA_TOO_EXPENSIVE) --- 5974,5988 ---- #endif break; } ! // Copy submatch info to the recursive call, opposite of what ! // happens afterwards. copy_sub_off(&m->norm, &t->subs.norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) copy_sub_off(&m->synt, &t->subs.synt); #endif ! // First try matching the pattern. result = recursive_regmatch(t->state, NULL, prog, submatch, m, &listids, &listids_len); if (result == NFA_TOO_EXPENSIVE) *************** *** 6001,6016 **** fprintf(log_fd, "NFA_START_PATTERN matches:\n"); log_subsexpr(m); #endif ! /* Copy submatch info from the recursive call */ copy_sub_off(&t->subs.norm, &m->norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) copy_sub_off(&t->subs.synt, &m->synt); #endif ! /* Now we need to skip over the matched text and then ! * continue with what follows. */ if (REG_MULTI) ! /* TODO: multi-line match */ bytelen = m->norm.list.multi[0].end_col - (int)(rex.input - rex.line); else --- 5998,6013 ---- fprintf(log_fd, "NFA_START_PATTERN matches:\n"); log_subsexpr(m); #endif ! // Copy submatch info from the recursive call copy_sub_off(&t->subs.norm, &m->norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) copy_sub_off(&t->subs.synt, &m->synt); #endif ! // Now we need to skip over the matched text and then ! // continue with what follows. if (REG_MULTI) ! // TODO: multi-line match bytelen = m->norm.list.multi[0].end_col - (int)(rex.input - rex.line); else *************** *** 6021,6043 **** #endif if (bytelen == 0) { ! /* empty match, output of corresponding ! * NFA_END_PATTERN/NFA_SKIP to be used at current ! * position */ add_here = TRUE; add_state = t->state->out1->out->out; } else if (bytelen <= clen) { ! /* match current character, output of corresponding ! * NFA_END_PATTERN to be used at next position. */ add_state = t->state->out1->out->out; add_off = clen; } else { ! /* skip over the matched characters, set character ! * count in NFA_SKIP */ add_state = t->state->out1->out; add_off = bytelen; add_count = bytelen - clen; --- 6018,6040 ---- #endif if (bytelen == 0) { ! // empty match, output of corresponding ! // NFA_END_PATTERN/NFA_SKIP to be used at current ! // position add_here = TRUE; add_state = t->state->out1->out->out; } else if (bytelen <= clen) { ! // match current character, output of corresponding ! // NFA_END_PATTERN to be used at next position. add_state = t->state->out1->out->out; add_off = clen; } else { ! // skip over the matched characters, set character ! // count in NFA_SKIP add_state = t->state->out1->out; add_off = bytelen; add_count = bytelen - clen; *************** *** 6071,6077 **** { int this_class; ! /* Get class of current and previous char (if it exists). */ this_class = mb_get_class_buf(rex.input, rex.reg_buf); if (this_class <= 1) result = FALSE; --- 6068,6074 ---- { int this_class; ! // Get class of current and previous char (if it exists). this_class = mb_get_class_buf(rex.input, rex.reg_buf); if (this_class <= 1) result = FALSE; *************** *** 6097,6103 **** { int this_class, prev_class; ! /* Get class of current and previous char (if it exists). */ this_class = mb_get_class_buf(rex.input, rex.reg_buf); prev_class = reg_prev_class(); if (this_class == prev_class --- 6094,6100 ---- { int this_class, prev_class; ! // Get class of current and previous char (if it exists). this_class = mb_get_class_buf(rex.input, rex.reg_buf); prev_class = reg_prev_class(); if (this_class == prev_class *************** *** 6146,6160 **** len = 0; if (utf_iscomposing(sta->c)) { ! /* Only match composing character(s), ignore base ! * character. Used for ".{composing}" and "{composing}" ! * (no preceding character). */ len += mb_char2len(mc); } if (rex.reg_icombine && len == 0) { ! /* If \Z was present, then ignore composing characters. ! * When ignoring the base character this always matches. */ if (sta->c != curc) result = FAIL; else --- 6143,6157 ---- len = 0; if (utf_iscomposing(sta->c)) { ! // Only match composing character(s), ignore base ! // character. Used for ".{composing}" and "{composing}" ! // (no preceding character). len += mb_char2len(mc); } if (rex.reg_icombine && len == 0) { ! // If \Z was present, then ignore composing characters. ! // When ignoring the base character this always matches. if (sta->c != curc) result = FAIL; else *************** *** 6163,6169 **** sta = sta->out; } ! /* Check base character matches first, unless ignored. */ else if (len > 0 || mc == sta->c) { if (len == 0) --- 6160,6166 ---- sta = sta->out; } ! // Check base character matches first, unless ignored. else if (len > 0 || mc == sta->c) { if (len == 0) *************** *** 6172,6179 **** sta = sta->out; } ! /* We don't care about the order of composing characters. ! * Get them into cchars[] first. */ while (len < clen) { mc = mb_ptr2char(rex.input + len); --- 6169,6176 ---- sta = sta->out; } ! // We don't care about the order of composing characters. ! // Get them into cchars[] first. while (len < clen) { mc = mb_ptr2char(rex.input + len); *************** *** 6183,6191 **** break; } ! /* Check that each composing char in the pattern matches a ! * composing char in the text. We do not check if all ! * composing chars are matched. */ result = OK; while (sta->c != NFA_END_COMPOSING) { --- 6180,6188 ---- break; } ! // Check that each composing char in the pattern matches a ! // composing char in the text. We do not check if all ! // composing chars are matched. result = OK; while (sta->c != NFA_END_COMPOSING) { *************** *** 6203,6209 **** else result = FAIL; ! end = t->state->out1; /* NFA_END_COMPOSING */ ADD_STATE_IF_MATCH(end); break; } --- 6200,6206 ---- else result = FAIL; ! end = t->state->out1; // NFA_END_COMPOSING ADD_STATE_IF_MATCH(end); break; } *************** *** 6213,6226 **** && rex.lnum <= rex.reg_maxline) { go_to_nextline = TRUE; ! /* Pass -1 for the offset, which means taking the position ! * at the start of the next line. */ add_state = t->state->out; add_off = -1; } else if (curc == '\n' && rex.reg_line_lbr) { ! /* match \n as if it is an ordinary character */ add_state = t->state->out; add_off = 1; } --- 6210,6223 ---- && rex.lnum <= rex.reg_maxline) { go_to_nextline = TRUE; ! // Pass -1 for the offset, which means taking the position ! // at the start of the next line. add_state = t->state->out; add_off = -1; } else if (curc == '\n' && rex.reg_line_lbr) { ! // match \n as if it is an ordinary character add_state = t->state->out; add_off = 1; } *************** *** 6229,6242 **** case NFA_START_COLL: case NFA_START_NEG_COLL: { ! /* What follows is a list of characters, until NFA_END_COLL. ! * One of them must match or none of them must match. */ nfa_state_T *state; int result_if_matched; int c1, c2; ! /* Never match EOL. If it's part of the collection it is added ! * as a separate state with an OR. */ if (curc == NUL) break; --- 6226,6239 ---- case NFA_START_COLL: case NFA_START_NEG_COLL: { ! // What follows is a list of characters, until NFA_END_COLL. ! // One of them must match or none of them must match. nfa_state_T *state; int result_if_matched; int c1, c2; ! // Never match EOL. If it's part of the collection it is added ! // as a separate state with an OR. if (curc == NUL) break; *************** *** 6252,6258 **** if (state->c == NFA_RANGE_MIN) { c1 = state->val; ! state = state->out; /* advance to NFA_RANGE_MAX */ c2 = state->val; #ifdef ENABLE_LOG fprintf(log_fd, "NFA_RANGE_MIN curc=%d c1=%d c2=%d\n", --- 6249,6255 ---- if (state->c == NFA_RANGE_MIN) { c1 = state->val; ! state = state->out; // advance to NFA_RANGE_MAX c2 = state->val; #ifdef ENABLE_LOG fprintf(log_fd, "NFA_RANGE_MIN curc=%d c1=%d c2=%d\n", *************** *** 6291,6298 **** } if (result) { ! /* next state is in out of the NFA_END_COLL, out1 of ! * START points to the END state */ add_state = t->state->out1->out; add_off = clen; } --- 6288,6295 ---- } if (result) { ! // next state is in out of the NFA_END_COLL, out1 of ! // START points to the END state add_state = t->state->out1->out; add_off = clen; } *************** *** 6300,6306 **** } case NFA_ANY: ! /* Any char except '\0', (end of input) does not match. */ if (curc > 0) { add_state = t->state->out; --- 6297,6303 ---- } case NFA_ANY: ! // Any char except '\0', (end of input) does not match. if (curc > 0) { add_state = t->state->out; *************** *** 6309,6316 **** break; case NFA_ANY_COMPOSING: ! /* On a composing character skip over it. Otherwise do ! * nothing. Always matches. */ if (enc_utf8 && utf_iscomposing(curc)) { add_off = clen; --- 6306,6313 ---- break; case NFA_ANY_COMPOSING: ! // On a composing character skip over it. Otherwise do ! // nothing. Always matches. if (enc_utf8 && utf_iscomposing(curc)) { add_off = clen; *************** *** 6326,6479 **** /* * Character classes like \a for alpha, \d for digit etc. */ ! case NFA_IDENT: /* \i */ result = vim_isIDc(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_SIDENT: /* \I */ result = !VIM_ISDIGIT(curc) && vim_isIDc(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_KWORD: /* \k */ result = vim_iswordp_buf(rex.input, rex.reg_buf); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_SKWORD: /* \K */ result = !VIM_ISDIGIT(curc) && vim_iswordp_buf(rex.input, rex.reg_buf); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_FNAME: /* \f */ result = vim_isfilec(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_SFNAME: /* \F */ result = !VIM_ISDIGIT(curc) && vim_isfilec(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_PRINT: /* \p */ result = vim_isprintc(PTR2CHAR(rex.input)); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_SPRINT: /* \P */ result = !VIM_ISDIGIT(curc) && vim_isprintc(PTR2CHAR(rex.input)); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_WHITE: /* \s */ result = VIM_ISWHITE(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NWHITE: /* \S */ result = curc != NUL && !VIM_ISWHITE(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_DIGIT: /* \d */ result = ri_digit(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NDIGIT: /* \D */ result = curc != NUL && !ri_digit(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_HEX: /* \x */ result = ri_hex(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NHEX: /* \X */ result = curc != NUL && !ri_hex(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_OCTAL: /* \o */ result = ri_octal(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NOCTAL: /* \O */ result = curc != NUL && !ri_octal(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_WORD: /* \w */ result = ri_word(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NWORD: /* \W */ result = curc != NUL && !ri_word(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_HEAD: /* \h */ result = ri_head(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NHEAD: /* \H */ result = curc != NUL && !ri_head(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_ALPHA: /* \a */ result = ri_alpha(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NALPHA: /* \A */ result = curc != NUL && !ri_alpha(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_LOWER: /* \l */ result = ri_lower(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NLOWER: /* \L */ result = curc != NUL && !ri_lower(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_UPPER: /* \u */ result = ri_upper(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NUPPER: /* \U */ result = curc != NUL && !ri_upper(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_LOWER_IC: /* [a-z] */ result = ri_lower(curc) || (rex.reg_ic && ri_upper(curc)); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NLOWER_IC: /* [^a-z] */ result = curc != NUL && !(ri_lower(curc) || (rex.reg_ic && ri_upper(curc))); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_UPPER_IC: /* [A-Z] */ result = ri_upper(curc) || (rex.reg_ic && ri_lower(curc)); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NUPPER_IC: /* ^[A-Z] */ result = curc != NUL && !(ri_upper(curc) || (rex.reg_ic && ri_lower(curc))); ADD_STATE_IF_MATCH(t->state); --- 6323,6476 ---- /* * Character classes like \a for alpha, \d for digit etc. */ ! case NFA_IDENT: // \i result = vim_isIDc(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_SIDENT: // \I result = !VIM_ISDIGIT(curc) && vim_isIDc(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_KWORD: // \k result = vim_iswordp_buf(rex.input, rex.reg_buf); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_SKWORD: // \K result = !VIM_ISDIGIT(curc) && vim_iswordp_buf(rex.input, rex.reg_buf); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_FNAME: // \f result = vim_isfilec(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_SFNAME: // \F result = !VIM_ISDIGIT(curc) && vim_isfilec(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_PRINT: // \p result = vim_isprintc(PTR2CHAR(rex.input)); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_SPRINT: // \P result = !VIM_ISDIGIT(curc) && vim_isprintc(PTR2CHAR(rex.input)); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_WHITE: // \s result = VIM_ISWHITE(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NWHITE: // \S result = curc != NUL && !VIM_ISWHITE(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_DIGIT: // \d result = ri_digit(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NDIGIT: // \D result = curc != NUL && !ri_digit(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_HEX: // \x result = ri_hex(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NHEX: // \X result = curc != NUL && !ri_hex(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_OCTAL: // \o result = ri_octal(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NOCTAL: // \O result = curc != NUL && !ri_octal(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_WORD: // \w result = ri_word(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NWORD: // \W result = curc != NUL && !ri_word(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_HEAD: // \h result = ri_head(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NHEAD: // \H result = curc != NUL && !ri_head(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_ALPHA: // \a result = ri_alpha(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NALPHA: // \A result = curc != NUL && !ri_alpha(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_LOWER: // \l result = ri_lower(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NLOWER: // \L result = curc != NUL && !ri_lower(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_UPPER: // \u result = ri_upper(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NUPPER: // \U result = curc != NUL && !ri_upper(curc); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_LOWER_IC: // [a-z] result = ri_lower(curc) || (rex.reg_ic && ri_upper(curc)); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NLOWER_IC: // [^a-z] result = curc != NUL && !(ri_lower(curc) || (rex.reg_ic && ri_upper(curc))); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_UPPER_IC: // [A-Z] result = ri_upper(curc) || (rex.reg_ic && ri_lower(curc)); ADD_STATE_IF_MATCH(t->state); break; ! case NFA_NUPPER_IC: // ^[A-Z] result = curc != NUL && !(ri_upper(curc) || (rex.reg_ic && ri_lower(curc))); ADD_STATE_IF_MATCH(t->state); *************** *** 6499,6505 **** case NFA_ZREF8: case NFA_ZREF9: #endif ! /* \1 .. \9 \z1 .. \z9 */ { int subidx; int bytelen; --- 6496,6502 ---- case NFA_ZREF8: case NFA_ZREF9: #endif ! // \1 .. \9 \z1 .. \z9 { int subidx; int bytelen; *************** *** 6521,6542 **** { if (bytelen == 0) { ! /* empty match always works, output of NFA_SKIP to be ! * used next */ add_here = TRUE; add_state = t->state->out->out; } else if (bytelen <= clen) { ! /* match current character, jump ahead to out of ! * NFA_SKIP */ add_state = t->state->out->out; add_off = clen; } else { ! /* skip over the matched characters, set character ! * count in NFA_SKIP */ add_state = t->state->out; add_off = bytelen; add_count = bytelen - clen; --- 6518,6539 ---- { if (bytelen == 0) { ! // empty match always works, output of NFA_SKIP to be ! // used next add_here = TRUE; add_state = t->state->out->out; } else if (bytelen <= clen) { ! // match current character, jump ahead to out of ! // NFA_SKIP add_state = t->state->out->out; add_off = clen; } else { ! // skip over the matched characters, set character ! // count in NFA_SKIP add_state = t->state->out; add_off = bytelen; add_count = bytelen - clen; *************** *** 6545,6560 **** break; } case NFA_SKIP: ! /* character of previous matching \1 .. \9 or \@> */ if (t->count - clen <= 0) { ! /* end of match, go to what follows */ add_state = t->state->out; add_off = clen; } else { ! /* add state again with decremented count */ add_state = t->state; add_off = 0; add_count = t->count - clen; --- 6542,6557 ---- break; } case NFA_SKIP: ! // character of previous matching \1 .. \9 or \@> if (t->count - clen <= 0) { ! // end of match, go to what follows add_state = t->state->out; add_off = clen; } else { ! // add state again with decremented count add_state = t->state; add_off = 0; add_count = t->count - clen; *************** *** 6594,6601 **** colnr_T col = (colnr_T)(rex.input - rex.line); win_T *wp = rex.reg_win == NULL ? curwin : rex.reg_win; ! /* Bail out quickly when there can't be a match, avoid the ! * overhead of win_linetabsize() on long lines. */ if (op != 1 && col > t->state->val * (has_mbyte ? MB_MAXBYTES : 1)) break; --- 6591,6598 ---- colnr_T col = (colnr_T)(rex.input - rex.line); win_T *wp = rex.reg_win == NULL ? curwin : rex.reg_win; ! // Bail out quickly when there can't be a match, avoid the ! // overhead of win_linetabsize() on long lines. if (op != 1 && col > t->state->val * (has_mbyte ? MB_MAXBYTES : 1)) break; *************** *** 6604,6611 **** { int ts = wp->w_buffer->b_p_ts; ! /* Guess that a character won't use more columns than ! * 'tabstop', with a minimum of 4. */ if (ts < 4) ts = 4; result = col > t->state->val * ts; --- 6601,6608 ---- { int ts = wp->w_buffer->b_p_ts; ! // Guess that a character won't use more columns than ! // 'tabstop', with a minimum of 4. if (ts < 4) ts = 4; result = col > t->state->val * ts; *************** *** 6627,6635 **** { pos_T *pos = getmark_buf(rex.reg_buf, t->state->val, FALSE); ! /* Compare the mark position to the match position. */ ! result = (pos != NULL /* mark doesn't exist */ ! && pos->lnum > 0 /* mark isn't set in reg_buf */ && (pos->lnum == rex.lnum + rex.reg_firstlnum ? (pos->col == (colnr_T)(rex.input - rex.line) ? t->state->c == NFA_MARK --- 6624,6632 ---- { pos_T *pos = getmark_buf(rex.reg_buf, t->state->val, FALSE); ! // Compare the mark position to the match position. ! result = (pos != NULL // mark doesn't exist ! && pos->lnum > 0 // mark isn't set in reg_buf && (pos->lnum == rex.lnum + rex.reg_firstlnum ? (pos->col == (colnr_T)(rex.input - rex.line) ? t->state->c == NFA_MARK *************** *** 6692,6702 **** #endif case NFA_NOPEN: case NFA_ZSTART: ! /* These states are only added to be able to bail out when ! * they are added again, nothing is to be done. */ break; ! default: /* regular character */ { int c = t->state->c; --- 6689,6699 ---- #endif case NFA_NOPEN: case NFA_ZSTART: ! // These states are only added to be able to bail out when ! // they are added again, nothing is to be done. break; ! default: // regular character { int c = t->state->c; *************** *** 6708,6722 **** if (!result && rex.reg_ic) result = MB_TOLOWER(c) == MB_TOLOWER(curc); ! /* If rex.reg_icombine is not set only skip over the character ! * itself. When it is set skip over composing characters. */ if (result && enc_utf8 && !rex.reg_icombine) clen = utf_ptr2len(rex.input); ADD_STATE_IF_MATCH(t->state); break; } ! } /* switch (t->state->c) */ if (add_state != NULL) { --- 6705,6719 ---- if (!result && rex.reg_ic) result = MB_TOLOWER(c) == MB_TOLOWER(curc); ! // If rex.reg_icombine is not set only skip over the character ! // itself. When it is set skip over composing characters. if (result && enc_utf8 && !rex.reg_icombine) clen = utf_ptr2len(rex.input); ADD_STATE_IF_MATCH(t->state); break; } ! } // switch (t->state->c) if (add_state != NULL) { *************** *** 6728,6735 **** else pim = &t->pim; ! /* Handle the postponed invisible match if the match might end ! * without advancing and before the end of the line. */ if (pim != NULL && (clen == 0 || match_follows(add_state, 0))) { if (pim->result == NFA_PIM_TODO) --- 6725,6732 ---- else pim = &t->pim; ! // Handle the postponed invisible match if the match might end ! // without advancing and before the end of the line. if (pim != NULL && (clen == 0 || match_follows(add_state, 0))) { if (pim->result == NFA_PIM_TODO) *************** *** 6743,6750 **** result = recursive_regmatch(pim->state, pim, prog, submatch, m, &listids, &listids_len); pim->result = result ? NFA_PIM_MATCH : NFA_PIM_NOMATCH; ! /* for \@! and \@state->c == NFA_START_INVISIBLE_NEG || pim->state->c == NFA_START_INVISIBLE_NEG_FIRST || pim->state->c --- 6740,6747 ---- result = recursive_regmatch(pim->state, pim, prog, submatch, m, &listids, &listids_len); pim->result = result ? NFA_PIM_MATCH : NFA_PIM_NOMATCH; ! // for \@! and \@state->c == NFA_START_INVISIBLE_NEG || pim->state->c == NFA_START_INVISIBLE_NEG_FIRST || pim->state->c *************** *** 6752,6758 **** || pim->state->c == NFA_START_INVISIBLE_BEFORE_NEG_FIRST)) { ! /* Copy submatch info from the recursive call */ copy_sub_off(&pim->subs.norm, &m->norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) --- 6749,6755 ---- || pim->state->c == NFA_START_INVISIBLE_BEFORE_NEG_FIRST)) { ! // Copy submatch info from the recursive call copy_sub_off(&pim->subs.norm, &m->norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) *************** *** 6771,6777 **** #endif } ! /* for \@! and \@state->c == NFA_START_INVISIBLE_NEG || pim->state->c == NFA_START_INVISIBLE_NEG_FIRST || pim->state->c --- 6768,6774 ---- #endif } ! // for \@! and \@state->c == NFA_START_INVISIBLE_NEG || pim->state->c == NFA_START_INVISIBLE_NEG_FIRST || pim->state->c *************** *** 6779,6785 **** || pim->state->c == NFA_START_INVISIBLE_BEFORE_NEG_FIRST)) { ! /* Copy submatch info from the recursive call */ copy_sub_off(&t->subs.norm, &pim->subs.norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) --- 6776,6782 ---- || pim->state->c == NFA_START_INVISIBLE_BEFORE_NEG_FIRST)) { ! // Copy submatch info from the recursive call copy_sub_off(&t->subs.norm, &pim->subs.norm); #ifdef FEAT_SYN_HL if (rex.nfa_has_zsubexpr) *************** *** 6787,6803 **** #endif } else ! /* look-behind match failed, don't add the state */ continue; ! /* Postponed invisible match was handled, don't add it to ! * following states. */ pim = NULL; } ! /* If "pim" points into l->t it will become invalid when ! * adding the state causes the list to be reallocated. Make a ! * local copy to avoid that. */ if (pim == &t->pim) { copy_pim(&pim_copy, pim); --- 6784,6800 ---- #endif } else ! // look-behind match failed, don't add the state continue; ! // Postponed invisible match was handled, don't add it to ! // following states. pim = NULL; } ! // If "pim" points into l->t it will become invalid when ! // adding the state causes the list to be reallocated. Make a ! // local copy to avoid that. if (pim == &t->pim) { copy_pim(&pim_copy, pim); *************** *** 6820,6835 **** } } ! } /* for (thislist = thislist; thislist->state; thislist++) */ ! /* Look for the start of a match in the current position by adding the ! * start state to the list of states. ! * The first found match is the leftmost one, thus the order of states ! * matters! ! * Do not add the start state in recursive calls of nfa_regmatch(), ! * because recursive calls should only start in the first position. ! * Unless "nfa_endp" is not NULL, then we match the end position. ! * Also don't start a match past the first line. */ if (nfa_match == FALSE && ((toplevel && rex.lnum == 0 --- 6817,6832 ---- } } ! } // for (thislist = thislist; thislist->state; thislist++) ! // Look for the start of a match in the current position by adding the ! // start state to the list of states. ! // The first found match is the leftmost one, thus the order of states ! // matters! ! // Do not add the start state in recursive calls of nfa_regmatch(), ! // because recursive calls should only start in the first position. ! // Unless "nfa_endp" is not NULL, then we match the end position. ! // Also don't start a match past the first line. if (nfa_match == FALSE && ((toplevel && rex.lnum == 0 *************** *** 6847,6854 **** #ifdef ENABLE_LOG fprintf(log_fd, "(---) STARTSTATE\n"); #endif ! /* Inline optimized code for addstate() if we know the state is ! * the first MOPEN. */ if (toplevel) { int add = TRUE; --- 6844,6851 ---- #ifdef ENABLE_LOG fprintf(log_fd, "(---) STARTSTATE\n"); #endif ! // Inline optimized code for addstate() if we know the state is ! // the first MOPEN. if (toplevel) { int add = TRUE; *************** *** 6860,6867 **** { colnr_T col = (colnr_T)(rex.input - rex.line) + clen; ! /* Nextlist is empty, we can skip ahead to the ! * character that must appear at the start. */ if (skip_to_start(prog->regstart, &col) == FAIL) break; #ifdef ENABLE_LOG --- 6857,6864 ---- { colnr_T col = (colnr_T)(rex.input - rex.line) + clen; ! // Nextlist is empty, we can skip ahead to the ! // character that must appear at the start. if (skip_to_start(prog->regstart, &col) == FAIL) break; #ifdef ENABLE_LOG *************** *** 6872,6879 **** } else { ! /* Checking if the required start character matches is ! * cheaper than adding a state that won't match. */ c = PTR2CHAR(rex.input + clen); if (c != prog->regstart && (!rex.reg_ic || MB_TOLOWER(c) != MB_TOLOWER(prog->regstart))) --- 6869,6876 ---- } else { ! // Checking if the required start character matches is ! // cheaper than adding a state that won't match. c = PTR2CHAR(rex.input + clen); if (c != prog->regstart && (!rex.reg_ic || MB_TOLOWER(c) != MB_TOLOWER(prog->regstart))) *************** *** 6922,6929 **** #endif nextchar: ! /* Advance to the next character, or advance to the next line, or ! * finish. */ if (clen != 0) rex.input += clen; else if (go_to_nextline || (nfa_endp != NULL && REG_MULTI --- 6919,6926 ---- #endif nextchar: ! // Advance to the next character, or advance to the next line, or ! // finish. if (clen != 0) rex.input += clen; else if (go_to_nextline || (nfa_endp != NULL && REG_MULTI *************** *** 6932,6943 **** else break; ! /* Allow interrupting with CTRL-C. */ line_breakcheck(); if (got_int) break; #ifdef FEAT_RELTIME ! /* Check for timeout once in a twenty times to avoid overhead. */ if (nfa_time_limit != NULL && ++nfa_time_count == 20) { nfa_time_count = 0; --- 6929,6940 ---- else break; ! // Allow interrupting with CTRL-C. line_breakcheck(); if (got_int) break; #ifdef FEAT_RELTIME ! // Check for timeout once in a twenty times to avoid overhead. if (nfa_time_limit != NULL && ++nfa_time_count == 20) { nfa_time_count = 0; *************** *** 6954,6960 **** #endif theend: ! /* Free memory */ vim_free(list[0].t); vim_free(list[1].t); vim_free(listids); --- 6951,6957 ---- #endif theend: ! // Free memory vim_free(list[0].t); vim_free(list[1].t); vim_free(listids); *************** *** 6974,6981 **** nfa_regtry( nfa_regprog_T *prog, colnr_T col, ! proftime_T *tm UNUSED, /* timeout limit or NULL */ ! int *timed_out UNUSED) /* flag set on timeout or NULL */ { int i; regsubs_T subs, m; --- 6971,6978 ---- nfa_regtry( nfa_regprog_T *prog, colnr_T col, ! proftime_T *tm UNUSED, // timeout limit or NULL ! int *timed_out UNUSED) // flag set on timeout or NULL { int i; regsubs_T subs, m; *************** *** 7042,7053 **** } if (rex.reg_endpos[0].lnum < 0) { ! /* pattern has a \ze but it didn't match, use current end */ rex.reg_endpos[0].lnum = rex.lnum; rex.reg_endpos[0].col = (int)(rex.input - rex.line); } else ! /* Use line number of "\ze". */ rex.lnum = rex.reg_endpos[0].lnum; } else --- 7039,7050 ---- } if (rex.reg_endpos[0].lnum < 0) { ! // pattern has a \ze but it didn't match, use current end rex.reg_endpos[0].lnum = rex.lnum; rex.reg_endpos[0].col = (int)(rex.input - rex.line); } else ! // Use line number of "\ze". rex.lnum = rex.reg_endpos[0].lnum; } else *************** *** 7065,7071 **** } #ifdef FEAT_SYN_HL ! /* Package any found \z(...\) matches for export. Default is none. */ unref_extmatch(re_extmatch_out); re_extmatch_out = NULL; --- 7062,7068 ---- } #ifdef FEAT_SYN_HL ! // Package any found \z(...\) matches for export. Default is none. unref_extmatch(re_extmatch_out); re_extmatch_out = NULL; *************** *** 7073,7086 **** { cleanup_zsubexpr(); re_extmatch_out = make_extmatch(); ! /* Loop over \z1, \z2, etc. There is no \z0. */ for (i = 1; i < subs.synt.in_use; i++) { if (REG_MULTI) { struct multipos *mpos = &subs.synt.list.multi[i]; ! /* Only accept single line matches that are valid. */ if (mpos->start_lnum >= 0 && mpos->start_lnum == mpos->end_lnum && mpos->end_col >= mpos->start_col) --- 7070,7083 ---- { cleanup_zsubexpr(); re_extmatch_out = make_extmatch(); ! // Loop over \z1, \z2, etc. There is no \z0. for (i = 1; i < subs.synt.in_use; i++) { if (REG_MULTI) { struct multipos *mpos = &subs.synt.list.multi[i]; ! // Only accept single line matches that are valid. if (mpos->start_lnum >= 0 && mpos->start_lnum == mpos->end_lnum && mpos->end_col >= mpos->start_col) *************** *** 7114,7122 **** static long nfa_regexec_both( char_u *line, ! colnr_T startcol, /* column to start looking for match */ ! proftime_T *tm, /* timeout limit or NULL */ ! int *timed_out) /* flag set on timeout or NULL */ { nfa_regprog_T *prog; long retval = 0L; --- 7111,7119 ---- static long nfa_regexec_both( char_u *line, ! colnr_T startcol, // column to start looking for match ! proftime_T *tm, // timeout limit or NULL ! int *timed_out) // flag set on timeout or NULL { nfa_regprog_T *prog; long retval = 0L; *************** *** 7126,7132 **** if (REG_MULTI) { prog = (nfa_regprog_T *)rex.reg_mmatch->regprog; ! line = reg_getline((linenr_T)0); /* relative to the cursor */ rex.reg_startpos = rex.reg_mmatch->startpos; rex.reg_endpos = rex.reg_mmatch->endpos; } --- 7123,7129 ---- if (REG_MULTI) { prog = (nfa_regprog_T *)rex.reg_mmatch->regprog; ! line = reg_getline((linenr_T)0); // relative to the cursor rex.reg_startpos = rex.reg_mmatch->startpos; rex.reg_endpos = rex.reg_mmatch->endpos; } *************** *** 7137,7161 **** rex.reg_endp = rex.reg_match->endp; } ! /* Be paranoid... */ if (prog == NULL || line == NULL) { emsg(_(e_null)); goto theend; } ! /* If pattern contains "\c" or "\C": overrule value of rex.reg_ic */ if (prog->regflags & RF_ICASE) rex.reg_ic = TRUE; else if (prog->regflags & RF_NOICASE) rex.reg_ic = FALSE; ! /* If pattern contains "\Z" overrule value of rex.reg_icombine */ if (prog->regflags & RF_ICOMBINE) rex.reg_icombine = TRUE; rex.line = line; ! rex.lnum = 0; /* relative to line */ rex.nfa_has_zend = prog->has_zend; rex.nfa_has_backref = prog->has_backref; --- 7134,7158 ---- rex.reg_endp = rex.reg_match->endp; } ! // Be paranoid... if (prog == NULL || line == NULL) { emsg(_(e_null)); goto theend; } ! // If pattern contains "\c" or "\C": overrule value of rex.reg_ic if (prog->regflags & RF_ICASE) rex.reg_ic = TRUE; else if (prog->regflags & RF_NOICASE) rex.reg_ic = FALSE; ! // If pattern contains "\Z" overrule value of rex.reg_icombine if (prog->regflags & RF_ICOMBINE) rex.reg_icombine = TRUE; rex.line = line; ! rex.lnum = 0; // relative to line rex.nfa_has_zend = prog->has_zend; rex.nfa_has_backref = prog->has_backref; *************** *** 7171,7177 **** rex.need_clear_subexpr = TRUE; #ifdef FEAT_SYN_HL ! /* Clear the external match subpointers if necessary. */ if (prog->reghasz == REX_SET) { rex.nfa_has_zsubexpr = TRUE; --- 7168,7174 ---- rex.need_clear_subexpr = TRUE; #ifdef FEAT_SYN_HL ! // Clear the external match subpointers if necessary. if (prog->reghasz == REX_SET) { rex.nfa_has_zsubexpr = TRUE; *************** *** 7186,7203 **** if (prog->regstart != NUL) { ! /* Skip ahead until a character we know the match must start with. ! * When there is none there is no match. */ if (skip_to_start(prog->regstart, &col) == FAIL) return 0L; ! /* If match_text is set it contains the full text that must match. ! * Nothing else to try. Doesn't handle combining chars well. */ if (prog->match_text != NULL && !rex.reg_icombine) return find_match_text(col, prog->regstart, prog->match_text); } ! /* If the start column is past the maximum column: no need to try. */ if (rex.reg_maxcol > 0 && col >= rex.reg_maxcol) goto theend; --- 7183,7200 ---- if (prog->regstart != NUL) { ! // Skip ahead until a character we know the match must start with. ! // When there is none there is no match. if (skip_to_start(prog->regstart, &col) == FAIL) return 0L; ! // If match_text is set it contains the full text that must match. ! // Nothing else to try. Doesn't handle combining chars well. if (prog->match_text != NULL && !rex.reg_icombine) return find_match_text(col, prog->regstart, prog->match_text); } ! // If the start column is past the maximum column: no need to try. if (rex.reg_maxcol > 0 && col >= rex.reg_maxcol) goto theend; *************** *** 7245,7255 **** if (nfa_regcomp_start(expr, re_flags) == FAIL) return NULL; ! /* Build postfix form of the regexp. Needed to build the NFA ! * (and count its size). */ postfix = re2post(); if (postfix == NULL) ! goto fail; /* Cascaded (syntax?) error */ /* * In order to build the NFA, we parse the input regexp twice: --- 7242,7252 ---- if (nfa_regcomp_start(expr, re_flags) == FAIL) return NULL; ! // Build postfix form of the regexp. Needed to build the NFA ! // (and count its size). postfix = re2post(); if (postfix == NULL) ! goto fail; // Cascaded (syntax?) error /* * In order to build the NFA, we parse the input regexp twice: *************** *** 7274,7280 **** */ post2nfa(postfix, post_ptr, TRUE); ! /* allocate the regprog with space for the compiled regexp */ prog_size = sizeof(nfa_regprog_T) + sizeof(nfa_state_T) * (nstate - 1); prog = alloc(prog_size); if (prog == NULL) --- 7271,7277 ---- */ post2nfa(postfix, post_ptr, TRUE); ! // allocate the regprog with space for the compiled regexp prog_size = sizeof(nfa_regprog_T) + sizeof(nfa_state_T) * (nstate - 1); prog = alloc(prog_size); if (prog == NULL) *************** *** 7308,7314 **** nfa_dump(prog); #endif #ifdef FEAT_SYN_HL ! /* Remember whether this pattern has any \z specials in it. */ prog->reghasz = re_has_z; #endif prog->pattern = vim_strsave(expr); --- 7305,7311 ---- nfa_dump(prog); #endif #ifdef FEAT_SYN_HL ! // Remember whether this pattern has any \z specials in it. prog->reghasz = re_has_z; #endif prog->pattern = vim_strsave(expr); *************** *** 7358,7365 **** static int nfa_regexec_nl( regmatch_T *rmp, ! char_u *line, /* string to match against */ ! colnr_T col, /* column to start looking for match */ int line_lbr) { rex.reg_match = rmp; --- 7355,7362 ---- static int nfa_regexec_nl( regmatch_T *rmp, ! char_u *line, // string to match against ! colnr_T col, // column to start looking for match int line_lbr) { rex.reg_match = rmp; *************** *** 7403,7414 **** static long nfa_regexec_multi( regmmatch_T *rmp, ! win_T *win, /* window in which to search or NULL */ ! buf_T *buf, /* buffer in which to search */ ! linenr_T lnum, /* nr of line to start looking for match */ ! colnr_T col, /* column to start looking for match */ ! proftime_T *tm, /* timeout limit or NULL */ ! int *timed_out) /* flag set on timeout or NULL */ { rex.reg_match = NULL; rex.reg_mmatch = rmp; --- 7400,7411 ---- static long nfa_regexec_multi( regmmatch_T *rmp, ! win_T *win, // window in which to search or NULL ! buf_T *buf, // buffer in which to search ! linenr_T lnum, // nr of line to start looking for match ! colnr_T col, // column to start looking for match ! proftime_T *tm, // timeout limit or NULL ! int *timed_out) // flag set on timeout or NULL { rex.reg_match = NULL; rex.reg_mmatch = rmp; *** ../vim-8.1.2393/src/screen.c 2019-12-02 21:35:28.009111221 +0100 --- src/screen.c 2019-12-05 21:03:30.465015547 +0100 *************** *** 53,59 **** static void msg_pos_mode(void); static void recording_mode(int attr); ! /* Ugly global: overrule attribute used by screen_char() */ static int screen_char_attr = 0; #if defined(FEAT_CONCEAL) || defined(PROTO) --- 53,59 ---- static void msg_pos_mode(void); static void recording_mode(int attr); ! // Ugly global: overrule attribute used by screen_char() static int screen_char_attr = 0; #if defined(FEAT_CONCEAL) || defined(PROTO) *************** *** 90,97 **** if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin)) { need_cursor_line_redraw = TRUE; ! /* Need to recompute cursor column, e.g., when starting Visual mode ! * without concealing. */ curs_columns(TRUE); } } --- 90,97 ---- if (curwin->w_p_cole > 0 && conceal_cursor_line(curwin)) { need_cursor_line_redraw = TRUE; ! // Need to recompute cursor column, e.g., when starting Visual mode ! // without concealing. curs_columns(TRUE); } } *************** *** 244,251 **** fill_foldcolumn( char_u *p, win_T *wp, ! int closed, /* TRUE of FALSE */ ! linenr_T lnum) /* current line number */ { int i = 0; int level; --- 244,251 ---- fill_foldcolumn( char_u *p, win_T *wp, ! int closed, // TRUE of FALSE ! linenr_T lnum) // current line number { int i = 0; int level; *************** *** 253,269 **** int empty; int fdc = compute_foldcolumn(wp, 0); ! /* Init to all spaces. */ vim_memset(p, ' ', (size_t)fdc); level = win_foldinfo.fi_level; if (level > 0) { ! /* If there is only one column put more info in it. */ empty = (fdc == 1) ? 0 : 1; ! /* If the column is too narrow, we start at the lowest level that ! * fits and use numbers to indicated the depth. */ first_level = level - fdc - closed + 1 + empty; if (first_level < 1) first_level = 1; --- 253,269 ---- int empty; int fdc = compute_foldcolumn(wp, 0); ! // Init to all spaces. vim_memset(p, ' ', (size_t)fdc); level = win_foldinfo.fi_level; if (level > 0) { ! // If there is only one column put more info in it. empty = (fdc == 1) ? 0 : 1; ! // If the column is too narrow, we start at the lowest level that ! // fits and use numbers to indicated the depth. first_level = level - fdc - closed + 1 + empty; if (first_level < 1) first_level = 1; *************** *** 286,292 **** if (closed) p[i >= fdc ? i - 1 : i] = '+'; } ! #endif /* FEAT_FOLDING */ /* * Return if the composing characters at "off_from" and "off_to" differ. --- 286,292 ---- if (closed) p[i >= fdc ? i - 1 : i] = '+'; } ! #endif // FEAT_FOLDING /* * Return if the composing characters at "off_from" and "off_to" differ. *************** *** 409,427 **** unsigned max_off_to; int col = 0; int hl; ! int force = FALSE; /* force update rest of the line */ ! int redraw_this /* bool: does character need redraw? */ #ifdef FEAT_GUI ! = TRUE /* For GUI when while-loop empty */ #endif ; ! int redraw_next; /* redraw_this for next character */ int clear_next = FALSE; ! int char_cells; /* 1: normal char */ ! /* 2: occupies two display cells */ # define CHAR_CELLS char_cells ! /* Check for illegal row and col, just in case. */ if (row >= Rows) row = Rows - 1; if (endcol > Columns) --- 409,427 ---- unsigned max_off_to; int col = 0; int hl; ! int force = FALSE; // force update rest of the line ! int redraw_this // bool: does character need redraw? #ifdef FEAT_GUI ! = TRUE // For GUI when while-loop empty #endif ; ! int redraw_next; // redraw_this for next character int clear_next = FALSE; ! int char_cells; // 1: normal char ! // 2: occupies two display cells # define CHAR_CELLS char_cells ! // Check for illegal row and col, just in case. if (row >= Rows) row = Rows - 1; if (endcol > Columns) *************** *** 439,445 **** #ifdef FEAT_RIGHTLEFT if (flags & SLF_RIGHTLEFT) { ! /* Clear rest first, because it's left of the text. */ if (clear_width > 0) { while (col <= endcol && ScreenLines[off_to] == ' ' --- 439,445 ---- #ifdef FEAT_RIGHTLEFT if (flags & SLF_RIGHTLEFT) { ! // Clear rest first, because it's left of the text. if (clear_width > 0) { while (col <= endcol && ScreenLines[off_to] == ' ' *************** *** 458,464 **** off_from += col; endcol = (clear_width > 0 ? clear_width : -clear_width); } ! #endif /* FEAT_RIGHTLEFT */ #ifdef FEAT_PROP_POPUP // First char of a popup window may go on top of the right half of a --- 458,464 ---- off_from += col; endcol = (clear_width > 0 ? clear_width : -clear_width); } ! #endif // FEAT_RIGHTLEFT #ifdef FEAT_PROP_POPUP // First char of a popup window may go on top of the right half of a *************** *** 486,495 **** off_to + CHAR_CELLS, endcol - col - CHAR_CELLS); #ifdef FEAT_GUI ! /* If the next character was bold, then redraw the current character to ! * remove any pixels that might have spilt over into us. This only ! * happens in the GUI. ! */ if (redraw_next && gui.in_use) { hl = ScreenAttrs[off_to + CHAR_CELLS]; --- 486,494 ---- off_to + CHAR_CELLS, endcol - col - CHAR_CELLS); #ifdef FEAT_GUI ! // If the next character was bold, then redraw the current character to ! // remove any pixels that might have spilt over into us. This only ! // happens in the GUI. if (redraw_next && gui.in_use) { hl = ScreenAttrs[off_to + CHAR_CELLS]; *************** *** 529,538 **** * Need to remove highlighting attributes here. */ windgoto(row, col + coloff); ! out_str(T_CE); /* clear rest of this screen line */ ! screen_start(); /* don't know where cursor is now */ ! force = TRUE; /* force redraw of rest of the line */ ! redraw_next = TRUE; /* or else next char would miss out */ /* * If the previous character was highlighted, need to stop --- 528,537 ---- * Need to remove highlighting attributes here. */ windgoto(row, col + coloff); ! out_str(T_CE); // clear rest of this screen line ! screen_start(); // don't know where cursor is now ! force = TRUE; // force redraw of rest of the line ! redraw_next = TRUE; // or else next char would miss out /* * If the previous character was highlighted, need to stop *************** *** 545,564 **** screen_stop_highlight(); } else ! screen_attr = 0; /* highlighting has stopped */ } if (enc_dbcs != 0) { ! /* Check if overwriting a double-byte with a single-byte or ! * the other way around requires another character to be ! * redrawn. For UTF-8 this isn't needed, because comparing ! * ScreenLinesUC[] is sufficient. */ if (char_cells == 1 && col + 1 < endcol && (*mb_off2cells)(off_to, max_off_to) > 1) { ! /* Writing a single-cell character over a double-cell ! * character: need to redraw the next cell. */ ScreenLines[off_to + 1] = 0; redraw_next = TRUE; } --- 544,563 ---- screen_stop_highlight(); } else ! screen_attr = 0; // highlighting has stopped } if (enc_dbcs != 0) { ! // Check if overwriting a double-byte with a single-byte or ! // the other way around requires another character to be ! // redrawn. For UTF-8 this isn't needed, because comparing ! // ScreenLinesUC[] is sufficient. if (char_cells == 1 && col + 1 < endcol && (*mb_off2cells)(off_to, max_off_to) > 1) { ! // Writing a single-cell character over a double-cell ! // character: need to redraw the next cell. ScreenLines[off_to + 1] = 0; redraw_next = TRUE; } *************** *** 567,575 **** && (*mb_off2cells)(off_to, max_off_to) == 1 && (*mb_off2cells)(off_to + 1, max_off_to) > 1) { ! /* Writing the second half of a double-cell character over ! * a double-cell character: need to redraw the second ! * cell. */ ScreenLines[off_to + 2] = 0; redraw_next = TRUE; } --- 566,574 ---- && (*mb_off2cells)(off_to, max_off_to) == 1 && (*mb_off2cells)(off_to + 1, max_off_to) > 1) { ! // Writing the second half of a double-cell character over ! // a double-cell character: need to redraw the second ! // cell. ScreenLines[off_to + 2] = 0; redraw_next = TRUE; } *************** *** 577,587 **** if (enc_dbcs == DBCS_JPNU) ScreenLines2[off_to] = ScreenLines2[off_from]; } ! /* When writing a single-width character over a double-width ! * character and at the end of the redrawn text, need to clear out ! * the right halve of the old character. ! * Also required when writing the right halve of a double-width ! * char over the left halve of an existing one. */ if (has_mbyte && col + char_cells == endcol && ((char_cells == 1 && (*mb_off2cells)(off_to, max_off_to) > 1) --- 576,586 ---- if (enc_dbcs == DBCS_JPNU) ScreenLines2[off_to] = ScreenLines2[off_from]; } ! // When writing a single-width character over a double-width ! // character and at the end of the redrawn text, need to clear out ! // the right halve of the old character. ! // Also required when writing the right halve of a double-width ! // char over the left halve of an existing one. if (has_mbyte && col + char_cells == endcol && ((char_cells == 1 && (*mb_off2cells)(off_to, max_off_to) > 1) *************** *** 606,615 **** ScreenLines[off_to + 1] = ScreenLines[off_from + 1]; #if defined(FEAT_GUI) || defined(UNIX) ! /* The bold trick makes a single column of pixels appear in the ! * next character. When a bold character is removed, the next ! * character should be redrawn too. This happens for our own GUI ! * and for some xterms. */ if ( # ifdef FEAT_GUI gui.in_use --- 605,614 ---- ScreenLines[off_to + 1] = ScreenLines[off_from + 1]; #if defined(FEAT_GUI) || defined(UNIX) ! // The bold trick makes a single column of pixels appear in the ! // next character. When a bold character is removed, the next ! // character should be redrawn too. This happens for our own GUI ! // and for some xterms. if ( # ifdef FEAT_GUI gui.in_use *************** *** 631,638 **** #endif ScreenAttrs[off_to] = ScreenAttrs[off_from]; ! /* For simplicity set the attributes of second half of a ! * double-wide character equal to the first half. */ if (char_cells == 2) ScreenAttrs[off_to + 1] = ScreenAttrs[off_from]; --- 630,637 ---- #endif ScreenAttrs[off_to] = ScreenAttrs[off_from]; ! // For simplicity set the attributes of second half of a ! // double-wide character equal to the first half. if (char_cells == 2) ScreenAttrs[off_to + 1] = ScreenAttrs[off_from]; *************** *** 666,673 **** if (clear_next) { ! /* Clear the second half of a double-wide character of which the left ! * half was overwritten with a single-wide character. */ ScreenLines[off_to] = ' '; if (enc_utf8) ScreenLinesUC[off_to] = 0; --- 665,672 ---- if (clear_next) { ! // Clear the second half of a double-wide character of which the left ! // half was overwritten with a single-wide character. ScreenLines[off_to] = ' '; if (enc_utf8) ScreenLinesUC[off_to] = 0; *************** *** 684,690 **** int startCol = col; #endif ! /* blank out the rest of the line */ while (col < clear_width && ScreenLines[off_to] == ' ' && ScreenAttrs[off_to] == 0 && (!enc_utf8 || ScreenLinesUC[off_to] == 0)) --- 683,689 ---- int startCol = col; #endif ! // blank out the rest of the line while (col < clear_width && ScreenLines[off_to] == ' ' && ScreenAttrs[off_to] == 0 && (!enc_utf8 || ScreenLinesUC[off_to] == 0)) *************** *** 710,722 **** int prev_cells = 1; if (enc_utf8) ! /* for utf-8, ScreenLines[char_offset + 1] == 0 means ! * that its width is 2. */ prev_cells = ScreenLines[off_to - 1] == 0 ? 2 : 1; else if (enc_dbcs != 0) { ! /* find previous character by counting from first ! * column and get its width. */ unsigned off = LineOffset[row]; unsigned max_off = LineOffset[row] + screen_Columns; --- 709,721 ---- int prev_cells = 1; if (enc_utf8) ! // for utf-8, ScreenLines[char_offset + 1] == 0 means ! // that its width is 2. prev_cells = ScreenLines[off_to - 1] == 0 ? 2 : 1; else if (enc_dbcs != 0) { ! // find previous character by counting from first ! // column and get its width. unsigned off = LineOffset[row]; unsigned max_off = LineOffset[row] + screen_Columns; *************** *** 817,823 **** if (wp->w_vsep_width) { ! /* draw the vertical separator right of this window */ c = fillchar_vsep(&hl); screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + wp->w_height, W_ENDCOL(wp), W_ENDCOL(wp) + 1, --- 816,822 ---- if (wp->w_vsep_width) { ! // draw the vertical separator right of this window c = fillchar_vsep(&hl); screen_fill(W_WINROW(wp) + row, W_WINROW(wp) + wp->w_height, W_ENDCOL(wp), W_ENDCOL(wp) + 1, *************** *** 840,846 **** int emenu = (xp->xp_context == EXPAND_MENUS || xp->xp_context == EXPAND_MENUNAMES); ! /* Check for menu separators - replace with '|'. */ if (emenu && menu_is_separator(s)) return 1; #endif --- 839,845 ---- int emenu = (xp->xp_context == EXPAND_MENUS || xp->xp_context == EXPAND_MENUNAMES); ! // Check for menu separators - replace with '|'. if (emenu && menu_is_separator(s)) return 1; #endif *************** *** 890,896 **** win_redr_status_matches( expand_T *xp, int num_matches, ! char_u **matches, /* list of matches */ int match, int showtail) { --- 889,895 ---- win_redr_status_matches( expand_T *xp, int num_matches, ! char_u **matches, // list of matches int match, int showtail) { *************** *** 898,904 **** int row; char_u *buf; int len; ! int clen; /* length in screen cells */ int fillchar; int attr; int i; --- 897,903 ---- int row; char_u *buf; int len; ! int clen; // length in screen cells int fillchar; int attr; int i; *************** *** 914,920 **** #endif int l; ! if (matches == NULL) /* interrupted completion? */ return; if (has_mbyte) --- 913,919 ---- #endif int l; ! if (matches == NULL) // interrupted completion? return; if (has_mbyte) *************** *** 924,956 **** if (buf == NULL) return; ! if (match == -1) /* don't show match but original text */ { match = 0; highlight = FALSE; } ! /* count 1 for the ending ">" */ clen = status_match_len(xp, L_MATCH(match)) + 3; if (match == 0) first_match = 0; else if (match < first_match) { ! /* jumping left, as far as we can go */ first_match = match; add_left = TRUE; } else { ! /* check if match fits on the screen */ for (i = first_match; i < match; ++i) clen += status_match_len(xp, L_MATCH(i)) + 2; if (first_match > 0) clen += 2; ! /* jumping right, put match at the left */ if ((long)clen > Columns) { first_match = match; ! /* if showing the last match, we can add some on the left */ clen = 2; for (i = match; i < num_matches; ++i) { --- 923,955 ---- if (buf == NULL) return; ! if (match == -1) // don't show match but original text { match = 0; highlight = FALSE; } ! // count 1 for the ending ">" clen = status_match_len(xp, L_MATCH(match)) + 3; if (match == 0) first_match = 0; else if (match < first_match) { ! // jumping left, as far as we can go first_match = match; add_left = TRUE; } else { ! // check if match fits on the screen for (i = first_match; i < match; ++i) clen += status_match_len(xp, L_MATCH(i)) + 2; if (first_match > 0) clen += 2; ! // jumping right, put match at the left if ((long)clen > Columns) { first_match = match; ! // if showing the last match, we can add some on the left clen = 2; for (i = match; i < num_matches; ++i) { *************** *** 995,1001 **** } s = L_MATCH(i); ! /* Check for menu separators - replace with '|' */ #ifdef FEAT_MENU emenu = (xp->xp_context == EXPAND_MENUS || xp->xp_context == EXPAND_MENUNAMES); --- 994,1000 ---- } s = L_MATCH(i); ! // Check for menu separators - replace with '|' #ifdef FEAT_MENU emenu = (xp->xp_context == EXPAND_MENUS || xp->xp_context == EXPAND_MENUNAMES); *************** *** 1049,1056 **** { if (msg_scrolled > 0) { ! /* Put the wildmenu just above the command line. If there is ! * no room, scroll the screen one line up. */ if (cmdline_row == Rows - 1) { screen_del_lines(0, 0, 1, (int)Rows, TRUE, 0, NULL); --- 1048,1055 ---- { if (msg_scrolled > 0) { ! // Put the wildmenu just above the command line. If there is ! // no room, scroll the screen one line up. if (cmdline_row == Rows - 1) { screen_del_lines(0, 0, 1, (int)Rows, TRUE, 0, NULL); *************** *** 1065,1073 **** } else { ! /* Create status line if needed by setting 'laststatus' to 2. ! * Set 'winminheight' to zero to avoid that the window is ! * resized. */ if (lastwin->w_status_height == 0) { save_p_ls = p_ls; --- 1064,1072 ---- } else { ! // Create status line if needed by setting 'laststatus' to 2. ! // Set 'winminheight' to zero to avoid that the window is ! // resized. if (lastwin->w_status_height == 0) { save_p_ls = p_ls; *************** *** 1130,1138 **** int get_keymap_str( win_T *wp, ! char_u *fmt, /* format string containing one %s item */ ! char_u *buf, /* buffer for the result */ ! int len) /* length of buffer */ { char_u *p; --- 1129,1137 ---- int get_keymap_str( win_T *wp, ! char_u *fmt, // format string containing one %s item ! char_u *buf, // buffer for the result ! int len) // length of buffer { char_u *p; *************** *** 1147,1153 **** curbuf = wp->w_buffer; curwin = wp; ! STRCPY(buf, "b:keymap_name"); /* must be writable */ ++emsg_skip; s = p = eval_to_string(buf, NULL, FALSE); --emsg_skip; --- 1146,1152 ---- curbuf = wp->w_buffer; curwin = wp; ! STRCPY(buf, "b:keymap_name"); // must be writable ++emsg_skip; s = p = eval_to_string(buf, NULL, FALSE); --emsg_skip; *************** *** 1516,1522 **** && *ptr != NUL) { c = *ptr; ! /* check if this is the first byte of a multibyte */ if (has_mbyte) { if (enc_utf8 && len > 0) --- 1515,1521 ---- && *ptr != NUL) { c = *ptr; ! // check if this is the first byte of a multibyte if (has_mbyte) { if (enc_utf8 && len > 0) *************** *** 1527,1533 **** mbyte_cells = 1; else if (enc_dbcs != 0) mbyte_cells = mbyte_blen; ! else /* enc_utf8 */ { if (len >= 0) u8c = utfc_ptr2char_len(ptr, u8cc, --- 1526,1532 ---- mbyte_cells = 1; else if (enc_dbcs != 0) mbyte_cells = mbyte_blen; ! else // enc_utf8 { if (len >= 0) u8c = utfc_ptr2char_len(ptr, u8cc, *************** *** 1538,1547 **** #ifdef FEAT_ARABIC if (p_arshape && !p_tbidi && ARABIC_CHAR(u8c)) { ! /* Do Arabic shaping. */ if (len >= 0 && (int)(ptr - text) + mbyte_blen >= len) { ! /* Past end of string to be displayed. */ nc = NUL; nc1 = NUL; } --- 1537,1546 ---- #ifdef FEAT_ARABIC if (p_arshape && !p_tbidi && ARABIC_CHAR(u8c)) { ! // Do Arabic shaping. if (len >= 0 && (int)(ptr - text) + mbyte_blen >= len) { ! // Past end of string to be displayed. nc = NUL; nc1 = NUL; } *************** *** 1560,1567 **** #endif if (col + mbyte_cells > screen_Columns) { ! /* Only 1 cell left, but character requires 2 cells: ! * display a '>' in the last column to avoid wrapping. */ c = '>'; mbyte_cells = 1; } --- 1559,1566 ---- #endif if (col + mbyte_cells > screen_Columns) { ! // Only 1 cell left, but character requires 2 cells: ! // display a '>' in the last column to avoid wrapping. c = '>'; mbyte_cells = 1; } *************** *** 1592,1601 **** ) { #if defined(FEAT_GUI) || defined(UNIX) ! /* The bold trick makes a single row of pixels appear in the next ! * character. When a bold character is removed, the next ! * character should be redrawn too. This happens for our own GUI ! * and for some xterms. */ if (need_redraw && ScreenLines[off] != ' ' && ( # ifdef FEAT_GUI gui.in_use --- 1591,1600 ---- ) { #if defined(FEAT_GUI) || defined(UNIX) ! // The bold trick makes a single row of pixels appear in the next ! // character. When a bold character is removed, the next ! // character should be redrawn too. This happens for our own GUI ! // and for some xterms. if (need_redraw && ScreenLines[off] != ' ' && ( # ifdef FEAT_GUI gui.in_use *************** *** 1616,1626 **** force_redraw_next = TRUE; } #endif ! /* When at the end of the text and overwriting a two-cell ! * character with a one-cell character, need to clear the next ! * cell. Also when overwriting the left halve of a two-cell char ! * with the right halve of a two-cell char. Do this only once ! * (mb_off2cells() may return 2 on the right halve). */ if (clear_next_cell) clear_next_cell = FALSE; else if (has_mbyte --- 1615,1625 ---- force_redraw_next = TRUE; } #endif ! // When at the end of the text and overwriting a two-cell ! // character with a one-cell character, need to clear the next ! // cell. Also when overwriting the left halve of a two-cell char ! // with the right halve of a two-cell char. Do this only once ! // (mb_off2cells() may return 2 on the right halve). if (clear_next_cell) clear_next_cell = FALSE; else if (has_mbyte *************** *** 1632,1639 **** && (*mb_off2cells)(off + 1, max_off) > 1))) clear_next_cell = TRUE; ! /* Make sure we never leave a second byte of a double-byte behind, ! * it confuses mb_off2cells(). */ if (enc_dbcs && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1) || (mbyte_cells == 2 --- 1631,1638 ---- && (*mb_off2cells)(off + 1, max_off) > 1))) clear_next_cell = TRUE; ! // Make sure we never leave a second byte of a double-byte behind, ! // it confuses mb_off2cells(). if (enc_dbcs && ((mbyte_cells == 1 && (*mb_off2cells)(off, max_off) > 1) || (mbyte_cells == 2 *************** *** 1686,1692 **** ptr += mbyte_blen; if (clear_next_cell) { ! /* This only happens at the end, display one space next. */ ptr = (char_u *)" "; len = -1; } --- 1685,1691 ---- ptr += mbyte_blen; if (clear_next_cell) { ! // This only happens at the end, display one space next. ptr = (char_u *)" "; len = -1; } *************** *** 1699,1706 **** } } ! /* If we detected the next character needs to be redrawn, but the text ! * doesn't extend up to there, update the character here. */ if (force_redraw_next && col < screen_Columns) { if (enc_dbcs != 0 && dbcs_off2cells(off, max_off) > 1) --- 1698,1705 ---- } } ! // If we detected the next character needs to be redrawn, but the text ! // doesn't extend up to there, update the character here. if (force_redraw_next && col < screen_Columns) { if (enc_dbcs != 0 && dbcs_off2cells(off, max_off) > 1) *************** *** 1722,1728 **** last_pat_prog(&screen_search_hl.rm); screen_search_hl.attr = HL_ATTR(HLF_L); # ifdef FEAT_RELTIME ! /* Set the time limit to 'redrawtime'. */ profile_setlimit(p_rdt, &screen_search_hl.tm); # endif } --- 1721,1727 ---- last_pat_prog(&screen_search_hl.rm); screen_search_hl.attr = HL_ATTR(HLF_L); # ifdef FEAT_RELTIME ! // Set the time limit to 'redrawtime'. profile_setlimit(p_rdt, &screen_search_hl.tm); # endif } *************** *** 1759,1778 **** { char buf[20]; ! /* The GUI handles this internally. */ sprintf(buf, IF_EB("\033|%dh", ESC_STR "|%dh"), attr); OUT_STR(buf); } else #endif { ! if (attr > HL_ALL) /* special HL attr. */ { if (IS_CTERM) aep = syn_cterm_attr2entry(attr); else aep = syn_term_attr2entry(attr); ! if (aep == NULL) /* did ":syntax clear" */ attr = 0; else attr = aep->ae_attr; --- 1758,1777 ---- { char buf[20]; ! // The GUI handles this internally. sprintf(buf, IF_EB("\033|%dh", ESC_STR "|%dh"), attr); OUT_STR(buf); } else #endif { ! if (attr > HL_ALL) // special HL attr. { if (IS_CTERM) aep = syn_cterm_attr2entry(attr); else aep = syn_term_attr2entry(attr); ! if (aep == NULL) // did ":syntax clear" attr = 0; else attr = aep->ae_attr; *************** *** 1804,1810 **** } } #endif ! if ((attr & HL_BOLD) && *T_MD != NUL) /* bold */ out_str(T_MD); else if (aep != NULL && cterm_normal_fg_bold && ( #ifdef FEAT_TERMGUICOLORS --- 1803,1809 ---- } } #endif ! if ((attr & HL_BOLD) && *T_MD != NUL) // bold out_str(T_MD); else if (aep != NULL && cterm_normal_fg_bold && ( #ifdef FEAT_TERMGUICOLORS *************** *** 1813,1834 **** : #endif t_colors > 1 && aep->ae_u.cterm.fg_color)) ! /* If the Normal FG color has BOLD attribute and the new HL ! * has a FG color defined, clear BOLD. */ out_str(T_ME); ! if ((attr & HL_STANDOUT) && *T_SO != NUL) /* standout */ out_str(T_SO); ! if ((attr & HL_UNDERCURL) && *T_UCS != NUL) /* undercurl */ out_str(T_UCS); ! if (((attr & HL_UNDERLINE) /* underline or undercurl */ || ((attr & HL_UNDERCURL) && *T_UCS == NUL)) && *T_US != NUL) out_str(T_US); ! if ((attr & HL_ITALIC) && *T_CZH != NUL) /* italic */ out_str(T_CZH); ! if ((attr & HL_INVERSE) && *T_MR != NUL) /* inverse (reverse) */ out_str(T_MR); ! if ((attr & HL_STRIKETHROUGH) && *T_STS != NUL) /* strike */ out_str(T_STS); /* --- 1812,1833 ---- : #endif t_colors > 1 && aep->ae_u.cterm.fg_color)) ! // If the Normal FG color has BOLD attribute and the new HL ! // has a FG color defined, clear BOLD. out_str(T_ME); ! if ((attr & HL_STANDOUT) && *T_SO != NUL) // standout out_str(T_SO); ! if ((attr & HL_UNDERCURL) && *T_UCS != NUL) // undercurl out_str(T_UCS); ! if (((attr & HL_UNDERLINE) // underline or undercurl || ((attr & HL_UNDERCURL) && *T_UCS == NUL)) && *T_US != NUL) out_str(T_US); ! if ((attr & HL_ITALIC) && *T_CZH != NUL) // italic out_str(T_CZH); ! if ((attr & HL_INVERSE) && *T_MR != NUL) // inverse (reverse) out_str(T_MR); ! if ((attr & HL_STRIKETHROUGH) && *T_STS != NUL) // strike out_str(T_STS); /* *************** *** 1838,1846 **** if (aep != NULL) { #ifdef FEAT_TERMGUICOLORS ! /* When 'termguicolors' is set but fg or bg is unset, ! * fall back to the cterm colors. This helps for SpellBad, ! * where the GUI uses a red undercurl. */ if (p_tgc && aep->ae_u.cterm.fg_rgb != CTERMCOLOR) { if (aep->ae_u.cterm.fg_rgb != INVALCOLOR) --- 1837,1845 ---- if (aep != NULL) { #ifdef FEAT_TERMGUICOLORS ! // When 'termguicolors' is set but fg or bg is unset, ! // fall back to the cterm colors. This helps for SpellBad, ! // where the GUI uses a red undercurl. if (p_tgc && aep->ae_u.cterm.fg_rgb != CTERMCOLOR) { if (aep->ae_u.cterm.fg_rgb != INVALCOLOR) *************** *** 1880,1886 **** void screen_stop_highlight(void) { ! int do_ME = FALSE; /* output T_ME code */ if (screen_attr != 0 #ifdef MSWIN --- 1879,1885 ---- void screen_stop_highlight(void) { ! int do_ME = FALSE; // output T_ME code if (screen_attr != 0 #ifdef MSWIN *************** *** 1893,1906 **** { char buf[20]; ! /* use internal GUI code */ sprintf(buf, IF_EB("\033|%dH", ESC_STR "|%dH"), screen_attr); OUT_STR(buf); } else #endif { ! if (screen_attr > HL_ALL) /* special HL attr. */ { attrentry_T *aep; --- 1892,1905 ---- { char buf[20]; ! // use internal GUI code sprintf(buf, IF_EB("\033|%dH", ESC_STR "|%dH"), screen_attr); OUT_STR(buf); } else #endif { ! if (screen_attr > HL_ALL) // special HL attr. { attrentry_T *aep; *************** *** 1936,1942 **** out_str(aep->ae_u.term.stop); } } ! if (aep == NULL) /* did ":syntax clear" */ screen_attr = 0; else screen_attr = aep->ae_attr; --- 1935,1941 ---- out_str(aep->ae_u.term.stop); } } ! if (aep == NULL) // did ":syntax clear" screen_attr = 0; else screen_attr = aep->ae_attr; *************** *** 1998,2004 **** { if (t_colors > 1) { ! /* set Normal cterm colors */ if (cterm_normal_fg_color != 0) term_fg_color(cterm_normal_fg_color - 1); if (cterm_normal_bg_color != 0) --- 1997,2003 ---- { if (t_colors > 1) { ! // set Normal cterm colors if (cterm_normal_fg_color != 0) term_fg_color(cterm_normal_fg_color - 1); if (cterm_normal_bg_color != 0) *************** *** 2021,2027 **** { if (IS_CTERM) { ! /* set Normal cterm colors */ #ifdef FEAT_TERMGUICOLORS if (p_tgc ? (cterm_normal_fg_gui_color != INVALCOLOR || cterm_normal_bg_gui_color != INVALCOLOR) --- 2020,2026 ---- { if (IS_CTERM) { ! // set Normal cterm colors #ifdef FEAT_TERMGUICOLORS if (p_tgc ? (cterm_normal_fg_gui_color != INVALCOLOR || cterm_normal_bg_gui_color != INVALCOLOR) *************** *** 2050,2057 **** { int attr; ! /* Check for illegal values, just in case (could happen just after ! * resizing). */ if (row >= screen_Rows || col >= screen_Columns) return; --- 2049,2056 ---- { int attr; ! // Check for illegal values, just in case (could happen just after ! // resizing). if (row >= screen_Rows || col >= screen_Columns) return; *************** *** 2068,2080 **** return; #endif ! /* Outputting a character in the last cell on the screen may scroll the ! * screen up. Only do it when the "xn" termcap property is set, otherwise ! * mark the character invalid (update it when scrolled up). */ if (*T_XN == NUL && row == screen_Rows - 1 && col == screen_Columns - 1 #ifdef FEAT_RIGHTLEFT ! /* account for first command-line character in rightleft mode */ && !cmdmsg_rl #endif ) --- 2067,2079 ---- return; #endif ! // Outputting a character in the last cell on the screen may scroll the ! // screen up. Only do it when the "xn" termcap property is set, otherwise ! // mark the character invalid (update it when scrolled up). if (*T_XN == NUL && row == screen_Rows - 1 && col == screen_Columns - 1 #ifdef FEAT_RIGHTLEFT ! // account for first command-line character in rightleft mode && !cmdmsg_rl #endif ) *************** *** 2110,2128 **** #endif ) { ! /* Clear the two screen cells. If the character is actually ! * single width it won't change the second cell. */ out_str((char_u *)" "); term_windgoto(row, col); } ! /* not sure where the cursor is after drawing the ambiguous width ! * character */ screen_cur_col = 9999; } else if (utf_char2cells(ScreenLinesUC[off]) > 1) ++screen_cur_col; ! /* Convert the UTF-8 character to bytes and write it. */ buf[utfc_char2bytes(off, buf)] = NUL; out_str(buf); } --- 2109,2127 ---- #endif ) { ! // Clear the two screen cells. If the character is actually ! // single width it won't change the second cell. out_str((char_u *)" "); term_windgoto(row, col); } ! // not sure where the cursor is after drawing the ambiguous width ! // character screen_cur_col = 9999; } else if (utf_char2cells(ScreenLinesUC[off]) > 1) ++screen_cur_col; ! // Convert the UTF-8 character to bytes and write it. buf[utfc_char2bytes(off, buf)] = NUL; out_str(buf); } *************** *** 2130,2136 **** { out_flush_check(); out_char(ScreenLines[off]); ! /* double-byte character in single-width cell */ if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e) out_char(ScreenLines2[off]); } --- 2129,2135 ---- { out_flush_check(); out_char(ScreenLines[off]); ! // double-byte character in single-width cell if (enc_dbcs == DBCS_JPNU && ScreenLines[off] == 0x8e) out_char(ScreenLines2[off]); } *************** *** 2147,2166 **** static void screen_char_2(unsigned off, int row, int col) { ! /* Check for illegal values (could be wrong when screen was resized). */ if (off + 1 >= (unsigned)(screen_Rows * screen_Columns)) return; ! /* Outputting the last character on the screen may scrollup the screen. ! * Don't to it! Mark the character invalid (update it when scrolled up) */ if (row == screen_Rows - 1 && col >= screen_Columns - 2) { ScreenAttrs[off] = (sattr_T)-1; return; } ! /* Output the first byte normally (positions the cursor), then write the ! * second byte directly. */ screen_char(off, row, col); out_char(ScreenLines[off + 1]); ++screen_cur_col; --- 2146,2165 ---- static void screen_char_2(unsigned off, int row, int col) { ! // Check for illegal values (could be wrong when screen was resized). if (off + 1 >= (unsigned)(screen_Rows * screen_Columns)) return; ! // Outputting the last character on the screen may scrollup the screen. ! // Don't to it! Mark the character invalid (update it when scrolled up) if (row == screen_Rows - 1 && col >= screen_Columns - 2) { ScreenAttrs[off] = (sattr_T)-1; return; } ! // Output the first byte normally (positions the cursor), then write the ! // second byte directly. screen_char(off, row, col); out_char(ScreenLines[off + 1]); ++screen_cur_col; *************** *** 2182,2188 **** int off; int max_off; ! /* Can't use ScreenLines unless initialized */ if (ScreenLines == NULL) return; --- 2181,2187 ---- int off; int max_off; ! // Can't use ScreenLines unless initialized if (ScreenLines == NULL) return; *************** *** 2271,2286 **** int force_next = FALSE; #endif ! if (end_row > screen_Rows) /* safety check */ end_row = screen_Rows; ! if (end_col > screen_Columns) /* safety check */ end_col = screen_Columns; if (ScreenLines == NULL || start_row >= end_row ! || start_col >= end_col) /* nothing to do */ return; ! /* it's a "normal" terminal when not in a GUI or cterm */ norm_term = ( #ifdef FEAT_GUI !gui.in_use && --- 2270,2285 ---- int force_next = FALSE; #endif ! if (end_row > screen_Rows) // safety check end_row = screen_Rows; ! if (end_col > screen_Columns) // safety check end_col = screen_Columns; if (ScreenLines == NULL || start_row >= end_row ! || start_col >= end_col) // nothing to do return; ! // it's a "normal" terminal when not in a GUI or cterm norm_term = ( #ifdef FEAT_GUI !gui.in_use && *************** *** 2294,2303 **** #endif ) { ! /* When drawing over the right halve of a double-wide char clear ! * out the left halve. When drawing over the left halve of a ! * double wide-char clear out the right halve. Only needed in a ! * terminal. */ if (start_col > 0 && mb_fix_col(start_col, row) != start_col) screen_puts_len((char_u *)" ", 1, row, start_col - 1, 0); if (end_col < screen_Columns && mb_fix_col(end_col, row) != end_col) --- 2293,2302 ---- #endif ) { ! // When drawing over the right halve of a double-wide char clear ! // out the left halve. When drawing over the left halve of a ! // double wide-char clear out the right halve. Only needed in a ! // terminal. if (start_col > 0 && mb_fix_col(start_col, row) != start_col) screen_puts_len((char_u *)" ", 1, row, start_col - 1, 0); if (end_col < screen_Columns && mb_fix_col(end_col, row) != end_col) *************** *** 2321,2333 **** * check if we really need to clear something */ col = start_col; ! if (c1 != ' ') /* don't clear first char */ ++col; off = LineOffset[row] + col; end_off = LineOffset[row] + end_col; ! /* skip blanks (used often, keep it fast!) */ if (enc_utf8) while (off < end_off && ScreenLines[off] == ' ' && ScreenAttrs[off] == 0 && ScreenLinesUC[off] == 0) --- 2320,2332 ---- * check if we really need to clear something */ col = start_col; ! if (c1 != ' ') // don't clear first char ++col; off = LineOffset[row] + col; end_off = LineOffset[row] + end_col; ! // skip blanks (used often, keep it fast!) if (enc_utf8) while (off < end_off && ScreenLines[off] == ' ' && ScreenAttrs[off] == 0 && ScreenLinesUC[off] == 0) *************** *** 2336,2356 **** while (off < end_off && ScreenLines[off] == ' ' && ScreenAttrs[off] == 0) ++off; ! if (off < end_off) /* something to be cleared */ { col = off - LineOffset[row]; screen_stop_highlight(); ! term_windgoto(row, col);/* clear rest of this screen line */ out_str(T_CE); ! screen_start(); /* don't know where cursor is now */ col = end_col - col; ! while (col--) /* clear chars in ScreenLines */ { space_to_screenline(off, 0); ++off; } } ! did_delete = TRUE; /* the chars are cleared now */ } off = LineOffset[row] + start_col; --- 2335,2355 ---- while (off < end_off && ScreenLines[off] == ' ' && ScreenAttrs[off] == 0) ++off; ! if (off < end_off) // something to be cleared { col = off - LineOffset[row]; screen_stop_highlight(); ! term_windgoto(row, col);// clear rest of this screen line out_str(T_CE); ! screen_start(); // don't know where cursor is now col = end_col - col; ! while (col--) // clear chars in ScreenLines { space_to_screenline(off, 0); ++off; } } ! did_delete = TRUE; // the chars are cleared now } off = LineOffset[row] + start_col; *************** *** 2372,2381 **** ) { #if defined(FEAT_GUI) || defined(UNIX) ! /* The bold trick may make a single row of pixels appear in ! * the next character. When a bold character is removed, the ! * next character should be redrawn too. This happens for our ! * own GUI and for some xterms. */ if ( # ifdef FEAT_GUI gui.in_use --- 2371,2380 ---- ) { #if defined(FEAT_GUI) || defined(UNIX) ! // The bold trick may make a single row of pixels appear in ! // the next character. When a bold character is removed, the ! // next character should be redrawn too. This happens for our ! // own GUI and for some xterms. if ( # ifdef FEAT_GUI gui.in_use *************** *** 2421,2434 **** } if (end_col == Columns) LineWraps[row] = FALSE; ! if (row == Rows - 1) /* overwritten the command line */ { redraw_cmdline = TRUE; if (start_col == 0 && end_col == Columns && c1 == ' ' && c2 == ' ' && attr == 0) ! clear_cmdline = FALSE; /* command line has been cleared */ if (start_col == 0) ! mode_displayed = FALSE; /* mode cleared or overwritten */ } } } --- 2420,2433 ---- } if (end_col == Columns) LineWraps[row] = FALSE; ! if (row == Rows - 1) // overwritten the command line { redraw_cmdline = TRUE; if (start_col == 0 && end_col == Columns && c1 == ' ' && c2 == ' ' && attr == 0) ! clear_cmdline = FALSE; // command line has been cleared if (start_col == 0) ! mode_displayed = FALSE; // mode cleared or overwritten } } } *************** *** 2473,2479 **** int screen_valid(int doclear) { ! screenalloc(doclear); /* allocate screen buffers if size changed */ return (ScreenLines != NULL); } --- 2472,2478 ---- int screen_valid(int doclear) { ! screenalloc(doclear); // allocate screen buffers if size changed return (ScreenLines != NULL); } *************** *** 2512,2519 **** char *new_popup_transparent; #endif tabpage_T *tp; ! static int entered = FALSE; /* avoid recursiveness */ ! static int done_outofmem_msg = FALSE; /* did outofmem message */ int retry_count = 0; retry: --- 2511,2518 ---- char *new_popup_transparent; #endif tabpage_T *tp; ! static int entered = FALSE; // avoid recursiveness ! static int done_outofmem_msg = FALSE; // did outofmem message int retry_count = 0; retry: *************** *** 2548,2556 **** */ ++RedrawingDisabled; ! win_new_shellsize(); /* fit the windows in the new sized shell */ ! comp_col(); /* recompute columns for shown command and ruler */ /* * We're changing the size of the screen. --- 2547,2555 ---- */ ++RedrawingDisabled; ! win_new_shellsize(); // fit the windows in the new sized shell ! comp_col(); // recompute columns for shown command and ruler /* * We're changing the size of the screen. *************** *** 2648,2658 **** { if (ScreenLines != NULL || !done_outofmem_msg) { ! /* guess the size */ do_outofmem_msg((long_u)((Rows + 1) * Columns)); ! /* Remember we did this to avoid getting outofmem messages over ! * and over again. */ done_outofmem_msg = TRUE; } VIM_CLEAR(new_ScreenLines); --- 2647,2657 ---- { if (ScreenLines != NULL || !done_outofmem_msg) { ! // guess the size do_outofmem_msg((long_u)((Rows + 1) * Columns)); ! // Remember we did this to avoid getting outofmem messages over ! // and over again. done_outofmem_msg = TRUE; } VIM_CLEAR(new_ScreenLines); *************** *** 2710,2717 **** len = screen_Columns; else len = Columns; ! /* When switching to utf-8 don't copy characters, they ! * may be invalid now. Also when p_mco changes. */ if (!(enc_utf8 && ScreenLinesUC == NULL) && p_mco == Screen_mco) mch_memmove(new_ScreenLines + new_LineOffset[new_row], --- 2709,2716 ---- len = screen_Columns; else len = Columns; ! // When switching to utf-8 don't copy characters, they ! // may be invalid now. Also when p_mco changes. if (!(enc_utf8 && ScreenLinesUC == NULL) && p_mco == Screen_mco) mch_memmove(new_ScreenLines + new_LineOffset[new_row], *************** *** 2739,2745 **** } } } ! /* Use the last line of the screen for the current line. */ current_ScreenLine = new_ScreenLines + Rows * Columns; #ifdef FEAT_PROP_POPUP --- 2738,2744 ---- } } } ! // Use the last line of the screen for the current line. current_ScreenLine = new_ScreenLines + Rows * Columns; #ifdef FEAT_PROP_POPUP *************** *** 2768,2782 **** popup_mask_refresh = TRUE; #endif ! /* It's important that screen_Rows and screen_Columns reflect the actual ! * size of ScreenLines[]. Set them before calling anything. */ #ifdef FEAT_GUI old_Rows = screen_Rows; #endif screen_Rows = Rows; screen_Columns = Columns; ! must_redraw = CLEAR; /* need to clear the screen later */ if (doclear) screenclear2(); #ifdef FEAT_GUI --- 2767,2781 ---- popup_mask_refresh = TRUE; #endif ! // It's important that screen_Rows and screen_Columns reflect the actual ! // size of ScreenLines[]. Set them before calling anything. #ifdef FEAT_GUI old_Rows = screen_Rows; #endif screen_Rows = Rows; screen_Columns = Columns; ! must_redraw = CLEAR; // need to clear the screen later if (doclear) screenclear2(); #ifdef FEAT_GUI *************** *** 2790,2801 **** * Adjust the position of the cursor, for when executing an external * command. */ ! if (msg_row >= Rows) /* Rows got smaller */ ! msg_row = Rows - 1; /* put cursor at last row */ ! else if (Rows > old_Rows) /* Rows got bigger */ ! msg_row += Rows - old_Rows; /* put cursor in same place */ ! if (msg_col >= Columns) /* Columns got smaller */ ! msg_col = Columns - 1; /* put cursor at last column */ } #endif clear_TabPageIdxs(); --- 2789,2800 ---- * Adjust the position of the cursor, for when executing an external * command. */ ! if (msg_row >= Rows) // Rows got smaller ! msg_row = Rows - 1; // put cursor at last row ! else if (Rows > old_Rows) // Rows got bigger ! msg_row += Rows - old_Rows; // put cursor in same place ! if (msg_col >= Columns) // Columns got smaller ! msg_col = Columns - 1; // put cursor at last column } #endif clear_TabPageIdxs(); *************** *** 2810,2817 **** if (starting == 0 && ++retry_count <= 3) { apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, FALSE, curbuf); ! /* In rare cases, autocommands may have altered Rows or Columns, ! * jump back to check if we need to allocate the screen again. */ goto retry; } } --- 2809,2816 ---- if (starting == 0 && ++retry_count <= 3) { apply_autocmds(EVENT_VIMRESIZED, NULL, NULL, FALSE, curbuf); ! // In rare cases, autocommands may have altered Rows or Columns, ! // jump back to check if we need to allocate the screen again. goto retry; } } *************** *** 2841,2848 **** screenclear(void) { check_for_delay(FALSE); ! screenalloc(FALSE); /* allocate screen buffers if size changed */ ! screenclear2(); /* clear the screen */ } static void --- 2840,2847 ---- screenclear(void) { check_for_delay(FALSE); ! screenalloc(FALSE); // allocate screen buffers if size changed ! screenclear2(); // clear the screen } static void *************** *** 2860,2874 **** #ifdef FEAT_GUI if (!gui.in_use) #endif ! screen_attr = -1; /* force setting the Normal colors */ ! screen_stop_highlight(); /* don't want highlighting here */ #ifdef FEAT_CLIPBOARD ! /* disable selection without redrawing it */ clip_scroll_selection(9999); #endif ! /* blank out ScreenLines */ for (i = 0; i < Rows; ++i) { lineclear(LineOffset[i], (int)Columns, 0); --- 2859,2873 ---- #ifdef FEAT_GUI if (!gui.in_use) #endif ! screen_attr = -1; // force setting the Normal colors ! screen_stop_highlight(); // don't want highlighting here #ifdef FEAT_CLIPBOARD ! // disable selection without redrawing it clip_scroll_selection(9999); #endif ! // blank out ScreenLines for (i = 0; i < Rows; ++i) { lineclear(LineOffset[i], (int)Columns, 0); *************** *** 2877,2906 **** if (can_clear(T_CL)) { ! out_str(T_CL); /* clear the display */ clear_cmdline = FALSE; mode_displayed = FALSE; } else { ! /* can't clear the screen, mark all chars with invalid attributes */ for (i = 0; i < Rows; ++i) lineinvalid(LineOffset[i], (int)Columns); clear_cmdline = TRUE; } ! screen_cleared = TRUE; /* can use contents of ScreenLines now */ win_rest_invalid(firstwin); redraw_cmdline = TRUE; redraw_tabline = TRUE; ! if (must_redraw == CLEAR) /* no need to clear again */ must_redraw = NOT_VALID; compute_cmdrow(); ! msg_row = cmdline_row; /* put cursor on last line for messages */ msg_col = 0; ! screen_start(); /* don't know where cursor is now */ ! msg_scrolled = 0; /* can't scroll back */ msg_didany = FALSE; msg_didout = FALSE; } --- 2876,2905 ---- if (can_clear(T_CL)) { ! out_str(T_CL); // clear the display clear_cmdline = FALSE; mode_displayed = FALSE; } else { ! // can't clear the screen, mark all chars with invalid attributes for (i = 0; i < Rows; ++i) lineinvalid(LineOffset[i], (int)Columns); clear_cmdline = TRUE; } ! screen_cleared = TRUE; // can use contents of ScreenLines now win_rest_invalid(firstwin); redraw_cmdline = TRUE; redraw_tabline = TRUE; ! if (must_redraw == CLEAR) // no need to clear again must_redraw = NOT_VALID; compute_cmdrow(); ! msg_row = cmdline_row; // put cursor on last line for messages msg_col = 0; ! screen_start(); // don't know where cursor is now ! msg_scrolled = 0; // can't scroll back msg_didany = FALSE; msg_didout = FALSE; } *************** *** 3010,3037 **** int goto_cost; int attr; ! #define GOTO_COST 7 /* assume a term_windgoto() takes about 7 chars */ ! #define HIGHL_COST 5 /* assume unhighlight takes 5 chars */ #define PLAN_LE 1 #define PLAN_CR 2 #define PLAN_NL 3 #define PLAN_WRITE 4 ! /* Can't use ScreenLines unless initialized */ if (ScreenLines == NULL) return; if (col != screen_cur_col || row != screen_cur_row) { ! /* Check for valid position. */ ! if (row < 0) /* window without text lines? */ row = 0; if (row >= screen_Rows) row = screen_Rows - 1; if (col >= screen_Columns) col = screen_Columns - 1; ! /* check if no cursor movement is allowed in highlight mode */ if (screen_attr && *T_MS == NUL) noinvcurs = HIGHL_COST; else --- 3009,3036 ---- int goto_cost; int attr; ! #define GOTO_COST 7 // assume a term_windgoto() takes about 7 chars ! #define HIGHL_COST 5 // assume unhighlight takes 5 chars #define PLAN_LE 1 #define PLAN_CR 2 #define PLAN_NL 3 #define PLAN_WRITE 4 ! // Can't use ScreenLines unless initialized if (ScreenLines == NULL) return; if (col != screen_cur_col || row != screen_cur_row) { ! // Check for valid position. ! if (row < 0) // window without text lines? row = 0; if (row >= screen_Rows) row = screen_Rows - 1; if (col >= screen_Columns) col = screen_Columns - 1; ! // check if no cursor movement is allowed in highlight mode if (screen_attr && *T_MS == NUL) noinvcurs = HIGHL_COST; else *************** *** 3057,3087 **** * If the cursor is in the same row, bigger col, we can use CR * or T_LE. */ ! bs = NULL; /* init for GCC */ attr = screen_attr; if (row == screen_cur_row && col < screen_cur_col) { ! /* "le" is preferred over "bc", because "bc" is obsolete */ if (*T_LE) ! bs = T_LE; /* "cursor left" */ else ! bs = T_BC; /* "backspace character (old) */ if (*bs) cost = (screen_cur_col - col) * (int)STRLEN(bs); else cost = 999; ! if (col + 1 < cost) /* using CR is less characters */ { plan = PLAN_CR; wouldbe_col = 0; ! cost = 1; /* CR is just one character */ } else { plan = PLAN_LE; wouldbe_col = col; } ! if (noinvcurs) /* will stop highlighting */ { cost += noinvcurs; attr = 0; --- 3056,3086 ---- * If the cursor is in the same row, bigger col, we can use CR * or T_LE. */ ! bs = NULL; // init for GCC attr = screen_attr; if (row == screen_cur_row && col < screen_cur_col) { ! // "le" is preferred over "bc", because "bc" is obsolete if (*T_LE) ! bs = T_LE; // "cursor left" else ! bs = T_BC; // "backspace character (old) if (*bs) cost = (screen_cur_col - col) * (int)STRLEN(bs); else cost = 999; ! if (col + 1 < cost) // using CR is less characters { plan = PLAN_CR; wouldbe_col = 0; ! cost = 1; // CR is just one character } else { plan = PLAN_LE; wouldbe_col = col; } ! if (noinvcurs) // will stop highlighting { cost += noinvcurs; attr = 0; *************** *** 3095,3102 **** { plan = PLAN_NL; wouldbe_col = 0; ! cost = (row - screen_cur_row) * 2; /* CR LF */ ! if (noinvcurs) /* will stop highlighting */ { cost += noinvcurs; attr = 0; --- 3094,3101 ---- { plan = PLAN_NL; wouldbe_col = 0; ! cost = (row - screen_cur_row) * 2; // CR LF ! if (noinvcurs) // will stop highlighting { cost += noinvcurs; attr = 0; *************** *** 3141,3151 **** --i; } if (i != 0) ! cost = 999; /* different attributes, don't do it */ } if (enc_utf8) { ! /* Don't use an UTF-8 char for positioning, it's slow. */ for (i = wouldbe_col; i < col; ++i) if (ScreenLinesUC[LineOffset[row] + i] != 0) { --- 3140,3150 ---- --i; } if (i != 0) ! cost = 999; // different attributes, don't do it } if (enc_utf8) { ! // Don't use an UTF-8 char for positioning, it's slow. for (i = wouldbe_col; i < col; ++i) if (ScreenLinesUC[LineOffset[row] + i] != 0) { *************** *** 3262,3269 **** windgoto(W_WINROW(curwin) + curwin->w_wrow, curwin->w_wincol + ( #ifdef FEAT_RIGHTLEFT ! /* With 'rightleft' set and the cursor on a double-wide ! * character, position it on the leftmost column. */ curwin->w_p_rl ? ((int)curwin->w_width - curwin->w_wcol - ((has_mbyte && (*mb_ptr2cells)(ml_get_cursor()) == 2 --- 3261,3268 ---- windgoto(W_WINROW(curwin) + curwin->w_wrow, curwin->w_wincol + ( #ifdef FEAT_RIGHTLEFT ! // With 'rightleft' set and the cursor on a double-wide ! // character, position it on the leftmost column. curwin->w_p_rl ? ((int)curwin->w_width - curwin->w_wcol - ((has_mbyte && (*mb_ptr2cells)(ml_get_cursor()) == 2 *************** *** 3367,3373 **** int line_count, int invalid, int mayclear, ! int clear_attr) /* for clearing lines */ { int retval; --- 3366,3372 ---- int line_count, int invalid, int mayclear, ! int clear_attr) // for clearing lines { int retval; *************** *** 3486,3492 **** return retval; } ! if (wp->w_next != NULL && p_tf) /* don't delete/insert on fast terminal */ return FAIL; return MAYBE; --- 3485,3491 ---- return retval; } ! if (wp->w_next != NULL && p_tf) // don't delete/insert on fast terminal return FAIL; return MAYBE; *************** *** 3545,3551 **** int line_count, int end, int clear_attr, ! win_T *wp) /* NULL or window to use width from */ { int i; int j; --- 3544,3550 ---- int line_count, int end, int clear_attr, ! win_T *wp) // NULL or window to use width from { int i; int j; *************** *** 3639,3646 **** screen_del_lines(off, end - line_count, line_count, end, FALSE, 0, wp); #ifdef FEAT_CLIPBOARD ! /* Remove a modeless selection when inserting lines halfway the screen ! * or not the full width of the screen. */ if (off + row > 0 || (wp != NULL && wp->w_width != Columns)) clip_clear_selection(&clip_star); else --- 3638,3645 ---- screen_del_lines(off, end - line_count, line_count, end, FALSE, 0, wp); #ifdef FEAT_CLIPBOARD ! // Remove a modeless selection when inserting lines halfway the screen ! // or not the full width of the screen. if (off + row > 0 || (wp != NULL && wp->w_width != Columns)) clip_clear_selection(&clip_star); else *************** *** 3648,3662 **** #endif #ifdef FEAT_GUI ! /* Don't update the GUI cursor here, ScreenLines[] is invalid until the ! * scrolling is actually carried out. */ gui_dont_update_cursor(row + off <= gui.cursor_row); #endif if (wp != NULL && wp->w_wincol != 0 && *T_CSV != NUL && *T_CCS == NUL) cursor_col = wp->w_wincol; ! if (*T_CCS != NUL) /* cursor relative to region */ cursor_row = row; else cursor_row = row + off; --- 3647,3661 ---- #endif #ifdef FEAT_GUI ! // Don't update the GUI cursor here, ScreenLines[] is invalid until the ! // scrolling is actually carried out. gui_dont_update_cursor(row + off <= gui.cursor_row); #endif if (wp != NULL && wp->w_wincol != 0 && *T_CSV != NUL && *T_CCS == NUL) cursor_col = wp->w_wincol; ! if (*T_CCS != NUL) // cursor relative to region cursor_row = row; else cursor_row = row + off; *************** *** 3671,3677 **** { if (wp != NULL && wp->w_width != Columns) { ! /* need to copy part of a line */ j = end - 1 - i; while ((j -= line_count) >= row) linecopy(j + line_count, j, wp); --- 3670,3676 ---- { if (wp != NULL && wp->w_width != Columns) { ! // need to copy part of a line j = end - 1 - i; while ((j -= line_count) >= row) linecopy(j + line_count, j, wp); *************** *** 3706,3718 **** if (clear_attr != 0) screen_start_highlight(clear_attr); ! /* redraw the characters */ if (type == USE_REDRAW) redraw_block(row, end, wp); else if (type == USE_T_CAL) { term_append_lines(line_count); ! screen_start(); /* don't know where cursor is now */ } else { --- 3705,3717 ---- if (clear_attr != 0) screen_start_highlight(clear_attr); ! // redraw the characters if (type == USE_REDRAW) redraw_block(row, end, wp); else if (type == USE_T_CAL) { term_append_lines(line_count); ! screen_start(); // don't know where cursor is now } else { *************** *** 3724,3732 **** windgoto(cursor_row, cursor_col); out_str(T_AL); } ! else /* type == USE_T_SR */ out_str(T_SR); ! screen_start(); /* don't know where cursor is now */ } } --- 3723,3731 ---- windgoto(cursor_row, cursor_col); out_str(T_AL); } ! else // type == USE_T_SR out_str(T_SR); ! screen_start(); // don't know where cursor is now } } *************** *** 3740,3753 **** { windgoto(off + i, cursor_col); out_str(T_CE); ! screen_start(); /* don't know where cursor is now */ } } #ifdef FEAT_GUI gui_can_update_cursor(); if (gui.in_use) ! out_flush(); /* always flush after a scroll */ #endif return OK; } --- 3739,3752 ---- { windgoto(off + i, cursor_col); out_str(T_CE); ! screen_start(); // don't know where cursor is now } } #ifdef FEAT_GUI gui_can_update_cursor(); if (gui.in_use) ! out_flush(); // always flush after a scroll #endif return OK; } *************** *** 3766,3774 **** int row, int line_count, int end, ! int force, /* even when line_count > p_ttyscroll */ ! int clear_attr, /* used for clearing lines */ ! win_T *wp UNUSED) /* NULL or window to use width from */ { int j; int i; --- 3765,3773 ---- int row, int line_count, int end, ! int force, // even when line_count > p_ttyscroll ! int clear_attr, // used for clearing lines ! win_T *wp UNUSED) // NULL or window to use width from { int j; int i; *************** *** 3776,3783 **** int cursor_row; int cursor_col = 0; int cursor_end; ! int result_empty; /* result is empty until end of region */ ! int can_delete; /* deleting line codes can be used */ int type; /* --- 3775,3782 ---- int cursor_row; int cursor_col = 0; int cursor_end; ! int result_empty; // result is empty until end of region ! int can_delete; // deleting line codes can be used int type; /* *************** *** 3839,3846 **** #else else if (row == 0 && ( #ifndef AMIGA ! /* On the Amiga, somehow '\n' on the last line doesn't always scroll ! * up, so use delete-line command */ line_count == 1 || #endif *T_CDL == NUL)) --- 3838,3845 ---- #else else if (row == 0 && ( #ifndef AMIGA ! // On the Amiga, somehow '\n' on the last line doesn't always scroll ! // up, so use delete-line command line_count == 1 || #endif *T_CDL == NUL)) *************** *** 3859,3866 **** return FAIL; #ifdef FEAT_CLIPBOARD ! /* Remove a modeless selection when deleting lines halfway the screen or ! * not the full width of the screen. */ if (off + row > 0 || (wp != NULL && wp->w_width != Columns)) clip_clear_selection(&clip_star); else --- 3858,3865 ---- return FAIL; #ifdef FEAT_CLIPBOARD ! // Remove a modeless selection when deleting lines halfway the screen or ! // not the full width of the screen. if (off + row > 0 || (wp != NULL && wp->w_width != Columns)) clip_clear_selection(&clip_star); else *************** *** 3868,3875 **** #endif #ifdef FEAT_GUI ! /* Don't update the GUI cursor here, ScreenLines[] is invalid until the ! * scrolling is actually carried out. */ gui_dont_update_cursor(gui.cursor_row >= row + off && gui.cursor_row < end + off); #endif --- 3867,3874 ---- #endif #ifdef FEAT_GUI ! // Don't update the GUI cursor here, ScreenLines[] is invalid until the ! // scrolling is actually carried out. gui_dont_update_cursor(gui.cursor_row >= row + off && gui.cursor_row < end + off); #endif *************** *** 3877,3883 **** if (wp != NULL && wp->w_wincol != 0 && *T_CSV != NUL && *T_CCS == NUL) cursor_col = wp->w_wincol; ! if (*T_CCS != NUL) /* cursor relative to region */ { cursor_row = row; cursor_end = end; --- 3876,3882 ---- if (wp != NULL && wp->w_wincol != 0 && *T_CSV != NUL && *T_CCS == NUL) cursor_col = wp->w_wincol; ! if (*T_CCS != NUL) // cursor relative to region { cursor_row = row; cursor_end = end; *************** *** 3898,3904 **** { if (wp != NULL && wp->w_width != Columns) { ! /* need to copy part of a line */ j = row + i; while ((j += line_count) <= end - 1) linecopy(j - line_count, j, wp); --- 3897,3903 ---- { if (wp != NULL && wp->w_width != Columns) { ! // need to copy part of a line j = row + i; while ((j += line_count) <= end - 1) linecopy(j - line_count, j, wp); *************** *** 3912,3918 **** } else { ! /* whole width, moving the line pointers is faster */ j = row + i; temp = LineOffset[j]; while ((j += line_count) <= end - 1) --- 3911,3917 ---- } else { ! // whole width, moving the line pointers is faster j = row + i; temp = LineOffset[j]; while ((j += line_count) <= end - 1) *************** *** 3934,3953 **** if (clear_attr != 0) screen_start_highlight(clear_attr); ! /* redraw the characters */ if (type == USE_REDRAW) redraw_block(row, end, wp); ! else if (type == USE_T_CD) /* delete the lines */ { windgoto(cursor_row, cursor_col); out_str(T_CD); ! screen_start(); /* don't know where cursor is now */ } else if (type == USE_T_CDL) { windgoto(cursor_row, cursor_col); term_delete_lines(line_count); ! screen_start(); /* don't know where cursor is now */ } /* * Deleting lines at top of the screen or scroll region: Just scroll --- 3933,3952 ---- if (clear_attr != 0) screen_start_highlight(clear_attr); ! // redraw the characters if (type == USE_REDRAW) redraw_block(row, end, wp); ! else if (type == USE_T_CD) // delete the lines { windgoto(cursor_row, cursor_col); out_str(T_CD); ! screen_start(); // don't know where cursor is now } else if (type == USE_T_CDL) { windgoto(cursor_row, cursor_col); term_delete_lines(line_count); ! screen_start(); // don't know where cursor is now } /* * Deleting lines at top of the screen or scroll region: Just scroll *************** *** 3958,3964 **** { windgoto(cursor_end - 1, cursor_col); for (i = line_count; --i >= 0; ) ! out_char('\n'); /* cursor will remain on same line */ } else { --- 3957,3963 ---- { windgoto(cursor_end - 1, cursor_col); for (i = line_count; --i >= 0; ) ! out_char('\n'); // cursor will remain on same line } else { *************** *** 3967,3980 **** if (type == USE_T_DL) { windgoto(cursor_row, cursor_col); ! out_str(T_DL); /* delete a line */ } ! else /* type == USE_T_CE */ { windgoto(cursor_row + i, cursor_col); ! out_str(T_CE); /* erase a line */ } ! screen_start(); /* don't know where cursor is now */ } } --- 3966,3979 ---- if (type == USE_T_DL) { windgoto(cursor_row, cursor_col); ! out_str(T_DL); // delete a line } ! else // type == USE_T_CE { windgoto(cursor_row + i, cursor_col); ! out_str(T_CE); // erase a line } ! screen_start(); // don't know where cursor is now } } *************** *** 3987,4001 **** for (i = line_count; i > 0; --i) { windgoto(cursor_end - i, cursor_col); ! out_str(T_CE); /* erase a line */ ! screen_start(); /* don't know where cursor is now */ } } #ifdef FEAT_GUI gui_can_update_cursor(); if (gui.in_use) ! out_flush(); /* always flush after a scroll */ #endif return OK; --- 3986,4000 ---- for (i = line_count; i > 0; --i) { windgoto(cursor_end - i, cursor_col); ! out_str(T_CE); // erase a line ! screen_start(); // don't know where cursor is now } } #ifdef FEAT_GUI gui_can_update_cursor(); if (gui.in_use) ! out_flush(); // always flush after a scroll #endif return OK; *************** *** 4051,4068 **** nwr_save = need_wait_return; ! /* wait a bit before overwriting an important message */ check_for_delay(FALSE); ! /* if the cmdline is more than one line high, erase top lines */ need_clear = clear_cmdline; if (clear_cmdline && cmdline_row < Rows - 1) ! msg_clr_cmdline(); /* will reset clear_cmdline */ ! /* Position on the last line in the window, column 0 */ msg_pos_mode(); cursor_off(); ! attr = HL_ATTR(HLF_CM); /* Highlight mode */ if (do_mode) { msg_puts_attr("--", attr); --- 4050,4067 ---- nwr_save = need_wait_return; ! // wait a bit before overwriting an important message check_for_delay(FALSE); ! // if the cmdline is more than one line high, erase top lines need_clear = clear_cmdline; if (clear_cmdline && cmdline_row < Rows - 1) ! msg_clr_cmdline(); // will reset clear_cmdline ! // Position on the last line in the window, column 0 msg_pos_mode(); cursor_off(); ! attr = HL_ATTR(HLF_CM); // Highlight mode if (do_mode) { msg_puts_attr("--", attr); *************** *** 4074,4090 **** im_get_status() # endif ) ! # ifdef FEAT_GUI_GTK /* most of the time, it's not XIM being used */ msg_puts_attr(" IM", attr); # else msg_puts_attr(" XIM", attr); # endif #endif ! /* CTRL-X in Insert mode */ if (edit_submode != NULL && !shortmess(SHM_COMPLETIONMENU)) { ! /* These messages can get long, avoid a wrap in a narrow ! * window. Prefer showing edit_submode_extra. */ length = (Rows - msg_row) * Columns - 3; if (edit_submode_extra != NULL) length -= vim_strsize(edit_submode_extra); --- 4073,4089 ---- im_get_status() # endif ) ! # ifdef FEAT_GUI_GTK // most of the time, it's not XIM being used msg_puts_attr(" IM", attr); # else msg_puts_attr(" XIM", attr); # endif #endif ! // CTRL-X in Insert mode if (edit_submode != NULL && !shortmess(SHM_COMPLETIONMENU)) { ! // These messages can get long, avoid a wrap in a narrow ! // window. Prefer showing edit_submode_extra. length = (Rows - msg_row) * Columns - 3; if (edit_submode_extra != NULL) length -= vim_strsize(edit_submode_extra); *************** *** 4100,4106 **** } if (edit_submode_extra != NULL) { ! msg_puts_attr(" ", attr); /* add a space in between */ if ((int)edit_submode_highl < (int)HLF_COUNT) sub_attr = HL_ATTR(edit_submode_highl); else --- 4099,4105 ---- } if (edit_submode_extra != NULL) { ! msg_puts_attr(" ", attr); // add a space in between if ((int)edit_submode_highl < (int)HLF_COUNT) sub_attr = HL_ATTR(edit_submode_highl); else *************** *** 4153,4160 **** { char *p; ! /* Don't concatenate separate words to avoid translation ! * problems. */ switch ((VIsual_select ? 4 : 0) + (VIsual_mode == Ctrl_V) * 2 + (VIsual_mode == 'V')) --- 4152,4159 ---- { char *p; ! // Don't concatenate separate words to avoid translation ! // problems. switch ((VIsual_select ? 4 : 0) + (VIsual_mode == Ctrl_V) * 2 + (VIsual_mode == 'V')) *************** *** 4183,4195 **** mode_displayed = TRUE; if (need_clear || clear_cmdline || redraw_mode) msg_clr_eos(); ! msg_didout = FALSE; /* overwrite this message */ length = msg_col; msg_col = 0; ! need_wait_return = nwr_save; /* never ask for hit-return for this */ } else if (clear_cmdline && msg_silent == 0) ! /* Clear the whole command line. Will reset "clear_cmdline". */ msg_clr_cmdline(); else if (redraw_mode) { --- 4182,4194 ---- mode_displayed = TRUE; if (need_clear || clear_cmdline || redraw_mode) msg_clr_eos(); ! msg_didout = FALSE; // overwrite this message length = msg_col; msg_col = 0; ! need_wait_return = nwr_save; // never ask for hit-return for this } else if (clear_cmdline && msg_silent == 0) ! // Clear the whole command line. Will reset "clear_cmdline". msg_clr_cmdline(); else if (redraw_mode) { *************** *** 4198,4209 **** } #ifdef FEAT_CMDL_INFO ! /* In Visual mode the size of the selected area must be redrawn. */ if (VIsual_active) clear_showcmd(); ! /* If the last window has no status line, the ruler is after the mode ! * message and must be redrawn */ if (redrawing() && lastwin->w_status_height == 0) win_redr_ruler(lastwin, TRUE, FALSE); #endif --- 4197,4208 ---- } #ifdef FEAT_CMDL_INFO ! // In Visual mode the size of the selected area must be redrawn. if (VIsual_active) clear_showcmd(); ! // If the last window has no status line, the ruler is after the mode ! // message and must be redrawn if (redrawing() && lastwin->w_status_height == 0) win_redr_ruler(lastwin, TRUE, FALSE); #endif *************** *** 4236,4242 **** * Don't delete it right now, when not redrawing or inside a mapping. */ if (!redrawing() || (!force && char_avail() && !KeyTyped)) ! redraw_cmdline = TRUE; /* delete mode later */ else clearmode(); } --- 4235,4241 ---- * Don't delete it right now, when not redrawing or inside a mapping. */ if (!redrawing() || (!force && char_avail() && !KeyTyped)) ! redraw_cmdline = TRUE; // delete mode later else clearmode(); } *************** *** 4309,4315 **** redraw_tabline = FALSE; #ifdef FEAT_GUI_TABLINE ! /* Take care of a GUI tabline. */ if (gui_use_tabline()) { gui_update_tabline(); --- 4308,4314 ---- redraw_tabline = FALSE; #ifdef FEAT_GUI_TABLINE ! // Take care of a GUI tabline. if (gui_use_tabline()) { gui_update_tabline(); *************** *** 4323,4335 **** #if defined(FEAT_STL_OPT) clear_TabPageIdxs(); ! /* Use the 'tabline' option if it's set. */ if (*p_tal != NUL) { int saved_did_emsg = did_emsg; ! /* Check for an error. If there is one we would loop in redrawing the ! * screen. Avoid that by making 'tabline' empty. */ did_emsg = FALSE; win_redr_custom(NULL, FALSE); if (did_emsg) --- 4322,4334 ---- #if defined(FEAT_STL_OPT) clear_TabPageIdxs(); ! // Use the 'tabline' option if it's set. if (*p_tal != NUL) { int saved_did_emsg = did_emsg; ! // Check for an error. If there is one we would loop in redrawing the ! // screen. Avoid that by making 'tabline' empty. did_emsg = FALSE; win_redr_custom(NULL, FALSE); if (did_emsg) *************** *** 4404,4410 **** room = scol - col + tabwidth - 1; if (room > 0) { ! /* Get buffer name in NameBuff[] */ get_trans_bufname(cwp->w_buffer); shorten_dir(NameBuff); len = vim_strsize(NameBuff); --- 4403,4409 ---- room = scol - col + tabwidth - 1; if (room > 0) { ! // Get buffer name in NameBuff[] get_trans_bufname(cwp->w_buffer); shorten_dir(NameBuff); len = vim_strsize(NameBuff); *************** *** 4428,4435 **** } screen_putchar(' ', 0, col++, attr); ! /* Store the tab page number in TabPageIdxs[], so that ! * jump_to_mouse() knows where each one is. */ ++tabcount; while (scol < col) TabPageIdxs[scol++] = tabcount; --- 4427,4434 ---- } screen_putchar(' ', 0, col++, attr); ! // Store the tab page number in TabPageIdxs[], so that ! // jump_to_mouse() knows where each one is. ++tabcount; while (scol < col) TabPageIdxs[scol++] = tabcount; *************** *** 4441,4447 **** c = ' '; screen_fill(0, 1, col, (int)Columns, c, c, attr_fill); ! /* Put an "X" for closing the current tab if there are several. */ if (first_tabpage->tp_next != NULL) { screen_putchar('X', 0, (int)Columns - 1, attr_nosel); --- 4440,4446 ---- c = ' '; screen_fill(0, 1, col, (int)Columns, c, c, attr_fill); ! // Put an "X" for closing the current tab if there are several. if (first_tabpage->tp_next != NULL) { screen_putchar('X', 0, (int)Columns - 1, attr_nosel); *************** *** 4449,4456 **** } } ! /* Reset the flag here again, in case evaluating 'tabline' causes it to be ! * set. */ redraw_tabline = FALSE; } --- 4448,4455 ---- } } ! // Reset the flag here again, in case evaluating 'tabline' causes it to be ! // set. redraw_tabline = FALSE; } *************** *** 4502,4510 **** *attr = HL_ATTR(HLF_SNC); fill = fill_stlnc; } ! /* Use fill when there is highlighting, and highlighting of current ! * window differs, or the fillchars differ, or this is not the ! * current window */ if (*attr != 0 && ((HL_ATTR(HLF_S) != HL_ATTR(HLF_SNC) || wp != curwin || ONE_WINDOW) || (fill_stl != fill_stlnc))) --- 4501,4509 ---- *attr = HL_ATTR(HLF_SNC); fill = fill_stlnc; } ! // Use fill when there is highlighting, and highlighting of current ! // window differs, or the fillchars differ, or this is not the ! // current window if (*attr != 0 && ((HL_ATTR(HLF_S) != HL_ATTR(HLF_SNC) || wp != curwin || ONE_WINDOW) || (fill_stl != fill_stlnc))) *************** *** 4617,4626 **** linenr_T lnum; if (wp->w_p_rnu && !wp->w_p_nu) ! /* cursor line shows "0" */ lnum = wp->w_height; else ! /* cursor line shows absolute line number */ lnum = wp->w_buffer->b_ml.ml_line_count; if (lnum == wp->w_nrwidth_line_count && wp->w_nuw_cached == wp->w_p_nuw) --- 4616,4625 ---- linenr_T lnum; if (wp->w_p_rnu && !wp->w_p_nu) ! // cursor line shows "0" lnum = wp->w_height; else ! // cursor line shows absolute line number lnum = wp->w_buffer->b_ml.ml_line_count; if (lnum == wp->w_nrwidth_line_count && wp->w_nuw_cached == wp->w_p_nuw) *************** *** 4634,4640 **** ++n; } while (lnum > 0); ! /* 'numberwidth' gives the minimal width plus one */ if (n < wp->w_p_nuw - 1) n = wp->w_p_nuw - 1; --- 4633,4639 ---- ++n; } while (lnum > 0); ! // 'numberwidth' gives the minimal width plus one if (n < wp->w_p_nuw - 1) n = wp->w_p_nuw - 1; *** ../vim-8.1.2393/src/search.c 2019-11-30 22:47:42.655331183 +0100 --- src/search.c 2019-12-05 21:07:47.940112509 +0100 *************** *** 55,82 **** */ static spat_T spats[2] = { ! {NULL, TRUE, FALSE, {'/', 0, 0, 0L}}, /* last used search pat */ ! {NULL, TRUE, FALSE, {'/', 0, 0, 0L}} /* last used substitute pat */ }; ! static int last_idx = 0; /* index in spats[] for RE_LAST */ ! static char_u lastc[2] = {NUL, NUL}; /* last character searched for */ ! static int lastcdir = FORWARD; /* last direction of character search */ ! static int last_t_cmd = TRUE; /* last search t_cmd */ static char_u lastc_bytes[MB_MAXBYTES + 1]; ! static int lastc_bytelen = 1; /* >1 for multi-byte char */ ! /* copy of spats[], for keeping the search patterns while executing autocmds */ static spat_T saved_spats[2]; # ifdef FEAT_SEARCH_EXTRA static int saved_spats_last_idx = 0; static int saved_spats_no_hlsearch = 0; # endif ! static char_u *mr_pattern = NULL; /* pattern used by search_regcomp() */ #ifdef FEAT_RIGHTLEFT ! static int mr_pattern_alloced = FALSE; /* mr_pattern was allocated */ #endif #ifdef FEAT_FIND_ID --- 55,82 ---- */ static spat_T spats[2] = { ! {NULL, TRUE, FALSE, {'/', 0, 0, 0L}}, // last used search pat ! {NULL, TRUE, FALSE, {'/', 0, 0, 0L}} // last used substitute pat }; ! static int last_idx = 0; // index in spats[] for RE_LAST ! static char_u lastc[2] = {NUL, NUL}; // last character searched for ! static int lastcdir = FORWARD; // last direction of character search ! static int last_t_cmd = TRUE; // last search t_cmd static char_u lastc_bytes[MB_MAXBYTES + 1]; ! static int lastc_bytelen = 1; // >1 for multi-byte char ! // copy of spats[], for keeping the search patterns while executing autocmds static spat_T saved_spats[2]; # ifdef FEAT_SEARCH_EXTRA static int saved_spats_last_idx = 0; static int saved_spats_no_hlsearch = 0; # endif ! static char_u *mr_pattern = NULL; // pattern used by search_regcomp() #ifdef FEAT_RIGHTLEFT ! static int mr_pattern_alloced = FALSE; // mr_pattern was allocated #endif #ifdef FEAT_FIND_ID *************** *** 86,95 **** */ typedef struct SearchedFile { ! FILE *fp; /* File pointer */ ! char_u *name; /* Full name of file */ ! linenr_T lnum; /* Line we were up to in file */ ! int matched; /* Found a match in this file */ } SearchedFile; #endif --- 86,95 ---- */ typedef struct SearchedFile { ! FILE *fp; // File pointer ! char_u *name; // Full name of file ! linenr_T lnum; // Line we were up to in file ! int matched; // Found a match in this file } SearchedFile; #endif *************** *** 113,119 **** int pat_save, int pat_use, int options, ! regmmatch_T *regmatch) /* return: pattern and ignore-case flag */ { int magic; int i; --- 113,119 ---- int pat_save, int pat_use, int options, ! regmmatch_T *regmatch) // return: pattern and ignore-case flag { int magic; int i; *************** *** 130,136 **** i = last_idx; else i = pat_use; ! if (spats[i].pat == NULL) /* pattern was never defined */ { if (pat_use == RE_SUBST) emsg(_(e_nopresub)); --- 130,136 ---- i = last_idx; else i = pat_use; ! if (spats[i].pat == NULL) // pattern was never defined { if (pat_use == RE_SUBST) emsg(_(e_nopresub)); *************** *** 143,149 **** magic = spats[i].magic; no_smartcase = spats[i].no_scs; } ! else if (options & SEARCH_HIS) /* put new pattern in history */ add_to_history(HIST_SEARCH, pat, TRUE, NUL); #ifdef FEAT_RIGHTLEFT --- 143,149 ---- magic = spats[i].magic; no_smartcase = spats[i].no_scs; } ! else if (options & SEARCH_HIS) // put new pattern in history add_to_history(HIST_SEARCH, pat, TRUE, NUL); #ifdef FEAT_RIGHTLEFT *************** *** 159,165 **** rev_pattern = reverse_text(pat); if (rev_pattern == NULL) ! mr_pattern = pat; /* out of memory, keep normal pattern. */ else { mr_pattern = rev_pattern; --- 159,165 ---- rev_pattern = reverse_text(pat); if (rev_pattern == NULL) ! mr_pattern = pat; // out of memory, keep normal pattern. else { mr_pattern = rev_pattern; *************** *** 176,185 **** */ if (!(options & SEARCH_KEEP) && !cmdmod.keeppatterns) { ! /* search or global command */ if (pat_save == RE_SEARCH || pat_save == RE_BOTH) save_re_pat(RE_SEARCH, pat, magic); ! /* substitute or global command */ if (pat_save == RE_SUBST || pat_save == RE_BOTH) save_re_pat(RE_SUBST, pat, magic); } --- 176,185 ---- */ if (!(options & SEARCH_KEEP) && !cmdmod.keeppatterns) { ! // search or global command if (pat_save == RE_SEARCH || pat_save == RE_BOTH) save_re_pat(RE_SEARCH, pat, magic); ! // substitute or global command if (pat_save == RE_SUBST || pat_save == RE_BOTH) save_re_pat(RE_SUBST, pat, magic); } *************** *** 253,259 **** spats[idx].no_scs = no_smartcase; last_idx = idx; #ifdef FEAT_SEARCH_EXTRA ! /* If 'hlsearch' set and search pat changed: need redraw. */ if (p_hls) redraw_all_later(SOME_VALID); set_no_hlsearch(FALSE); --- 253,259 ---- spats[idx].no_scs = no_smartcase; last_idx = idx; #ifdef FEAT_SEARCH_EXTRA ! // If 'hlsearch' set and search pat changed: need redraw. if (p_hls) redraw_all_later(SOME_VALID); set_no_hlsearch(FALSE); *************** *** 426,436 **** } else if (*p == '\\') { ! if (p[1] == '_' && p[2] != NUL) /* skip "\_X" */ p += 3; ! else if (p[1] == '%' && p[2] != NUL) /* skip "\%X" */ p += 3; ! else if (p[1] != NUL) /* skip "\X" */ p += 2; else p += 1; --- 426,436 ---- } else if (*p == '\\') { ! if (p[1] == '_' && p[2] != NUL) // skip "\_X" p += 3; ! else if (p[1] == '%' && p[2] != NUL) // skip "\%X" p += 3; ! else if (p[1] != NUL) // skip "\X" p += 2; else p += 1; *************** *** 517,523 **** int setlast) { vim_free(spats[idx].pat); ! /* An empty string means that nothing should be matched. */ if (*s == NUL) spats[idx].pat = NULL; else --- 517,523 ---- int setlast) { vim_free(spats[idx].pat); ! // An empty string means that nothing should be matched. if (*s == NUL) spats[idx].pat = NULL; else *************** *** 546,552 **** # endif } # ifdef FEAT_SEARCH_EXTRA ! /* If 'hlsearch' set and search pat changed: need redraw. */ if (p_hls && idx == last_idx && !no_hlsearch) redraw_all_later(SOME_VALID); # endif --- 546,552 ---- # endif } # ifdef FEAT_SEARCH_EXTRA ! // If 'hlsearch' set and search pat changed: need redraw. if (p_hls && idx == last_idx && !no_hlsearch) redraw_all_later(SOME_VALID); # endif *************** *** 567,573 **** regmatch->regprog = NULL; return; } ! ++emsg_off; /* So it doesn't beep if bad expr */ (void)search_regcomp((char_u *)"", 0, last_idx, SEARCH_KEEP, regmatch); --emsg_off; } --- 567,573 ---- regmatch->regprog = NULL; return; } ! ++emsg_off; // So it doesn't beep if bad expr (void)search_regcomp((char_u *)"", 0, last_idx, SEARCH_KEEP, regmatch); --emsg_off; } *************** *** 608,614 **** searchit_arg_T *extra_arg) // optional extra arguments, can be NULL { int found; ! linenr_T lnum; /* no init to shut up Apollo cc */ colnr_T col; regmmatch_T regmatch; char_u *ptr; --- 608,614 ---- searchit_arg_T *extra_arg) // optional extra arguments, can be NULL { int found; ! linenr_T lnum; // no init to shut up Apollo cc colnr_T col; regmmatch_T regmatch; char_u *ptr; *************** *** 655,668 **** * find the string */ called_emsg = FALSE; ! do /* loop for count */ { ! /* When not accepting a match at the start position set "extra_col" to ! * a non-zero value. Don't do that when starting at MAXCOL, since ! * MAXCOL + 1 is zero. */ if (pos->col == MAXCOL) start_char_len = 0; ! /* Watch out for the "col" being MAXCOL - 2, used in a closed fold. */ else if (has_mbyte && pos->lnum >= 1 && pos->lnum <= buf->b_ml.ml_line_count && pos->col < MAXCOL - 2) --- 655,668 ---- * find the string */ called_emsg = FALSE; ! do // loop for count { ! // When not accepting a match at the start position set "extra_col" to ! // a non-zero value. Don't do that when starting at MAXCOL, since ! // MAXCOL + 1 is zero. if (pos->col == MAXCOL) start_char_len = 0; ! // Watch out for the "col" being MAXCOL - 2, used in a closed fold. else if (has_mbyte && pos->lnum >= 1 && pos->lnum <= buf->b_ml.ml_line_count && pos->col < MAXCOL - 2) *************** *** 690,703 **** extra_col = 0; } ! start_pos = *pos; /* remember start pos for detecting no match */ ! found = 0; /* default: not found */ ! at_first_line = TRUE; /* default: start in first line */ ! if (pos->lnum == 0) /* correct lnum for when starting in line 0 */ { pos->lnum = 1; pos->col = 0; ! at_first_line = FALSE; /* not in first line now */ } /* --- 690,703 ---- extra_col = 0; } ! start_pos = *pos; // remember start pos for detecting no match ! found = 0; // default: not found ! at_first_line = TRUE; // default: start in first line ! if (pos->lnum == 0) // correct lnum for when starting in line 0 { pos->lnum = 1; pos->col = 0; ! at_first_line = FALSE; // not in first line now } /* *************** *** 716,732 **** else lnum = pos->lnum; ! for (loop = 0; loop <= 1; ++loop) /* loop twice if 'wrapscan' set */ { for ( ; lnum > 0 && lnum <= buf->b_ml.ml_line_count; lnum += dir, at_first_line = FALSE) { ! /* Stop after checking "stop_lnum", if it's set. */ if (stop_lnum != 0 && (dir == FORWARD ? lnum > stop_lnum : lnum < stop_lnum)) break; #ifdef FEAT_RELTIME ! /* Stop after passing the "tm" time limit. */ if (tm != NULL && profile_passed_limit(tm)) break; #endif --- 716,732 ---- else lnum = pos->lnum; ! for (loop = 0; loop <= 1; ++loop) // loop twice if 'wrapscan' set { for ( ; lnum > 0 && lnum <= buf->b_ml.ml_line_count; lnum += dir, at_first_line = FALSE) { ! // Stop after checking "stop_lnum", if it's set. if (stop_lnum != 0 && (dir == FORWARD ? lnum > stop_lnum : lnum < stop_lnum)) break; #ifdef FEAT_RELTIME ! // Stop after passing the "tm" time limit. if (tm != NULL && profile_passed_limit(tm)) break; #endif *************** *** 744,750 **** NULL, NULL #endif ); ! /* Abort searching on an error (e.g., out of stack). */ if (called_emsg #ifdef FEAT_RELTIME || (timed_out != NULL && *timed_out) --- 744,750 ---- NULL, NULL #endif ); ! // Abort searching on an error (e.g., out of stack). if (called_emsg #ifdef FEAT_RELTIME || (timed_out != NULL && *timed_out) *************** *** 753,765 **** break; if (nmatched > 0) { ! /* match may actually be in another line when using \zs */ matchpos = regmatch.startpos[0]; endpos = regmatch.endpos[0]; #ifdef FEAT_EVAL submatch = first_submatch(®match); #endif ! /* "lnum" may be past end of buffer for "\n\zs". */ if (lnum + matchpos.lnum > buf->b_ml.ml_line_count) ptr = (char_u *)""; else --- 753,765 ---- break; if (nmatched > 0) { ! // match may actually be in another line when using \zs matchpos = regmatch.startpos[0]; endpos = regmatch.endpos[0]; #ifdef FEAT_EVAL submatch = first_submatch(®match); #endif ! // "lnum" may be past end of buffer for "\n\zs". if (lnum + matchpos.lnum > buf->b_ml.ml_line_count) ptr = (char_u *)""; else *************** *** 798,810 **** { if (nmatched > 1) { ! /* end is in next line, thus no match in ! * this line */ match_ok = FALSE; break; } matchcol = endpos.col; ! /* for empty match: advance one char */ if (matchcol == matchpos.col && ptr[matchcol] != NUL) { --- 798,810 ---- { if (nmatched > 1) { ! // end is in next line, thus no match in ! // this line match_ok = FALSE; break; } matchcol = endpos.col; ! // for empty match: advance one char if (matchcol == matchpos.col && ptr[matchcol] != NUL) { *************** *** 849,856 **** submatch = first_submatch(®match); # endif ! /* Need to get the line pointer again, a ! * multi-line search may have made it invalid. */ ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE); } if (!match_ok) --- 849,856 ---- submatch = first_submatch(®match); # endif ! // Need to get the line pointer again, a ! // multi-line search may have made it invalid. ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE); } if (!match_ok) *************** *** 868,877 **** match_ok = FALSE; for (;;) { ! /* Remember a position that is before the start ! * position, we use it if it's the last match in ! * the line. Always accept a position after ! * wrapping around. */ if (loop || ((options & SEARCH_END) ? (lnum + regmatch.endpos[0].lnum --- 868,877 ---- match_ok = FALSE; for (;;) { ! // Remember a position that is before the start ! // position, we use it if it's the last match in ! // the line. Always accept a position after ! // wrapping around. if (loop || ((options & SEARCH_END) ? (lnum + regmatch.endpos[0].lnum *************** *** 911,917 **** if (nmatched > 1) break; matchcol = endpos.col; ! /* for empty match: advance one char */ if (matchcol == matchpos.col && ptr[matchcol] != NUL) { --- 911,917 ---- if (nmatched > 1) break; matchcol = endpos.col; ! // for empty match: advance one char if (matchcol == matchpos.col && ptr[matchcol] != NUL) { *************** *** 924,930 **** } else { ! /* Stop when the match is in a next line. */ if (matchpos.lnum > 0) break; matchcol = matchpos.col; --- 924,930 ---- } else { ! // Stop when the match is in a next line. if (matchpos.lnum > 0) break; matchcol = matchpos.col; *************** *** 949,965 **** )) == 0) { #ifdef FEAT_RELTIME ! /* If the search timed out, we did find a match ! * but it might be the wrong one, so that's not ! * OK. */ if (timed_out != NULL && *timed_out) match_ok = FALSE; #endif break; } ! /* Need to get the line pointer again, a ! * multi-line search may have made it invalid. */ ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE); } --- 949,965 ---- )) == 0) { #ifdef FEAT_RELTIME ! // If the search timed out, we did find a match ! // but it might be the wrong one, so that's not ! // OK. if (timed_out != NULL && *timed_out) match_ok = FALSE; #endif break; } ! // Need to get the line pointer again, a ! // multi-line search may have made it invalid. ptr = ml_get_buf(buf, lnum + matchpos.lnum, FALSE); } *************** *** 971,990 **** continue; } ! /* With the SEARCH_END option move to the last character ! * of the match. Don't do it for an empty match, end ! * should be same as start then. */ if ((options & SEARCH_END) && !(options & SEARCH_NOOF) && !(matchpos.lnum == endpos.lnum && matchpos.col == endpos.col)) { ! /* For a match in the first column, set the position ! * on the NUL in the previous line. */ pos->lnum = lnum + endpos.lnum; pos->col = endpos.col; if (endpos.col == 0) { ! if (pos->lnum > 1) /* just in case */ { --pos->lnum; pos->col = (colnr_T)STRLEN(ml_get_buf(buf, --- 971,990 ---- continue; } ! // With the SEARCH_END option move to the last character ! // of the match. Don't do it for an empty match, end ! // should be same as start then. if ((options & SEARCH_END) && !(options & SEARCH_NOOF) && !(matchpos.lnum == endpos.lnum && matchpos.col == endpos.col)) { ! // For a match in the first column, set the position ! // on the NUL in the previous line. pos->lnum = lnum + endpos.lnum; pos->col = endpos.col; if (endpos.col == 0) { ! if (pos->lnum > 1) // just in case { --pos->lnum; pos->col = (colnr_T)STRLEN(ml_get_buf(buf, *************** *** 1023,1041 **** found = 1; first_match = FALSE; ! /* Set variables used for 'incsearch' highlighting. */ search_match_lines = endpos.lnum - matchpos.lnum; search_match_endcol = endpos.col; break; } ! line_breakcheck(); /* stop if ctrl-C typed */ if (got_int) break; #ifdef FEAT_SEARCH_EXTRA ! /* Cancel searching if a character was typed. Used for ! * 'incsearch'. Don't check too often, that would slowdown ! * searching too much. */ if ((options & SEARCH_PEEK) && ((lnum - pos->lnum) & 0x3f) == 0 && char_avail()) --- 1023,1041 ---- found = 1; first_match = FALSE; ! // Set variables used for 'incsearch' highlighting. search_match_lines = endpos.lnum - matchpos.lnum; search_match_endcol = endpos.col; break; } ! line_breakcheck(); // stop if ctrl-C typed if (got_int) break; #ifdef FEAT_SEARCH_EXTRA ! // Cancel searching if a character was typed. Used for ! // 'incsearch'. Don't check too often, that would slowdown ! // searching too much. if ((options & SEARCH_PEEK) && ((lnum - pos->lnum) & 0x3f) == 0 && char_avail()) *************** *** 1046,1052 **** #endif if (loop && lnum == start_pos.lnum) ! break; /* if second loop, stop where started */ } at_first_line = FALSE; --- 1046,1052 ---- #endif if (loop && lnum == start_pos.lnum) ! break; // if second loop, stop where started } at_first_line = FALSE; *************** *** 1072,1078 **** * is redrawn. The keep_msg is cleared whenever another message is * written. */ ! if (dir == BACKWARD) /* start second loop at the other end */ lnum = buf->b_ml.ml_line_count; else lnum = 1; --- 1072,1078 ---- * is redrawn. The keep_msg is cleared whenever another message is * written. */ ! if (dir == BACKWARD) // start second loop at the other end lnum = buf->b_ml.ml_line_count; else lnum = 1; *************** *** 1092,1104 **** ) break; } ! while (--count > 0 && found); /* stop after count matches or no match */ vim_regfree(regmatch.regprog); called_emsg |= save_called_emsg; ! if (!found) /* did not find it */ { if (got_int) emsg(_(e_interr)); --- 1092,1104 ---- ) break; } ! while (--count > 0 && found); // stop after count matches or no match vim_regfree(regmatch.regprog); called_emsg |= save_called_emsg; ! if (!found) // did not find it { if (got_int) emsg(_(e_interr)); *************** *** 1116,1122 **** return FAIL; } ! /* A pattern like "\n\zs" may go past the last line. */ if (pos->lnum > buf->b_ml.ml_line_count) { pos->lnum = buf->b_ml.ml_line_count; --- 1116,1122 ---- return FAIL; } ! // A pattern like "\n\zs" may go past the last line. if (pos->lnum > buf->b_ml.ml_line_count) { pos->lnum = buf->b_ml.ml_line_count; *************** *** 1187,1203 **** */ int do_search( ! oparg_T *oap, /* can be NULL */ ! int dirc, /* '/' or '?' */ char_u *pat, long count, int options, searchit_arg_T *sia) // optional arguments or NULL { ! pos_T pos; /* position of the last match */ char_u *searchstr; soffset_T old_off; ! int retval; /* Return value */ char_u *p; long c; char_u *dircp; --- 1187,1203 ---- */ int do_search( ! oparg_T *oap, // can be NULL ! int dirc, // '/' or '?' char_u *pat, long count, int options, searchit_arg_T *sia) // optional arguments or NULL { ! pos_T pos; // position of the last match char_u *searchstr; soffset_T old_off; ! int retval; // Return value char_u *p; long c; char_u *dircp; *************** *** 1223,1229 **** */ old_off = spats[0].off; ! pos = curwin->w_cursor; /* start searching at the cursor position */ /* * Find out the direction of the search. --- 1223,1229 ---- */ old_off = spats[0].off; ! pos = curwin->w_cursor; // start searching at the cursor position /* * Find out the direction of the search. *************** *** 1240,1247 **** if (options & SEARCH_REV) { #ifdef MSWIN ! /* There is a bug in the Visual C++ 2.2 compiler which means that ! * dirc always ends up being '/' */ dirc = (dirc == '/') ? '?' : '/'; #else if (dirc == '/') --- 1240,1247 ---- if (options & SEARCH_REV) { #ifdef MSWIN ! // There is a bug in the Visual C++ 2.2 compiler which means that ! // dirc always ends up being '/' dirc = (dirc == '/') ? '?' : '/'; #else if (dirc == '/') *************** *** 1252,1263 **** } #ifdef FEAT_FOLDING ! /* If the cursor is in a closed fold, don't find another match in the same ! * fold. */ if (dirc == '/') { if (hasFolding(pos.lnum, NULL, &pos.lnum)) ! pos.col = MAXCOL - 2; /* avoid overflow when adding 1 */ } else { --- 1252,1263 ---- } #ifdef FEAT_FOLDING ! // If the cursor is in a closed fold, don't find another match in the same ! // fold. if (dirc == '/') { if (hasFolding(pos.lnum, NULL, &pos.lnum)) ! pos.col = MAXCOL - 2; // avoid overflow when adding 1 } else { *************** *** 1286,1295 **** searchstr = pat; dircp = NULL; ! /* use previous pattern */ if (pat == NULL || *pat == NUL || *pat == dirc) { ! if (spats[RE_SEARCH].pat == NULL) /* no previous pattern */ { searchstr = spats[RE_SUBST].pat; if (searchstr == NULL) --- 1286,1295 ---- searchstr = pat; dircp = NULL; ! // use previous pattern if (pat == NULL || *pat == NUL || *pat == dirc) { ! if (spats[RE_SEARCH].pat == NULL) // no previous pattern { searchstr = spats[RE_SUBST].pat; if (searchstr == NULL) *************** *** 1301,1312 **** } else { ! /* make search_regcomp() use spats[RE_SEARCH].pat */ searchstr = (char_u *)""; } } ! if (pat != NULL && *pat != NUL) /* look for (new) offset */ { /* * Find end of regular expression. --- 1301,1312 ---- } else { ! // make search_regcomp() use spats[RE_SEARCH].pat searchstr = (char_u *)""; } } ! if (pat != NULL && *pat != NUL) // look for (new) offset { /* * Find end of regular expression. *************** *** 1316,1329 **** p = skip_regexp(pat, dirc, (int)p_magic, &strcopy); if (strcopy != ps) { ! /* made a copy of "pat" to change "\?" to "?" */ searchcmdlen += (int)(STRLEN(pat) - STRLEN(strcopy)); pat = strcopy; searchstr = strcopy; } if (*p == dirc) { ! dircp = p; /* remember where we put the NUL */ *p++ = NUL; } spats[0].off.line = FALSE; --- 1316,1329 ---- p = skip_regexp(pat, dirc, (int)p_magic, &strcopy); if (strcopy != ps) { ! // made a copy of "pat" to change "\?" to "?" searchcmdlen += (int)(STRLEN(pat) - STRLEN(strcopy)); pat = strcopy; searchstr = strcopy; } if (*p == dirc) { ! dircp = p; // remember where we put the NUL *p++ = NUL; } spats[0].off.line = FALSE; *************** *** 1340,1367 **** else if ((options & SEARCH_OPT) && (*p == 'e' || *p == 's' || *p == 'b')) { ! if (*p == 'e') /* end */ spats[0].off.end = SEARCH_END; ++p; } ! if (VIM_ISDIGIT(*p) || *p == '+' || *p == '-') /* got an offset */ { ! /* 'nr' or '+nr' or '-nr' */ if (VIM_ISDIGIT(*p) || VIM_ISDIGIT(*(p + 1))) spats[0].off.off = atol((char *)p); ! else if (*p == '-') /* single '-' */ spats[0].off.off = -1; ! else /* single '+' */ spats[0].off.off = 1; ++p; ! while (VIM_ISDIGIT(*p)) /* skip number */ ++p; } ! /* compute length of search command for get_address() */ searchcmdlen += (int)(p - pat); ! pat = p; /* put pat after search command */ } if ((options & SEARCH_ECHO) && messaging() && --- 1340,1367 ---- else if ((options & SEARCH_OPT) && (*p == 'e' || *p == 's' || *p == 'b')) { ! if (*p == 'e') // end spats[0].off.end = SEARCH_END; ++p; } ! if (VIM_ISDIGIT(*p) || *p == '+' || *p == '-') // got an offset { ! // 'nr' or '+nr' or '-nr' if (VIM_ISDIGIT(*p) || VIM_ISDIGIT(*(p + 1))) spats[0].off.off = atol((char *)p); ! else if (*p == '-') // single '-' spats[0].off.off = -1; ! else // single '+' spats[0].off.off = 1; ++p; ! while (VIM_ISDIGIT(*p)) // skip number ++p; } ! // compute length of search command for get_address() searchcmdlen += (int)(p - pat); ! pat = p; // put pat after search command } if ((options & SEARCH_ECHO) && messaging() && *************** *** 1499,1507 **** for (c = spats[0].off.off; c; --c) if (decl(&pos) == -1) break; ! if (c) /* at start of buffer */ { ! pos.lnum = 0; /* allow lnum == 0 here */ pos.col = MAXCOL; } } --- 1499,1507 ---- for (c = spats[0].off.off; c; --c) if (decl(&pos) == -1) break; ! if (c) // at start of buffer { ! pos.lnum = 0; // allow lnum == 0 here pos.col = MAXCOL; } } *************** *** 1510,1516 **** for (c = spats[0].off.off; c; ++c) if (incl(&pos) == -1) break; ! if (c) /* at end of buffer */ { pos.lnum = curbuf->b_ml.ml_line_count + 1; pos.col = 0; --- 1510,1516 ---- for (c = spats[0].off.off; c; ++c) if (incl(&pos) == -1) break; ! if (c) // at end of buffer { pos.lnum = curbuf->b_ml.ml_line_count + 1; pos.col = 0; *************** *** 1540,1548 **** goto end_do_search; } if (spats[0].off.end && oap != NULL) ! oap->inclusive = TRUE; /* 'e' includes last character */ ! retval = 1; /* pattern found */ /* * Add character and/or line offset --- 1540,1548 ---- goto end_do_search; } if (spats[0].off.end && oap != NULL) ! oap->inclusive = TRUE; // 'e' includes last character ! retval = 1; // pattern found /* * Add character and/or line offset *************** *** 1551,1557 **** { pos_T org_pos = pos; ! if (spats[0].off.line) /* Add the offset to the line number. */ { c = pos.lnum + spats[0].off.off; if (c < 1) --- 1551,1557 ---- { pos_T org_pos = pos; ! if (spats[0].off.line) // Add the offset to the line number. { c = pos.lnum + spats[0].off.off; if (c < 1) *************** *** 1562,1572 **** pos.lnum = c; pos.col = 0; ! retval = 2; /* pattern found, line offset added */ } ! else if (pos.col < MAXCOL - 2) /* just in case */ { ! /* to the right, check for end of file */ c = spats[0].off.off; if (c > 0) { --- 1562,1572 ---- pos.lnum = c; pos.col = 0; ! retval = 2; // pattern found, line offset added } ! else if (pos.col < MAXCOL - 2) // just in case { ! // to the right, check for end of file c = spats[0].off.off; if (c > 0) { *************** *** 1574,1580 **** if (incl(&pos) == -1) break; } ! /* to the left, check for start of file */ else { while (c++ < 0) --- 1574,1580 ---- if (incl(&pos) == -1) break; } ! // to the left, check for start of file else { while (c++ < 0) *************** *** 1692,1707 **** p = skipwhite(ptr); pos->col = (colnr_T) (p - ptr); ! /* when adding lines the matching line may be empty but it is not ! * ignored because we are interested in the next line -- Acevedo */ if ((compl_cont_status & CONT_ADDING) && !(compl_cont_status & CONT_SOL)) { if ((p_ic ? MB_STRICMP(p, pat) : STRCMP(p, pat)) == 0) return OK; } ! else if (*p != NUL) /* ignore empty lines */ ! { /* expanding lines or words */ if ((p_ic ? MB_STRNICMP(p, pat, compl_length) : STRNCMP(p, pat, compl_length)) == 0) return OK; --- 1692,1707 ---- p = skipwhite(ptr); pos->col = (colnr_T) (p - ptr); ! // when adding lines the matching line may be empty but it is not ! // ignored because we are interested in the next line -- Acevedo if ((compl_cont_status & CONT_ADDING) && !(compl_cont_status & CONT_SOL)) { if ((p_ic ? MB_STRICMP(p, pat) : STRCMP(p, pat)) == 0) return OK; } ! else if (*p != NUL) // ignore empty lines ! { // expanding lines or words if ((p_ic ? MB_STRNICMP(p, pat, compl_length) : STRNCMP(p, pat, compl_length)) == 0) return OK; *************** *** 1723,1739 **** int searchc(cmdarg_T *cap, int t_cmd) { ! int c = cap->nchar; /* char to search for */ ! int dir = cap->arg; /* TRUE for searching forward */ ! long count = cap->count1; /* repeat count */ int col; char_u *p; int len; int stop = TRUE; ! if (c != NUL) /* normal search: remember args for repeat */ { ! if (!KeyStuffed) /* don't remember when redoing */ { *lastc = c; set_csearch_direction(dir); --- 1723,1739 ---- int searchc(cmdarg_T *cap, int t_cmd) { ! int c = cap->nchar; // char to search for ! int dir = cap->arg; // TRUE for searching forward ! long count = cap->count1; // repeat count int col; char_u *p; int len; int stop = TRUE; ! if (c != NUL) // normal search: remember args for repeat { ! if (!KeyStuffed) // don't remember when redoing { *lastc = c; set_csearch_direction(dir); *************** *** 1749,1769 **** } } } ! else /* repeat previous search */ { if (*lastc == NUL && lastc_bytelen == 1) return FAIL; ! if (dir) /* repeat in opposite direction */ dir = -lastcdir; else dir = lastcdir; t_cmd = last_t_cmd; c = *lastc; ! /* For multi-byte re-use last lastc_bytes[] and lastc_bytelen. */ ! /* Force a move of at least one char, so ";" and "," will move the ! * cursor, even if the cursor is right in front of char we are looking ! * at. */ if (vim_strchr(p_cpo, CPO_SCOLON) == NULL && count == 1 && t_cmd) stop = FALSE; } --- 1749,1769 ---- } } } ! else // repeat previous search { if (*lastc == NUL && lastc_bytelen == 1) return FAIL; ! if (dir) // repeat in opposite direction dir = -lastcdir; else dir = lastcdir; t_cmd = last_t_cmd; c = *lastc; ! // For multi-byte re-use last lastc_bytes[] and lastc_bytelen. ! // Force a move of at least one char, so ";" and "," will move the ! // cursor, even if the cursor is right in front of char we are looking ! // at. if (vim_strchr(p_cpo, CPO_SCOLON) == NULL && count == 1 && t_cmd) stop = FALSE; } *************** *** 1821,1835 **** if (t_cmd) { ! /* backup to before the character (possibly double-byte) */ col -= dir; if (has_mbyte) { if (dir < 0) ! /* Landed on the search char which is lastc_bytelen long */ col += lastc_bytelen - 1; else ! /* To previous char, which may be multi-byte. */ col -= (*mb_head_off)(p, p + col); } } --- 1821,1835 ---- if (t_cmd) { ! // backup to before the character (possibly double-byte) col -= dir; if (has_mbyte) { if (dir < 0) ! // Landed on the search char which is lastc_bytelen long col += lastc_bytelen - 1; else ! // To previous char, which may be multi-byte. col -= (*mb_head_off)(p, p + col); } } *************** *** 2041,2071 **** int flags, int maxtravel) { ! static pos_T pos; /* current search position */ ! int findc = 0; /* matching brace */ int c; ! int count = 0; /* cumulative number of braces */ ! int backwards = FALSE; /* init for gcc */ ! int raw_string = FALSE; /* search for raw string */ ! int inquote = FALSE; /* TRUE when inside quotes */ ! char_u *linep; /* pointer to current line */ char_u *ptr; ! int do_quotes; /* check for quotes in current line */ ! int at_start; /* do_quotes value at start position */ ! int hash_dir = 0; /* Direction searched for # things */ ! int comment_dir = 0; /* Direction searched for comments */ ! pos_T match_pos; /* Where last slash-star was found */ ! int start_in_quotes; /* start position is in quotes */ ! int traveled = 0; /* how far we've searched so far */ ! int ignore_cend = FALSE; /* ignore comment end */ ! int cpo_match; /* vi compatible matching */ ! int cpo_bsl; /* don't recognize backslashes */ ! int match_escaped = 0; /* search for escaped match */ ! int dir; /* Direction to search */ ! int comment_col = MAXCOL; /* start of / / comment */ #ifdef FEAT_LISP ! int lispcomm = FALSE; /* inside of Lisp-style comment */ ! int lisp = curbuf->b_p_lisp; /* engage Lisp-specific hacks ;) */ #endif pos = curwin->w_cursor; --- 2041,2071 ---- int flags, int maxtravel) { ! static pos_T pos; // current search position ! int findc = 0; // matching brace int c; ! int count = 0; // cumulative number of braces ! int backwards = FALSE; // init for gcc ! int raw_string = FALSE; // search for raw string ! int inquote = FALSE; // TRUE when inside quotes ! char_u *linep; // pointer to current line char_u *ptr; ! int do_quotes; // check for quotes in current line ! int at_start; // do_quotes value at start position ! int hash_dir = 0; // Direction searched for # things ! int comment_dir = 0; // Direction searched for comments ! pos_T match_pos; // Where last slash-star was found ! int start_in_quotes; // start position is in quotes ! int traveled = 0; // how far we've searched so far ! int ignore_cend = FALSE; // ignore comment end ! int cpo_match; // vi compatible matching ! int cpo_bsl; // don't recognize backslashes ! int match_escaped = 0; // search for escaped match ! int dir; // Direction to search ! int comment_col = MAXCOL; // start of / / comment #ifdef FEAT_LISP ! int lispcomm = FALSE; // inside of Lisp-style comment ! int lisp = curbuf->b_p_lisp; // engage Lisp-specific hacks ;) #endif pos = curwin->w_cursor; *************** *** 2075,2081 **** cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL); cpo_bsl = (vim_strchr(p_cpo, CPO_MATCHBSL) != NULL); ! /* Direction to search when initc is '/', '*' or '#' */ if (flags & FM_BACKWARD) dir = BACKWARD; else if (flags & FM_FORWARD) --- 2075,2081 ---- cpo_match = (vim_strchr(p_cpo, CPO_MATCH) != NULL); cpo_bsl = (vim_strchr(p_cpo, CPO_MATCHBSL) != NULL); ! // Direction to search when initc is '/', '*' or '#' if (flags & FM_BACKWARD) dir = BACKWARD; else if (flags & FM_FORWARD) *************** *** 2123,2129 **** */ if (!cpo_match) { ! /* Are we before or at #if, #else etc.? */ ptr = skipwhite(linep); if (*ptr == '#' && pos.col <= (colnr_T)(ptr - linep)) { --- 2123,2129 ---- */ if (!cpo_match) { ! // Are we before or at #if, #else etc.? ptr = skipwhite(linep); if (*ptr == '#' && pos.col <= (colnr_T)(ptr - linep)) { *************** *** 2134,2140 **** hash_dir = 1; } ! /* Are we on a comment? */ else if (linep[pos.col] == '/') { if (linep[pos.col + 1] == '*') --- 2134,2140 ---- hash_dir = 1; } ! // Are we on a comment? else if (linep[pos.col] == '/') { if (linep[pos.col + 1] == '*') *************** *** 2191,2197 **** } if (!findc) { ! /* no brace in the line, maybe use " #if" then */ if (!cpo_match && *skipwhite(linep) == '#') hash_dir = 1; else --- 2191,2197 ---- } if (!findc) { ! // no brace in the line, maybe use " #if" then if (!cpo_match && *skipwhite(linep) == '#') hash_dir = 1; else *************** *** 2201,2208 **** { int col, bslcnt = 0; ! /* Set "match_escaped" if there are an odd number of ! * backslashes. */ for (col = pos.col; check_prevcol(linep, col, '\\', &col);) bslcnt++; match_escaped = (bslcnt & 1); --- 2201,2208 ---- { int col, bslcnt = 0; ! // Set "match_escaped" if there are an odd number of ! // backslashes. for (col = pos.col; check_prevcol(linep, col, '\\', &col);) bslcnt++; match_escaped = (bslcnt & 1); *************** *** 2215,2221 **** * Look for matching #if, #else, #elif, or #endif */ if (oap != NULL) ! oap->motion_type = MLINE; /* Linewise for this case only */ if (initc != '#') { ptr = skipwhite(skipwhite(linep) + 1); --- 2215,2221 ---- * Look for matching #if, #else, #elif, or #endif */ if (oap != NULL) ! oap->motion_type = MLINE; // Linewise for this case only if (initc != '#') { ptr = skipwhite(skipwhite(linep) + 1); *************** *** 2238,2244 **** break; pos.lnum += hash_dir; linep = ml_get(pos.lnum); ! line_breakcheck(); /* check for CTRL-C typed */ ptr = skipwhite(linep); if (*ptr != '#') continue; --- 2238,2244 ---- break; pos.lnum += hash_dir; linep = ml_get(pos.lnum); ! line_breakcheck(); // check for CTRL-C typed ptr = skipwhite(linep); if (*ptr != '#') continue; *************** *** 2282,2289 **** } #ifdef FEAT_RIGHTLEFT ! /* This is just guessing: when 'rightleft' is set, search for a matching ! * paren/brace in the other direction. */ if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL) backwards = !backwards; #endif --- 2282,2289 ---- } #ifdef FEAT_RIGHTLEFT ! // This is just guessing: when 'rightleft' is set, search for a matching ! // paren/brace in the other direction. if (curwin->w_p_rl && vim_strchr((char_u *)"()[]{}<>", initc) != NULL) backwards = !backwards; #endif *************** *** 2292,2298 **** start_in_quotes = MAYBE; CLEAR_POS(&match_pos); ! /* backward search: Check if this line contains a single-line comment */ if ((backwards && comment_dir) #ifdef FEAT_LISP || lisp --- 2292,2298 ---- start_in_quotes = MAYBE; CLEAR_POS(&match_pos); ! // backward search: Check if this line contains a single-line comment if ((backwards && comment_dir) #ifdef FEAT_LISP || lisp *************** *** 2301,2307 **** comment_col = check_linecomment(linep); #ifdef FEAT_LISP if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col) ! lispcomm = TRUE; /* find match inside this comment */ #endif while (!got_int) { --- 2301,2307 ---- comment_col = check_linecomment(linep); #ifdef FEAT_LISP if (lisp && comment_col != MAXCOL && pos.col > (colnr_T)comment_col) ! lispcomm = TRUE; // find match inside this comment #endif while (!got_int) { *************** *** 2312,2324 **** if (backwards) { #ifdef FEAT_LISP ! /* char to match is inside of comment, don't search outside */ if (lispcomm && pos.col < (colnr_T)comment_col) break; #endif ! if (pos.col == 0) /* at start of line, go to prev. one */ { ! if (pos.lnum == 1) /* start of file */ break; --pos.lnum; --- 2312,2324 ---- if (backwards) { #ifdef FEAT_LISP ! // char to match is inside of comment, don't search outside if (lispcomm && pos.col < (colnr_T)comment_col) break; #endif ! if (pos.col == 0) // at start of line, go to prev. one { ! if (pos.lnum == 1) // start of file break; --pos.lnum; *************** *** 2326,2336 **** break; linep = ml_get(pos.lnum); ! pos.col = (colnr_T)STRLEN(linep); /* pos.col on trailing NUL */ do_quotes = -1; line_breakcheck(); ! /* Check if this line contains a single-line comment */ if (comment_dir #ifdef FEAT_LISP || lisp --- 2326,2336 ---- break; linep = ml_get(pos.lnum); ! pos.col = (colnr_T)STRLEN(linep); // pos.col on trailing NUL do_quotes = -1; line_breakcheck(); ! // Check if this line contains a single-line comment if (comment_dir #ifdef FEAT_LISP || lisp *************** *** 2338,2344 **** ) comment_col = check_linecomment(linep); #ifdef FEAT_LISP ! /* skip comment */ if (lisp && comment_col != MAXCOL) pos.col = comment_col; #endif --- 2338,2344 ---- ) comment_col = check_linecomment(linep); #ifdef FEAT_LISP ! // skip comment if (lisp && comment_col != MAXCOL) pos.col = comment_col; #endif *************** *** 2350,2370 **** pos.col -= (*mb_head_off)(linep, linep + pos.col); } } ! else /* forward search */ { if (linep[pos.col] == NUL ! /* at end of line, go to next one */ #ifdef FEAT_LISP ! /* don't search for match in comment */ || (lisp && comment_col != MAXCOL && pos.col == (colnr_T)comment_col) #endif ) { ! if (pos.lnum == curbuf->b_ml.ml_line_count /* end of file */ #ifdef FEAT_LISP ! /* line is exhausted and comment with it, ! * don't search for match in code */ || lispcomm #endif ) --- 2350,2370 ---- pos.col -= (*mb_head_off)(linep, linep + pos.col); } } ! else // forward search { if (linep[pos.col] == NUL ! // at end of line, go to next one #ifdef FEAT_LISP ! // don't search for match in comment || (lisp && comment_col != MAXCOL && pos.col == (colnr_T)comment_col) #endif ) { ! if (pos.lnum == curbuf->b_ml.ml_line_count // end of file #ifdef FEAT_LISP ! // line is exhausted and comment with it, ! // don't search for match in code || lispcomm #endif ) *************** *** 2379,2385 **** do_quotes = -1; line_breakcheck(); #ifdef FEAT_LISP ! if (lisp) /* find comment pos in new line */ comment_col = check_linecomment(linep); #endif } --- 2379,2385 ---- do_quotes = -1; line_breakcheck(); #ifdef FEAT_LISP ! if (lisp) // find comment pos in new line comment_col = check_linecomment(linep); #endif } *************** *** 2398,2412 **** if (pos.col == 0 && (flags & FM_BLOCKSTOP) && (linep[0] == '{' || linep[0] == '}')) { ! if (linep[0] == findc && count == 0) /* match! */ return &pos; ! break; /* out of scope */ } if (comment_dir) { ! /* Note: comments do not nest, and we ignore quotes in them */ ! /* TODO: ignore comment brackets inside strings */ if (comment_dir == FORWARD) { if (linep[pos.col] == '*' && linep[pos.col + 1] == '/') --- 2398,2412 ---- if (pos.col == 0 && (flags & FM_BLOCKSTOP) && (linep[0] == '{' || linep[0] == '}')) { ! if (linep[0] == findc && count == 0) // match! return &pos; ! break; // out of scope } if (comment_dir) { ! // Note: comments do not nest, and we ignore quotes in them ! // TODO: ignore comment brackets inside strings if (comment_dir == FORWARD) { if (linep[pos.col] == '*' && linep[pos.col + 1] == '/') *************** *** 2415,2421 **** return &pos; } } ! else /* Searching backwards */ { /* * A comment may contain / * or / /, it may also start or end --- 2415,2421 ---- return &pos; } } ! else // Searching backwards { /* * A comment may contain / * or / /, it may also start or end *************** *** 2429,2438 **** && linep[pos.col] == '"' && vim_strchr(linep + pos.col + 1, '(') != NULL) { ! /* Possible start of raw string. Now that we have the ! * delimiter we can check if it ends before where we ! * started searching, or before the previously found ! * raw string start. */ if (!find_rawstring_end(linep, &pos, count > 0 ? &match_pos : &curwin->w_cursor)) { --- 2429,2438 ---- && linep[pos.col] == '"' && vim_strchr(linep + pos.col + 1, '(') != NULL) { ! // Possible start of raw string. Now that we have the ! // delimiter we can check if it ends before where we ! // started searching, or before the previously found ! // raw string start. if (!find_rawstring_end(linep, &pos, count > 0 ? &match_pos : &curwin->w_cursor)) { *************** *** 2440,2446 **** match_pos = pos; match_pos.col--; } ! linep = ml_get(pos.lnum); /* may have been released */ } } else if ( linep[pos.col - 1] == '/' --- 2440,2446 ---- match_pos = pos; match_pos.col--; } ! linep = ml_get(pos.lnum); // may have been released } } else if ( linep[pos.col - 1] == '/' *************** *** 2493,2499 **** if (*ptr == '\\' && ptr[1] != NUL) ++ptr; } ! do_quotes &= 1; /* result is 1 with even number of quotes */ /* * If we find an uneven count, check current line and previous --- 2493,2499 ---- if (*ptr == '\\' && ptr[1] != NUL) ++ptr; } ! do_quotes &= 1; // result is 1 with even number of quotes /* * If we find an uneven count, check current line and previous *************** *** 2507,2513 **** do_quotes = 1; if (start_in_quotes == MAYBE) { ! /* Do we need to use at_start here? */ inquote = TRUE; start_in_quotes = TRUE; } --- 2507,2513 ---- do_quotes = 1; if (start_in_quotes == MAYBE) { ! // Do we need to use at_start here? inquote = TRUE; start_in_quotes = TRUE; } *************** *** 2530,2536 **** inquote = TRUE; } ! /* ml_get() only keeps one line, need to get linep again */ linep = ml_get(pos.lnum); } } --- 2530,2536 ---- inquote = TRUE; } ! // ml_get() only keeps one line, need to get linep again linep = ml_get(pos.lnum); } } *************** *** 2553,2559 **** switch (c) { case NUL: ! /* at end of line without trailing backslash, reset inquote */ if (pos.col == 0 || linep[pos.col - 1] != '\\') { inquote = FALSE; --- 2553,2559 ---- switch (c) { case NUL: ! // at end of line without trailing backslash, reset inquote if (pos.col == 0 || linep[pos.col - 1] != '\\') { inquote = FALSE; *************** *** 2562,2569 **** break; case '"': ! /* a quote that is preceded with an odd number of backslashes is ! * ignored */ if (do_quotes) { int col; --- 2562,2569 ---- break; case '"': ! // a quote that is preceded with an odd number of backslashes is ! // ignored if (do_quotes) { int col; *************** *** 2606,2612 **** } } } ! else if (linep[pos.col + 1]) /* forward search */ { if (linep[pos.col + 1] == '\\' && linep[pos.col + 2] && linep[pos.col + 3] == '\'') --- 2606,2612 ---- } } } ! else if (linep[pos.col + 1]) // forward search { if (linep[pos.col + 1] == '\\' && linep[pos.col + 2] && linep[pos.col + 3] == '\'') *************** *** 2621,2627 **** } } } ! /* FALLTHROUGH */ default: #ifdef FEAT_LISP --- 2621,2627 ---- } } } ! // FALLTHROUGH default: #ifdef FEAT_LISP *************** *** 2637,2644 **** break; #endif ! /* Check for match outside of quotes, and inside of ! * quotes when the start is also inside of quotes. */ if ((!inquote || start_in_quotes == TRUE) && (c == initc || c == findc)) { --- 2637,2644 ---- break; #endif ! // Check for match outside of quotes, and inside of ! // quotes when the start is also inside of quotes. if ((!inquote || start_in_quotes == TRUE) && (c == initc || c == findc)) { *************** *** 2649,2656 **** for (col = pos.col; check_prevcol(linep, col, '\\', &col);) bslcnt++; } ! /* Only accept a match when 'M' is in 'cpo' or when escaping ! * is what we expect. */ if (cpo_bsl || (bslcnt & 1) == match_escaped) { if (c == initc) --- 2649,2656 ---- for (col = pos.col; check_prevcol(linep, col, '\\', &col);) bslcnt++; } ! // Only accept a match when 'M' is in 'cpo' or when escaping ! // is what we expect. if (cpo_bsl || (bslcnt & 1) == match_escaped) { if (c == initc) *************** *** 2671,2677 **** pos = match_pos; return &pos; } ! return (pos_T *)NULL; /* never found it */ } /* --- 2671,2677 ---- pos = match_pos; return &pos; } ! return (pos_T *)NULL; // never found it } /* *************** *** 2686,2716 **** p = line; #ifdef FEAT_LISP ! /* skip Lispish one-line comments */ if (curbuf->b_p_lisp) { ! if (vim_strchr(p, ';') != NULL) /* there may be comments */ { ! int in_str = FALSE; /* inside of string */ ! p = line; /* scan from start */ while ((p = vim_strpbrk(p, (char_u *)"\";")) != NULL) { if (*p == '"') { if (in_str) { ! if (*(p - 1) != '\\') /* skip escaped quote */ in_str = FALSE; } else if (p == line || ((p - line) >= 2 ! /* skip #\" form */ && *(p - 1) != '\\' && *(p - 2) != '#')) in_str = TRUE; } else if (!in_str && ((p - line) < 2 || (*(p - 1) != '\\' && *(p - 2) != '#'))) ! break; /* found! */ ++p; } } --- 2686,2716 ---- p = line; #ifdef FEAT_LISP ! // skip Lispish one-line comments if (curbuf->b_p_lisp) { ! if (vim_strchr(p, ';') != NULL) // there may be comments { ! int in_str = FALSE; // inside of string ! p = line; // scan from start while ((p = vim_strpbrk(p, (char_u *)"\";")) != NULL) { if (*p == '"') { if (in_str) { ! if (*(p - 1) != '\\') // skip escaped quote in_str = FALSE; } else if (p == line || ((p - line) >= 2 ! // skip #\" form && *(p - 1) != '\\' && *(p - 2) != '#')) in_str = TRUE; } else if (!in_str && ((p - line) < 2 || (*(p - 1) != '\\' && *(p - 2) != '#'))) ! break; // found! ++p; } } *************** *** 2721,2728 **** #endif while ((p = vim_strchr(p, '/')) != NULL) { ! /* accept a double /, unless it's preceded with * and followed by *, ! * because * / / * is an end and start of a C comment */ if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*')) break; ++p; --- 2721,2728 ---- #endif while ((p = vim_strchr(p, '/')) != NULL) { ! // accept a double /, unless it's preceded with * and followed by *, ! // because * / / * is an end and start of a C comment if (p[1] == '/' && (p == line || p[-1] != '*' || p[2] != '*')) break; ++p; *************** *** 2741,2747 **** */ void showmatch( ! int c) /* char to show match for */ { pos_T *lpos, save_cursor; pos_T mpos; --- 2741,2747 ---- */ void showmatch( ! int c) // char to show match for { pos_T *lpos, save_cursor; pos_T mpos; *************** *** 2759,2765 **** /* * Only show match for chars in the 'matchpairs' option. */ ! /* 'matchpairs' is "x:y,x:y" */ for (p = curbuf->b_p_mps; *p != NUL; ++p) { #ifdef FEAT_RIGHTLEFT --- 2759,2765 ---- /* * Only show match for chars in the 'matchpairs' option. */ ! // 'matchpairs' is "x:y,x:y" for (p = curbuf->b_p_mps; *p != NUL; ++p) { #ifdef FEAT_RIGHTLEFT *************** *** 2778,2784 **** return; } ! if ((lpos = findmatch(NULL, NUL)) == NULL) /* no match, so beep */ vim_beep(BO_MATCH); else if (lpos->lnum >= curwin->w_topline && lpos->lnum < curwin->w_botline) { --- 2778,2784 ---- return; } ! if ((lpos = findmatch(NULL, NUL)) == NULL) // no match, so beep vim_beep(BO_MATCH); else if (lpos->lnum >= curwin->w_topline && lpos->lnum < curwin->w_botline) { *************** *** 2787,2820 **** if (curwin->w_p_wrap || (vcol >= curwin->w_leftcol && vcol < curwin->w_leftcol + curwin->w_width)) { ! mpos = *lpos; /* save the pos, update_screen() may change it */ save_cursor = curwin->w_cursor; save_so = *so; save_siso = *siso; ! /* Handle "$" in 'cpo': If the ')' is typed on top of the "$", ! * stop displaying the "$". */ if (dollar_vcol >= 0 && dollar_vcol == curwin->w_virtcol) dollar_vcol = -1; ! ++curwin->w_virtcol; /* do display ')' just before "$" */ ! update_screen(VALID); /* show the new char first */ save_dollar_vcol = dollar_vcol; #ifdef CURSOR_SHAPE save_state = State; State = SHOWMATCH; ! ui_cursor_shape(); /* may show different cursor shape */ #endif ! curwin->w_cursor = mpos; /* move to matching char */ ! *so = 0; /* don't use 'scrolloff' here */ ! *siso = 0; /* don't use 'sidescrolloff' here */ showruler(FALSE); setcursor(); ! cursor_on(); /* make sure that the cursor is shown */ out_flush_cursor(TRUE, FALSE); ! /* Restore dollar_vcol(), because setcursor() may call curs_rows() ! * which resets it if the matching position is in a previous line ! * and has a higher column number. */ dollar_vcol = save_dollar_vcol; /* --- 2787,2820 ---- if (curwin->w_p_wrap || (vcol >= curwin->w_leftcol && vcol < curwin->w_leftcol + curwin->w_width)) { ! mpos = *lpos; // save the pos, update_screen() may change it save_cursor = curwin->w_cursor; save_so = *so; save_siso = *siso; ! // Handle "$" in 'cpo': If the ')' is typed on top of the "$", ! // stop displaying the "$". if (dollar_vcol >= 0 && dollar_vcol == curwin->w_virtcol) dollar_vcol = -1; ! ++curwin->w_virtcol; // do display ')' just before "$" ! update_screen(VALID); // show the new char first save_dollar_vcol = dollar_vcol; #ifdef CURSOR_SHAPE save_state = State; State = SHOWMATCH; ! ui_cursor_shape(); // may show different cursor shape #endif ! curwin->w_cursor = mpos; // move to matching char ! *so = 0; // don't use 'scrolloff' here ! *siso = 0; // don't use 'sidescrolloff' here showruler(FALSE); setcursor(); ! cursor_on(); // make sure that the cursor is shown out_flush_cursor(TRUE, FALSE); ! // Restore dollar_vcol(), because setcursor() may call curs_rows() ! // which resets it if the matching position is in a previous line ! // and has a higher column number. dollar_vcol = save_dollar_vcol; /* *************** *** 2825,2836 **** ui_delay(p_mat * 100L + 8, TRUE); else if (!char_avail()) ui_delay(p_mat * 100L + 9, FALSE); ! curwin->w_cursor = save_cursor; /* restore cursor position */ *so = save_so; *siso = save_siso; #ifdef CURSOR_SHAPE State = save_state; ! ui_cursor_shape(); /* may show different cursor shape */ #endif } } --- 2825,2836 ---- ui_delay(p_mat * 100L + 8, TRUE); else if (!char_avail()) ui_delay(p_mat * 100L + 9, FALSE); ! curwin->w_cursor = save_cursor; // restore cursor position *so = save_so; *siso = save_siso; #ifdef CURSOR_SHAPE State = save_state; ! ui_cursor_shape(); // may show different cursor shape #endif } } *************** *** 2850,2856 **** int c; int (*func)(pos_T *); int startlnum; ! int noskip = FALSE; /* do not skip blanks */ int cpo_J; int found_dot; --- 2850,2856 ---- int c; int (*func)(pos_T *); int startlnum; ! int noskip = FALSE; // do not skip blanks int cpo_J; int found_dot; *************** *** 2910,2920 **** decl(&pos); } ! /* remember the line where the search started */ startlnum = pos.lnum; cpo_J = vim_strchr(p_cpo, CPO_ENDOFSENT) != NULL; ! for (;;) /* find end of sentence */ { c = gchar_pos(&pos); if (c == NUL || (pos.col == 0 && startPS(pos.lnum, NUL, FALSE))) --- 2910,2920 ---- decl(&pos); } ! // remember the line where the search started startlnum = pos.lnum; cpo_J = vim_strchr(p_cpo, CPO_ENDOFSENT) != NULL; ! for (;;) // find end of sentence { c = gchar_pos(&pos); if (c == NUL || (pos.col == 0 && startPS(pos.lnum, NUL, FALSE))) *************** *** 2936,2942 **** && gchar_pos(&tpos) == ' '))) { pos = tpos; ! if (gchar_pos(&pos) == NUL) /* skip NUL at EOL */ inc(&pos); break; } --- 2936,2942 ---- && gchar_pos(&tpos) == ' '))) { pos = tpos; ! if (gchar_pos(&pos) == NUL) // skip NUL at EOL inc(&pos); break; } *************** *** 2950,2956 **** } } found: ! /* skip white space */ while (!noskip && ((c = gchar_pos(&pos)) == ' ' || c == '\t')) if (incl(&pos) == -1) break; --- 2950,2956 ---- } } found: ! // skip white space while (!noskip && ((c = gchar_pos(&pos)) == ' ' || c == '\t')) if (incl(&pos) == -1) break; *************** *** 2971,2991 **** */ int findpar( ! int *pincl, /* Return: TRUE if last char is to be included */ int dir, long count, int what, int both) { linenr_T curr; ! int did_skip; /* TRUE after separating lines have been skipped */ ! int first; /* TRUE on first line */ int posix = (vim_strchr(p_cpo, CPO_PARA) != NULL); #ifdef FEAT_FOLDING ! linenr_T fold_first; /* first line of a closed fold */ ! linenr_T fold_last; /* last line of a closed fold */ ! int fold_skipped; /* TRUE if a closed fold was skipped this ! iteration */ #endif curr = curwin->w_cursor.lnum; --- 2971,2991 ---- */ int findpar( ! int *pincl, // Return: TRUE if last char is to be included int dir, long count, int what, int both) { linenr_T curr; ! int did_skip; // TRUE after separating lines have been skipped ! int first; // TRUE on first line int posix = (vim_strchr(p_cpo, CPO_PARA) != NULL); #ifdef FEAT_FOLDING ! linenr_T fold_first; // first line of a closed fold ! linenr_T fold_last; // last line of a closed fold ! int fold_skipped; // TRUE if a closed fold was skipped this ! // iteration #endif curr = curwin->w_cursor.lnum; *************** *** 2999,3005 **** did_skip = TRUE; #ifdef FEAT_FOLDING ! /* skip folded lines */ fold_skipped = FALSE; if (first && hasFolding(curr, &fold_first, &fold_last)) { --- 2999,3005 ---- did_skip = TRUE; #ifdef FEAT_FOLDING ! // skip folded lines fold_skipped = FALSE; if (first && hasFolding(curr, &fold_first, &fold_last)) { *************** *** 3008,3016 **** } #endif ! /* POSIX has its own ideas of what a paragraph boundary is and it ! * doesn't match historical Vi: It also stops at a "{" in the ! * first column and at an empty line. */ if (!first && did_skip && (startPS(curr, what, both) || (posix && what == NUL && *ml_get(curr) == '{'))) break; --- 3008,3016 ---- } #endif ! // POSIX has its own ideas of what a paragraph boundary is and it ! // doesn't match historical Vi: It also stops at a "{" in the ! // first column and at an empty line. if (!first && did_skip && (startPS(curr, what, both) || (posix && what == NUL && *ml_get(curr) == '{'))) break; *************** *** 3029,3043 **** } } setpcmark(); ! if (both && *ml_get(curr) == '}') /* include line with '}' */ ++curr; curwin->w_cursor.lnum = curr; if (curr == curbuf->b_ml.ml_line_count && what != '}') { char_u *line = ml_get(curr); ! /* Put the cursor on the last character in the last line and make the ! * motion inclusive. */ if ((curwin->w_cursor.col = (colnr_T)STRLEN(line)) != 0) { --curwin->w_cursor.col; --- 3029,3043 ---- } } setpcmark(); ! if (both && *ml_get(curr) == '}') // include line with '}' ++curr; curwin->w_cursor.lnum = curr; if (curr == curbuf->b_ml.ml_line_count && what != '}') { char_u *line = ml_get(curr); ! // Put the cursor on the last character in the last line and make the ! // motion inclusive. if ((curwin->w_cursor.col = (colnr_T)STRLEN(line)) != 0) { --curwin->w_cursor.col; *************** *** 3061,3069 **** for (macro = opt; macro[0]; ++macro) { ! /* Accept two characters in the option being equal to two characters ! * in the line. A space in the option matches with a space in the ! * line or the line having ended. */ if ( (macro[0] == s[0] || (macro[0] == ' ' && (s[0] == NUL || s[0] == ' '))) --- 3061,3069 ---- for (macro = opt; macro[0]; ++macro) { ! // Accept two characters in the option being equal to two characters ! // in the line. A space in the option matches with a space in the ! // line or the line having ended. if ( (macro[0] == s[0] || (macro[0] == ' ' && (s[0] == NUL || s[0] == ' '))) *************** *** 3113,3119 **** * 2 or higher - keyword characters (letters, digits and underscore) */ ! static int cls_bigword; /* TRUE for "W", "B" or "E" */ /* * cls() - returns the class of character at curwin->w_cursor --- 3113,3119 ---- * 2 or higher - keyword characters (letters, digits and underscore) */ ! static int cls_bigword; // TRUE for "W", "B" or "E" /* * cls() - returns the class of character at curwin->w_cursor *************** *** 3132,3142 **** return 0; if (enc_dbcs != 0 && c > 0xFF) { ! /* If cls_bigword, report multi-byte chars as class 1. */ if (enc_dbcs == DBCS_KOR && cls_bigword) return 1; ! /* process code leading/trailing bytes */ return dbcs_class(((unsigned)c >> 8), (c & 0xFF)); } if (enc_utf8) --- 3132,3142 ---- return 0; if (enc_dbcs != 0 && c > 0xFF) { ! // If cls_bigword, report multi-byte chars as class 1. if (enc_dbcs == DBCS_KOR && cls_bigword) return 1; ! // process code leading/trailing bytes return dbcs_class(((unsigned)c >> 8), (c & 0xFF)); } if (enc_utf8) *************** *** 3147,3153 **** return c; } ! /* If cls_bigword is TRUE, report all non-blanks as class 1. */ if (cls_bigword) return 1; --- 3147,3153 ---- return c; } ! // If cls_bigword is TRUE, report all non-blanks as class 1. if (cls_bigword) return 1; *************** *** 3166,3175 **** int fwd_word( long count, ! int bigword, /* "W", "E" or "B" */ int eol) { ! int sclass; /* starting class */ int i; int last_line; --- 3166,3175 ---- int fwd_word( long count, ! int bigword, // "W", "E" or "B" int eol) { ! int sclass; // starting class int i; int last_line; *************** *** 3178,3185 **** while (--count >= 0) { #ifdef FEAT_FOLDING ! /* When inside a range of folded lines, move to the last char of the ! * last line. */ if (hasFolding(curwin->w_cursor.lnum, NULL, &curwin->w_cursor.lnum)) coladvance((colnr_T)MAXCOL); #endif --- 3178,3185 ---- while (--count >= 0) { #ifdef FEAT_FOLDING ! // When inside a range of folded lines, move to the last char of the ! // last line. if (hasFolding(curwin->w_cursor.lnum, NULL, &curwin->w_cursor.lnum)) coladvance((colnr_T)MAXCOL); #endif *************** *** 3191,3199 **** */ last_line = (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count); i = inc_cursor(); ! if (i == -1 || (i >= 1 && last_line)) /* started at last char in file */ return FAIL; ! if (i >= 1 && eol && count == 0) /* started at last char in line */ return OK; /* --- 3191,3199 ---- */ last_line = (curwin->w_cursor.lnum == curbuf->b_ml.ml_line_count); i = inc_cursor(); ! if (i == -1 || (i >= 1 && last_line)) // started at last char in file return FAIL; ! if (i >= 1 && eol && count == 0) // started at last char in line return OK; /* *************** *** 3236,3255 **** int bck_word(long count, int bigword, int stop) { ! int sclass; /* starting class */ curwin->w_cursor.coladd = 0; cls_bigword = bigword; while (--count >= 0) { #ifdef FEAT_FOLDING ! /* When inside a range of folded lines, move to the first char of the ! * first line. */ if (hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL)) curwin->w_cursor.col = 0; #endif sclass = cls(); ! if (dec_cursor() == -1) /* started at start of file */ return FAIL; if (!stop || sclass == cls() || sclass == 0) --- 3236,3255 ---- int bck_word(long count, int bigword, int stop) { ! int sclass; // starting class curwin->w_cursor.coladd = 0; cls_bigword = bigword; while (--count >= 0) { #ifdef FEAT_FOLDING ! // When inside a range of folded lines, move to the first char of the ! // first line. if (hasFolding(curwin->w_cursor.lnum, &curwin->w_cursor.lnum, NULL)) curwin->w_cursor.col = 0; #endif sclass = cls(); ! if (dec_cursor() == -1) // started at start of file return FAIL; if (!stop || sclass == cls() || sclass == 0) *************** *** 3263,3269 **** if (curwin->w_cursor.col == 0 && LINEEMPTY(curwin->w_cursor.lnum)) goto finished; ! if (dec_cursor() == -1) /* hit start of file, stop here */ return OK; } --- 3263,3269 ---- if (curwin->w_cursor.col == 0 && LINEEMPTY(curwin->w_cursor.lnum)) goto finished; ! if (dec_cursor() == -1) // hit start of file, stop here return OK; } *************** *** 3274,3280 **** return OK; } ! inc_cursor(); /* overshot - forward one */ finished: stop = FALSE; } --- 3274,3280 ---- return OK; } ! inc_cursor(); // overshot - forward one finished: stop = FALSE; } *************** *** 3303,3317 **** int stop, int empty) { ! int sclass; /* starting class */ curwin->w_cursor.coladd = 0; cls_bigword = bigword; while (--count >= 0) { #ifdef FEAT_FOLDING ! /* When inside a range of folded lines, move to the last char of the ! * last line. */ if (hasFolding(curwin->w_cursor.lnum, NULL, &curwin->w_cursor.lnum)) coladvance((colnr_T)MAXCOL); #endif --- 3303,3317 ---- int stop, int empty) { ! int sclass; // starting class curwin->w_cursor.coladd = 0; cls_bigword = bigword; while (--count >= 0) { #ifdef FEAT_FOLDING ! // When inside a range of folded lines, move to the last char of the ! // last line. if (hasFolding(curwin->w_cursor.lnum, NULL, &curwin->w_cursor.lnum)) coladvance((colnr_T)MAXCOL); #endif *************** *** 3342,3348 **** if (empty && curwin->w_cursor.col == 0 && LINEEMPTY(curwin->w_cursor.lnum)) goto finished; ! if (inc_cursor() == -1) /* hit end of file, stop here */ return FAIL; } --- 3342,3348 ---- if (empty && curwin->w_cursor.col == 0 && LINEEMPTY(curwin->w_cursor.lnum)) goto finished; ! if (inc_cursor() == -1) // hit end of file, stop here return FAIL; } *************** *** 3352,3360 **** if (skip_chars(cls(), FORWARD)) return FAIL; } ! dec_cursor(); /* overshot - one char backward */ finished: ! stop = FALSE; /* we move only one word less */ } return OK; } --- 3352,3360 ---- if (skip_chars(cls(), FORWARD)) return FAIL; } ! dec_cursor(); // overshot - one char backward finished: ! stop = FALSE; // we move only one word less } return OK; } *************** *** 3367,3376 **** int bckend_word( long count, ! int bigword, /* TRUE for "B" */ ! int eol) /* TRUE: stop at end of line. */ { ! int sclass; /* starting class */ int i; curwin->w_cursor.coladd = 0; --- 3367,3376 ---- int bckend_word( long count, ! int bigword, // TRUE for "B" ! int eol) // TRUE: stop at end of line. { ! int sclass; // starting class int i; curwin->w_cursor.coladd = 0; *************** *** 3427,3441 **** static void back_in_line(void) { ! int sclass; /* starting class */ sclass = cls(); for (;;) { ! if (curwin->w_cursor.col == 0) /* stop at start of line */ break; dec_cursor(); ! if (cls() != sclass) /* stop at start of word */ { inc_cursor(); break; --- 3427,3441 ---- static void back_in_line(void) { ! int sclass; // starting class sclass = cls(); for (;;) { ! if (curwin->w_cursor.col == 0) // stop at start of line break; dec_cursor(); ! if (cls() != sclass) // stop at start of word { inc_cursor(); break; *************** *** 3465,3471 **** static void findsent_forward( long count, ! int at_start_sent) /* cursor is at start of sentence */ { while (count--) { --- 3465,3471 ---- static void findsent_forward( long count, ! int at_start_sent) // cursor is at start of sentence { while (count--) { *************** *** 3486,3493 **** current_word( oparg_T *oap, long count, ! int include, /* TRUE: include word and white space */ ! int bigword) /* FALSE == word, TRUE == WORD */ { pos_T start_pos; pos_T pos; --- 3486,3493 ---- current_word( oparg_T *oap, long count, ! int include, // TRUE: include word and white space ! int bigword) // FALSE == word, TRUE == WORD { pos_T start_pos; pos_T pos; *************** *** 3497,3503 **** cls_bigword = bigword; CLEAR_POS(&start_pos); ! /* Correct cursor when 'selection' is exclusive */ if (VIsual_active && *p_sel == 'e' && LT_POS(VIsual, curwin->w_cursor)) dec_cursor(); --- 3497,3503 ---- cls_bigword = bigword; CLEAR_POS(&start_pos); ! // Correct cursor when 'selection' is exclusive if (VIsual_active && *p_sel == 'e' && LT_POS(VIsual, curwin->w_cursor)) dec_cursor(); *************** *** 3544,3552 **** if (VIsual_active) { ! /* should do something when inclusive == FALSE ! */ VIsual = start_pos; ! redraw_curbuf_later(INVERTED); /* update the inversion */ } else { --- 3544,3552 ---- if (VIsual_active) { ! // should do something when inclusive == FALSE ! VIsual = start_pos; ! redraw_curbuf_later(INVERTED); // update the inversion } else { *************** *** 3620,3626 **** * (cursor is at start of next line). * But don't delete white space at start of line (indent). */ ! pos = curwin->w_cursor; /* save cursor position */ curwin->w_cursor = start_pos; if (oneleft() == OK) { --- 3620,3626 ---- * (cursor is at start of next line). * But don't delete white space at start of line (indent). */ ! pos = curwin->w_cursor; // save cursor position curwin->w_cursor = start_pos; if (oneleft() == OK) { *************** *** 3633,3639 **** oap->start = curwin->w_cursor; } } ! curwin->w_cursor = pos; /* put cursor back at end */ } if (VIsual_active) --- 3633,3639 ---- oap->start = curwin->w_cursor; } } ! curwin->w_cursor = pos; // put cursor back at end } if (VIsual_active) *************** *** 3643,3649 **** if (VIsual_mode == 'V') { VIsual_mode = 'v'; ! redraw_cmdline = TRUE; /* show mode later */ } } else --- 3643,3649 ---- if (VIsual_mode == 'V') { VIsual_mode = 'v'; ! redraw_cmdline = TRUE; // show mode later } } else *************** *** 3668,3674 **** start_pos = curwin->w_cursor; pos = start_pos; ! findsent(FORWARD, 1L); /* Find start of next sentence. */ /* * When the Visual area is bigger than one character: Extend it. --- 3668,3674 ---- start_pos = curwin->w_cursor; pos = start_pos; ! findsent(FORWARD, 1L); // Find start of next sentence. /* * When the Visual area is bigger than one character: Extend it. *************** *** 3701,3712 **** { findsent(BACKWARD, 1L); if (EQUAL_POS(curwin->w_cursor, start_pos)) ! at_start_sent = TRUE; /* exactly at start of sentence */ else ! /* inside a sentence, go to its end (start of next) */ findsent(FORWARD, 1L); } ! if (include) /* "as" gets twice as much as "is" */ count *= 2; while (count--) { --- 3701,3712 ---- { findsent(BACKWARD, 1L); if (EQUAL_POS(curwin->w_cursor, start_pos)) ! at_start_sent = TRUE; // exactly at start of sentence else ! // inside a sentence, go to its end (start of next) findsent(FORWARD, 1L); } ! if (include) // "as" gets twice as much as "is" count *= 2; while (count--) { *************** *** 3729,3735 **** */ incl(&pos); at_start_sent = TRUE; ! /* not just before a sentence */ if (!EQUAL_POS(pos, curwin->w_cursor)) { at_start_sent = FALSE; --- 3729,3735 ---- */ incl(&pos); at_start_sent = TRUE; ! // not just before a sentence if (!EQUAL_POS(pos, curwin->w_cursor)) { at_start_sent = FALSE; *************** *** 3743,3755 **** } incl(&pos); } ! if (at_start_sent) /* in the sentence */ findsent(BACKWARD, 1L); ! else /* in/before white before a sentence */ curwin->w_cursor = start_pos; } ! if (include) /* "as" gets twice as much as "is" */ count *= 2; findsent_forward(count, at_start_sent); if (*p_sel == 'e') --- 3743,3755 ---- } incl(&pos); } ! if (at_start_sent) // in the sentence findsent(BACKWARD, 1L); ! else // in/before white before a sentence curwin->w_cursor = start_pos; } ! if (include) // "as" gets twice as much as "is" count *= 2; findsent_forward(count, at_start_sent); if (*p_sel == 'e') *************** *** 3762,3773 **** * If the cursor started on a blank, check if it is just before the start * of the next sentence. */ ! while (c = gchar_pos(&pos), VIM_ISWHITE(c)) /* VIM_ISWHITE() is a macro */ incl(&pos); if (EQUAL_POS(pos, curwin->w_cursor)) { start_blank = TRUE; ! find_first_blank(&start_pos); /* go back to first blank */ } else { --- 3762,3773 ---- * If the cursor started on a blank, check if it is just before the start * of the next sentence. */ ! while (c = gchar_pos(&pos), VIM_ISWHITE(c)) // VIM_ISWHITE() is a macro incl(&pos); if (EQUAL_POS(pos, curwin->w_cursor)) { start_blank = TRUE; ! find_first_blank(&start_pos); // go back to first blank } else { *************** *** 3798,3804 **** if (start_blank) { find_first_blank(&curwin->w_cursor); ! c = gchar_pos(&curwin->w_cursor); /* VIM_ISWHITE() is a macro */ if (VIM_ISWHITE(c)) decl(&curwin->w_cursor); } --- 3798,3804 ---- if (start_blank) { find_first_blank(&curwin->w_cursor); ! c = gchar_pos(&curwin->w_cursor); // VIM_ISWHITE() is a macro if (VIM_ISWHITE(c)) decl(&curwin->w_cursor); } *************** *** 3808,3826 **** if (VIsual_active) { ! /* Avoid getting stuck with "is" on a single space before a sentence. */ if (EQUAL_POS(start_pos, curwin->w_cursor)) goto extend; if (*p_sel == 'e') ++curwin->w_cursor.col; VIsual = start_pos; VIsual_mode = 'v'; ! redraw_cmdline = TRUE; /* show mode later */ ! redraw_curbuf_later(INVERTED); /* update the inversion */ } else { ! /* include a newline after the sentence, if there is one */ if (incl(&curwin->w_cursor) == -1) oap->inclusive = TRUE; else --- 3808,3826 ---- if (VIsual_active) { ! // Avoid getting stuck with "is" on a single space before a sentence. if (EQUAL_POS(start_pos, curwin->w_cursor)) goto extend; if (*p_sel == 'e') ++curwin->w_cursor.col; VIsual = start_pos; VIsual_mode = 'v'; ! redraw_cmdline = TRUE; // show mode later ! redraw_curbuf_later(INVERTED); // update the inversion } else { ! // include a newline after the sentence, if there is one if (incl(&curwin->w_cursor) == -1) oap->inclusive = TRUE; else *************** *** 3839,3847 **** current_block( oparg_T *oap, long count, ! int include, /* TRUE == include white space */ ! int what, /* '(', '{', etc. */ ! int other) /* ')', '}', etc. */ { pos_T old_pos; pos_T *pos = NULL; --- 3839,3847 ---- current_block( oparg_T *oap, long count, ! int include, // TRUE == include white space ! int what, // '(', '{', etc. ! int other) // ')', '}', etc. { pos_T old_pos; pos_T *pos = NULL; *************** *** 3849,3858 **** pos_T *end_pos; pos_T old_start, old_end; char_u *save_cpo; ! int sol = FALSE; /* '{' at start of line */ old_pos = curwin->w_cursor; ! old_end = curwin->w_cursor; /* remember where we started */ old_start = old_end; /* --- 3849,3858 ---- pos_T *end_pos; pos_T old_start, old_end; char_u *save_cpo; ! int sol = FALSE; // '{' at start of line old_pos = curwin->w_cursor; ! old_end = curwin->w_cursor; // remember where we started old_start = old_end; /* *************** *** 3861,3878 **** if (!VIsual_active || EQUAL_POS(VIsual, curwin->w_cursor)) { setpcmark(); ! if (what == '{') /* ignore indent */ while (inindent(1)) if (inc_cursor() != 0) break; if (gchar_cursor() == what) ! /* cursor on '(' or '{', move cursor just after it */ ++curwin->w_cursor.col; } else if (LT_POS(VIsual, curwin->w_cursor)) { old_start = VIsual; ! curwin->w_cursor = VIsual; /* cursor at low end of Visual */ } else old_end = VIsual; --- 3861,3878 ---- if (!VIsual_active || EQUAL_POS(VIsual, curwin->w_cursor)) { setpcmark(); ! if (what == '{') // ignore indent while (inindent(1)) if (inc_cursor() != 0) break; if (gchar_cursor() == what) ! // cursor on '(' or '{', move cursor just after it ++curwin->w_cursor.col; } else if (LT_POS(VIsual, curwin->w_cursor)) { old_start = VIsual; ! curwin->w_cursor = VIsual; // cursor at low end of Visual } else old_end = VIsual; *************** *** 3890,3896 **** if ((pos = findmatch(NULL, what)) == NULL) break; curwin->w_cursor = *pos; ! start_pos = *pos; /* the findmatch for end_pos will overwrite *pos */ } p_cpo = save_cpo; --- 3890,3896 ---- if ((pos = findmatch(NULL, what)) == NULL) break; curwin->w_cursor = *pos; ! start_pos = *pos; // the findmatch for end_pos will overwrite *pos } p_cpo = save_cpo; *************** *** 3955,3964 **** if (*p_sel == 'e') inc(&curwin->w_cursor); if (sol && gchar_cursor() != NUL) ! inc(&curwin->w_cursor); /* include the line break */ VIsual = start_pos; VIsual_mode = 'v'; ! redraw_curbuf_later(INVERTED); /* update the inversion */ showmode(); } else --- 3955,3964 ---- if (*p_sel == 'e') inc(&curwin->w_cursor); if (sol && gchar_cursor() != NUL) ! inc(&curwin->w_cursor); // include the line break VIsual = start_pos; VIsual_mode = 'v'; ! redraw_curbuf_later(INVERTED); // update the inversion showmode(); } else *************** *** 3969,3979 **** if (sol) incl(&curwin->w_cursor); else if (LTOREQ_POS(start_pos, curwin->w_cursor)) ! /* Include the character under the cursor. */ oap->inclusive = TRUE; else ! /* End is before the start (no text in between <>, [], etc.): don't ! * operate on any text. */ curwin->w_cursor = start_pos; } --- 3969,3979 ---- if (sol) incl(&curwin->w_cursor); else if (LTOREQ_POS(start_pos, curwin->w_cursor)) ! // Include the character under the cursor. oap->inclusive = TRUE; else ! // End is before the start (no text in between <>, [], etc.): don't ! // operate on any text. curwin->w_cursor = start_pos; } *************** *** 3998,4012 **** { char_u *lp = NULL; ! /* We search forward until the cursor, because searching backwards is ! * very slow for DBCS encodings. */ for (p = line; p < line + curwin->w_cursor.col; MB_PTR_ADV(p)) if (*p == '>' || *p == '<') { lc = *p; lp = p; } ! if (*p != '<') /* check for '<' under cursor */ { if (lc != '<') return FALSE; --- 3998,4012 ---- { char_u *lp = NULL; ! // We search forward until the cursor, because searching backwards is ! // very slow for DBCS encodings. for (p = line; p < line + curwin->w_cursor.col; MB_PTR_ADV(p)) if (*p == '>' || *p == '<') { lc = *p; lp = p; } ! if (*p != '<') // check for '<' under cursor { if (lc != '<') return FALSE; *************** *** 4017,4026 **** { for (p = line + curwin->w_cursor.col; p > line; ) { ! if (*p == '<') /* find '<' under/before cursor */ break; MB_PTR_BACK(line, p); ! if (*p == '>') /* find '>' before cursor */ break; } if (*p != '<') --- 4017,4026 ---- { for (p = line + curwin->w_cursor.col; p > line; ) { ! if (*p == '<') // find '<' under/before cursor break; MB_PTR_BACK(line, p); ! if (*p == '>') // find '>' before cursor break; } if (*p != '<') *************** *** 4032,4045 **** MB_PTR_ADV(p); if (end_tag) ! /* check that there is a '/' after the '<' */ return *p == '/'; ! /* check that there is no '/' after the '<' */ if (*p == '/') return FALSE; ! /* check that the matching '>' is not preceded by '/' */ for (;;) { if (inc(&pos) < 0) --- 4032,4045 ---- MB_PTR_ADV(p); if (end_tag) ! // check that there is a '/' after the '<' return *p == '/'; ! // check that there is no '/' after the '<' if (*p == '/') return FALSE; ! // check that the matching '>' is not preceded by '/' for (;;) { if (inc(&pos) < 0) *************** *** 4059,4065 **** current_tagblock( oparg_T *oap, long count_arg, ! int include) /* TRUE == include white space */ { long count = count_arg; long n; --- 4059,4065 ---- current_tagblock( oparg_T *oap, long count_arg, ! int include) // TRUE == include white space { long count = count_arg; long n; *************** *** 4080,4089 **** p_ws = FALSE; old_pos = curwin->w_cursor; ! old_end = curwin->w_cursor; /* remember where we started */ old_start = old_end; if (!VIsual_active || *p_sel == 'e') ! decl(&old_end); /* old_end is inclusive */ /* * If we start on "" select that block. --- 4080,4089 ---- p_ws = FALSE; old_pos = curwin->w_cursor; ! old_end = curwin->w_cursor; // remember where we started old_start = old_end; if (!VIsual_active || *p_sel == 'e') ! decl(&old_end); // old_end is inclusive /* * If we start on "" select that block. *************** *** 4092,4112 **** { setpcmark(); ! /* ignore indent */ while (inindent(1)) if (inc_cursor() != 0) break; if (in_html_tag(FALSE)) { ! /* cursor on start tag, move to its '>' */ while (*ml_get_cursor() != '>') if (inc_cursor() < 0) break; } else if (in_html_tag(TRUE)) { ! /* cursor on end tag, move to just before it */ while (*ml_get_cursor() != '<') if (dec_cursor() < 0) break; --- 4092,4112 ---- { setpcmark(); ! // ignore indent while (inindent(1)) if (inc_cursor() != 0) break; if (in_html_tag(FALSE)) { ! // cursor on start tag, move to its '>' while (*ml_get_cursor() != '>') if (inc_cursor() < 0) break; } else if (in_html_tag(TRUE)) { ! // cursor on end tag, move to just before it while (*ml_get_cursor() != '<') if (dec_cursor() < 0) break; *************** *** 4117,4123 **** else if (LT_POS(VIsual, curwin->w_cursor)) { old_start = VIsual; ! curwin->w_cursor = VIsual; /* cursor at low end of Visual */ } else old_end = VIsual; --- 4117,4123 ---- else if (LT_POS(VIsual, curwin->w_cursor)) { old_start = VIsual; ! curwin->w_cursor = VIsual; // cursor at low end of Visual } else old_end = VIsual; *************** *** 4173,4181 **** if (r < 1 || LT_POS(curwin->w_cursor, old_end)) { ! /* Can't find other end or it's before the previous end. Could be a ! * HTML tag that doesn't have a matching end. Search backwards for ! * another starting tag. */ count = 1; curwin->w_cursor = start_pos; goto again; --- 4173,4181 ---- if (r < 1 || LT_POS(curwin->w_cursor, old_end)) { ! // Can't find other end or it's before the previous end. Could be a ! // HTML tag that doesn't have a matching end. Search backwards for ! // another starting tag. count = 1; curwin->w_cursor = start_pos; goto again; *************** *** 4183,4189 **** if (do_include) { ! /* Include up to the '>'. */ while (*ml_get_cursor() != '>') if (inc_cursor() < 0) break; --- 4183,4189 ---- if (do_include) { ! // Include up to the '>'. while (*ml_get_cursor() != '>') if (inc_cursor() < 0) break; *************** *** 4192,4202 **** { char_u *c = ml_get_cursor(); ! /* Exclude the '<' of the end tag. ! * If the closing tag is on new line, do not decrement cursor, but ! * make operation exclusive, so that the linefeed will be selected */ if (*c == '<' && !VIsual_active && curwin->w_cursor.col == 0) ! /* do not decrement cursor */ is_inclusive = FALSE; else if (*c == '<') dec_cursor(); --- 4192,4202 ---- { char_u *c = ml_get_cursor(); ! // Exclude the '<' of the end tag. ! // If the closing tag is on new line, do not decrement cursor, but ! // make operation exclusive, so that the linefeed will be selected if (*c == '<' && !VIsual_active && curwin->w_cursor.col == 0) ! // do not decrement cursor is_inclusive = FALSE; else if (*c == '<') dec_cursor(); *************** *** 4205,4211 **** if (!do_include) { ! /* Exclude the start tag. */ curwin->w_cursor = start_pos; while (inc_cursor() >= 0) if (*ml_get_cursor() == '>') --- 4205,4211 ---- if (!do_include) { ! // Exclude the start tag. curwin->w_cursor = start_pos; while (inc_cursor() >= 0) if (*ml_get_cursor() == '>') *************** *** 4230,4244 **** if (VIsual_active) { ! /* If the end is before the start there is no text between tags, select ! * the char under the cursor. */ if (LT_POS(end_pos, start_pos)) curwin->w_cursor = start_pos; else if (*p_sel == 'e') inc_cursor(); VIsual = start_pos; VIsual_mode = 'v'; ! redraw_curbuf_later(INVERTED); /* update the inversion */ showmode(); } else --- 4230,4244 ---- if (VIsual_active) { ! // If the end is before the start there is no text between tags, select ! // the char under the cursor. if (LT_POS(end_pos, start_pos)) curwin->w_cursor = start_pos; else if (*p_sel == 'e') inc_cursor(); VIsual = start_pos; VIsual_mode = 'v'; ! redraw_curbuf_later(INVERTED); // update the inversion showmode(); } else *************** *** 4247,4254 **** oap->motion_type = MCHAR; if (LT_POS(end_pos, start_pos)) { ! /* End is before the start: there is no text between tags; operate ! * on an empty area. */ curwin->w_cursor = start_pos; oap->inclusive = FALSE; } --- 4247,4254 ---- oap->motion_type = MCHAR; if (LT_POS(end_pos, start_pos)) { ! // End is before the start: there is no text between tags; operate ! // on an empty area. curwin->w_cursor = start_pos; oap->inclusive = FALSE; } *************** *** 4266,4273 **** current_par( oparg_T *oap, long count, ! int include, /* TRUE == include white space */ ! int type) /* 'p' for paragraph, 'S' for section */ { linenr_T start_lnum; linenr_T end_lnum; --- 4266,4273 ---- current_par( oparg_T *oap, long count, ! int include, // TRUE == include white space ! int type) // 'p' for paragraph, 'S' for section { linenr_T start_lnum; linenr_T end_lnum; *************** *** 4280,4286 **** int t; int i; ! if (type == 'S') /* not implemented yet */ return FAIL; start_lnum = curwin->w_cursor.lnum; --- 4280,4286 ---- int t; int i; ! if (type == 'S') // not implemented yet return FAIL; start_lnum = curwin->w_cursor.lnum; *************** *** 4345,4356 **** white_in_front = linewhite(start_lnum); while (start_lnum > 1) { ! if (white_in_front) /* stop at first white line */ { if (!linewhite(start_lnum - 1)) break; } ! else /* stop at first non-white line of start of paragraph */ { if (linewhite(start_lnum - 1) || startPS(start_lnum, 0, 0)) break; --- 4345,4356 ---- white_in_front = linewhite(start_lnum); while (start_lnum > 1) { ! if (white_in_front) // stop at first white line { if (!linewhite(start_lnum - 1)) break; } ! else // stop at first non-white line of start of paragraph { if (linewhite(start_lnum - 1) || startPS(start_lnum, 0, 0)) break; *************** *** 4411,4418 **** if (VIsual_active) { ! /* Problem: when doing "Vipipip" nothing happens in a single white ! * line, we get stuck there. Trap this here. */ if (VIsual_mode == 'V' && start_lnum == curwin->w_cursor.lnum) goto extend; if (VIsual.lnum != start_lnum) --- 4411,4418 ---- if (VIsual_active) { ! // Problem: when doing "Vipipip" nothing happens in a single white ! // line, we get stuck there. Trap this here. if (VIsual_mode == 'V' && start_lnum == curwin->w_cursor.lnum) goto extend; if (VIsual.lnum != start_lnum) *************** *** 4421,4427 **** VIsual.col = 0; } VIsual_mode = 'V'; ! redraw_curbuf_later(INVERTED); /* update the inversion */ showmode(); } else --- 4421,4427 ---- VIsual.col = 0; } VIsual_mode = 'V'; ! redraw_curbuf_later(INVERTED); // update the inversion showmode(); } else *************** *** 4447,4453 **** char_u *line, int col, int quotechar, ! char_u *escape) /* escape characters, can be NULL */ { int c; --- 4447,4453 ---- char_u *line, int col, int quotechar, ! char_u *escape) // escape characters, can be NULL { int c; *************** *** 4479,4485 **** char_u *line, int col_start, int quotechar, ! char_u *escape) /* escape characters, can be NULL */ { int n; --- 4479,4485 ---- char_u *line, int col_start, int quotechar, ! char_u *escape) // escape characters, can be NULL { int n; *************** *** 4493,4499 **** line[col_start - n - 1]) != NULL) ++n; if (n & 1) ! col_start -= n; /* uneven number of escape chars, skip it */ else if (line[col_start] == quotechar) break; } --- 4493,4499 ---- line[col_start - n - 1]) != NULL) ++n; if (n & 1) ! col_start -= n; // uneven number of escape chars, skip it else if (line[col_start] == quotechar) break; } *************** *** 4528,4534 **** // The cursor then is moved forward after adjusting the area. if (VIsual_active) { ! /* this only works within one line */ if (VIsual.lnum != curwin->w_cursor.lnum) return FALSE; --- 4528,4534 ---- // The cursor then is moved forward after adjusting the area. if (VIsual_active) { ! // this only works within one line if (VIsual.lnum != curwin->w_cursor.lnum) return FALSE; *************** *** 4562,4569 **** if (!vis_empty) { ! /* Check if the existing selection exactly spans the text inside ! * quotes. */ if (vis_bef_curs) { inside_quotes = VIsual.col > 0 --- 4562,4569 ---- if (!vis_empty) { ! // Check if the existing selection exactly spans the text inside ! // quotes. if (vis_bef_curs) { inside_quotes = VIsual.col > 0 *************** *** 4583,4589 **** col_end = VIsual.col; } ! /* Find out if we have a quote in the selection. */ while (i <= col_end) if (line[i++] == quotechar) { --- 4583,4589 ---- col_end = VIsual.col; } ! // Find out if we have a quote in the selection. while (i <= col_end) if (line[i++] == quotechar) { *************** *** 4594,4605 **** if (!vis_empty && line[col_start] == quotechar) { ! /* Already selecting something and on a quote character. Find the ! * next quoted string. */ if (vis_bef_curs) { ! /* Assume we are on a closing quote: move to after the next ! * opening quote. */ col_start = find_next_quote(line, col_start + 1, quotechar, NULL); if (col_start < 0) goto abort_search; --- 4594,4605 ---- if (!vis_empty && line[col_start] == quotechar) { ! // Already selecting something and on a quote character. Find the ! // next quoted string. if (vis_bef_curs) { ! // Assume we are on a closing quote: move to after the next ! // opening quote. col_start = find_next_quote(line, col_start + 1, quotechar, NULL); if (col_start < 0) goto abort_search; *************** *** 4607,4613 **** curbuf->b_p_qe); if (col_end < 0) { ! /* We were on a starting quote perhaps? */ col_end = col_start; col_start = curwin->w_cursor.col; } --- 4607,4613 ---- curbuf->b_p_qe); if (col_end < 0) { ! // We were on a starting quote perhaps? col_end = col_start; col_start = curwin->w_cursor.col; } *************** *** 4621,4627 **** curbuf->b_p_qe); if (line[col_start] != quotechar) { ! /* We were on an ending quote perhaps? */ col_start = col_end; col_end = curwin->w_cursor.col; } --- 4621,4627 ---- curbuf->b_p_qe); if (line[col_start] != quotechar) { ! // We were on an ending quote perhaps? col_start = col_end; col_end = curwin->w_cursor.col; } *************** *** 4641,4664 **** first_col = find_prev_quote(line, col_start, quotechar, NULL); } ! /* The cursor is on a quote, we don't know if it's the opening or ! * closing quote. Search from the start of the line to find out. ! * Also do this when there is a Visual area, a' may leave the cursor ! * in between two strings. */ col_start = 0; for (;;) { ! /* Find open quote character. */ col_start = find_next_quote(line, col_start, quotechar, NULL); if (col_start < 0 || col_start > first_col) goto abort_search; ! /* Find close quote character. */ col_end = find_next_quote(line, col_start + 1, quotechar, curbuf->b_p_qe); if (col_end < 0) goto abort_search; ! /* If is cursor between start and end quote character, it is ! * target text object. */ if (col_start <= first_col && first_col <= col_end) break; col_start = col_end + 1; --- 4641,4664 ---- first_col = find_prev_quote(line, col_start, quotechar, NULL); } ! // The cursor is on a quote, we don't know if it's the opening or ! // closing quote. Search from the start of the line to find out. ! // Also do this when there is a Visual area, a' may leave the cursor ! // in between two strings. col_start = 0; for (;;) { ! // Find open quote character. col_start = find_next_quote(line, col_start, quotechar, NULL); if (col_start < 0 || col_start > first_col) goto abort_search; ! // Find close quote character. col_end = find_next_quote(line, col_start + 1, quotechar, curbuf->b_p_qe); if (col_end < 0) goto abort_search; ! // If is cursor between start and end quote character, it is ! // target text object. if (col_start <= first_col && first_col <= col_end) break; col_start = col_end + 1; *************** *** 4666,4690 **** } else { ! /* Search backward for a starting quote. */ col_start = find_prev_quote(line, col_start, quotechar, curbuf->b_p_qe); if (line[col_start] != quotechar) { ! /* No quote before the cursor, look after the cursor. */ col_start = find_next_quote(line, col_start, quotechar, NULL); if (col_start < 0) goto abort_search; } ! /* Find close quote character. */ col_end = find_next_quote(line, col_start + 1, quotechar, curbuf->b_p_qe); if (col_end < 0) goto abort_search; } ! /* When "include" is TRUE, include spaces after closing quote or before ! * the starting quote. */ if (include) { if (VIM_ISWHITE(line[col_end + 1])) --- 4666,4690 ---- } else { ! // Search backward for a starting quote. col_start = find_prev_quote(line, col_start, quotechar, curbuf->b_p_qe); if (line[col_start] != quotechar) { ! // No quote before the cursor, look after the cursor. col_start = find_next_quote(line, col_start, quotechar, NULL); if (col_start < 0) goto abort_search; } ! // Find close quote character. col_end = find_next_quote(line, col_start + 1, quotechar, curbuf->b_p_qe); if (col_end < 0) goto abort_search; } ! // When "include" is TRUE, include spaces after closing quote or before ! // the starting quote. if (include) { if (VIM_ISWHITE(line[col_end + 1])) *************** *** 4695,4711 **** --col_start; } ! /* Set start position. After vi" another i" must include the ". ! * For v2i" include the quotes. */ if (!include && count < 2 && (vis_empty || !inside_quotes)) ++col_start; curwin->w_cursor.col = col_start; if (VIsual_active) { ! /* Set the start of the Visual area when the Visual area was empty, we ! * were just inside quotes or the Visual area didn't start at a quote ! * and didn't include a quote. ! */ if (vis_empty || (vis_bef_curs && !selected_quote --- 4695,4710 ---- --col_start; } ! // Set start position. After vi" another i" must include the ". ! // For v2i" include the quotes. if (!include && count < 2 && (vis_empty || !inside_quotes)) ++col_start; curwin->w_cursor.col = col_start; if (VIsual_active) { ! // Set the start of the Visual area when the Visual area was empty, we ! // were just inside quotes or the Visual area didn't start at a quote ! // and didn't include a quote. if (vis_empty || (vis_bef_curs && !selected_quote *************** *** 4724,4732 **** oap->motion_type = MCHAR; } ! /* Set end position. */ curwin->w_cursor.col = col_end; ! if ((include || count > 1 /* After vi" another i" must include the ". */ || (!vis_empty && inside_quotes) ) && inc_cursor() == 2) inclusive = TRUE; --- 4723,4731 ---- oap->motion_type = MCHAR; } ! // Set end position. curwin->w_cursor.col = col_end; ! if ((include || count > 1 // After vi" another i" must include the ". || (!vis_empty && inside_quotes) ) && inc_cursor() == 2) inclusive = TRUE; *************** *** 4740,4748 **** } else { ! /* Cursor is at start of Visual area. Set the end of the Visual ! * area when it was just inside quotes or it didn't end at a ! * quote. */ if (inside_quotes || (!selected_quote && line[VIsual.col] != quotechar --- 4739,4747 ---- } else { ! // Cursor is at start of Visual area. Set the end of the Visual ! // area when it was just inside quotes or it didn't end at a ! // quote. if (inside_quotes || (!selected_quote && line[VIsual.col] != quotechar *************** *** 4757,4768 **** if (VIsual_mode == 'V') { VIsual_mode = 'v'; ! redraw_cmdline = TRUE; /* show mode later */ } } else { ! /* Set inclusive and other oap's flags. */ oap->inclusive = inclusive; } --- 4756,4767 ---- if (VIsual_mode == 'V') { VIsual_mode = 'v'; ! redraw_cmdline = TRUE; // show mode later } } else { ! // Set inclusive and other oap's flags. oap->inclusive = inclusive; } *************** *** 4784,4790 **** return FALSE; } ! #endif /* FEAT_TEXTOBJ */ /* * Check if the pattern is zero-width. --- 4783,4789 ---- return FALSE; } ! #endif // FEAT_TEXTOBJ /* * Check if the pattern is zero-width. *************** *** 4875,4881 **** pos_T save_VIsual = VIsual; int zero_width; ! /* Correct cursor when 'selection' is exclusive */ if (VIsual_active && *p_sel == 'e' && LT_POS(VIsual, curwin->w_cursor)) dec_cursor(); --- 4874,4880 ---- pos_T save_VIsual = VIsual; int zero_width; ! // Correct cursor when 'selection' is exclusive if (VIsual_active && *p_sel == 'e' && LT_POS(VIsual, curwin->w_cursor)) dec_cursor(); *************** *** 4888,4899 **** decl(&pos); } ! /* Is the pattern is zero-width?, this time, don't care about the direction ! */ zero_width = is_zero_width(spats[last_idx].pat, TRUE, &curwin->w_cursor, FORWARD); if (zero_width == -1) ! return FAIL; /* pattern not found */ /* * The trick is to first search backwards and then search forward again, --- 4887,4897 ---- decl(&pos); } ! // Is the pattern is zero-width?, this time, don't care about the direction zero_width = is_zero_width(spats[last_idx].pat, TRUE, &curwin->w_cursor, FORWARD); if (zero_width == -1) ! return FAIL; // pattern not found /* * The trick is to first search backwards and then search forward again, *************** *** 4923,4933 **** p_ws = old_p_ws; ! /* First search may fail, but then start searching from the ! * beginning of the file (cursor might be on the search match) ! * except when Visual mode is active, so that extending the visual ! * selection works. */ ! if (i == 1 && !result) /* not found, abort */ { curwin->w_cursor = orig_pos; if (VIsual_active) --- 4921,4931 ---- p_ws = old_p_ws; ! // First search may fail, but then start searching from the ! // beginning of the file (cursor might be on the search match) ! // except when Visual mode is active, so that extending the visual ! // selection works. ! if (i == 1 && !result) // not found, abort { curwin->w_cursor = orig_pos; if (VIsual_active) *************** *** 4938,4950 **** { if (forward) { ! /* try again from start of buffer */ CLEAR_POS(&pos); } else { ! /* try again from end of buffer */ ! /* searching backwards, so set pos to last line and col */ pos.lnum = curwin->w_buffer->b_ml.ml_line_count; pos.col = (colnr_T)STRLEN( ml_get(curwin->w_buffer->b_ml.ml_line_count)); --- 4936,4948 ---- { if (forward) { ! // try again from start of buffer CLEAR_POS(&pos); } else { ! // try again from end of buffer ! // searching backwards, so set pos to last line and col pos.lnum = curwin->w_buffer->b_ml.ml_line_count; pos.col = (colnr_T)STRLEN( ml_get(curwin->w_buffer->b_ml.ml_line_count)); *************** *** 4968,4974 **** if (*p_sel == 'e') { ! /* Correction for exclusive selection depends on the direction. */ if (forward && LTOREQ_POS(VIsual, curwin->w_cursor)) inc_cursor(); else if (!forward && LTOREQ_POS(curwin->w_cursor, VIsual)) --- 4966,4972 ---- if (*p_sel == 'e') { ! // Correction for exclusive selection depends on the direction. if (forward && LTOREQ_POS(VIsual, curwin->w_cursor)) inc_cursor(); else if (!forward && LTOREQ_POS(curwin->w_cursor, VIsual)) *************** *** 4983,4990 **** may_start_select('c'); setmouse(); #ifdef FEAT_CLIPBOARD ! /* Make sure the clipboard gets updated. Needed because start and ! * end are still the same, and the selection needs to be owned */ clip_star.vmode = NUL; #endif redraw_curbuf_later(INVERTED); --- 4981,4988 ---- may_start_select('c'); setmouse(); #ifdef FEAT_CLIPBOARD ! // Make sure the clipboard gets updated. Needed because start and ! // end are still the same, and the selection needs to be owned clip_star.vmode = NUL; #endif redraw_curbuf_later(INVERTED); *************** *** 5147,5166 **** */ void find_pattern_in_path( ! char_u *ptr, /* pointer to search pattern */ ! int dir UNUSED, /* direction of expansion */ ! int len, /* length of search pattern */ ! int whole, /* match whole words only */ ! int skip_comments, /* don't match inside comments */ ! int type, /* Type of search; are we looking for a type? ! a macro? */ long count, ! int action, /* What to do when we find it */ ! linenr_T start_lnum, /* first line to start searching */ ! linenr_T end_lnum) /* last line for searching */ { ! SearchedFile *files; /* Stack of included files */ ! SearchedFile *bigger; /* When we need more space */ int max_path_depth = 50; long match_count = 1; --- 5145,5164 ---- */ void find_pattern_in_path( ! char_u *ptr, // pointer to search pattern ! int dir UNUSED, // direction of expansion ! int len, // length of search pattern ! int whole, // match whole words only ! int skip_comments, // don't match inside comments ! int type, // Type of search; are we looking for a type? ! // a macro? long count, ! int action, // What to do when we find it ! linenr_T start_lnum, // first line to start searching ! linenr_T end_lnum) // last line for searching { ! SearchedFile *files; // Stack of included files ! SearchedFile *bigger; // When we need more space int max_path_depth = 50; long match_count = 1; *************** *** 5170,5176 **** char_u *prev_fname = NULL; linenr_T lnum; int depth; ! int depth_displayed; /* For type==CHECK_PATH */ int old_files; int already_searched; char_u *file_line; --- 5168,5174 ---- char_u *prev_fname = NULL; linenr_T lnum; int depth; ! int depth_displayed; // For type==CHECK_PATH int old_files; int already_searched; char_u *file_line; *************** *** 5201,5215 **** return; if (type != CHECK_PATH && type != FIND_DEFINE ! /* when CONT_SOL is set compare "ptr" with the beginning of the line ! * is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo */ && !(compl_cont_status & CONT_SOL)) { pat = alloc(len + 5); if (pat == NULL) goto fpip_end; sprintf((char *)pat, whole ? "\\<%.*s\\>" : "%.*s", len, ptr); ! /* ignore case according to p_ic, p_scs and pat */ regmatch.rm_ic = ignorecase(pat); regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); vim_free(pat); --- 5199,5213 ---- return; if (type != CHECK_PATH && type != FIND_DEFINE ! // when CONT_SOL is set compare "ptr" with the beginning of the line ! // is faster than quote_meta/regcomp/regexec "ptr" -- Acevedo && !(compl_cont_status & CONT_SOL)) { pat = alloc(len + 5); if (pat == NULL) goto fpip_end; sprintf((char *)pat, whole ? "\\<%.*s\\>" : "%.*s", len, ptr); ! // ignore case according to p_ic, p_scs and pat regmatch.rm_ic = ignorecase(pat); regmatch.regprog = vim_regcomp(pat, p_magic ? RE_MAGIC : 0); vim_free(pat); *************** *** 5222,5228 **** incl_regmatch.regprog = vim_regcomp(inc_opt, p_magic ? RE_MAGIC : 0); if (incl_regmatch.regprog == NULL) goto fpip_end; ! incl_regmatch.rm_ic = FALSE; /* don't ignore case in incl. pat. */ } if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL)) { --- 5220,5226 ---- incl_regmatch.regprog = vim_regcomp(inc_opt, p_magic ? RE_MAGIC : 0); if (incl_regmatch.regprog == NULL) goto fpip_end; ! incl_regmatch.rm_ic = FALSE; // don't ignore case in incl. pat. } if (type == FIND_DEFINE && (*curbuf->b_p_def != NUL || *p_def != NUL)) { *************** *** 5230,5236 **** ? p_def : curbuf->b_p_def, p_magic ? RE_MAGIC : 0); if (def_regmatch.regprog == NULL) goto fpip_end; ! def_regmatch.rm_ic = FALSE; /* don't ignore case in define pat. */ } files = lalloc_clear(max_path_depth * sizeof(SearchedFile), TRUE); if (files == NULL) --- 5228,5234 ---- ? p_def : curbuf->b_p_def, p_magic ? RE_MAGIC : 0); if (def_regmatch.regprog == NULL) goto fpip_end; ! def_regmatch.rm_ic = FALSE; // don't ignore case in define pat. } files = lalloc_clear(max_path_depth * sizeof(SearchedFile), TRUE); if (files == NULL) *************** *** 5241,5247 **** lnum = start_lnum; if (end_lnum > curbuf->b_ml.ml_line_count) end_lnum = curbuf->b_ml.ml_line_count; ! if (lnum > end_lnum) /* do at least one line */ lnum = end_lnum; line = ml_get(lnum); --- 5239,5245 ---- lnum = start_lnum; if (end_lnum > curbuf->b_ml.ml_line_count) end_lnum = curbuf->b_ml.ml_line_count; ! if (lnum > end_lnum) // do at least one line lnum = end_lnum; line = ml_get(lnum); *************** *** 5254,5271 **** ? curbuf->b_ffname : curr_fname; if (inc_opt != NULL && strstr((char *)inc_opt, "\\zs") != NULL) ! /* Use text from '\zs' to '\ze' (or end) of 'include'. */ new_fname = find_file_name_in_path(incl_regmatch.startp[0], (int)(incl_regmatch.endp[0] - incl_regmatch.startp[0]), FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname); else ! /* Use text after match with 'include'. */ new_fname = file_name_in_line(incl_regmatch.endp[0], 0, FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname, NULL); already_searched = FALSE; if (new_fname != NULL) { ! /* Check whether we have already searched in this file */ for (i = 0;; i++) { if (i == depth + 1) --- 5252,5269 ---- ? curbuf->b_ffname : curr_fname; if (inc_opt != NULL && strstr((char *)inc_opt, "\\zs") != NULL) ! // Use text from '\zs' to '\ze' (or end) of 'include'. new_fname = find_file_name_in_path(incl_regmatch.startp[0], (int)(incl_regmatch.endp[0] - incl_regmatch.startp[0]), FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname); else ! // Use text after match with 'include'. new_fname = file_name_in_line(incl_regmatch.endp[0], 0, FNAME_EXP|FNAME_INCL|FNAME_REL, 1L, p_fname, NULL); already_searched = FALSE; if (new_fname != NULL) { ! // Check whether we have already searched in this file for (i = 0;; i++) { if (i == depth + 1) *************** *** 5278,5287 **** if (type != CHECK_PATH && action == ACTION_SHOW_ALL && files[i].matched) { ! msg_putchar('\n'); /* cursor below last one */ ! if (!got_int) /* don't display if 'q' ! typed at "--more--" ! message */ { msg_home_replace_hl(new_fname); msg_puts(_(" (includes previously listed match)")); --- 5276,5285 ---- if (type != CHECK_PATH && action == ACTION_SHOW_ALL && files[i].matched) { ! msg_putchar('\n'); // cursor below last one ! if (!got_int) // don't display if 'q' ! // typed at "--more--" ! // message { msg_home_replace_hl(new_fname); msg_puts(_(" (includes previously listed match)")); *************** *** 5299,5308 **** || (new_fname == NULL && !already_searched))) { if (did_show) ! msg_putchar('\n'); /* cursor below last one */ else { ! gotocmdline(TRUE); /* cursor at status line */ msg_puts_title(_("--- Included files ")); if (action != ACTION_SHOW_ALL) msg_puts_title(_("not found ")); --- 5297,5306 ---- || (new_fname == NULL && !already_searched))) { if (did_show) ! msg_putchar('\n'); // cursor below last one else { ! gotocmdline(TRUE); // cursor at status line msg_puts_title(_("--- Included files ")); if (action != ACTION_SHOW_ALL) msg_puts_title(_("not found ")); *************** *** 5317,5331 **** msg_home_replace(files[depth_displayed].name); msg_puts(" -->\n"); } ! if (!got_int) /* don't display if 'q' typed ! for "--more--" message */ { for (i = 0; i <= depth_displayed; i++) msg_puts(" "); if (new_fname != NULL) { ! /* using "new_fname" is more reliable, e.g., when ! * 'includeexpr' is set. */ msg_outtrans_attr(new_fname, HL_ATTR(HLF_D)); } else --- 5315,5329 ---- msg_home_replace(files[depth_displayed].name); msg_puts(" -->\n"); } ! if (!got_int) // don't display if 'q' typed ! // for "--more--" message { for (i = 0; i <= depth_displayed; i++) msg_puts(" "); if (new_fname != NULL) { ! // using "new_fname" is more reliable, e.g., when ! // 'includeexpr' is set. msg_outtrans_attr(new_fname, HL_ATTR(HLF_D)); } else *************** *** 5337,5350 **** if (inc_opt != NULL && strstr((char *)inc_opt, "\\zs") != NULL) { ! /* pattern contains \zs, use the match */ p = incl_regmatch.startp[0]; i = (int)(incl_regmatch.endp[0] - incl_regmatch.startp[0]); } else { ! /* find the file name after the end of the match */ for (p = incl_regmatch.endp[0]; *p && !vim_isfilec(*p); p++) ; --- 5335,5348 ---- if (inc_opt != NULL && strstr((char *)inc_opt, "\\zs") != NULL) { ! // pattern contains \zs, use the match p = incl_regmatch.startp[0]; i = (int)(incl_regmatch.endp[0] - incl_regmatch.startp[0]); } else { ! // find the file name after the end of the match for (p = incl_regmatch.endp[0]; *p && !vim_isfilec(*p); p++) ; *************** *** 5354,5365 **** if (i == 0) { ! /* Nothing found, use the rest of the line. */ p = incl_regmatch.endp[0]; i = (int)STRLEN(p); } ! /* Avoid checking before the start of the line, can ! * happen if \zs appears in the regexp. */ else if (p > line) { if (p[-1] == '"' || p[-1] == '<') --- 5352,5363 ---- if (i == 0) { ! // Nothing found, use the rest of the line. p = incl_regmatch.endp[0]; i = (int)STRLEN(p); } ! // Avoid checking before the start of the line, can ! // happen if \zs appears in the regexp. else if (p > line) { if (p[-1] == '"' || p[-1] == '<') *************** *** 5384,5395 **** msg_puts(_(" NOT FOUND")); } } ! out_flush(); /* output each line directly */ } if (new_fname != NULL) { ! /* Push the new file onto the file stack */ if (depth + 1 == old_files) { bigger = ALLOC_MULT(SearchedFile, max_path_depth * 2); --- 5382,5393 ---- msg_puts(_(" NOT FOUND")); } } ! out_flush(); // output each line directly } if (new_fname != NULL) { ! // Push the new file onto the file stack if (depth + 1 == old_files) { bigger = ALLOC_MULT(SearchedFile, max_path_depth * 2); *************** *** 5431,5437 **** files[depth].matched = FALSE; if (action == ACTION_EXPAND) { ! msg_hist_off = TRUE; /* reset in msg_trunc_attr() */ vim_snprintf((char*)IObuff, IOSIZE, _("Scanning included file: %s"), (char *)new_fname); --- 5429,5435 ---- files[depth].matched = FALSE; if (action == ACTION_EXPAND) { ! msg_hist_off = TRUE; // reset in msg_trunc_attr() vim_snprintf((char*)IObuff, IOSIZE, _("Scanning included file: %s"), (char *)new_fname); *************** *** 5478,5484 **** { if (define_matched || (compl_cont_status & CONT_SOL)) { ! /* compare the first "len" chars from "ptr" */ startp = skipwhite(p); if (p_ic) matched = !MB_STRNICMP(startp, ptr, len); --- 5476,5482 ---- { if (define_matched || (compl_cont_status & CONT_SOL)) { ! // compare the first "len" chars from "ptr" startp = skipwhite(p); if (p_ic) matched = !MB_STRNICMP(startp, ptr, len); *************** *** 5521,5534 **** && (p[1] == '*' || p[1] == '/')) { matched = FALSE; ! /* After "//" all text is comment */ if (p[1] == '/') break; ++p; } else if (!matched && p[0] == '*' && p[1] == '/') { ! /* Can find match after "* /". */ matched = TRUE; ++p; } --- 5519,5532 ---- && (p[1] == '*' || p[1] == '/')) { matched = FALSE; ! // After "//" all text is comment if (p[1] == '/') break; ++p; } else if (!matched && p[0] == '*' && p[1] == '/') { ! // Can find match after "* /". matched = TRUE; ++p; } *************** *** 5561,5572 **** if ((compl_cont_status & CONT_ADDING) && i == compl_length) { ! /* IOSIZE > compl_length, so the STRNCPY works */ STRNCPY(IObuff, aux, i); ! /* Get the next line: when "depth" < 0 from the current ! * buffer, otherwise from the included file. Jump to ! * exit_matched when past the last line. */ if (depth < 0) { if (lnum >= end_lnum) --- 5559,5570 ---- if ((compl_cont_status & CONT_ADDING) && i == compl_length) { ! // IOSIZE > compl_length, so the STRNCPY works STRNCPY(IObuff, aux, i); ! // Get the next line: when "depth" < 0 from the current ! // buffer, otherwise from the included file. Jump to ! // exit_matched when past the last line. if (depth < 0) { if (lnum >= end_lnum) *************** *** 5577,5585 **** LSIZE, files[depth].fp)) goto exit_matched; ! /* we read a line, set "already" to check this "line" later ! * if depth >= 0 we'll increase files[depth].lnum far ! * bellow -- Acevedo */ already = aux = p = skipwhite(line); p = find_word_start(p); p = find_word_end(p); --- 5575,5583 ---- LSIZE, files[depth].fp)) goto exit_matched; ! // we read a line, set "already" to check this "line" later ! // if depth >= 0 we'll increase files[depth].lnum far ! // bellow -- Acevedo already = aux = p = skipwhite(line); p = find_word_start(p); p = find_word_end(p); *************** *** 5589,5595 **** { if (IObuff[i-1] != ' ') IObuff[i++] = ' '; ! /* IObuf =~ "\(\k\|\i\).* ", thus i >= 2*/ if (p_js && (IObuff[i-2] == '.' || (vim_strchr(p_cpo, CPO_JOINSP) == NULL --- 5587,5593 ---- { if (IObuff[i-1] != ' ') IObuff[i++] = ' '; ! // IObuf =~ "\(\k\|\i\).* ", thus i >= 2 if (p_js && (IObuff[i-2] == '.' || (vim_strchr(p_cpo, CPO_JOINSP) == NULL *************** *** 5597,5603 **** || IObuff[i-2] == '!')))) IObuff[i++] = ' '; } ! /* copy as much as possible of the new word */ if (p - aux >= IOSIZE - i) p = aux + IOSIZE - i - 1; STRNCPY(IObuff + i, aux, p - aux); --- 5595,5601 ---- || IObuff[i-2] == '!')))) IObuff[i++] = ' '; } ! // copy as much as possible of the new word if (p - aux >= IOSIZE - i) p = aux + IOSIZE - i - 1; STRNCPY(IObuff + i, aux, p - aux); *************** *** 5615,5621 **** curr_fname == curbuf->b_fname ? NULL : curr_fname, dir, cont_s_ipos); if (add_r == OK) ! /* if dir was BACKWARD then honor it just once */ dir = FORWARD; else if (add_r == FAIL) break; --- 5613,5619 ---- curr_fname == curbuf->b_fname ? NULL : curr_fname, dir, cont_s_ipos); if (add_r == OK) ! // if dir was BACKWARD then honor it just once dir = FORWARD; else if (add_r == FAIL) break; *************** *** 5624,5636 **** { found = TRUE; if (!did_show) ! gotocmdline(TRUE); /* cursor at status line */ if (curr_fname != prev_fname) { if (did_show) ! msg_putchar('\n'); /* cursor below last one */ ! if (!got_int) /* don't display if 'q' typed ! at "--more--" message */ msg_home_replace_hl(curr_fname); prev_fname = curr_fname; } --- 5622,5634 ---- { found = TRUE; if (!did_show) ! gotocmdline(TRUE); // cursor at status line if (curr_fname != prev_fname) { if (did_show) ! msg_putchar('\n'); // cursor below last one ! if (!got_int) // don't display if 'q' typed ! // at "--more--" message msg_home_replace_hl(curr_fname); prev_fname = curr_fname; } *************** *** 5641,5648 **** (depth == -1) ? &lnum : &files[depth].lnum, match_count++); ! /* Set matched flag for this file and all the ones that ! * include it */ for (i = 0; i <= depth; ++i) files[i].matched = TRUE; } --- 5639,5646 ---- (depth == -1) ? &lnum : &files[depth].lnum, match_count++); ! // Set matched flag for this file and all the ones that ! // include it for (i = 0; i <= depth; ++i) files[i].matched = TRUE; } *************** *** 5668,5674 **** need_mouse_correct = TRUE; #endif #if defined(FEAT_QUICKFIX) ! /* ":psearch" uses the preview window */ if (g_do_tagpreview != 0) { curwin_save = curwin; --- 5666,5672 ---- need_mouse_correct = TRUE; #endif #if defined(FEAT_QUICKFIX) ! // ":psearch" uses the preview window if (g_do_tagpreview != 0) { curwin_save = curwin; *************** *** 5683,5696 **** } if (depth == -1) { ! /* match in current file */ #if defined(FEAT_QUICKFIX) if (g_do_tagpreview != 0) { if (!GETFILE_SUCCESS(getfile( curwin_save->w_buffer->b_fnum, NULL, NULL, TRUE, lnum, FALSE))) ! break; /* failed to jump to file */ } else #endif --- 5681,5694 ---- } if (depth == -1) { ! // match in current file #if defined(FEAT_QUICKFIX) if (g_do_tagpreview != 0) { if (!GETFILE_SUCCESS(getfile( curwin_save->w_buffer->b_fnum, NULL, NULL, TRUE, lnum, FALSE))) ! break; // failed to jump to file } else #endif *************** *** 5703,5711 **** if (!GETFILE_SUCCESS(getfile( 0, files[depth].name, NULL, TRUE, files[depth].lnum, FALSE))) ! break; /* failed to jump to file */ ! /* autocommands may have changed the lnum, we don't ! * want that here */ curwin->w_cursor.lnum = files[depth].lnum; } } --- 5701,5709 ---- if (!GETFILE_SUCCESS(getfile( 0, files[depth].name, NULL, TRUE, files[depth].lnum, FALSE))) ! break; // failed to jump to file ! // autocommands may have changed the lnum, we don't ! // want that here curwin->w_cursor.lnum = files[depth].lnum; } } *************** *** 5719,5725 **** if (g_do_tagpreview != 0 && curwin != curwin_save && win_valid(curwin_save)) { ! /* Return cursor to where we were */ validate_cursor(); redraw_later(VALID); win_enter(curwin_save, TRUE); --- 5717,5723 ---- if (g_do_tagpreview != 0 && curwin != curwin_save && win_valid(curwin_save)) { ! // Return cursor to where we were validate_cursor(); redraw_later(VALID); win_enter(curwin_save, TRUE); *************** *** 5734,5741 **** } exit_matched: matched = FALSE; ! /* look for other matches in the rest of the line if we ! * are not at the end of it already */ if (def_regmatch.regprog == NULL && action == ACTION_EXPAND && !(compl_cont_status & CONT_SOL) --- 5732,5739 ---- } exit_matched: matched = FALSE; ! // look for other matches in the rest of the line if we ! // are not at the end of it already if (def_regmatch.regprog == NULL && action == ACTION_EXPAND && !(compl_cont_status & CONT_SOL) *************** *** 5767,5776 **** if (depth < depth_displayed) depth_displayed = depth; } ! if (depth >= 0) /* we could read the line */ { files[depth].lnum++; ! /* Remove any CR and LF from the line. */ i = (int)STRLEN(line); if (i > 0 && line[i - 1] == '\n') line[--i] = NUL; --- 5765,5774 ---- if (depth < depth_displayed) depth_displayed = depth; } ! if (depth >= 0) // we could read the line { files[depth].lnum++; ! // Remove any CR and LF from the line. i = (int)STRLEN(line); if (i > 0 && line[i - 1] == '\n') line[--i] = NUL; *************** *** 5785,5793 **** } already = NULL; } ! /* End of big for (;;) loop. */ ! /* Close any files that are still open. */ for (i = 0; i <= depth; i++) { fclose(files[i].fp); --- 5783,5791 ---- } already = NULL; } ! // End of big for (;;) loop. ! // Close any files that are still open. for (i = 0; i <= depth; i++) { fclose(files[i].fp); *************** *** 5839,5855 **** char_u *p; if (did_show) ! msg_putchar('\n'); /* cursor below last one */ else if (!msg_silent) ! gotocmdline(TRUE); /* cursor at status line */ ! if (got_int) /* 'q' typed at "--more--" message */ return; for (;;) { p = line + STRLEN(line) - 1; if (fp != NULL) { ! /* We used fgets(), so get rid of newline at end */ if (p >= line && *p == '\n') --p; if (p >= line && *p == '\r') --- 5837,5853 ---- char_u *p; if (did_show) ! msg_putchar('\n'); // cursor below last one else if (!msg_silent) ! gotocmdline(TRUE); // cursor at status line ! if (got_int) // 'q' typed at "--more--" message return; for (;;) { p = line + STRLEN(line) - 1; if (fp != NULL) { ! // We used fgets(), so get rid of newline at end if (p >= line && *p == '\n') --p; if (p >= line && *p == '\r') *************** *** 5858,5880 **** } if (action == ACTION_SHOW_ALL) { ! sprintf((char *)IObuff, "%3ld: ", count); /* show match nr */ msg_puts((char *)IObuff); ! sprintf((char *)IObuff, "%4ld", *lnum); /* show line nr */ ! /* Highlight line numbers */ msg_puts_attr((char *)IObuff, HL_ATTR(HLF_N)); msg_puts(" "); } msg_prt_line(line, FALSE); ! out_flush(); /* show one line at a time */ ! /* Definition continues until line that doesn't end with '\' */ if (got_int || type != FIND_DEFINE || p < line || *p != '\\') break; if (fp != NULL) { ! if (vim_fgets(line, LSIZE, fp)) /* end of file */ break; ++*lnum; } --- 5856,5878 ---- } if (action == ACTION_SHOW_ALL) { ! sprintf((char *)IObuff, "%3ld: ", count); // show match nr msg_puts((char *)IObuff); ! sprintf((char *)IObuff, "%4ld", *lnum); // show line nr ! // Highlight line numbers msg_puts_attr((char *)IObuff, HL_ATTR(HLF_N)); msg_puts(" "); } msg_prt_line(line, FALSE); ! out_flush(); // show one line at a time ! // Definition continues until line that doesn't end with '\' if (got_int || type != FIND_DEFINE || p < line || *p != '\\') break; if (fp != NULL) { ! if (vim_fgets(line, LSIZE, fp)) // end of file break; ++*lnum; } *** ../vim-8.1.2393/src/sha256.c 2018-09-30 21:43:17.203693237 +0200 --- src/sha256.c 2019-12-05 21:08:11.368030602 +0100 *************** *** 260,266 **** PUT_UINT32(ctx->state[6], digest, 24); PUT_UINT32(ctx->state[7], digest, 28); } ! #endif /* FEAT_CRYPT || FEAT_PERSISTENT_UNDO */ #if defined(FEAT_CRYPT) || defined(PROTO) /* --- 260,266 ---- PUT_UINT32(ctx->state[6], digest, 24); PUT_UINT32(ctx->state[7], digest, 28); } ! #endif // FEAT_CRYPT || FEAT_PERSISTENT_UNDO #if defined(FEAT_CRYPT) || defined(PROTO) /* *************** *** 301,307 **** char_u *salt, int salt_len) { ! /* No passwd means don't encrypt */ if (buf == NULL || *buf == NUL) return (char_u *)""; --- 301,307 ---- char_u *salt, int salt_len) { ! // No passwd means don't encrypt if (buf == NULL || *buf == NUL) return (char_u *)""; *************** *** 370,376 **** { failures++; output[sizeof(output) - 1] = '\0'; ! /* printf("sha256_self_test %d failed %s\n", i, output); */ } } return failures > 0 ? FAIL : OK; --- 370,376 ---- { failures++; output[sizeof(output) - 1] = '\0'; ! // printf("sha256_self_test %d failed %s\n", i, output); } } return failures > 0 ? FAIL : OK; *************** *** 382,388 **** # ifdef HAVE_GETTIMEOFDAY struct timeval tv; ! /* Using usec makes it less predictable. */ gettimeofday(&tv, NULL); return (unsigned int)(tv.tv_sec + tv.tv_usec); # else --- 382,388 ---- # ifdef HAVE_GETTIMEOFDAY struct timeval tv; ! // Using usec makes it less predictable. gettimeofday(&tv, NULL); return (unsigned int)(tv.tv_sec + tv.tv_usec); # else *************** *** 414,427 **** sha256_update(&ctx, (char_u *)random_data, sizeof(random_data)); sha256_finish(&ctx, sha256sum); ! /* put first block into header. */ for (i = 0; i < header_len; i++) header[i] = sha256sum[i % sizeof(sha256sum)]; ! /* put remaining block into salt. */ if (salt != NULL) for (i = 0; i < salt_len; i++) salt[i] = sha256sum[(i + header_len) % sizeof(sha256sum)]; } ! #endif /* FEAT_CRYPT */ --- 414,427 ---- sha256_update(&ctx, (char_u *)random_data, sizeof(random_data)); sha256_finish(&ctx, sha256sum); ! // put first block into header. for (i = 0; i < header_len; i++) header[i] = sha256sum[i % sizeof(sha256sum)]; ! // put remaining block into salt. if (salt != NULL) for (i = 0; i < salt_len; i++) salt[i] = sha256sum[(i + header_len) % sizeof(sha256sum)]; } ! #endif // FEAT_CRYPT *** ../vim-8.1.2393/src/sign.c 2019-11-30 22:47:42.655331183 +0100 --- src/sign.c 2019-12-05 21:08:29.995965491 +0100 *************** *** 701,708 **** return count; } ! # endif /* FEAT_SIGN_ICONS */ ! # endif /* FEAT_NETBEANS_INTG */ /* * Delete signs in group 'group' in buffer "buf". If 'group' is '*', then --- 701,708 ---- return count; } ! # endif // FEAT_SIGN_ICONS ! # endif // FEAT_NETBEANS_INTG /* * Delete signs in group 'group' in buffer "buf". If 'group' is '*', then *************** *** 2744,2747 **** } } ! #endif /* FEAT_SIGNS */ --- 2744,2747 ---- } } ! #endif // FEAT_SIGNS *** ../vim-8.1.2393/src/version.c 2019-12-05 20:28:43.356760445 +0100 --- src/version.c 2019-12-05 20:53:42.515114190 +0100 *************** *** 744,745 **** --- 744,747 ---- { /* Add new patch number below this line */ + /**/ + 2394, /**/ -- % cat /usr/include/sys/errno.h #define EPERM 1 /* Operation not permitted */ #define ENOENT 2 /* No such file or directory */ #define ESRCH 3 /* No such process */ [...] #define EMACS 666 /* Too many macros */ % /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///