diff options
Diffstat (limited to 'src/nvim/ex_getln.c')
-rw-r--r-- | src/nvim/ex_getln.c | 84 |
1 files changed, 70 insertions, 14 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index e79476ab53..9c9ccbca4d 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -91,6 +91,13 @@ typedef struct { CmdlineColors colors; ///< Last colors. } ColoredCmdline; +/// Keeps track how much state must be sent to external ui. +typedef enum { + kCmdRedrawNone, + kCmdRedrawPos, + kCmdRedrawAll, +} CmdRedraw; + /* * Variables shared between getcmdline(), redrawcmdline() and others. * These need to be saved when using CTRL-R |, that's why they are in a @@ -120,6 +127,7 @@ struct cmdline_info { struct cmdline_info *prev_ccline; ///< pointer to saved cmdline state char special_char; ///< last putcmdline char (used for redraws) bool special_shift; ///< shift of last putcmdline char + CmdRedraw redraw_state; ///< needed redraw for external cmdline }; /// Last value of prompt_id, incremented when doing new prompt static unsigned last_prompt_id = 0; @@ -423,6 +431,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent) ccline.cmdbuff = NULL; if (ui_is_external(kUICmdline)) { + ccline.redraw_state = kCmdRedrawNone; ui_call_cmdline_hide(ccline.level); } ccline.level--; @@ -534,6 +543,9 @@ static int command_line_execute(VimState *state, int key) if (!(s->c == p_wc && KeyTyped) && s->c != p_wcm && s->c != Ctrl_N && s->c != Ctrl_P && s->c != Ctrl_A && s->c != Ctrl_L) { + if (ui_is_external(kUIWildmenu)) { + ui_call_wildmenu_hide(); + } if (s->xpc.xp_numfiles != -1) { (void)ExpandOne(&s->xpc, NULL, NULL, 0, WILD_FREE); } @@ -1813,7 +1825,8 @@ static int command_line_changed(CommandLineState *s) // right-left typing. Not efficient, but it works. // Do it only when there are no characters left to read // to avoid useless intermediate redraws. - if (vpeekc() == NUL) { + // if cmdline is external the ui handles shaping, no redraw needed. + if (!ui_is_external(kUICmdline) && vpeekc() == NUL) { redrawcmd(); } } @@ -2611,7 +2624,7 @@ static void draw_cmdline(int start, int len) if (ui_is_external(kUICmdline)) { ccline.special_char = NUL; - ui_ext_cmdline_show(&ccline); + ccline.redraw_state = kCmdRedrawAll; return; } @@ -2784,7 +2797,7 @@ void ui_ext_cmdline_block_append(int indent, const char *line) { char *buf = xmallocz(indent + strlen(line)); memset(buf, ' ', indent); - memcpy(buf+indent, line, strlen(line)); + memcpy(buf + indent, line, strlen(line)); // -V575 Array item = ARRAY_DICT_INIT; ADD(item, DICTIONARY_OBJ((Dictionary)ARRAY_DICT_INIT)); @@ -2823,7 +2836,7 @@ void cmdline_screen_cleared(void) if (prev_ccline->level == prev_level) { // don't redraw a cmdline already shown in the cmdline window if (prev_level != cmdwin_level) { - ui_ext_cmdline_show(prev_ccline); + prev_ccline->redraw_state = kCmdRedrawAll; } prev_level--; } @@ -2831,6 +2844,28 @@ void cmdline_screen_cleared(void) } } +/// called by ui_flush, do what redraws neccessary to keep cmdline updated. +void cmdline_ui_flush(void) +{ + if (!ui_is_external(kUICmdline)) { + return; + } + int level = ccline.level; + CmdlineInfo *line = &ccline; + while (level > 0 && line) { + if (line->level == level) { + if (line->redraw_state == kCmdRedrawAll) { + ui_ext_cmdline_show(line); + } else if (line->redraw_state == kCmdRedrawPos) { + ui_call_cmdline_pos(line->cmdpos, line->level); + } + line->redraw_state = kCmdRedrawNone; + level--; + } + line = line->prev_ccline; + } +} + /* * Put a character on the command line. Shifts the following text to the * right when "shift" is TRUE. Used for CTRL-V, CTRL-K, etc. @@ -2851,8 +2886,10 @@ void putcmdline(int c, int shift) } else { ccline.special_char = c; ccline.special_shift = shift; - ui_call_cmdline_special_char(cchar_to_string((char)(c)), shift, - ccline.level); + if (ccline.redraw_state != kCmdRedrawAll) { + ui_call_cmdline_special_char(cchar_to_string((char)(c)), shift, + ccline.level); + } } cursorcmd(); ui_cursor_shape(); @@ -3193,7 +3230,7 @@ static void redrawcmdprompt(void) if (cmd_silent) return; if (ui_is_external(kUICmdline)) { - ui_ext_cmdline_show(&ccline); + ccline.redraw_state = kCmdRedrawAll; return; } if (ccline.cmdfirstc != NUL) { @@ -3270,7 +3307,9 @@ static void cursorcmd(void) return; if (ui_is_external(kUICmdline)) { - ui_call_cmdline_pos(ccline.cmdpos, ccline.level); + if (ccline.redraw_state < kCmdRedrawPos) { + ccline.redraw_state = kCmdRedrawPos; + } return; } @@ -3515,11 +3554,17 @@ ExpandOne ( else findex = -1; } - if (p_wmnu) - win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files, - findex, cmd_showtail); - if (findex == -1) + if (p_wmnu) { + if (ui_is_external(kUIWildmenu)) { + ui_call_wildmenu_select(findex); + } else { + win_redr_status_matches(xp, xp->xp_numfiles, xp->xp_files, + findex, cmd_showtail); + } + } + if (findex == -1) { return vim_strsave(orig_save); + } return vim_strsave(xp->xp_files[findex]); } else return NULL; @@ -3876,6 +3921,15 @@ static int showmatches(expand_T *xp, int wildmenu) showtail = cmd_showtail; } + if (ui_is_external(kUIWildmenu)) { + Array args = ARRAY_DICT_INIT; + for (i = 0; i < num_files; i++) { + ADD(args, STRING_OBJ(cstr_to_string((char *)files_found[i]))); + } + ui_call_wildmenu_show(args); + return EXPAND_OK; + } + if (!wildmenu) { msg_didany = FALSE; /* lines_left will be set */ msg_start(); /* prepare for paging */ @@ -4093,7 +4147,9 @@ addstar ( || context == EXPAND_OWNSYNTAX || context == EXPAND_FILETYPE || context == EXPAND_PACKADD - || (context == EXPAND_TAGS && fname[0] == '/')) + || ((context == EXPAND_TAGS_LISTFILES + || context == EXPAND_TAGS) + && fname[0] == '/')) retval = vim_strnsave(fname, len); else { new_len = len + 2; /* +2 for '^' at start, NUL at end */ @@ -5849,6 +5905,7 @@ static int ex_window(void) changed_line_abv_curs(); invalidate_botline(); if (ui_is_external(kUICmdline)) { + ccline.redraw_state = kCmdRedrawNone; ui_call_cmdline_hide(ccline.level); } redraw_later(SOME_VALID); @@ -6128,4 +6185,3 @@ static void set_search_match(pos_T *t) coladvance((colnr_T)MAXCOL); } } - |