Mercurial > vim
comparison src/insexpand.c @ 16237:56451a2677dc v8.1.1123
patch 8.1.1123: no way to avoid filtering for autocomplete function
commit https://github.com/vim/vim/commit/73655cf0ca37a9aa8f56fc51bb853a8b1f7b43d4
Author: Bram Moolenaar <Bram@vim.org>
Date: Sat Apr 6 13:45:55 2019 +0200
patch 8.1.1123: no way to avoid filtering for autocomplete function
Problem: No way to avoid filtering for autocomplete function, causing
flickering of the popup menu.
Solution: Add the "equal" field to complete items. (closes #3887)
author | Bram Moolenaar <Bram@vim.org> |
---|---|
date | Sat, 06 Apr 2019 14:00:05 +0200 |
parents | cd5c83115ec6 |
children | 5df26b29e809 |
comparison
equal
deleted
inserted
replaced
16236:453a46ac5660 | 16237:56451a2677dc |
---|---|
99 typedef struct compl_S compl_T; | 99 typedef struct compl_S compl_T; |
100 struct compl_S | 100 struct compl_S |
101 { | 101 { |
102 compl_T *cp_next; | 102 compl_T *cp_next; |
103 compl_T *cp_prev; | 103 compl_T *cp_prev; |
104 char_u *cp_str; /* matched text */ | 104 char_u *cp_str; // matched text |
105 char cp_icase; /* TRUE or FALSE: ignore case */ | 105 char cp_icase; // TRUE or FALSE: ignore case |
106 char_u *(cp_text[CPT_COUNT]); /* text for the menu */ | 106 char cp_equal; // TRUE or FALSE: ins_compl_equal always ok |
107 char_u *cp_fname; /* file containing the match, allocated when | 107 char_u *(cp_text[CPT_COUNT]); // text for the menu |
108 * cp_flags has FREE_FNAME */ | 108 char_u *cp_fname; // file containing the match, allocated when |
109 int cp_flags; /* ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME */ | 109 // cp_flags has FREE_FNAME |
110 int cp_number; /* sequence number */ | 110 int cp_flags; // ORIGINAL_TEXT, CONT_S_IPOS or FREE_FNAME |
111 int cp_number; // sequence number | |
111 }; | 112 }; |
112 | 113 |
113 # define ORIGINAL_TEXT (1) /* the original text when the expansion begun */ | 114 // flags for ins_compl_add() |
115 # define ORIGINAL_TEXT (1) // the original text when the expansion begun | |
114 # define FREE_FNAME (2) | 116 # define FREE_FNAME (2) |
115 | 117 |
116 static char e_hitend[] = N_("Hit end of paragraph"); | 118 static char e_hitend[] = N_("Hit end of paragraph"); |
117 # ifdef FEAT_COMPL_FUNC | 119 # ifdef FEAT_COMPL_FUNC |
118 static char e_complwin[] = N_("E839: Completion function changed window"); | 120 static char e_complwin[] = N_("E839: Completion function changed window"); |
181 static expand_T compl_xp; | 183 static expand_T compl_xp; |
182 | 184 |
183 static int compl_opt_refresh_always = FALSE; | 185 static int compl_opt_refresh_always = FALSE; |
184 static int compl_opt_suppress_empty = FALSE; | 186 static int compl_opt_suppress_empty = FALSE; |
185 | 187 |
186 static int ins_compl_add(char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup); | 188 static int ins_compl_add(char_u *str, int len, int icase, char_u *fname, char_u **cptext, int cdir, int flags, int adup, int equal); |
187 static void ins_compl_longest_match(compl_T *match); | 189 static void ins_compl_longest_match(compl_T *match); |
188 static void ins_compl_del_pum(void); | 190 static void ins_compl_del_pum(void); |
189 static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir); | 191 static void ins_compl_files(int count, char_u **files, int thesaurus, int flags, regmatch_T *regmatch, char_u *buf, int *dir); |
190 static char_u *find_line_end(char_u *ptr); | 192 static char_u *find_line_end(char_u *ptr); |
191 static void ins_compl_free(void); | 193 static void ins_compl_free(void); |
411 * text is inferred, ie this tries to work out what case you probably wanted | 413 * text is inferred, ie this tries to work out what case you probably wanted |
412 * the rest of the word to be in -- webb | 414 * the rest of the word to be in -- webb |
413 */ | 415 */ |
414 int | 416 int |
415 ins_compl_add_infercase( | 417 ins_compl_add_infercase( |
416 char_u *str, | 418 char_u *str_arg, |
417 int len, | 419 int len, |
418 int icase, | 420 int icase, |
419 char_u *fname, | 421 char_u *fname, |
420 int dir, | 422 int dir, |
421 int flags) | 423 int flags) |
422 { | 424 { |
425 char_u *str = str_arg; | |
423 char_u *p; | 426 char_u *p; |
424 int i, c; | 427 int i, c; |
425 int actual_len; // Take multi-byte characters | 428 int actual_len; // Take multi-byte characters |
426 int actual_compl_length; // into account. | 429 int actual_compl_length; // into account. |
427 int min_len; | 430 int min_len; |
548 *p = NUL; | 551 *p = NUL; |
549 | 552 |
550 vim_free(wca); | 553 vim_free(wca); |
551 } | 554 } |
552 | 555 |
553 return ins_compl_add(IObuff, len, icase, fname, NULL, dir, | 556 str = IObuff; |
554 flags, FALSE); | 557 } |
555 } | 558 |
556 return ins_compl_add(str, len, icase, fname, NULL, dir, flags, FALSE); | 559 return ins_compl_add(str, len, icase, fname, NULL, dir, |
560 flags, FALSE, FALSE); | |
557 } | 561 } |
558 | 562 |
559 /* | 563 /* |
560 * Add a match to the list of matches. | 564 * Add a match to the list of matches. |
561 * If the given string is already in the list of completions, then return | 565 * If the given string is already in the list of completions, then return |
569 int icase, | 573 int icase, |
570 char_u *fname, | 574 char_u *fname, |
571 char_u **cptext, // extra text for popup menu or NULL | 575 char_u **cptext, // extra text for popup menu or NULL |
572 int cdir, | 576 int cdir, |
573 int flags, | 577 int flags, |
574 int adup) // accept duplicate match | 578 int adup, // accept duplicate match |
579 int equal) // match is always accepted by ins_compl_equal | |
575 { | 580 { |
576 compl_T *match; | 581 compl_T *match; |
577 int dir = (cdir == 0 ? compl_direction : cdir); | 582 int dir = (cdir == 0 ? compl_direction : cdir); |
578 | 583 |
579 ui_breakcheck(); | 584 ui_breakcheck(); |
611 { | 616 { |
612 vim_free(match); | 617 vim_free(match); |
613 return FAIL; | 618 return FAIL; |
614 } | 619 } |
615 match->cp_icase = icase; | 620 match->cp_icase = icase; |
621 match->cp_equal = equal; | |
616 | 622 |
617 // match-fname is: | 623 // match-fname is: |
618 // - compl_curr_match->cp_fname if it is a string equal to fname. | 624 // - compl_curr_match->cp_fname if it is a string equal to fname. |
619 // - a copy of fname, FREE_FNAME is set to free later THE allocated mem. | 625 // - a copy of fname, FREE_FNAME is set to free later THE allocated mem. |
620 // - NULL otherwise. --Acevedo | 626 // - NULL otherwise. --Acevedo |
674 * match->cp_icase. | 680 * match->cp_icase. |
675 */ | 681 */ |
676 static int | 682 static int |
677 ins_compl_equal(compl_T *match, char_u *str, int len) | 683 ins_compl_equal(compl_T *match, char_u *str, int len) |
678 { | 684 { |
685 if (match->cp_equal) | |
686 return TRUE; | |
679 if (match->cp_icase) | 687 if (match->cp_icase) |
680 return STRNICMP(match->cp_str, str, (size_t)len) == 0; | 688 return STRNICMP(match->cp_str, str, (size_t)len) == 0; |
681 return STRNCMP(match->cp_str, str, (size_t)len) == 0; | 689 return STRNCMP(match->cp_str, str, (size_t)len) == 0; |
682 } | 690 } |
683 | 691 |
774 int add_r = OK; | 782 int add_r = OK; |
775 int dir = compl_direction; | 783 int dir = compl_direction; |
776 | 784 |
777 for (i = 0; i < num_matches && add_r != FAIL; i++) | 785 for (i = 0; i < num_matches && add_r != FAIL; i++) |
778 if ((add_r = ins_compl_add(matches[i], -1, icase, | 786 if ((add_r = ins_compl_add(matches[i], -1, icase, |
779 NULL, NULL, dir, 0, FALSE)) == OK) | 787 NULL, NULL, dir, 0, FALSE, FALSE)) == OK) |
780 // if dir was BACKWARD then honor it just once | 788 // if dir was BACKWARD then honor it just once |
781 dir = FORWARD; | 789 dir = FORWARD; |
782 FreeWild(num_matches, matches); | 790 FreeWild(num_matches, matches); |
783 } | 791 } |
784 | 792 |
866 compl_col = startcol; | 874 compl_col = startcol; |
867 compl_length = (int)curwin->w_cursor.col - (int)startcol; | 875 compl_length = (int)curwin->w_cursor.col - (int)startcol; |
868 // compl_pattern doesn't need to be set | 876 // compl_pattern doesn't need to be set |
869 compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length); | 877 compl_orig_text = vim_strnsave(ml_get_curline() + compl_col, compl_length); |
870 if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, | 878 if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, |
871 -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) | 879 -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE, FALSE) != OK) |
872 return; | 880 return; |
873 | 881 |
874 ctrl_x_mode = CTRL_X_EVAL; | 882 ctrl_x_mode = CTRL_X_EVAL; |
875 | 883 |
876 ins_compl_add_list(list); | 884 ins_compl_add_list(list); |
2363 { | 2371 { |
2364 char_u *word; | 2372 char_u *word; |
2365 int icase = FALSE; | 2373 int icase = FALSE; |
2366 int adup = FALSE; | 2374 int adup = FALSE; |
2367 int aempty = FALSE; | 2375 int aempty = FALSE; |
2376 int aequal = FALSE; | |
2368 char_u *(cptext[CPT_COUNT]); | 2377 char_u *(cptext[CPT_COUNT]); |
2369 | 2378 |
2370 if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) | 2379 if (tv->v_type == VAR_DICT && tv->vval.v_dict != NULL) |
2371 { | 2380 { |
2372 word = dict_get_string(tv->vval.v_dict, (char_u *)"word", FALSE); | 2381 word = dict_get_string(tv->vval.v_dict, (char_u *)"word", FALSE); |
2384 icase = dict_get_number(tv->vval.v_dict, (char_u *)"icase"); | 2393 icase = dict_get_number(tv->vval.v_dict, (char_u *)"icase"); |
2385 if (dict_get_string(tv->vval.v_dict, (char_u *)"dup", FALSE) != NULL) | 2394 if (dict_get_string(tv->vval.v_dict, (char_u *)"dup", FALSE) != NULL) |
2386 adup = dict_get_number(tv->vval.v_dict, (char_u *)"dup"); | 2395 adup = dict_get_number(tv->vval.v_dict, (char_u *)"dup"); |
2387 if (dict_get_string(tv->vval.v_dict, (char_u *)"empty", FALSE) != NULL) | 2396 if (dict_get_string(tv->vval.v_dict, (char_u *)"empty", FALSE) != NULL) |
2388 aempty = dict_get_number(tv->vval.v_dict, (char_u *)"empty"); | 2397 aempty = dict_get_number(tv->vval.v_dict, (char_u *)"empty"); |
2398 if (dict_get_string(tv->vval.v_dict, (char_u *)"equal", FALSE) != NULL) | |
2399 aequal = dict_get_number(tv->vval.v_dict, (char_u *)"equal"); | |
2389 } | 2400 } |
2390 else | 2401 else |
2391 { | 2402 { |
2392 word = tv_get_string_chk(tv); | 2403 word = tv_get_string_chk(tv); |
2393 vim_memset(cptext, 0, sizeof(cptext)); | 2404 vim_memset(cptext, 0, sizeof(cptext)); |
2394 } | 2405 } |
2395 if (word == NULL || (!aempty && *word == NUL)) | 2406 if (word == NULL || (!aempty && *word == NUL)) |
2396 return FAIL; | 2407 return FAIL; |
2397 return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup); | 2408 return ins_compl_add(word, -1, icase, NULL, cptext, dir, 0, adup, aequal); |
2398 } | 2409 } |
2399 #endif | 2410 #endif |
2400 | 2411 |
2401 /* | 2412 /* |
2402 * Get the next expansion(s), using "compl_pattern". | 2413 * Get the next expansion(s), using "compl_pattern". |
3692 | 3703 |
3693 // Always add completion for the original text. | 3704 // Always add completion for the original text. |
3694 vim_free(compl_orig_text); | 3705 vim_free(compl_orig_text); |
3695 compl_orig_text = vim_strnsave(line + compl_col, compl_length); | 3706 compl_orig_text = vim_strnsave(line + compl_col, compl_length); |
3696 if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, | 3707 if (compl_orig_text == NULL || ins_compl_add(compl_orig_text, |
3697 -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE) != OK) | 3708 -1, p_ic, NULL, NULL, 0, ORIGINAL_TEXT, FALSE, FALSE) != OK) |
3698 { | 3709 { |
3699 VIM_CLEAR(compl_pattern); | 3710 VIM_CLEAR(compl_pattern); |
3700 VIM_CLEAR(compl_orig_text); | 3711 VIM_CLEAR(compl_orig_text); |
3701 return FAIL; | 3712 return FAIL; |
3702 } | 3713 } |