# HG changeset patch # User Bram Moolenaar # Date 1641316503 -3600 # Node ID 8dbdd68627bdaa3c4d8dc4f416ea1789bb299feb # Parent 61f686b38df9ee0e12bb7c0c2d00b3ec55262ded patch 8.2.4001: insert complete code uses global variables Commit: https://github.com/vim/vim/commit/d94fbfc74a8b8073e7a256c95fa6f39fc527c726 Author: Yegappan Lakshmanan Date: Tue Jan 4 17:01:44 2022 +0000 patch 8.2.4001: insert complete code uses global variables Problem: Insert complete code uses global variables. Solution: Make variables local to the file and use accessor functions. (Yegappan Lakshmanan, closes #9470) diff --git a/src/edit.c b/src/edit.c --- a/src/edit.c +++ b/src/edit.c @@ -1280,7 +1280,7 @@ doESCkey: // 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)) + && !compl_status_local()) goto normalchar; docomplete: @@ -1289,7 +1289,7 @@ docomplete: disable_fold_update++; // don't redraw folds here #endif if (ins_complete(c, TRUE) == FAIL) - compl_cont_status = 0; + compl_status_clear(); #ifdef FEAT_FOLDING disable_fold_update--; #endif diff --git a/src/getchar.c b/src/getchar.c --- a/src/getchar.c +++ b/src/getchar.c @@ -2453,7 +2453,7 @@ handle_mapping( && State != ASKMORE && State != CONFIRM && !((ctrl_x_mode_not_default() && at_ctrl_x_key()) - || ((compl_cont_status & CONT_LOCAL) + || (compl_status_local() && (tb_c1 == Ctrl_N || tb_c1 == Ctrl_P)))) { #ifdef FEAT_GUI diff --git a/src/globals.h b/src/globals.h --- a/src/globals.h +++ b/src/globals.h @@ -163,23 +163,6 @@ EXTERN colnr_T dollar_vcol INIT(= -1); * 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 diff --git a/src/insexpand.c b/src/insexpand.c --- a/src/insexpand.c +++ b/src/insexpand.c @@ -177,12 +177,15 @@ static int compl_started = FALSE; // Which Ctrl-X mode are we in? static int ctrl_x_mode = CTRL_X_NORMAL; -static int compl_matches = 0; +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,6 +193,19 @@ static char_u *compl_orig_text = NULL; 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,7 +217,7 @@ static char_u *find_line_end(char_u *ptr 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 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,6 +284,7 @@ int ctrl_x_mode_cmdline(void) { 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,7 +308,72 @@ ctrl_x_mode_not_defined_yet(void) } /* - * Return TRUE if the 'dict' or 'tsr' option can be used. + * 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,7 +410,7 @@ has_compl_option(int dict_opt) } /* - * Is the character 'c' a valid key to go to or keep us in CTRL-X mode? + * 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,16 +474,24 @@ vim_is_ctrl_x_key(int c) } /* - * Returns TRUE if the currently shown text is the original text when the - * completion began. + * Return TRUE if "match" is the original text when the completion began. */ static int -ins_compl_at_original_text(compl_T *match) +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,12 +736,12 @@ ins_compl_add( match = compl_first_match; do { - if (!ins_compl_at_original_text(match) + 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 && match != compl_first_match); + } while (match != NULL && !is_first_match(match)); } // Remove any popup menu before changing the list of matches. @@ -763,7 +853,7 @@ ins_compl_longest_match(compl_T *match) had_match = (curwin->w_cursor.col > compl_col); ins_compl_delete(); - ins_bytes(compl_leader + ins_compl_len()); + ins_bytes(compl_leader + get_compl_len()); ins_redraw(FALSE); // When the match isn't there (to avoid matching itself) remove it @@ -811,7 +901,7 @@ ins_compl_longest_match(compl_T *match) *p = NUL; had_match = (curwin->w_cursor.col > compl_col); ins_compl_delete(); - ins_bytes(compl_leader + ins_compl_len()); + ins_bytes(compl_leader + get_compl_len()); ins_redraw(FALSE); // When the match isn't there (to avoid matching itself) remove it @@ -861,7 +951,7 @@ ins_compl_make_cyclic(void) // 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) + while (match->cp_next != NULL && !is_first_match(match->cp_next)) { match = match->cp_next; ++count; @@ -980,11 +1070,10 @@ pum_enough_matches(void) i = 0; do { - if (compl == NULL - || (!ins_compl_at_original_text(compl) && ++i == 2)) + if (compl == NULL || (!match_at_original_text(compl) && ++i == 2)) break; compl = compl->cp_next; - } while (compl != compl_first_match); + } while (!is_first_match(compl)); if (strstr((char *)p_cot, "menuone") != NULL) return (i >= 1); @@ -1077,12 +1166,12 @@ ins_compl_build_pum(void) do { - if (!ins_compl_at_original_text(compl) + 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 && compl != compl_first_match); + } while (compl != NULL && !is_first_match(compl)); if (compl_match_arraysize == 0) return -1; @@ -1093,14 +1182,14 @@ ins_compl_build_pum(void) // 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)) + if (match_at_original_text(compl_shown_match)) shown_match_ok = TRUE; i = 0; compl = compl_first_match; do { - if (!ins_compl_at_original_text(compl) + if (!match_at_original_text(compl) && (compl_leader == NULL || ins_compl_equal(compl, compl_leader, lead_len))) { @@ -1141,7 +1230,7 @@ ins_compl_build_pum(void) // When the original text is the shown match don't set // compl_shown_match. - if (ins_compl_at_original_text(compl)) + if (match_at_original_text(compl)) shown_match_ok = TRUE; if (!shown_match_ok && shown_compl != NULL) @@ -1153,7 +1242,7 @@ ins_compl_build_pum(void) } } compl = compl->cp_next; - } while (compl != NULL && compl != compl_first_match); + } while (compl != NULL && !is_first_match(compl)); if (!shown_match_ok) // no displayed match at all cur = -1; @@ -1568,12 +1657,15 @@ ins_compl_free(void) clear_tv(&match->cp_user_data); #endif vim_free(match); - } while (compl_curr_match != NULL && compl_curr_match != compl_first_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,6 +1740,15 @@ ins_compl_col(void) } /* + * 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,9 +1768,8 @@ ins_compl_bs(void) // 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 + || ((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,7 +1802,7 @@ ins_compl_need_restart(void) // 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) + || ((ctrl_x_mode_function() || ctrl_x_mode_omni()) && compl_opt_refresh_always); } @@ -1716,7 +1816,7 @@ ins_compl_new_leader(void) { ins_compl_del_pum(); ins_compl_delete(); - ins_bytes(compl_leader + ins_compl_len()); + ins_bytes(compl_leader + get_compl_len()); compl_used_match = FALSE; if (compl_started) @@ -1759,7 +1859,7 @@ ins_compl_new_leader(void) * the cursor column. Making sure it never goes below zero. */ static int -ins_compl_len(void) +get_compl_len(void) { int off = (int)curwin->w_cursor.col - (int)compl_col; @@ -1838,7 +1938,7 @@ ins_compl_set_original_text(char_u *str) // 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 + if (match_at_original_text(compl_first_match)) // safety check { p = vim_strsave(str); if (p != NULL) @@ -1848,7 +1948,7 @@ ins_compl_set_original_text(char_u *str) } } else if (compl_first_match->cp_prev != NULL - && ins_compl_at_original_text(compl_first_match->cp_prev)) + && match_at_original_text(compl_first_match->cp_prev)) { p = vim_strsave(str); if (p != NULL) @@ -1876,12 +1976,12 @@ ins_compl_addfrommatch(void) { // When still at the original match use the first entry that matches // the leader. - if (!ins_compl_at_original_text(compl_shown_match)) + if (!match_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) + && !is_first_match(cp); cp = cp->cp_next) { if (compl_leader == NULL || ins_compl_equal(cp, compl_leader, @@ -1900,7 +2000,7 @@ ins_compl_addfrommatch(void) } /* - * Set the CTRL-X completion mode based on the key 'c' typed after a CTRL-X. + * 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,9 +2205,9 @@ ins_compl_stop(int c, int prev_mode, int { ins_compl_delete(); if (compl_leader != NULL) - ins_bytes(compl_leader + ins_compl_len()); + ins_bytes(compl_leader + get_compl_len()); else if (compl_first_match != NULL) - ins_bytes(compl_orig_text + ins_compl_len()); + ins_bytes(compl_orig_text + get_compl_len()); retval = TRUE; } @@ -2225,24 +2325,24 @@ ins_compl_prep(int c) } // 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)) + 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 == CTRL_X_NOT_DEFINED_YET) + 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 != CTRL_X_NORMAL) + 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 == CTRL_X_SCROLL) + if (ctrl_x_mode_scroll()) ctrl_x_mode = CTRL_X_NORMAL; else ctrl_x_mode = CTRL_X_FINISHED; @@ -2257,7 +2357,7 @@ ins_compl_prep(int c) // '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 + 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,7 +2490,7 @@ set_completefunc_option(void) /* * Copy the global 'completefunc' callback function to the buffer-local - * 'completefunc' callback for 'buf'. + * 'completefunc' callback for "buf". */ void set_buflocal_cfu_callback(buf_T *buf UNUSED) @@ -2420,7 +2520,7 @@ set_omnifunc_option(void) /* * Copy the global 'omnifunc' callback function to the buffer-local 'omnifunc' - * callback for 'buf'. + * callback for "buf". */ void set_buflocal_ofu_callback(buf_T *buf UNUSED) @@ -2458,7 +2558,7 @@ set_thesaurusfunc_option(void) /* * Mark the global 'completefunc' 'omnifunc' and 'thesaurusfunc' callbacks with - * 'copyID' so that they are not garbage collected. + * "copyID" so that they are not garbage collected. */ int set_ref_in_insexpand_funcs(int copyID) @@ -2473,7 +2573,7 @@ set_ref_in_insexpand_funcs(int copyID) } /* - * Get the user-defined completion function name for completion 'type' + * Get the user-defined completion function name for completion "type" */ static char_u * get_complete_funcname(int type) @@ -2494,7 +2594,7 @@ get_complete_funcname(int type) /* * Get the callback to use for insert mode completion. */ - callback_T * + static callback_T * get_insert_callback(int type) { if (type == CTRL_X_FUNCTION) @@ -2702,7 +2802,7 @@ set_completion(colnr_T startcol, list_T int flags = CP_ORIGINAL_TEXT; // If already doing completions stop it. - if (ctrl_x_mode != CTRL_X_NORMAL) + if (ctrl_x_mode_not_default()) ins_compl_prep(' '); ins_compl_clear(); ins_compl_free(); @@ -2820,8 +2920,7 @@ f_complete_check(typval_T *argvars UNUSE static char_u * ins_compl_mode(void) { - if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET || ctrl_x_mode == CTRL_X_SCROLL - || compl_started) + 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,14 +2936,13 @@ ins_compl_update_sequence_numbers() int number = 0; compl_T *match; - if (compl_direction == FORWARD) + 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 - && match != compl_first_match; - match = match->cp_prev) + && !is_first_match(match); match = match->cp_prev) if (match->cp_number != -1) { number = match->cp_number; @@ -2864,8 +2962,7 @@ ins_compl_update_sequence_numbers() // 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) + && !is_first_match(match); match = match->cp_next) if (match->cp_number != -1) { number = match->cp_number; @@ -2941,7 +3038,7 @@ get_complete_info(list_T *what_list, dic match = compl_first_match; do { - if (!ins_compl_at_original_text(match)) + if (!match_at_original_text(match)) { di = dict_alloc(); if (di == NULL) @@ -2962,7 +3059,7 @@ get_complete_info(list_T *what_list, dic } match = match->cp_next; } - while (match != NULL && match != compl_first_match); + while (match != NULL && !is_first_match(match)); } } @@ -3087,7 +3184,7 @@ process_next_cpt_value( 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) + 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,7 +3338,7 @@ get_next_tag_completion(void) 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), + | (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,7 +3435,7 @@ ins_comp_get_next_word_or_line( cur_match_pos->col; if (ctrl_x_mode_line_or_eval()) { - if (compl_cont_status & CONT_ADDING) + if (compl_status_adding()) { if (cur_match_pos->lnum >= ins_buf->b_ml.ml_line_count) return NULL; @@ -3352,7 +3449,7 @@ ins_comp_get_next_word_or_line( { char_u *tmp_ptr = ptr; - if (compl_cont_status & CONT_ADDING) + if (compl_status_adding()) { tmp_ptr += compl_length; // Skip if already inside a word. @@ -3365,7 +3462,7 @@ ins_comp_get_next_word_or_line( tmp_ptr = find_word_end(tmp_ptr); len = (int)(tmp_ptr - ptr); - if ((compl_cont_status & CONT_ADDING) && len == compl_length) + if (compl_status_adding() && len == compl_length) { if (cur_match_pos->lnum < ins_buf->b_ml.ml_line_count) { @@ -3457,8 +3554,7 @@ get_next_default_completion(ins_compl_ne // 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)) + 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,7 +3575,7 @@ get_next_default_completion(ins_compl_ne { found_new_match = FAIL; } - else if ((compl_direction == FORWARD) + 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,7 +3585,7 @@ get_next_default_completion(ins_compl_ne else looped_around = TRUE; } - else if ((compl_direction != FORWARD) + 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,7 +3600,7 @@ get_next_default_completion(ins_compl_ne break; // when ADDING, the text before the cursor matches, skip it - if ((compl_cont_status & CONT_ADDING) && st->ins_buf == curbuf + 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,7 +3625,7 @@ get_next_default_completion(ins_compl_ne } /* - * get the next set of completion matches for 'type'. + * get the next set of completion matches for "type". * Returns TRUE if a new match is found. Otherwise returns FALSE. */ static int @@ -3623,7 +3719,7 @@ ins_compl_get_exp(pos_T *ini) 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.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,8 +3731,7 @@ ins_compl_get_exp(pos_T *ini) // 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()) + 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,8 +3753,8 @@ ins_compl_get_exp(pos_T *ini) // 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 ((ctrl_x_mode_not_default() && !ctrl_x_mode_line_or_eval()) + || found_new_match != FAIL) { if (got_int) break; @@ -3667,7 +3762,7 @@ ins_compl_get_exp(pos_T *ini) if (type != -1) ins_compl_check_keys(0, FALSE); - if ((ctrl_x_mode != CTRL_X_NORMAL + if ((ctrl_x_mode_not_default() && !ctrl_x_mode_line_or_eval()) || compl_interrupted) break; compl_started = TRUE; @@ -3683,12 +3778,12 @@ ins_compl_get_exp(pos_T *ini) } compl_started = TRUE; - if ((ctrl_x_mode == CTRL_X_NORMAL || ctrl_x_mode_line_or_eval()) + 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 != CTRL_X_NORMAL + if (found_new_match == FAIL || (ctrl_x_mode_not_default() && !ctrl_x_mode_line_or_eval())) i = ins_compl_make_cyclic(); @@ -3697,7 +3792,7 @@ ins_compl_get_exp(pos_T *ini) // 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_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,21 +3812,21 @@ ins_compl_update_shown_match(void) 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) + && !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 + 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)) + || 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 - && compl_shown_match->cp_prev != compl_first_match) + && !is_first_match(compl_shown_match->cp_prev)) compl_shown_match = compl_shown_match->cp_prev; } } @@ -3746,7 +3841,7 @@ ins_compl_delete(void) // 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); + col = compl_col + (compl_status_adding() ? compl_length : 0); if ((int)curwin->w_cursor.col > col) { if (stop_arrow() == FAIL) @@ -3770,13 +3865,13 @@ ins_compl_delete(void) void ins_compl_insert(int in_compl_func) { - int compl_len = ins_compl_len(); + 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 (ins_compl_at_original_text(compl_shown_match)) + if (match_at_original_text(compl_shown_match)) compl_used_match = FALSE; else compl_used_match = TRUE; @@ -3827,7 +3922,7 @@ ins_compl_show_filename(void) } /* - * Find the next set of matches for completion. Repeat the completion 'todo' + * 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,19 +3946,19 @@ find_next_completion_match( while (--todo >= 0) { - if (compl_shows_dir == FORWARD && compl_shown_match->cp_next != NULL) + 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)); + && (is_first_match(compl_shown_match->cp_next) + || is_first_match(compl_shown_match))); } - else if (compl_shows_dir == BACKWARD + else if (compl_shows_dir_backward() && compl_shown_match->cp_prev != NULL) { - found_end = (compl_shown_match == compl_first_match); + found_end = is_first_match(compl_shown_match); compl_shown_match = compl_shown_match->cp_prev; - found_end |= (compl_shown_match == compl_first_match); + found_end |= is_first_match(compl_shown_match); } else { @@ -3871,7 +3966,7 @@ find_next_completion_match( { if (advance) { - if (compl_shows_dir == BACKWARD) + if (compl_shows_dir_backward()) compl_pending -= todo + 1; else compl_pending += todo + 1; @@ -3881,7 +3976,7 @@ find_next_completion_match( if (!compl_no_select && advance) { - if (compl_shows_dir == BACKWARD) + if (compl_shows_dir_backward()) --compl_pending; else ++compl_pending; @@ -3909,7 +4004,7 @@ find_next_completion_match( } found_end = FALSE; } - if (!ins_compl_at_original_text(compl_shown_match) + if (!match_at_original_text(compl_shown_match) && compl_leader != NULL && !ins_compl_equal(compl_shown_match, compl_leader, (int)STRLEN(compl_leader))) @@ -3967,8 +4062,7 @@ ins_compl_next( if (compl_shown_match == NULL) return -1; - if (compl_leader != NULL - && !ins_compl_at_original_text(compl_shown_match)) + 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,7 +4091,7 @@ ins_compl_next( // Insert the text of the new completion, or the compl_leader. if (compl_no_insert && !started) { - ins_bytes(compl_orig_text + ins_compl_len()); + ins_bytes(compl_orig_text + get_compl_len()); compl_used_match = FALSE; } else if (insert_match) @@ -4005,7 +4099,7 @@ ins_compl_next( if (!compl_get_longest || compl_used_match) ins_compl_insert(in_compl_func); else - ins_bytes(compl_leader + ins_compl_len()); + ins_bytes(compl_leader + get_compl_len()); } else compl_used_match = FALSE; @@ -4191,9 +4285,9 @@ ins_compl_use_match(int c) 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_SOL) || ctrl_x_mode_path_defines()) { - if (!(compl_cont_status & CONT_ADDING)) + if (!compl_status_adding()) { while (--startcol >= 0 && vim_isIDc(line[startcol])) ; @@ -4208,7 +4302,7 @@ get_normal_compl_info(char_u *line, int if (compl_pattern == NULL) return FAIL; } - else if (compl_cont_status & CONT_ADDING) + else if (compl_status_adding()) { char_u *prefix = (char_u *)"\\<"; @@ -4391,7 +4485,7 @@ get_userdefined_compl_info(colnr_T curs_ funcname = get_complete_funcname(ctrl_x_mode); if (*funcname == NUL) { - semsg(_(e_option_str_is_not_set), ctrl_x_mode == CTRL_X_FUNCTION + semsg(_(e_option_str_is_not_set), ctrl_x_mode_function() ? "completefunc" : "omnifunc"); return FAIL; } @@ -4495,11 +4589,16 @@ get_spell_compl_info(int startcol UNUSED /* * 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 == CTRL_X_NORMAL + if (ctrl_x_mode_normal() || (ctrl_x_mode & CTRL_X_WANT_IDENT && !thesaurus_func_complete(ctrl_x_mode))) { @@ -4509,7 +4608,7 @@ compl_get_info(char_u *line, int startco { return get_wholeline_compl_info(line, curs_col); } - else if (ctrl_x_mode == CTRL_X_FILES) + else if (ctrl_x_mode_files()) { return get_filename_compl_info(line, startcol, curs_col); } @@ -4517,18 +4616,18 @@ compl_get_info(char_u *line, int startco { return get_cmdline_compl_info(line, curs_col); } - else if (ctrl_x_mode == CTRL_X_FUNCTION || ctrl_x_mode == CTRL_X_OMNI + 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 + *line_invalid = TRUE; // "line" may have become invalid } - else if (ctrl_x_mode == CTRL_X_SPELL) + 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 + *line_invalid = TRUE; // "line" may have become invalid } else { @@ -4554,9 +4653,8 @@ ins_compl_continue_search(char_u *line) { // 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 (ctrl_x_mode_normal() || ctrl_x_mode_path_patterns() + || ctrl_x_mode_path_defines()) { if (compl_startpos.lnum != curwin->w_cursor.lnum) { @@ -4639,10 +4737,10 @@ ins_compl_start(void) else compl_cont_status &= CONT_LOCAL; - if (!(compl_cont_status & CONT_ADDING)) // normal expansion + if (!compl_status_adding()) // normal expansion { compl_cont_mode = ctrl_x_mode; - if (ctrl_x_mode != CTRL_X_NORMAL) + 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,8 +4752,8 @@ ins_compl_start(void) // 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)) + 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,7 +4762,7 @@ ins_compl_start(void) if (line_invalid) line = ml_get(curwin->w_cursor.lnum); - if (compl_cont_status & CONT_ADDING) + if (compl_status_adding()) { edit_submode_pre = (char_u *)_(" Adding"); if (ctrl_x_mode_line_or_eval()) @@ -4728,10 +4826,9 @@ ins_compl_start(void) 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) + if (is_first_match(compl_first_match->cp_next)) { - edit_submode_extra = (compl_cont_status & CONT_ADDING) - && compl_length > 1 + 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,7 +4836,7 @@ ins_compl_show_statusmsg(void) if (edit_submode_extra == NULL) { - if (ins_compl_at_original_text(compl_curr_match)) + if (match_at_original_text(compl_curr_match)) { edit_submode_extra = (char_u *)_("Back at original"); edit_submode_highl = HLF_W; @@ -4858,17 +4955,17 @@ ins_complete(int c, int enable_pum) } // we found no match if the list has only the "compl_orig_text"-entry - if (compl_first_match == compl_first_match->cp_next) + 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_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_status_adding() + || (ctrl_x_mode_not_default() + && !ctrl_x_mode_path_patterns() + && !ctrl_x_mode_path_defines())) compl_cont_status &= ~CONT_N_ADDS; } @@ -4929,8 +5026,7 @@ quote_meta(char_u *dest, char_u *src, in case '.': case '*': case '[': - if (ctrl_x_mode == CTRL_X_DICTIONARY - || ctrl_x_mode == CTRL_X_THESAURUS) + if (ctrl_x_mode_dictionary() || ctrl_x_mode_thesaurus()) break; // FALLTHROUGH case '~': @@ -4938,8 +5034,7 @@ quote_meta(char_u *dest, char_u *src, in break; // FALLTHROUGH case '\\': - if (ctrl_x_mode == CTRL_X_DICTIONARY - || ctrl_x_mode == CTRL_X_THESAURUS) + if (ctrl_x_mode_dictionary() || ctrl_x_mode_thesaurus()) break; // FALLTHROUGH case '^': // currently it's not needed. diff --git a/src/proto/insexpand.pro b/src/proto/insexpand.pro --- a/src/proto/insexpand.pro +++ b/src/proto/insexpand.pro @@ -17,6 +17,10 @@ int ctrl_x_mode_spell(void); 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,6 +39,7 @@ void ins_compl_init_get_longest(void); 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,7 +50,6 @@ int set_omnifunc_option(void); 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); diff --git a/src/search.c b/src/search.c --- a/src/search.c +++ b/src/search.c @@ -1727,16 +1727,15 @@ search_for_exact_line( // 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 (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, compl_length) - : STRNCMP(p, pat, compl_length)) == 0) + if ((p_ic ? MB_STRNICMP(p, pat, ins_compl_len()) + : STRNCMP(p, pat, ins_compl_len())) == 0) return OK; } } @@ -3317,7 +3316,7 @@ update_search_stat( #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. + * If p_ic && compl_status_sol() then ptr must be in lowercase. */ void find_pattern_in_path( @@ -3375,9 +3374,9 @@ find_pattern_in_path( 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)) + // 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,7 +3651,7 @@ search_line: */ if (def_regmatch.regprog == NULL || define_matched) { - if (define_matched || (compl_cont_status & CONT_SOL)) + if (define_matched || compl_status_sol()) { // compare the first "len" chars from "ptr" startp = skipwhite(p); @@ -3725,9 +3724,9 @@ search_line: break; found = TRUE; aux = p = startp; - if (compl_cont_status & CONT_ADDING) + if (compl_status_adding()) { - p += compl_length; + p += ins_compl_len(); if (vim_iswordp(p)) goto exit_matched; p = find_word_start(p); @@ -3735,7 +3734,7 @@ search_line: p = find_word_end(p); i = (int)(p - aux); - if ((compl_cont_status & CONT_ADDING) && i == compl_length) + if (compl_status_adding() && i == ins_compl_len()) { // IOSIZE > compl_length, so the STRNCPY works STRNCPY(IObuff, aux, i); @@ -3783,7 +3782,7 @@ search_line: IObuff[i] = NUL; aux = IObuff; - if (i == compl_length) + if (i == ins_compl_len()) goto exit_matched; } @@ -3916,7 +3915,7 @@ exit_matched: // are not at the end of it already if (def_regmatch.regprog == NULL && action == ACTION_EXPAND - && !(compl_cont_status & CONT_SOL) + && !compl_status_sol() && *startp != NUL && *(p = startp + mb_ptr2len(startp)) != NUL) goto search_line; diff --git a/src/version.c b/src/version.c --- a/src/version.c +++ b/src/version.c @@ -751,6 +751,8 @@ static char *(features[]) = static int included_patches[] = { /* Add new patch number below this line */ /**/ + 4001, +/**/ 4000, /**/ 3999,