diff options
Diffstat (limited to 'src/nvim/edit.c')
-rw-r--r-- | src/nvim/edit.c | 127 |
1 files changed, 70 insertions, 57 deletions
diff --git a/src/nvim/edit.c b/src/nvim/edit.c index 213df4f65a..6313ea2e81 100644 --- a/src/nvim/edit.c +++ b/src/nvim/edit.c @@ -1247,7 +1247,7 @@ normalchar: static void insert_do_complete(InsertState *s) { compl_busy = true; - if (ins_complete(s->c) == FAIL) { + if (ins_complete(s->c, true) == FAIL) { compl_cont_status = 0; } compl_busy = false; @@ -2321,9 +2321,10 @@ static int ins_compl_make_cyclic(void) */ void set_completion(colnr_T startcol, list_T *list) { - /* If already doing completions stop it. */ - if (ctrl_x_mode != 0) + // If already doing completions stop it. + if (ctrl_x_mode != 0) { ins_compl_prep(' '); + } ins_compl_clear(); if (stop_arrow() == FAIL) @@ -2349,16 +2350,23 @@ void set_completion(colnr_T startcol, list_T *list) compl_started = TRUE; compl_used_match = TRUE; compl_cont_status = 0; + int save_w_wrow = curwin->w_wrow; compl_curr_match = compl_first_match; if (compl_no_insert) { - ins_complete(K_DOWN); + ins_complete(K_DOWN, false); } else { - ins_complete(Ctrl_N); + ins_complete(Ctrl_N, false); if (compl_no_select) { - ins_complete(Ctrl_P); + ins_complete(Ctrl_P, false); } } + + // Lazily show the popup menu, unless we got interrupted. + if (!compl_interrupted) { + show_pum(save_w_wrow); + } + ui_flush(); } @@ -2464,6 +2472,14 @@ void ins_compl_show_pum(void) /* Need to build the popup menu list. */ compl_match_arraysize = 0; compl = compl_first_match; + /* + * If it's user complete function and refresh_always, + * not use "compl_leader" as prefix filter. + */ + if (ins_compl_need_restart()){ + xfree(compl_leader); + compl_leader = NULL; + } if (compl_leader != NULL) lead_len = (int)STRLEN(compl_leader); do { @@ -2927,20 +2943,17 @@ static void ins_compl_new_leader(void) ins_bytes(compl_leader + ins_compl_len()); compl_used_match = FALSE; - if (compl_started) + if (compl_started) { ins_compl_set_original_text(compl_leader); - else { - spell_bad_len = 0; /* need to redetect bad word */ - /* - * Matches were cleared, need to search for them now. First display - * the changed text before the cursor. Set "compl_restarting" to - * avoid that the first match is inserted. - */ - update_screen(0); - compl_restarting = TRUE; - if (ins_complete(Ctrl_N) == FAIL) + } else { + spell_bad_len = 0; // need to redetect bad word + // Matches were cleared, need to search for them now. + // Set "compl_restarting" to avoid that the first match is inserted. + compl_restarting = true; + if (ins_complete(Ctrl_N, true) == FAIL) { compl_cont_status = 0; - compl_restarting = FALSE; + } + compl_restarting = false; } compl_enter_selects = !compl_used_match; @@ -2948,8 +2961,9 @@ static void ins_compl_new_leader(void) /* Show the popup menu with a different set of matches. */ ins_compl_show_pum(); - /* Don't let Enter select the original text when there is no popup menu. */ - if (compl_match_array == NULL) + /* Don't let Enter select the original text when there is no popup menu. + * Don't let Enter select when use user function and refresh_always is set */ + if (compl_match_array == NULL || ins_compl_need_restart()) compl_enter_selects = FALSE; } @@ -2980,27 +2994,18 @@ static void ins_compl_addleader(int c) (*mb_char2bytes)(c, buf); buf[cc] = NUL; ins_char_bytes(buf, cc); - if (compl_opt_refresh_always) - AppendToRedobuff(buf); } else { ins_char(c); - if (compl_opt_refresh_always) - AppendCharToRedobuff(c); } /* If we didn't complete finding matches we must search again. */ if (ins_compl_need_restart()) ins_compl_restart(); - /* When 'always' is set, don't reset compl_leader. While completing, - * cursor doesn't point original position, changing compl_leader would - * break redo. */ - if (!compl_opt_refresh_always) { - xfree(compl_leader); - compl_leader = vim_strnsave(get_cursor_line_ptr() + compl_col, - (int)(curwin->w_cursor.col - compl_col)); - ins_compl_new_leader(); - } + xfree(compl_leader); + compl_leader = vim_strnsave(get_cursor_line_ptr() + compl_col, + (int)(curwin->w_cursor.col - compl_col)); + ins_compl_new_leader(); } /* @@ -3009,6 +3014,10 @@ static void ins_compl_addleader(int c) */ static void ins_compl_restart(void) { + /* update screen before restart. + * so if complete is blocked, + * will stay to the last popup menu and reduce flicker */ + update_screen(0); ins_compl_free(); compl_started = FALSE; compl_matches = 0; @@ -4296,7 +4305,7 @@ static int ins_compl_use_match(int c) * Called when character "c" was typed, which has a meaning for completion. * Returns OK if completion was done, FAIL if something failed. */ -static int ins_complete(int c) +static int ins_complete(int c, bool enable_pum) { char_u *line; int startcol = 0; /* column where searched text starts */ @@ -4779,20 +4788,9 @@ static int ins_complete(int c) } } - /* Show the popup menu, unless we got interrupted. */ - if (!compl_interrupted) { - /* RedrawingDisabled may be set when invoked through complete(). */ - n = RedrawingDisabled; - RedrawingDisabled = 0; - - /* If the cursor moved we need to remove the pum first. */ - setcursor(); - if (save_w_wrow != curwin->w_wrow) - ins_compl_del_pum(); - - ins_compl_show_pum(); - setcursor(); - RedrawingDisabled = n; + // Show the popup menu, unless we got interrupted. + if (enable_pum && !compl_interrupted) { + show_pum(save_w_wrow); } compl_was_interrupted = compl_interrupted; compl_interrupted = FALSE; @@ -4945,15 +4943,10 @@ int get_literal(void) return cc; } -/* - * Insert character, taking care of special keys and mod_mask - */ -static void -insert_special ( - int c, - int allow_modmask, - int ctrlv /* c was typed after CTRL-V */ -) +/// Insert character, taking care of special keys and mod_mask +/// +/// @param ctrlv `c` was typed after CTRL-V +static void insert_special(int c, int allow_modmask, int ctrlv) { char_u *p; int len; @@ -4965,6 +4958,9 @@ insert_special ( * Only use mod_mask for special keys, to avoid things like <S-Space>, * unless 'allow_modmask' is TRUE. */ + if (mod_mask & MOD_MASK_CMD) { // Command-key never produces a normal key. + allow_modmask = true; + } if (IS_SPECIAL(c) || (mod_mask && allow_modmask)) { p = get_special_key_name(c, mod_mask); len = (int)STRLEN(p); @@ -8520,3 +8516,20 @@ static char_u *do_insert_char_pre(int c) return res; } + +static void show_pum(int save_w_wrow) +{ + // RedrawingDisabled may be set when invoked through complete(). + int n = RedrawingDisabled; + RedrawingDisabled = 0; + + // If the cursor moved we need to remove the pum first. + setcursor(); + if (save_w_wrow != curwin->w_wrow) { + ins_compl_del_pum(); + } + + ins_compl_show_pum(); + setcursor(); + RedrawingDisabled = n; +} |