To: vim_dev@googlegroups.com Subject: Patch 8.2.4001 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.2.4001 Problem: Insert complete code uses global variables. Solution: Make variables local to the file and use accessor functions. (Yegappan Lakshmanan, closes #9470) Files: src/edit.c, src/getchar.c, src/globals.h, src/insexpand.c, src/proto/insexpand.pro, src/search.c *** ../vim-8.2.4000/src/edit.c 2022-01-01 15:58:19.110486371 +0000 --- src/edit.c 2022-01-04 16:56:10.531131161 +0000 *************** *** 1280,1286 **** // but it is under other ^X modes if (*curbuf->b_p_cpt == NUL && (ctrl_x_mode_normal() || ctrl_x_mode_whole_line()) ! && !(compl_cont_status & CONT_LOCAL)) goto normalchar; docomplete: --- 1280,1286 ---- // but it is under other ^X modes if (*curbuf->b_p_cpt == NUL && (ctrl_x_mode_normal() || ctrl_x_mode_whole_line()) ! && !compl_status_local()) goto normalchar; docomplete: *************** *** 1289,1295 **** disable_fold_update++; // don't redraw folds here #endif if (ins_complete(c, TRUE) == FAIL) ! compl_cont_status = 0; #ifdef FEAT_FOLDING disable_fold_update--; #endif --- 1289,1295 ---- disable_fold_update++; // don't redraw folds here #endif if (ins_complete(c, TRUE) == FAIL) ! compl_status_clear(); #ifdef FEAT_FOLDING disable_fold_update--; #endif *** ../vim-8.2.4000/src/getchar.c 2022-01-03 13:47:45.956911773 +0000 --- src/getchar.c 2022-01-04 16:56:10.531131161 +0000 *************** *** 2453,2459 **** && State != ASKMORE && State != CONFIRM && !((ctrl_x_mode_not_default() && at_ctrl_x_key()) ! || ((compl_cont_status & CONT_LOCAL) && (tb_c1 == Ctrl_N || tb_c1 == Ctrl_P)))) { #ifdef FEAT_GUI --- 2453,2459 ---- && State != ASKMORE && State != CONFIRM && !((ctrl_x_mode_not_default() && at_ctrl_x_key()) ! || (compl_status_local() && (tb_c1 == Ctrl_N || tb_c1 == Ctrl_P)))) { #ifdef FEAT_GUI *** ../vim-8.2.4000/src/globals.h 2022-01-01 16:20:56.896401505 +0000 --- src/globals.h 2022-01-04 16:56:10.531131161 +0000 *************** *** 163,185 **** * Variables for Insert mode completion. */ - // Length in bytes of the text being completed (this is deleted to be replaced - // by the match.) - EXTERN int compl_length INIT(= 0); - - // List of flags for method of completion. - EXTERN int compl_cont_status INIT(= 0); - # define CONT_ADDING 1 // "normal" or "adding" expansion - # define CONT_INTRPT (2 + 4) // a ^X interrupted the current expansion - // it's set only iff N_ADDS is set - # define CONT_N_ADDS 4 // next ^X<> will add-new or expand-current - # define CONT_S_IPOS 8 // next ^X<> will set initial_pos? - // if so, word-wise-expansion will set SOL - # define CONT_SOL 16 // pattern includes start of line, just for - // word-wise expansion, not set for ^X^L - # define CONT_LOCAL 32 // for ctrl_x_mode 0, ^X^P/^X^N do a local - // expansion, (eg use complete=.) - EXTERN char_u *edit_submode INIT(= NULL); // msg for CTRL-X submode EXTERN char_u *edit_submode_pre INIT(= NULL); // prepended to edit_submode EXTERN char_u *edit_submode_extra INIT(= NULL);// appended to edit_submode --- 163,168 ---- *** ../vim-8.2.4000/src/insexpand.c 2022-01-03 11:03:42.538752401 +0000 --- src/insexpand.c 2022-01-04 16:56:10.531131161 +0000 *************** *** 177,188 **** // Which Ctrl-X mode are we in? static int ctrl_x_mode = CTRL_X_NORMAL; ! static int compl_matches = 0; static char_u *compl_pattern = NULL; static int compl_direction = FORWARD; static int compl_shows_dir = FORWARD; static int compl_pending = 0; // > 1 for postponed CTRL-N static pos_T compl_startpos; static colnr_T compl_col = 0; // column where the text starts // that is being completed static char_u *compl_orig_text = NULL; // text as it was before --- 177,191 ---- // Which Ctrl-X mode are we in? static int ctrl_x_mode = CTRL_X_NORMAL; ! static int compl_matches = 0; // number of completion matches static char_u *compl_pattern = NULL; static int compl_direction = FORWARD; static int compl_shows_dir = FORWARD; static int compl_pending = 0; // > 1 for postponed CTRL-N static pos_T compl_startpos; + // Length in bytes of the text being completed (this is deleted to be replaced + // by the match.) + static int compl_length = 0; static colnr_T compl_col = 0; // column where the text starts // that is being completed static char_u *compl_orig_text = NULL; // text as it was before *************** *** 190,195 **** --- 193,211 ---- static int compl_cont_mode = 0; static expand_T compl_xp; + // List of flags for method of completion. + static int compl_cont_status = 0; + # define CONT_ADDING 1 // "normal" or "adding" expansion + # define CONT_INTRPT (2 + 4) // a ^X interrupted the current expansion + // it's set only iff N_ADDS is set + # define CONT_N_ADDS 4 // next ^X<> will add-new or expand-current + # define CONT_S_IPOS 8 // next ^X<> will set initial_pos? + // if so, word-wise-expansion will set SOL + # define CONT_SOL 16 // pattern includes start of line, just for + // word-wise expansion, not set for ^X^L + # define CONT_LOCAL 32 // for ctrl_x_mode 0, ^X^P/^X^N do a local + // expansion, (eg use complete=.) + static int compl_opt_refresh_always = FALSE; static int compl_opt_suppress_empty = FALSE; *************** *** 201,207 **** static void ins_compl_free(void); static int ins_compl_need_restart(void); static void ins_compl_new_leader(void); ! static int ins_compl_len(void); static void ins_compl_restart(void); static void ins_compl_set_original_text(char_u *str); static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg); --- 217,223 ---- static void ins_compl_free(void); static int ins_compl_need_restart(void); static void ins_compl_new_leader(void); ! static int get_compl_len(void); static void ins_compl_restart(void); static void ins_compl_set_original_text(char_u *str); static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg); *************** *** 268,273 **** --- 284,290 ---- int ctrl_x_mode_function(void) { return ctrl_x_mode == CTRL_X_FUNCTION; } int ctrl_x_mode_omni(void) { return ctrl_x_mode == CTRL_X_OMNI; } int ctrl_x_mode_spell(void) { return ctrl_x_mode == CTRL_X_SPELL; } + static int ctrl_x_mode_eval(void) { return ctrl_x_mode == CTRL_X_EVAL; } int ctrl_x_mode_line_or_eval(void) { return ctrl_x_mode == CTRL_X_WHOLE_LINE || ctrl_x_mode == CTRL_X_EVAL; } *************** *** 291,297 **** } /* ! * Return TRUE if the 'dict' or 'tsr' option can be used. */ int has_compl_option(int dict_opt) --- 308,379 ---- } /* ! * Return TRUE if currently in "normal" or "adding" insert completion matches ! * state ! */ ! int ! compl_status_adding(void) ! { ! return compl_cont_status & CONT_ADDING; ! } ! ! /* ! * Return TRUE if the completion pattern includes start of line, just for ! * word-wise expansion. ! */ ! int ! compl_status_sol(void) ! { ! return compl_cont_status & CONT_SOL; ! } ! ! /* ! * Return TRUE if ^X^P/^X^N will do a local completion (i.e. use complete=.) ! */ ! int ! compl_status_local(void) ! { ! return compl_cont_status & CONT_LOCAL; ! } ! ! /* ! * Clear the completion status flags ! */ ! void ! compl_status_clear(void) ! { ! compl_cont_status = 0; ! } ! ! /* ! * Return TRUE if completion is using the forward direction matches ! */ ! static int ! compl_dir_forward(void) ! { ! return compl_direction == FORWARD; ! } ! ! /* ! * Return TRUE if currently showing forward completion matches ! */ ! static int ! compl_shows_dir_forward(void) ! { ! return compl_shows_dir == FORWARD; ! } ! ! /* ! * Return TRUE if currently showing backward completion matches ! */ ! static int ! compl_shows_dir_backward(void) ! { ! return compl_shows_dir == BACKWARD; ! } ! ! /* ! * Return TRUE if the 'dictionary' or 'thesaurus' option can be used. */ int has_compl_option(int dict_opt) *************** *** 328,334 **** } /* ! * Is the character 'c' a valid key to go to or keep us in CTRL-X mode? * This depends on the current mode. */ int --- 410,416 ---- } /* ! * Is the character "c" a valid key to go to or keep us in CTRL-X mode? * This depends on the current mode. */ int *************** *** 392,407 **** } /* ! * Returns TRUE if the currently shown text is the original text when the ! * completion began. */ static int ! ins_compl_at_original_text(compl_T *match) { return match->cp_flags & CP_ORIGINAL_TEXT; } /* * Return TRUE when character "c" is part of the item currently being * completed. Used to decide whether to abandon complete mode when the menu * is visible. --- 474,497 ---- } /* ! * Return TRUE if "match" is the original text when the completion began. */ static int ! match_at_original_text(compl_T *match) { return match->cp_flags & CP_ORIGINAL_TEXT; } /* + * Returns TRUE if "match" is the first match in the completion list. + */ + static int + is_first_match(compl_T *match) + { + return match == compl_first_match; + } + + /* * Return TRUE when character "c" is part of the item currently being * completed. Used to decide whether to abandon complete mode when the menu * is visible. *************** *** 646,657 **** match = compl_first_match; do { ! if (!ins_compl_at_original_text(match) && STRNCMP(match->cp_str, str, len) == 0 && match->cp_str[len] == NUL) return NOTDONE; match = match->cp_next; ! } while (match != NULL && match != compl_first_match); } // Remove any popup menu before changing the list of matches. --- 736,747 ---- match = compl_first_match; do { ! if (!match_at_original_text(match) && STRNCMP(match->cp_str, str, len) == 0 && match->cp_str[len] == NUL) return NOTDONE; match = match->cp_next; ! } while (match != NULL && !is_first_match(match)); } // Remove any popup menu before changing the list of matches. *************** *** 763,769 **** had_match = (curwin->w_cursor.col > compl_col); ins_compl_delete(); ! ins_bytes(compl_leader + ins_compl_len()); ins_redraw(FALSE); // When the match isn't there (to avoid matching itself) remove it --- 853,859 ---- had_match = (curwin->w_cursor.col > compl_col); ins_compl_delete(); ! ins_bytes(compl_leader + get_compl_len()); ins_redraw(FALSE); // When the match isn't there (to avoid matching itself) remove it *************** *** 811,817 **** *p = NUL; had_match = (curwin->w_cursor.col > compl_col); ins_compl_delete(); ! ins_bytes(compl_leader + ins_compl_len()); ins_redraw(FALSE); // When the match isn't there (to avoid matching itself) remove it --- 901,907 ---- *p = NUL; had_match = (curwin->w_cursor.col > compl_col); ins_compl_delete(); ! ins_bytes(compl_leader + get_compl_len()); ins_redraw(FALSE); // When the match isn't there (to avoid matching itself) remove it *************** *** 861,867 **** // Find the end of the list. match = compl_first_match; // there's always an entry for the compl_orig_text, it doesn't count. ! while (match->cp_next != NULL && match->cp_next != compl_first_match) { match = match->cp_next; ++count; --- 951,957 ---- // Find the end of the list. match = compl_first_match; // there's always an entry for the compl_orig_text, it doesn't count. ! while (match->cp_next != NULL && !is_first_match(match->cp_next)) { match = match->cp_next; ++count; *************** *** 980,990 **** i = 0; do { ! if (compl == NULL ! || (!ins_compl_at_original_text(compl) && ++i == 2)) break; compl = compl->cp_next; ! } while (compl != compl_first_match); if (strstr((char *)p_cot, "menuone") != NULL) return (i >= 1); --- 1070,1079 ---- i = 0; do { ! if (compl == NULL || (!match_at_original_text(compl) && ++i == 2)) break; compl = compl->cp_next; ! } while (!is_first_match(compl)); if (strstr((char *)p_cot, "menuone") != NULL) return (i >= 1); *************** *** 1077,1088 **** do { ! if (!ins_compl_at_original_text(compl) && (compl_leader == NULL || ins_compl_equal(compl, compl_leader, lead_len))) ++compl_match_arraysize; compl = compl->cp_next; ! } while (compl != NULL && compl != compl_first_match); if (compl_match_arraysize == 0) return -1; --- 1166,1177 ---- do { ! if (!match_at_original_text(compl) && (compl_leader == NULL || ins_compl_equal(compl, compl_leader, lead_len))) ++compl_match_arraysize; compl = compl->cp_next; ! } while (compl != NULL && !is_first_match(compl)); if (compl_match_arraysize == 0) return -1; *************** *** 1093,1106 **** // If the current match is the original text don't find the first // match after it, don't highlight anything. ! if (ins_compl_at_original_text(compl_shown_match)) shown_match_ok = TRUE; i = 0; compl = compl_first_match; do { ! if (!ins_compl_at_original_text(compl) && (compl_leader == NULL || ins_compl_equal(compl, compl_leader, lead_len))) { --- 1182,1195 ---- // If the current match is the original text don't find the first // match after it, don't highlight anything. ! if (match_at_original_text(compl_shown_match)) shown_match_ok = TRUE; i = 0; compl = compl_first_match; do { ! if (!match_at_original_text(compl) && (compl_leader == NULL || ins_compl_equal(compl, compl_leader, lead_len))) { *************** *** 1141,1147 **** // When the original text is the shown match don't set // compl_shown_match. ! if (ins_compl_at_original_text(compl)) shown_match_ok = TRUE; if (!shown_match_ok && shown_compl != NULL) --- 1230,1236 ---- // When the original text is the shown match don't set // compl_shown_match. ! if (match_at_original_text(compl)) shown_match_ok = TRUE; if (!shown_match_ok && shown_compl != NULL) *************** *** 1153,1159 **** } } compl = compl->cp_next; ! } while (compl != NULL && compl != compl_first_match); if (!shown_match_ok) // no displayed match at all cur = -1; --- 1242,1248 ---- } } compl = compl->cp_next; ! } while (compl != NULL && !is_first_match(compl)); if (!shown_match_ok) // no displayed match at all cur = -1; *************** *** 1568,1579 **** clear_tv(&match->cp_user_data); #endif vim_free(match); ! } while (compl_curr_match != NULL && compl_curr_match != compl_first_match); compl_first_match = compl_curr_match = NULL; compl_shown_match = NULL; compl_old_match = NULL; } void ins_compl_clear(void) { --- 1657,1671 ---- clear_tv(&match->cp_user_data); #endif vim_free(match); ! } while (compl_curr_match != NULL && !is_first_match(compl_curr_match)); compl_first_match = compl_curr_match = NULL; compl_shown_match = NULL; compl_old_match = NULL; } + /* + * Reset/clear the completion state. + */ void ins_compl_clear(void) { *************** *** 1648,1653 **** --- 1740,1754 ---- } /* + * Return the length in bytes of the text being completed + */ + int + ins_compl_len(void) + { + return compl_length; + } + + /* * Delete one character before the cursor and show the subset of the matches * that match the word that is now before the cursor. * Returns the character to be used, NUL if the work is done and another char *************** *** 1667,1675 **** // allow the word to be deleted, we won't match everything. // Respect the 'backspace' option. if ((int)(p - line) - (int)compl_col < 0 ! || ((int)(p - line) - (int)compl_col == 0 ! && ctrl_x_mode != CTRL_X_OMNI) ! || ctrl_x_mode == CTRL_X_EVAL || (!can_bs(BS_START) && (int)(p - line) - (int)compl_col - compl_length < 0)) return K_BS; --- 1768,1775 ---- // allow the word to be deleted, we won't match everything. // Respect the 'backspace' option. if ((int)(p - line) - (int)compl_col < 0 ! || ((int)(p - line) - (int)compl_col == 0 && !ctrl_x_mode_omni()) ! || ctrl_x_mode_eval() || (!can_bs(BS_START) && (int)(p - line) - (int)compl_col - compl_length < 0)) return K_BS; *************** *** 1702,1708 **** // Return TRUE if we didn't complete finding matches or when the // 'completefunc' returned "always" in the "refresh" dictionary item. return compl_was_interrupted ! || ((ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI) && compl_opt_refresh_always); } --- 1802,1808 ---- // Return TRUE if we didn't complete finding matches or when the // 'completefunc' returned "always" in the "refresh" dictionary item. return compl_was_interrupted ! || ((ctrl_x_mode_function() || ctrl_x_mode_omni()) && compl_opt_refresh_always); } *************** *** 1716,1722 **** { ins_compl_del_pum(); ins_compl_delete(); ! ins_bytes(compl_leader + ins_compl_len()); compl_used_match = FALSE; if (compl_started) --- 1816,1822 ---- { ins_compl_del_pum(); ins_compl_delete(); ! ins_bytes(compl_leader + get_compl_len()); compl_used_match = FALSE; if (compl_started) *************** *** 1759,1765 **** * the cursor column. Making sure it never goes below zero. */ static int ! ins_compl_len(void) { int off = (int)curwin->w_cursor.col - (int)compl_col; --- 1859,1865 ---- * the cursor column. Making sure it never goes below zero. */ static int ! get_compl_len(void) { int off = (int)curwin->w_cursor.col - (int)compl_col; *************** *** 1838,1844 **** // Replace the original text entry. // The CP_ORIGINAL_TEXT flag is either at the first item or might possibly // be at the last item for backward completion ! if (ins_compl_at_original_text(compl_first_match)) // safety check { p = vim_strsave(str); if (p != NULL) --- 1938,1944 ---- // Replace the original text entry. // The CP_ORIGINAL_TEXT flag is either at the first item or might possibly // be at the last item for backward completion ! if (match_at_original_text(compl_first_match)) // safety check { p = vim_strsave(str); if (p != NULL) *************** *** 1848,1854 **** } } else if (compl_first_match->cp_prev != NULL ! && ins_compl_at_original_text(compl_first_match->cp_prev)) { p = vim_strsave(str); if (p != NULL) --- 1948,1954 ---- } } else if (compl_first_match->cp_prev != NULL ! && match_at_original_text(compl_first_match->cp_prev)) { p = vim_strsave(str); if (p != NULL) *************** *** 1876,1887 **** { // When still at the original match use the first entry that matches // the leader. ! if (!ins_compl_at_original_text(compl_shown_match)) return; p = NULL; for (cp = compl_shown_match->cp_next; cp != NULL ! && cp != compl_first_match; cp = cp->cp_next) { if (compl_leader == NULL || ins_compl_equal(cp, compl_leader, --- 1976,1987 ---- { // When still at the original match use the first entry that matches // the leader. ! if (!match_at_original_text(compl_shown_match)) return; p = NULL; for (cp = compl_shown_match->cp_next; cp != NULL ! && !is_first_match(cp); cp = cp->cp_next) { if (compl_leader == NULL || ins_compl_equal(cp, compl_leader, *************** *** 1900,1906 **** } /* ! * Set the CTRL-X completion mode based on the key 'c' typed after a CTRL-X. * Uses the global variables: ctrl_x_mode, edit_submode, edit_submode_pre, * compl_cont_mode and compl_cont_status. * Returns TRUE when the character is not to be inserted. --- 2000,2006 ---- } /* ! * Set the CTRL-X completion mode based on the key "c" typed after a CTRL-X. * Uses the global variables: ctrl_x_mode, edit_submode, edit_submode_pre, * compl_cont_mode and compl_cont_status. * Returns TRUE when the character is not to be inserted. *************** *** 2105,2113 **** { ins_compl_delete(); if (compl_leader != NULL) ! ins_bytes(compl_leader + ins_compl_len()); else if (compl_first_match != NULL) ! ins_bytes(compl_orig_text + ins_compl_len()); retval = TRUE; } --- 2205,2213 ---- { ins_compl_delete(); if (compl_leader != NULL) ! ins_bytes(compl_leader + get_compl_len()); else if (compl_first_match != NULL) ! ins_bytes(compl_orig_text + get_compl_len()); retval = TRUE; } *************** *** 2225,2248 **** } // Set "compl_get_longest" when finding the first matches. ! if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET ! || (ctrl_x_mode == CTRL_X_NORMAL && !compl_started)) { compl_get_longest = (strstr((char *)p_cot, "longest") != NULL); compl_used_match = TRUE; } ! if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET) // We have just typed CTRL-X and aren't quite sure which CTRL-X mode // it will be yet. Now we decide. retval = set_ctrl_x_mode(c); ! else if (ctrl_x_mode != CTRL_X_NORMAL) { // We're already in CTRL-X mode, do we stay in it? if (!vim_is_ctrl_x_key(c)) { ! if (ctrl_x_mode == CTRL_X_SCROLL) ctrl_x_mode = CTRL_X_NORMAL; else ctrl_x_mode = CTRL_X_FINISHED; --- 2325,2348 ---- } // Set "compl_get_longest" when finding the first matches. ! if (ctrl_x_mode_not_defined_yet() ! || (ctrl_x_mode_normal() && !compl_started)) { compl_get_longest = (strstr((char *)p_cot, "longest") != NULL); compl_used_match = TRUE; } ! if (ctrl_x_mode_not_defined_yet()) // We have just typed CTRL-X and aren't quite sure which CTRL-X mode // it will be yet. Now we decide. retval = set_ctrl_x_mode(c); ! else if (ctrl_x_mode_not_default()) { // We're already in CTRL-X mode, do we stay in it? if (!vim_is_ctrl_x_key(c)) { ! if (ctrl_x_mode_scroll()) ctrl_x_mode = CTRL_X_NORMAL; else ctrl_x_mode = CTRL_X_FINISHED; *************** *** 2257,2263 **** // 'Pattern not found') until another key is hit, then go back to // showing what mode we are in. showmode(); ! if ((ctrl_x_mode == CTRL_X_NORMAL && c != Ctrl_N && c != Ctrl_P && c != Ctrl_R && !ins_compl_pum_key(c)) || ctrl_x_mode == CTRL_X_FINISHED) retval = ins_compl_stop(c, prev_mode, retval); --- 2357,2363 ---- // 'Pattern not found') until another key is hit, then go back to // showing what mode we are in. showmode(); ! if ((ctrl_x_mode_normal() && c != Ctrl_N && c != Ctrl_P && c != Ctrl_R && !ins_compl_pum_key(c)) || ctrl_x_mode == CTRL_X_FINISHED) retval = ins_compl_stop(c, prev_mode, retval); *************** *** 2390,2396 **** /* * Copy the global 'completefunc' callback function to the buffer-local ! * 'completefunc' callback for 'buf'. */ void set_buflocal_cfu_callback(buf_T *buf UNUSED) --- 2490,2496 ---- /* * Copy the global 'completefunc' callback function to the buffer-local ! * 'completefunc' callback for "buf". */ void set_buflocal_cfu_callback(buf_T *buf UNUSED) *************** *** 2420,2426 **** /* * Copy the global 'omnifunc' callback function to the buffer-local 'omnifunc' ! * callback for 'buf'. */ void set_buflocal_ofu_callback(buf_T *buf UNUSED) --- 2520,2526 ---- /* * Copy the global 'omnifunc' callback function to the buffer-local 'omnifunc' ! * callback for "buf". */ void set_buflocal_ofu_callback(buf_T *buf UNUSED) *************** *** 2458,2464 **** /* * Mark the global 'completefunc' 'omnifunc' and 'thesaurusfunc' callbacks with ! * 'copyID' so that they are not garbage collected. */ int set_ref_in_insexpand_funcs(int copyID) --- 2558,2564 ---- /* * Mark the global 'completefunc' 'omnifunc' and 'thesaurusfunc' callbacks with ! * "copyID" so that they are not garbage collected. */ int set_ref_in_insexpand_funcs(int copyID) *************** *** 2473,2479 **** } /* ! * Get the user-defined completion function name for completion 'type' */ static char_u * get_complete_funcname(int type) --- 2573,2579 ---- } /* ! * Get the user-defined completion function name for completion "type" */ static char_u * get_complete_funcname(int type) *************** *** 2494,2500 **** /* * Get the callback to use for insert mode completion. */ ! callback_T * get_insert_callback(int type) { if (type == CTRL_X_FUNCTION) --- 2594,2600 ---- /* * Get the callback to use for insert mode completion. */ ! static callback_T * get_insert_callback(int type) { if (type == CTRL_X_FUNCTION) *************** *** 2702,2708 **** int flags = CP_ORIGINAL_TEXT; // If already doing completions stop it. ! if (ctrl_x_mode != CTRL_X_NORMAL) ins_compl_prep(' '); ins_compl_clear(); ins_compl_free(); --- 2802,2808 ---- int flags = CP_ORIGINAL_TEXT; // If already doing completions stop it. ! if (ctrl_x_mode_not_default()) ins_compl_prep(' '); ins_compl_clear(); ins_compl_free(); *************** *** 2820,2827 **** static char_u * ins_compl_mode(void) { ! if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET || ctrl_x_mode == CTRL_X_SCROLL ! || compl_started) return (char_u *)ctrl_x_mode_names[ctrl_x_mode & ~CTRL_X_WANT_IDENT]; return (char_u *)""; --- 2920,2926 ---- static char_u * ins_compl_mode(void) { ! if (ctrl_x_mode_not_defined_yet() || ctrl_x_mode_scroll() || compl_started) return (char_u *)ctrl_x_mode_names[ctrl_x_mode & ~CTRL_X_WANT_IDENT]; return (char_u *)""; *************** *** 2837,2850 **** int number = 0; compl_T *match; ! if (compl_direction == FORWARD) { // search backwards for the first valid (!= -1) number. // This should normally succeed already at the first loop // cycle, so it's fast! for (match = compl_curr_match->cp_prev; match != NULL ! && match != compl_first_match; ! match = match->cp_prev) if (match->cp_number != -1) { number = match->cp_number; --- 2936,2948 ---- int number = 0; compl_T *match; ! if (compl_dir_forward()) { // search backwards for the first valid (!= -1) number. // This should normally succeed already at the first loop // cycle, so it's fast! for (match = compl_curr_match->cp_prev; match != NULL ! && !is_first_match(match); match = match->cp_prev) if (match->cp_number != -1) { number = match->cp_number; *************** *** 2864,2871 **** // number. This should normally succeed already at the // first loop cycle, so it's fast! for (match = compl_curr_match->cp_next; match != NULL ! && match != compl_first_match; ! match = match->cp_next) if (match->cp_number != -1) { number = match->cp_number; --- 2962,2968 ---- // number. This should normally succeed already at the // first loop cycle, so it's fast! for (match = compl_curr_match->cp_next; match != NULL ! && !is_first_match(match); match = match->cp_next) if (match->cp_number != -1) { number = match->cp_number; *************** *** 2941,2947 **** match = compl_first_match; do { ! if (!ins_compl_at_original_text(match)) { di = dict_alloc(); if (di == NULL) --- 3038,3044 ---- match = compl_first_match; do { ! if (!match_at_original_text(match)) { di = dict_alloc(); if (di == NULL) *************** *** 2962,2968 **** } match = match->cp_next; } ! while (match != NULL && match != compl_first_match); } } --- 3059,3065 ---- } match = match->cp_next; } ! while (match != NULL && !is_first_match(match)); } } *************** *** 3087,3093 **** st->first_match_pos = *start_match_pos; // Move the cursor back one character so that ^N can match the // word immediately after the cursor. ! if (ctrl_x_mode == CTRL_X_NORMAL && dec(&st->first_match_pos) < 0) { // Move the cursor to after the last character in the // buffer, so that word at start of buffer is found --- 3184,3190 ---- st->first_match_pos = *start_match_pos; // Move the cursor back one character so that ^N can match the // word immediately after the cursor. ! if (ctrl_x_mode_normal() && dec(&st->first_match_pos) < 0) { // Move the cursor to after the last character in the // buffer, so that word at start of buffer is found *************** *** 3241,3247 **** g_tag_at_cursor = TRUE; if (find_tags(compl_pattern, &num_matches, &matches, TAG_REGEXP | TAG_NAMES | TAG_NOIC | TAG_INS_COMP ! | (ctrl_x_mode != CTRL_X_NORMAL ? TAG_VERBOSE : 0), TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0) ins_compl_add_matches(num_matches, matches, p_ic); g_tag_at_cursor = FALSE; --- 3338,3344 ---- g_tag_at_cursor = TRUE; if (find_tags(compl_pattern, &num_matches, &matches, TAG_REGEXP | TAG_NAMES | TAG_NOIC | TAG_INS_COMP ! | (ctrl_x_mode_not_default() ? TAG_VERBOSE : 0), TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0) ins_compl_add_matches(num_matches, matches, p_ic); g_tag_at_cursor = FALSE; *************** *** 3338,3344 **** cur_match_pos->col; if (ctrl_x_mode_line_or_eval()) { ! if (compl_cont_status & CONT_ADDING) { if (cur_match_pos->lnum >= ins_buf->b_ml.ml_line_count) return NULL; --- 3435,3441 ---- cur_match_pos->col; if (ctrl_x_mode_line_or_eval()) { ! if (compl_status_adding()) { if (cur_match_pos->lnum >= ins_buf->b_ml.ml_line_count) return NULL; *************** *** 3352,3358 **** { char_u *tmp_ptr = ptr; ! if (compl_cont_status & CONT_ADDING) { tmp_ptr += compl_length; // Skip if already inside a word. --- 3449,3455 ---- { char_u *tmp_ptr = ptr; ! if (compl_status_adding()) { tmp_ptr += compl_length; // Skip if already inside a word. *************** *** 3365,3371 **** tmp_ptr = find_word_end(tmp_ptr); len = (int)(tmp_ptr - ptr); ! if ((compl_cont_status & CONT_ADDING) && len == compl_length) { if (cur_match_pos->lnum < ins_buf->b_ml.ml_line_count) { --- 3462,3468 ---- tmp_ptr = find_word_end(tmp_ptr); len = (int)(tmp_ptr - ptr); ! if (compl_status_adding() && len == compl_length) { if (cur_match_pos->lnum < ins_buf->b_ml.ml_line_count) { *************** *** 3457,3464 **** // ctrl_x_mode_line_or_eval() || word-wise search that // has added a word that was at the beginning of the line ! if (ctrl_x_mode_line_or_eval() ! || (compl_cont_status & CONT_SOL)) found_new_match = search_for_exact_line(st->ins_buf, st->cur_match_pos, compl_direction, compl_pattern); else --- 3554,3560 ---- // ctrl_x_mode_line_or_eval() || word-wise search that // has added a word that was at the beginning of the line ! if (ctrl_x_mode_line_or_eval() || (compl_cont_status & CONT_SOL)) found_new_match = search_for_exact_line(st->ins_buf, st->cur_match_pos, compl_direction, compl_pattern); else *************** *** 3479,3485 **** { found_new_match = FAIL; } ! else if ((compl_direction == FORWARD) && (st->prev_match_pos.lnum > st->cur_match_pos->lnum || (st->prev_match_pos.lnum == st->cur_match_pos->lnum && st->prev_match_pos.col >= st->cur_match_pos->col))) --- 3575,3581 ---- { found_new_match = FAIL; } ! else if (compl_dir_forward() && (st->prev_match_pos.lnum > st->cur_match_pos->lnum || (st->prev_match_pos.lnum == st->cur_match_pos->lnum && st->prev_match_pos.col >= st->cur_match_pos->col))) *************** *** 3489,3495 **** else looped_around = TRUE; } ! else if ((compl_direction != FORWARD) && (st->prev_match_pos.lnum < st->cur_match_pos->lnum || (st->prev_match_pos.lnum == st->cur_match_pos->lnum && st->prev_match_pos.col <= st->cur_match_pos->col))) --- 3585,3591 ---- else looped_around = TRUE; } ! else if (!compl_dir_forward() && (st->prev_match_pos.lnum < st->cur_match_pos->lnum || (st->prev_match_pos.lnum == st->cur_match_pos->lnum && st->prev_match_pos.col <= st->cur_match_pos->col))) *************** *** 3504,3510 **** break; // when ADDING, the text before the cursor matches, skip it ! if ((compl_cont_status & CONT_ADDING) && st->ins_buf == curbuf && start_pos->lnum == st->cur_match_pos->lnum && start_pos->col == st->cur_match_pos->col) continue; --- 3600,3606 ---- break; // when ADDING, the text before the cursor matches, skip it ! if (compl_status_adding() && st->ins_buf == curbuf && start_pos->lnum == st->cur_match_pos->lnum && start_pos->col == st->cur_match_pos->col) continue; *************** *** 3529,3535 **** } /* ! * get the next set of completion matches for 'type'. * Returns TRUE if a new match is found. Otherwise returns FALSE. */ static int --- 3625,3631 ---- } /* ! * get the next set of completion matches for "type". * Returns TRUE if a new match is found. Otherwise returns FALSE. */ static int *************** *** 3623,3629 **** st.ins_buf = curbuf; // In case the buffer was wiped out. compl_old_match = compl_curr_match; // remember the last current match ! st.cur_match_pos = (compl_direction == FORWARD) ? &st.last_match_pos : &st.first_match_pos; // For ^N/^P loop over all the flags/windows/buffers in 'complete'. --- 3719,3725 ---- st.ins_buf = curbuf; // In case the buffer was wiped out. compl_old_match = compl_curr_match; // remember the last current match ! st.cur_match_pos = (compl_dir_forward()) ? &st.last_match_pos : &st.first_match_pos; // For ^N/^P loop over all the flags/windows/buffers in 'complete'. *************** *** 3635,3642 **** // For ^N/^P pick a new entry from e_cpt if compl_started is off, // or if found_all says this entry is done. For ^X^L only use the // entries from 'complete' that look in loaded buffers. ! if ((ctrl_x_mode == CTRL_X_NORMAL ! || ctrl_x_mode_line_or_eval()) && (!compl_started || st.found_all)) { int status = process_next_cpt_value(&st, &type, ini); --- 3731,3737 ---- // For ^N/^P pick a new entry from e_cpt if compl_started is off, // or if found_all says this entry is done. For ^X^L only use the // entries from 'complete' that look in loaded buffers. ! if ((ctrl_x_mode_normal() || ctrl_x_mode_line_or_eval()) && (!compl_started || st.found_all)) { int status = process_next_cpt_value(&st, &type, ini); *************** *** 3658,3665 **** // break the loop for specialized modes (use 'complete' just for the // generic ctrl_x_mode == CTRL_X_NORMAL) or when we've found a new // match ! if ((ctrl_x_mode != CTRL_X_NORMAL ! && !ctrl_x_mode_line_or_eval()) || found_new_match != FAIL) { if (got_int) break; --- 3753,3760 ---- // break the loop for specialized modes (use 'complete' just for the // generic ctrl_x_mode == CTRL_X_NORMAL) or when we've found a new // match ! if ((ctrl_x_mode_not_default() && !ctrl_x_mode_line_or_eval()) ! || found_new_match != FAIL) { if (got_int) break; *************** *** 3667,3673 **** if (type != -1) ins_compl_check_keys(0, FALSE); ! if ((ctrl_x_mode != CTRL_X_NORMAL && !ctrl_x_mode_line_or_eval()) || compl_interrupted) break; compl_started = TRUE; --- 3762,3768 ---- if (type != -1) ins_compl_check_keys(0, FALSE); ! if ((ctrl_x_mode_not_default() && !ctrl_x_mode_line_or_eval()) || compl_interrupted) break; compl_started = TRUE; *************** *** 3683,3694 **** } compl_started = TRUE; ! if ((ctrl_x_mode == CTRL_X_NORMAL || ctrl_x_mode_line_or_eval()) && *st.e_cpt == NUL) // Got to end of 'complete' found_new_match = FAIL; i = -1; // total of matches, unknown ! if (found_new_match == FAIL || (ctrl_x_mode != CTRL_X_NORMAL && !ctrl_x_mode_line_or_eval())) i = ins_compl_make_cyclic(); --- 3778,3789 ---- } compl_started = TRUE; ! if ((ctrl_x_mode_normal() || ctrl_x_mode_line_or_eval()) && *st.e_cpt == NUL) // Got to end of 'complete' found_new_match = FAIL; i = -1; // total of matches, unknown ! if (found_new_match == FAIL || (ctrl_x_mode_not_default() && !ctrl_x_mode_line_or_eval())) i = ins_compl_make_cyclic(); *************** *** 3697,3703 **** // If several matches were added (FORWARD) or the search failed and has // just been made cyclic then we have to move compl_curr_match to the // next or previous entry (if any) -- Acevedo ! compl_curr_match = compl_direction == FORWARD ? compl_old_match->cp_next : compl_old_match->cp_prev; if (compl_curr_match == NULL) compl_curr_match = compl_old_match; --- 3792,3798 ---- // If several matches were added (FORWARD) or the search failed and has // just been made cyclic then we have to move compl_curr_match to the // next or previous entry (if any) -- Acevedo ! compl_curr_match = compl_dir_forward() ? compl_old_match->cp_next : compl_old_match->cp_prev; if (compl_curr_match == NULL) compl_curr_match = compl_old_match; *************** *** 3717,3737 **** while (!ins_compl_equal(compl_shown_match, compl_leader, (int)STRLEN(compl_leader)) && compl_shown_match->cp_next != NULL ! && compl_shown_match->cp_next != compl_first_match) compl_shown_match = compl_shown_match->cp_next; // If we didn't find it searching forward, and compl_shows_dir is // backward, find the last match. ! if (compl_shows_dir == BACKWARD && !ins_compl_equal(compl_shown_match, compl_leader, (int)STRLEN(compl_leader)) && (compl_shown_match->cp_next == NULL ! || compl_shown_match->cp_next == compl_first_match)) { while (!ins_compl_equal(compl_shown_match, compl_leader, (int)STRLEN(compl_leader)) && compl_shown_match->cp_prev != NULL ! && compl_shown_match->cp_prev != compl_first_match) compl_shown_match = compl_shown_match->cp_prev; } } --- 3812,3832 ---- while (!ins_compl_equal(compl_shown_match, compl_leader, (int)STRLEN(compl_leader)) && compl_shown_match->cp_next != NULL ! && !is_first_match(compl_shown_match->cp_next)) compl_shown_match = compl_shown_match->cp_next; // If we didn't find it searching forward, and compl_shows_dir is // backward, find the last match. ! if (compl_shows_dir_backward() && !ins_compl_equal(compl_shown_match, compl_leader, (int)STRLEN(compl_leader)) && (compl_shown_match->cp_next == NULL ! || is_first_match(compl_shown_match->cp_next))) { while (!ins_compl_equal(compl_shown_match, compl_leader, (int)STRLEN(compl_leader)) && compl_shown_match->cp_prev != NULL ! && !is_first_match(compl_shown_match->cp_prev)) compl_shown_match = compl_shown_match->cp_prev; } } *************** *** 3746,3752 **** // In insert mode: Delete the typed part. // In replace mode: Put the old characters back, if any. ! col = compl_col + (compl_cont_status & CONT_ADDING ? compl_length : 0); if ((int)curwin->w_cursor.col > col) { if (stop_arrow() == FAIL) --- 3841,3847 ---- // In insert mode: Delete the typed part. // In replace mode: Put the old characters back, if any. ! col = compl_col + (compl_status_adding() ? compl_length : 0); if ((int)curwin->w_cursor.col > col) { if (stop_arrow() == FAIL) *************** *** 3770,3782 **** void ins_compl_insert(int in_compl_func) { ! int compl_len = ins_compl_len(); // Make sure we don't go over the end of the string, this can happen with // illegal bytes. if (compl_len < (int)STRLEN(compl_shown_match->cp_str)) ins_bytes(compl_shown_match->cp_str + compl_len); ! if (ins_compl_at_original_text(compl_shown_match)) compl_used_match = FALSE; else compl_used_match = TRUE; --- 3865,3877 ---- void ins_compl_insert(int in_compl_func) { ! int compl_len = get_compl_len(); // Make sure we don't go over the end of the string, this can happen with // illegal bytes. if (compl_len < (int)STRLEN(compl_shown_match->cp_str)) ins_bytes(compl_shown_match->cp_str + compl_len); ! if (match_at_original_text(compl_shown_match)) compl_used_match = FALSE; else compl_used_match = TRUE; *************** *** 3827,3833 **** } /* ! * Find the next set of matches for completion. Repeat the completion 'todo' * times. The number of matches found is returned in 'num_matches'. * * If "allow_get_expansion" is TRUE, then ins_compl_get_exp() may be called to --- 3922,3928 ---- } /* ! * Find the next set of matches for completion. Repeat the completion "todo" * times. The number of matches found is returned in 'num_matches'. * * If "allow_get_expansion" is TRUE, then ins_compl_get_exp() may be called to *************** *** 3851,3869 **** while (--todo >= 0) { ! if (compl_shows_dir == FORWARD && compl_shown_match->cp_next != NULL) { compl_shown_match = compl_shown_match->cp_next; found_end = (compl_first_match != NULL ! && (compl_shown_match->cp_next == compl_first_match ! || compl_shown_match == compl_first_match)); } ! else if (compl_shows_dir == BACKWARD && compl_shown_match->cp_prev != NULL) { ! found_end = (compl_shown_match == compl_first_match); compl_shown_match = compl_shown_match->cp_prev; ! found_end |= (compl_shown_match == compl_first_match); } else { --- 3946,3964 ---- while (--todo >= 0) { ! if (compl_shows_dir_forward() && compl_shown_match->cp_next != NULL) { compl_shown_match = compl_shown_match->cp_next; found_end = (compl_first_match != NULL ! && (is_first_match(compl_shown_match->cp_next) ! || is_first_match(compl_shown_match))); } ! else if (compl_shows_dir_backward() && compl_shown_match->cp_prev != NULL) { ! found_end = is_first_match(compl_shown_match); compl_shown_match = compl_shown_match->cp_prev; ! found_end |= is_first_match(compl_shown_match); } else { *************** *** 3871,3877 **** { if (advance) { ! if (compl_shows_dir == BACKWARD) compl_pending -= todo + 1; else compl_pending += todo + 1; --- 3966,3972 ---- { if (advance) { ! if (compl_shows_dir_backward()) compl_pending -= todo + 1; else compl_pending += todo + 1; *************** *** 3881,3887 **** if (!compl_no_select && advance) { ! if (compl_shows_dir == BACKWARD) --compl_pending; else ++compl_pending; --- 3976,3982 ---- if (!compl_no_select && advance) { ! if (compl_shows_dir_backward()) --compl_pending; else ++compl_pending; *************** *** 3909,3915 **** } found_end = FALSE; } ! if (!ins_compl_at_original_text(compl_shown_match) && compl_leader != NULL && !ins_compl_equal(compl_shown_match, compl_leader, (int)STRLEN(compl_leader))) --- 4004,4010 ---- } found_end = FALSE; } ! if (!match_at_original_text(compl_shown_match) && compl_leader != NULL && !ins_compl_equal(compl_shown_match, compl_leader, (int)STRLEN(compl_leader))) *************** *** 3967,3974 **** if (compl_shown_match == NULL) return -1; ! if (compl_leader != NULL ! && !ins_compl_at_original_text(compl_shown_match)) // Update "compl_shown_match" to the actually shown match ins_compl_update_shown_match(); --- 4062,4068 ---- if (compl_shown_match == NULL) return -1; ! if (compl_leader != NULL && !match_at_original_text(compl_shown_match)) // Update "compl_shown_match" to the actually shown match ins_compl_update_shown_match(); *************** *** 3997,4003 **** // Insert the text of the new completion, or the compl_leader. if (compl_no_insert && !started) { ! ins_bytes(compl_orig_text + ins_compl_len()); compl_used_match = FALSE; } else if (insert_match) --- 4091,4097 ---- // Insert the text of the new completion, or the compl_leader. if (compl_no_insert && !started) { ! ins_bytes(compl_orig_text + get_compl_len()); compl_used_match = FALSE; } else if (insert_match) *************** *** 4005,4011 **** if (!compl_get_longest || compl_used_match) ins_compl_insert(in_compl_func); else ! ins_bytes(compl_leader + ins_compl_len()); } else compl_used_match = FALSE; --- 4099,4105 ---- if (!compl_get_longest || compl_used_match) ins_compl_insert(in_compl_func); else ! ins_bytes(compl_leader + get_compl_len()); } else compl_used_match = FALSE; *************** *** 4191,4199 **** static int get_normal_compl_info(char_u *line, int startcol, colnr_T curs_col) { ! if ((compl_cont_status & CONT_SOL) || ctrl_x_mode == CTRL_X_PATH_DEFINES) { ! if (!(compl_cont_status & CONT_ADDING)) { while (--startcol >= 0 && vim_isIDc(line[startcol])) ; --- 4285,4293 ---- static int get_normal_compl_info(char_u *line, int startcol, colnr_T curs_col) { ! if ((compl_cont_status & CONT_SOL) || ctrl_x_mode_path_defines()) { ! if (!compl_status_adding()) { while (--startcol >= 0 && vim_isIDc(line[startcol])) ; *************** *** 4208,4214 **** if (compl_pattern == NULL) return FAIL; } ! else if (compl_cont_status & CONT_ADDING) { char_u *prefix = (char_u *)"\\<"; --- 4302,4308 ---- if (compl_pattern == NULL) return FAIL; } ! else if (compl_status_adding()) { char_u *prefix = (char_u *)"\\<"; *************** *** 4391,4397 **** funcname = get_complete_funcname(ctrl_x_mode); if (*funcname == NUL) { ! semsg(_(e_option_str_is_not_set), ctrl_x_mode == CTRL_X_FUNCTION ? "completefunc" : "omnifunc"); return FAIL; } --- 4485,4491 ---- funcname = get_complete_funcname(ctrl_x_mode); if (*funcname == NUL) { ! semsg(_(e_option_str_is_not_set), ctrl_x_mode_function() ? "completefunc" : "omnifunc"); return FAIL; } *************** *** 4495,4505 **** /* * Get the completion pattern, column and length. */ static int compl_get_info(char_u *line, int startcol, colnr_T curs_col, int *line_invalid) { ! if (ctrl_x_mode == CTRL_X_NORMAL || (ctrl_x_mode & CTRL_X_WANT_IDENT && !thesaurus_func_complete(ctrl_x_mode))) { --- 4589,4604 ---- /* * Get the completion pattern, column and length. + * "startcol" - start column number of the completion pattern/text + * "cur_col" - current cursor column + * On return, "line_invalid" is set to TRUE, if the current line may have + * become invalid and needs to be fetched again. + * Returns OK on success. */ static int compl_get_info(char_u *line, int startcol, colnr_T curs_col, int *line_invalid) { ! if (ctrl_x_mode_normal() || (ctrl_x_mode & CTRL_X_WANT_IDENT && !thesaurus_func_complete(ctrl_x_mode))) { *************** *** 4509,4515 **** { return get_wholeline_compl_info(line, curs_col); } ! else if (ctrl_x_mode == CTRL_X_FILES) { return get_filename_compl_info(line, startcol, curs_col); } --- 4608,4614 ---- { return get_wholeline_compl_info(line, curs_col); } ! else if (ctrl_x_mode_files()) { return get_filename_compl_info(line, startcol, curs_col); } *************** *** 4517,4534 **** { return get_cmdline_compl_info(line, curs_col); } ! else if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI || thesaurus_func_complete(ctrl_x_mode)) { if (get_userdefined_compl_info(curs_col) == FAIL) return FAIL; ! *line_invalid = TRUE; // 'line' may have become invalid } ! else if (ctrl_x_mode == CTRL_X_SPELL) { if (get_spell_compl_info(startcol, curs_col) == FAIL) return FAIL; ! *line_invalid = TRUE; // 'line' may have become invalid } else { --- 4616,4633 ---- { return get_cmdline_compl_info(line, curs_col); } ! else if (ctrl_x_mode_function() || ctrl_x_mode_omni() || thesaurus_func_complete(ctrl_x_mode)) { if (get_userdefined_compl_info(curs_col) == FAIL) return FAIL; ! *line_invalid = TRUE; // "line" may have become invalid } ! else if (ctrl_x_mode_spell()) { if (get_spell_compl_info(startcol, curs_col) == FAIL) return FAIL; ! *line_invalid = TRUE; // "line" may have become invalid } else { *************** *** 4554,4562 **** { // it is a continued search compl_cont_status &= ~CONT_INTRPT; // remove INTRPT ! if (ctrl_x_mode == CTRL_X_NORMAL ! || ctrl_x_mode == CTRL_X_PATH_PATTERNS ! || ctrl_x_mode == CTRL_X_PATH_DEFINES) { if (compl_startpos.lnum != curwin->w_cursor.lnum) { --- 4653,4660 ---- { // it is a continued search compl_cont_status &= ~CONT_INTRPT; // remove INTRPT ! if (ctrl_x_mode_normal() || ctrl_x_mode_path_patterns() ! || ctrl_x_mode_path_defines()) { if (compl_startpos.lnum != curwin->w_cursor.lnum) { *************** *** 4639,4648 **** else compl_cont_status &= CONT_LOCAL; ! if (!(compl_cont_status & CONT_ADDING)) // normal expansion { compl_cont_mode = ctrl_x_mode; ! if (ctrl_x_mode != CTRL_X_NORMAL) // Remove LOCAL if ctrl_x_mode != CTRL_X_NORMAL compl_cont_status = 0; compl_cont_status |= CONT_N_ADDS; --- 4737,4746 ---- else compl_cont_status &= CONT_LOCAL; ! if (!compl_status_adding()) // normal expansion { compl_cont_mode = ctrl_x_mode; ! if (ctrl_x_mode_not_default()) // Remove LOCAL if ctrl_x_mode != CTRL_X_NORMAL compl_cont_status = 0; compl_cont_status |= CONT_N_ADDS; *************** *** 4654,4661 **** // Work out completion pattern and original text -- webb if (compl_get_info(line, startcol, curs_col, &line_invalid) == FAIL) { ! if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI ! || thesaurus_func_complete(ctrl_x_mode)) // restore did_ai, so that adding comment leader works did_ai = save_did_ai; return FAIL; --- 4752,4759 ---- // Work out completion pattern and original text -- webb if (compl_get_info(line, startcol, curs_col, &line_invalid) == FAIL) { ! if (ctrl_x_mode_function() || ctrl_x_mode_omni() ! || thesaurus_func_complete(ctrl_x_mode)) // restore did_ai, so that adding comment leader works did_ai = save_did_ai; return FAIL; *************** *** 4664,4670 **** if (line_invalid) line = ml_get(curwin->w_cursor.lnum); ! if (compl_cont_status & CONT_ADDING) { edit_submode_pre = (char_u *)_(" Adding"); if (ctrl_x_mode_line_or_eval()) --- 4762,4768 ---- if (line_invalid) line = ml_get(curwin->w_cursor.lnum); ! if (compl_status_adding()) { edit_submode_pre = (char_u *)_(" Adding"); if (ctrl_x_mode_line_or_eval()) *************** *** 4728,4737 **** ins_compl_show_statusmsg(void) { // we found no match if the list has only the "compl_orig_text"-entry ! if (compl_first_match == compl_first_match->cp_next) { ! edit_submode_extra = (compl_cont_status & CONT_ADDING) ! && compl_length > 1 ? (char_u *)_(e_hitend) : (char_u *)_(e_pattern_not_found); edit_submode_highl = HLF_E; --- 4826,4834 ---- ins_compl_show_statusmsg(void) { // we found no match if the list has only the "compl_orig_text"-entry ! if (is_first_match(compl_first_match->cp_next)) { ! edit_submode_extra = compl_status_adding() && compl_length > 1 ? (char_u *)_(e_hitend) : (char_u *)_(e_pattern_not_found); edit_submode_highl = HLF_E; *************** *** 4739,4745 **** if (edit_submode_extra == NULL) { ! if (ins_compl_at_original_text(compl_curr_match)) { edit_submode_extra = (char_u *)_("Back at original"); edit_submode_highl = HLF_W; --- 4836,4842 ---- if (edit_submode_extra == NULL) { ! if (match_at_original_text(compl_curr_match)) { edit_submode_extra = (char_u *)_("Back at original"); edit_submode_highl = HLF_W; *************** *** 4858,4874 **** } // we found no match if the list has only the "compl_orig_text"-entry ! if (compl_first_match == compl_first_match->cp_next) { // remove N_ADDS flag, so next ^X<> won't try to go to ADDING mode, // because we couldn't expand anything at first place, but if we used // ^P, ^N, ^X^I or ^X^D we might want to add-expand a single-char-word // (such as M in M'exico) if not tried already. -- Acevedo if (compl_length > 1 ! || (compl_cont_status & CONT_ADDING) ! || (ctrl_x_mode != CTRL_X_NORMAL ! && ctrl_x_mode != CTRL_X_PATH_PATTERNS ! && ctrl_x_mode != CTRL_X_PATH_DEFINES)) compl_cont_status &= ~CONT_N_ADDS; } --- 4955,4971 ---- } // we found no match if the list has only the "compl_orig_text"-entry ! if (is_first_match(compl_first_match->cp_next)) { // remove N_ADDS flag, so next ^X<> won't try to go to ADDING mode, // because we couldn't expand anything at first place, but if we used // ^P, ^N, ^X^I or ^X^D we might want to add-expand a single-char-word // (such as M in M'exico) if not tried already. -- Acevedo if (compl_length > 1 ! || compl_status_adding() ! || (ctrl_x_mode_not_default() ! && !ctrl_x_mode_path_patterns() ! && !ctrl_x_mode_path_defines())) compl_cont_status &= ~CONT_N_ADDS; } *************** *** 4929,4936 **** case '.': case '*': case '[': ! if (ctrl_x_mode == CTRL_X_DICTIONARY ! || ctrl_x_mode == CTRL_X_THESAURUS) break; // FALLTHROUGH case '~': --- 5026,5032 ---- case '.': case '*': case '[': ! if (ctrl_x_mode_dictionary() || ctrl_x_mode_thesaurus()) break; // FALLTHROUGH case '~': *************** *** 4938,4945 **** break; // FALLTHROUGH case '\\': ! if (ctrl_x_mode == CTRL_X_DICTIONARY ! || ctrl_x_mode == CTRL_X_THESAURUS) break; // FALLTHROUGH case '^': // currently it's not needed. --- 5034,5040 ---- break; // FALLTHROUGH case '\\': ! if (ctrl_x_mode_dictionary() || ctrl_x_mode_thesaurus()) break; // FALLTHROUGH case '^': // currently it's not needed. *** ../vim-8.2.4000/src/proto/insexpand.pro 2021-12-12 16:26:35.868627601 +0000 --- src/proto/insexpand.pro 2022-01-04 16:56:10.531131161 +0000 *************** *** 17,22 **** --- 17,26 ---- int ctrl_x_mode_line_or_eval(void); int ctrl_x_mode_not_default(void); int ctrl_x_mode_not_defined_yet(void); + int compl_status_adding(void); + int compl_status_sol(void); + int compl_status_local(void); + void compl_status_clear(void); int has_compl_option(int dict_opt); int vim_is_ctrl_x_key(int c); int ins_compl_accept_char(int c); *************** *** 35,40 **** --- 39,45 ---- int ins_compl_interrupted(void); int ins_compl_enter_selects(void); colnr_T ins_compl_col(void); + int ins_compl_len(void); int ins_compl_bs(void); void ins_compl_addleader(int c); void ins_compl_addfrommatch(void); *************** *** 45,51 **** void set_buflocal_ofu_callback(buf_T *buf); int set_thesaurusfunc_option(void); int set_ref_in_insexpand_funcs(int copyID); - callback_T *get_insert_callback(int type); void f_complete(typval_T *argvars, typval_T *rettv); void f_complete_add(typval_T *argvars, typval_T *rettv); void f_complete_check(typval_T *argvars, typval_T *rettv); --- 50,55 ---- *** ../vim-8.2.4000/src/search.c 2022-01-02 19:25:22.850078488 +0000 --- src/search.c 2022-01-04 16:56:10.535131155 +0000 *************** *** 1727,1742 **** // 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; } } --- 1727,1741 ---- // 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_status_adding() && !compl_status_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, ins_compl_len()) ! : STRNCMP(p, pat, ins_compl_len())) == 0) return OK; } } *************** *** 3317,3323 **** #if defined(FEAT_FIND_ID) || defined(PROTO) /* * Find identifiers or defines in included files. ! * If p_ic && (compl_cont_status & CONT_SOL) then ptr must be in lowercase. */ void find_pattern_in_path( --- 3316,3322 ---- #if defined(FEAT_FIND_ID) || defined(PROTO) /* * Find identifiers or defines in included files. ! * If p_ic && compl_status_sol() then ptr must be in lowercase. */ void find_pattern_in_path( *************** *** 3375,3383 **** 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) --- 3374,3382 ---- 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_status_sol()) { pat = alloc(len + 5); if (pat == NULL) *************** *** 3652,3658 **** */ if (def_regmatch.regprog == NULL || define_matched) { ! if (define_matched || (compl_cont_status & CONT_SOL)) { // compare the first "len" chars from "ptr" startp = skipwhite(p); --- 3651,3657 ---- */ if (def_regmatch.regprog == NULL || define_matched) { ! if (define_matched || compl_status_sol()) { // compare the first "len" chars from "ptr" startp = skipwhite(p); *************** *** 3725,3733 **** break; found = TRUE; aux = p = startp; ! if (compl_cont_status & CONT_ADDING) { ! p += compl_length; if (vim_iswordp(p)) goto exit_matched; p = find_word_start(p); --- 3724,3732 ---- break; found = TRUE; aux = p = startp; ! if (compl_status_adding()) { ! p += ins_compl_len(); if (vim_iswordp(p)) goto exit_matched; p = find_word_start(p); *************** *** 3735,3741 **** p = find_word_end(p); i = (int)(p - aux); ! if ((compl_cont_status & CONT_ADDING) && i == compl_length) { // IOSIZE > compl_length, so the STRNCPY works STRNCPY(IObuff, aux, i); --- 3734,3740 ---- p = find_word_end(p); i = (int)(p - aux); ! if (compl_status_adding() && i == ins_compl_len()) { // IOSIZE > compl_length, so the STRNCPY works STRNCPY(IObuff, aux, i); *************** *** 3783,3789 **** IObuff[i] = NUL; aux = IObuff; ! if (i == compl_length) goto exit_matched; } --- 3782,3788 ---- IObuff[i] = NUL; aux = IObuff; ! if (i == ins_compl_len()) goto exit_matched; } *************** *** 3916,3922 **** // are not at the end of it already if (def_regmatch.regprog == NULL && action == ACTION_EXPAND ! && !(compl_cont_status & CONT_SOL) && *startp != NUL && *(p = startp + mb_ptr2len(startp)) != NUL) goto search_line; --- 3915,3921 ---- // are not at the end of it already if (def_regmatch.regprog == NULL && action == ACTION_EXPAND ! && !compl_status_sol() && *startp != NUL && *(p = startp + mb_ptr2len(startp)) != NUL) goto search_line; *** ../vim-8.2.4000/src/version.c 2022-01-04 16:44:52.980024484 +0000 --- src/version.c 2022-01-04 16:57:42.927001386 +0000 *************** *** 752,753 **** --- 752,755 ---- { /* Add new patch number below this line */ + /**/ + 4001, /**/ -- 'Psychologist' -- Someone who looks at everyone else when an attractive woman enters the room. /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// \\\ \\\ sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///