To: vim_dev@googlegroups.com Subject: Patch 8.0.1479 Fcc: outbox From: Bram Moolenaar Mime-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ------------ Patch 8.0.1479 Problem: Insert mode completion state is confusing. Solution: Move ctrl_x_mode into edit.c. Add CTRL_X_NORMAL for zero. Files: src/edit.c, src/globals.h, src/proto/edit.pro, src/search.c, src/getchar.c *** ../vim-8.0.1478/src/edit.c 2018-01-31 20:51:40.301835954 +0100 --- src/edit.c 2018-02-09 12:11:33.979442709 +0100 *************** *** 17,55 **** /* * definitions used for CTRL-X submode */ ! #define CTRL_X_WANT_IDENT 0x100 ! #define CTRL_X_NOT_DEFINED_YET 1 ! #define CTRL_X_SCROLL 2 ! #define CTRL_X_WHOLE_LINE 3 ! #define CTRL_X_FILES 4 ! #define CTRL_X_TAGS (5 + CTRL_X_WANT_IDENT) ! #define CTRL_X_PATH_PATTERNS (6 + CTRL_X_WANT_IDENT) ! #define CTRL_X_PATH_DEFINES (7 + CTRL_X_WANT_IDENT) ! #define CTRL_X_FINISHED 8 ! #define CTRL_X_DICTIONARY (9 + CTRL_X_WANT_IDENT) ! #define CTRL_X_THESAURUS (10 + CTRL_X_WANT_IDENT) ! #define CTRL_X_CMDLINE 11 ! #define CTRL_X_FUNCTION 12 ! #define CTRL_X_OMNI 13 ! #define CTRL_X_SPELL 14 ! #define CTRL_X_LOCAL_MSG 15 /* only used in "ctrl_x_msgs" */ ! #define CTRL_X_EVAL 16 /* for builtin function complete() */ ! #define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT] ! #define CTRL_X_MODE_LINE_OR_EVAL(m) (m == CTRL_X_WHOLE_LINE || m == CTRL_X_EVAL) static char *ctrl_x_msgs[] = { ! N_(" Keyword completion (^N^P)"), /* ctrl_x_mode == 0, ^P/^N compl. */ N_(" ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"), ! NULL, N_(" Whole line completion (^L^N^P)"), N_(" File name completion (^F^N^P)"), N_(" Tag completion (^]^N^P)"), N_(" Path pattern completion (^N^P)"), N_(" Definition completion (^D^N^P)"), ! NULL, N_(" Dictionary completion (^K^N^P)"), N_(" Thesaurus completion (^T^N^P)"), N_(" Command-line completion (^V^N^P)"), --- 17,57 ---- /* * definitions used for CTRL-X submode */ ! # define CTRL_X_WANT_IDENT 0x100 ! # define CTRL_X_NORMAL 0 /* CTRL-N CTRL-P completion, default */ ! # define CTRL_X_NOT_DEFINED_YET 1 ! # define CTRL_X_SCROLL 2 ! # define CTRL_X_WHOLE_LINE 3 ! # define CTRL_X_FILES 4 ! # define CTRL_X_TAGS (5 + CTRL_X_WANT_IDENT) ! # define CTRL_X_PATH_PATTERNS (6 + CTRL_X_WANT_IDENT) ! # define CTRL_X_PATH_DEFINES (7 + CTRL_X_WANT_IDENT) ! # define CTRL_X_FINISHED 8 ! # define CTRL_X_DICTIONARY (9 + CTRL_X_WANT_IDENT) ! # define CTRL_X_THESAURUS (10 + CTRL_X_WANT_IDENT) ! # define CTRL_X_CMDLINE 11 ! # define CTRL_X_FUNCTION 12 ! # define CTRL_X_OMNI 13 ! # define CTRL_X_SPELL 14 ! # define CTRL_X_LOCAL_MSG 15 /* only used in "ctrl_x_msgs" */ ! # define CTRL_X_EVAL 16 /* for builtin function complete() */ ! # define CTRL_X_MSG(i) ctrl_x_msgs[(i) & ~CTRL_X_WANT_IDENT] ! # define CTRL_X_MODE_LINE_OR_EVAL(m) ((m) == CTRL_X_WHOLE_LINE || (m) == CTRL_X_EVAL) + /* Message for CTRL-X mode, index is ctrl_x_mode. */ static char *ctrl_x_msgs[] = { ! N_(" Keyword completion (^N^P)"), /* CTRL_X_NORMAL, ^P/^N compl. */ N_(" ^X mode (^]^D^E^F^I^K^L^N^O^Ps^U^V^Y)"), ! NULL, /* CTRL_X_SCROLL: depends on state */ N_(" Whole line completion (^L^N^P)"), N_(" File name completion (^F^N^P)"), N_(" Tag completion (^]^N^P)"), N_(" Path pattern completion (^N^P)"), N_(" Definition completion (^D^N^P)"), ! NULL, /* CTRL_X_FINISHED */ N_(" Dictionary completion (^K^N^P)"), N_(" Thesaurus completion (^T^N^P)"), N_(" Command-line completion (^V^N^P)"), *************** *** 61,70 **** }; static char e_hitend[] = N_("Hit end of paragraph"); ! #ifdef FEAT_COMPL_FUNC static char e_complwin[] = N_("E839: Completion function changed window"); static char e_compldel[] = N_("E840: Completion function deleted text"); ! #endif /* * Structure used to store one match for insert completion. --- 63,72 ---- }; static char e_hitend[] = N_("Hit end of paragraph"); ! # ifdef FEAT_COMPL_FUNC static char e_complwin[] = N_("E839: Completion function changed window"); static char e_compldel[] = N_("E840: Completion function deleted text"); ! # endif /* * Structure used to store one match for insert completion. *************** *** 83,90 **** int cp_number; /* sequence number */ }; ! #define ORIGINAL_TEXT (1) /* the original text when the expansion begun */ ! #define FREE_FNAME (2) /* * All the current matches are stored in a list. --- 85,92 ---- int cp_number; /* sequence number */ }; ! # define ORIGINAL_TEXT (1) /* the original text when the expansion begun */ ! # define FREE_FNAME (2) /* * All the current matches are stored in a list. *************** *** 127,132 **** --- 129,137 ---- * FALSE the word to be completed must be located. */ static int compl_started = FALSE; + /* Which Ctrl-X mode are we in? */ + static int ctrl_x_mode = CTRL_X_NORMAL; + /* Set when doing something for completion that may call edit() recursively, * which is not allowed. */ static int compl_busy = FALSE; *************** *** 174,183 **** static int ins_compl_prep(int c); static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg); static buf_T *ins_compl_next_buf(buf_T *buf, int flag); ! #if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) static void ins_compl_add_list(list_T *list); static void ins_compl_add_dict(dict_T *dict); ! #endif static int ins_compl_get_exp(pos_T *ini); static void ins_compl_delete(void); static void ins_compl_insert(int in_compl_func); --- 179,188 ---- static int ins_compl_prep(int c); static void ins_compl_fixRedoBufForLeader(char_u *ptr_arg); static buf_T *ins_compl_next_buf(buf_T *buf, int flag); ! # if defined(FEAT_COMPL_FUNC) || defined(FEAT_EVAL) static void ins_compl_add_list(list_T *list); static void ins_compl_add_dict(dict_T *dict); ! # endif static int ins_compl_get_exp(pos_T *ini); static void ins_compl_delete(void); static void ins_compl_insert(int in_compl_func); *************** *** 2242,2247 **** --- 2247,2270 ---- } /* + * Whether other than default completion has been selected. + */ + int + ctrl_x_mode_not_default(void) + { + return ctrl_x_mode != CTRL_X_NORMAL; + } + + /* + * Whether CTRL-X was typed without a following character. + */ + int + ctrl_x_mode_not_defined_yet(void) + { + return ctrl_x_mode == CTRL_X_NOT_DEFINED_YET; + } + + /* * Return TRUE if the 'dict' or 'tsr' option can be used. */ static int *************** *** 2254,2260 **** ) : (*curbuf->b_p_tsr == NUL && *p_tsr == NUL)) { ! ctrl_x_mode = 0; edit_submode = NULL; msg_attr(dict_opt ? (char_u *)_("'dictionary' option is empty") : (char_u *)_("'thesaurus' option is empty"), --- 2277,2283 ---- ) : (*curbuf->b_p_tsr == NUL && *p_tsr == NUL)) { ! ctrl_x_mode = CTRL_X_NORMAL; edit_submode = NULL; msg_attr(dict_opt ? (char_u *)_("'dictionary' option is empty") : (char_u *)_("'thesaurus' option is empty"), *************** *** 2830,2836 **** int save_w_leftcol = curwin->w_leftcol; /* If already doing completions stop it. */ ! if (ctrl_x_mode != 0) ins_compl_prep(' '); ins_compl_clear(); ins_compl_free(); --- 2853,2859 ---- int save_w_leftcol = curwin->w_leftcol; /* If already doing completions stop it. */ ! if (ctrl_x_mode != CTRL_X_NORMAL) ins_compl_prep(' '); ins_compl_clear(); ins_compl_free(); *************** *** 3736,3742 **** /* Set "compl_get_longest" when finding the first matches. */ if (ctrl_x_mode == CTRL_X_NOT_DEFINED_YET ! || (ctrl_x_mode == 0 && !compl_started)) { compl_get_longest = (strstr((char *)p_cot, "longest") != NULL); compl_used_match = TRUE; --- 3759,3765 ---- /* 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; *************** *** 3841,3859 **** else compl_cont_mode = CTRL_X_NOT_DEFINED_YET; } ! ctrl_x_mode = 0; edit_submode = NULL; showmode(); break; } } ! else if (ctrl_x_mode != 0) { /* 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 = 0; else ctrl_x_mode = CTRL_X_FINISHED; edit_submode = NULL; --- 3864,3882 ---- else compl_cont_mode = CTRL_X_NOT_DEFINED_YET; } ! ctrl_x_mode = CTRL_X_NORMAL; edit_submode = NULL; showmode(); break; } } ! 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; edit_submode = NULL; *************** *** 3867,3874 **** * 'Pattern not found') until another key is hit, then go back to * showing what mode we are in. */ showmode(); ! if ((ctrl_x_mode == 0 && c != Ctrl_N && c != Ctrl_P && c != Ctrl_R ! && !ins_compl_pum_key(c)) || ctrl_x_mode == CTRL_X_FINISHED) { /* Get here when we have finished typing a sequence of ^N and --- 3890,3897 ---- * '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) { /* Get here when we have finished typing a sequence of ^N and *************** *** 3951,3957 **** compl_matches = 0; if (!shortmess(SHM_COMPLETIONMENU)) msg_clr_cmdline(); /* necessary for "noshowmode" */ ! ctrl_x_mode = 0; compl_enter_selects = FALSE; if (edit_submode != NULL) { --- 3974,3980 ---- compl_matches = 0; if (!shortmess(SHM_COMPLETIONMENU)) msg_clr_cmdline(); /* necessary for "noshowmode" */ ! ctrl_x_mode = CTRL_X_NORMAL; compl_enter_selects = FALSE; if (edit_submode != NULL) { *************** *** 4292,4298 **** /* 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 == 0 || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) && (!compl_started || found_all)) { found_all = FALSE; --- 4315,4322 ---- /* 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(ctrl_x_mode)) && (!compl_started || found_all)) { found_all = FALSE; *************** *** 4304,4310 **** first_match_pos = *ini; /* Move the cursor back one character so that ^N can match the * word immediately after the cursor. */ ! if (ctrl_x_mode == 0 && dec(&first_match_pos) < 0) { /* Move the cursor to after the last character in the * buffer, so that word at start of buffer is found --- 4328,4334 ---- first_match_pos = *ini; /* 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(&first_match_pos) < 0) { /* Move the cursor to after the last character in the * buffer, so that word at start of buffer is found *************** *** 4437,4444 **** /* Find up to TAG_MANY matches. Avoids that an enormous number * of matches is found when compl_pattern is empty */ if (find_tags(compl_pattern, &num_matches, &matches, ! TAG_REGEXP | TAG_NAMES | TAG_NOIC | ! TAG_INS_COMP | (ctrl_x_mode ? TAG_VERBOSE : 0), TAG_MANY, curbuf->b_ffname) == OK && num_matches > 0) { ins_compl_add_matches(num_matches, matches, p_ic); --- 4461,4468 ---- /* Find up to TAG_MANY matches. Avoids that an enormous number * of matches is found when compl_pattern is empty */ 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); *************** *** 4633,4640 **** found_new_match = OK; /* break the loop for specialized modes (use 'complete' just for the ! * generic ctrl_x_mode == 0) or when we've found a new match */ ! if ((ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) || found_new_match != FAIL) { if (got_int) --- 4657,4666 ---- found_new_match = OK; /* 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(ctrl_x_mode)) || found_new_match != FAIL) { if (got_int) *************** *** 4643,4649 **** if (type != -1) ins_compl_check_keys(0, FALSE); ! if ((ctrl_x_mode != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) || compl_interrupted) break; compl_started = TRUE; --- 4669,4676 ---- if (type != -1) ins_compl_check_keys(0, FALSE); ! if ((ctrl_x_mode != CTRL_X_NORMAL ! && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) || compl_interrupted) break; compl_started = TRUE; *************** *** 4659,4671 **** } compl_started = TRUE; ! if ((ctrl_x_mode == 0 || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) && *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 != 0 && !CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode))) i = ins_compl_make_cyclic(); if (compl_old_match != NULL) --- 4686,4698 ---- } compl_started = TRUE; ! if ((ctrl_x_mode == CTRL_X_NORMAL || CTRL_X_MODE_LINE_OR_EVAL(ctrl_x_mode)) && *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(ctrl_x_mode))) i = ins_compl_make_cyclic(); if (compl_old_match != NULL) *************** *** 5166,5173 **** * it is a continued search */ compl_cont_status &= ~CONT_INTRPT; /* remove INTRPT */ ! if (ctrl_x_mode == 0 || ctrl_x_mode == CTRL_X_PATH_PATTERNS ! || ctrl_x_mode == CTRL_X_PATH_DEFINES) { if (compl_startpos.lnum != curwin->w_cursor.lnum) { --- 5193,5201 ---- * 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) { *************** *** 5219,5225 **** if (!(compl_cont_status & CONT_ADDING)) /* normal expansion */ { compl_cont_mode = ctrl_x_mode; ! if (ctrl_x_mode != 0) /* Remove LOCAL if ctrl_x_mode != 0 */ compl_cont_status = 0; compl_cont_status |= CONT_N_ADDS; compl_startpos = curwin->w_cursor; --- 5247,5254 ---- 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; compl_startpos = curwin->w_cursor; *************** *** 5228,5234 **** } /* Work out completion pattern and original text -- webb */ ! if (ctrl_x_mode == 0 || (ctrl_x_mode & CTRL_X_WANT_IDENT)) { if ((compl_cont_status & CONT_SOL) || ctrl_x_mode == CTRL_X_PATH_DEFINES) --- 5257,5263 ---- } /* Work out completion pattern and original text -- webb */ ! if (ctrl_x_mode == CTRL_X_NORMAL || (ctrl_x_mode & CTRL_X_WANT_IDENT)) { if ((compl_cont_status & CONT_SOL) || ctrl_x_mode == CTRL_X_PATH_DEFINES) *************** *** 5445,5451 **** return FAIL; if (col == -3) { ! ctrl_x_mode = 0; edit_submode = NULL; if (!shortmess(SHM_COMPLETIONMENU)) msg_clr_cmdline(); --- 5474,5480 ---- return FAIL; if (col == -3) { ! ctrl_x_mode = CTRL_X_NORMAL; edit_submode = NULL; if (!shortmess(SHM_COMPLETIONMENU)) msg_clr_cmdline(); *************** *** 5604,5610 **** * (such as M in M'exico) if not tried already. -- Acevedo */ if ( compl_length > 1 || (compl_cont_status & CONT_ADDING) ! || (ctrl_x_mode != 0 && ctrl_x_mode != CTRL_X_PATH_PATTERNS && ctrl_x_mode != CTRL_X_PATH_DEFINES)) compl_cont_status &= ~CONT_N_ADDS; --- 5633,5639 ---- * (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; *** ../vim-8.0.1478/src/globals.h 2017-11-25 17:14:29.608189513 +0100 --- src/globals.h 2018-02-09 11:43:36.279931534 +0100 *************** *** 964,970 **** EXTERN char_u *edit_submode_pre INIT(= NULL); /* prepended to edit_submode */ EXTERN char_u *edit_submode_extra INIT(= NULL);/* appended to edit_submode */ EXTERN hlf_T edit_submode_highl; /* highl. method for extra info */ - EXTERN int ctrl_x_mode INIT(= 0); /* Which Ctrl-X mode are we in? */ #endif EXTERN int no_abbr INIT(= TRUE); /* TRUE when no abbreviations loaded */ --- 964,969 ---- *** ../vim-8.0.1478/src/proto/edit.pro 2017-01-21 20:04:17.570757762 +0100 --- src/proto/edit.pro 2018-02-09 12:11:08.903625442 +0100 *************** *** 6,11 **** --- 6,13 ---- void change_indent(int type, int amount, int round, int replaced, int call_changed_bytes); void truncate_spaces(char_u *line); void backspace_until_column(int col); + int ctrl_x_mode_not_default(void); + int ctrl_x_mode_not_defined_yet(void); int vim_is_ctrl_x_key(int c); int ins_compl_add_infercase(char_u *str, int len, int icase, char_u *fname, int dir, int flags); void completeopt_was_set(void); *** ../vim-8.0.1478/src/search.c 2018-01-31 20:51:40.309835870 +0100 --- src/search.c 2018-02-09 11:53:42.751894976 +0100 *************** *** 421,427 **** if (ic && !no_smartcase && scs #ifdef FEAT_INS_EXPAND ! && !(ctrl_x_mode && curbuf->b_p_inf) #endif ) ic = !pat_has_uppercase(pat); --- 421,427 ---- if (ic && !no_smartcase && scs #ifdef FEAT_INS_EXPAND ! && !(ctrl_x_mode_not_default() && curbuf->b_p_inf) #endif ) ic = !pat_has_uppercase(pat); *** ../vim-8.0.1478/src/getchar.c 2018-01-31 20:51:40.301835954 +0100 --- src/getchar.c 2018-02-09 11:54:20.307644418 +0100 *************** *** 2115,2121 **** && State != ASKMORE && State != CONFIRM #ifdef FEAT_INS_EXPAND ! && !((ctrl_x_mode != 0 && vim_is_ctrl_x_key(c1)) || ((compl_cont_status & CONT_LOCAL) && (c1 == Ctrl_N || c1 == Ctrl_P))) #endif --- 2115,2122 ---- && State != ASKMORE && State != CONFIRM #ifdef FEAT_INS_EXPAND ! && !((ctrl_x_mode_not_default() ! && vim_is_ctrl_x_key(c1)) || ((compl_cont_status & CONT_LOCAL) && (c1 == Ctrl_N || c1 == Ctrl_P))) #endif *** ../vim-8.0.1478/src/version.c 2018-02-08 22:45:13.115323597 +0100 --- src/version.c 2018-02-09 12:12:54.966855037 +0100 *************** *** 773,774 **** --- 773,776 ---- { /* Add new patch number below this line */ + /**/ + 1479, /**/ -- 'I generally avoid temptation unless I can't resist it." -- Mae West /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ \\\ an exciting new programming language -- http://www.Zimbu.org /// \\\ help me help AIDS victims -- http://ICCF-Holland.org ///