diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2025-02-05 23:09:29 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2025-02-05 23:09:29 +0000 |
commit | d5f194ce780c95821a855aca3c19426576d28ae0 (patch) | |
tree | d45f461b19f9118ad2bb1f440a7a08973ad18832 /src/nvim/ex_getln.c | |
parent | c5d770d311841ea5230426cc4c868e8db27300a8 (diff) | |
parent | 44740e561fc93afe3ebecfd3618bda2d2abeafb0 (diff) | |
download | rneovim-rahm.tar.gz rneovim-rahm.tar.bz2 rneovim-rahm.zip |
Diffstat (limited to 'src/nvim/ex_getln.c')
-rw-r--r-- | src/nvim/ex_getln.c | 272 |
1 files changed, 152 insertions, 120 deletions
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c index ace62ea729..fc20748309 100644 --- a/src/nvim/ex_getln.c +++ b/src/nvim/ex_getln.c @@ -14,7 +14,6 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/helpers.h" #include "nvim/api/vim.h" -#include "nvim/arabic.h" #include "nvim/ascii_defs.h" #include "nvim/autocmd.h" #include "nvim/autocmd_defs.h" @@ -43,7 +42,6 @@ #include "nvim/getchar.h" #include "nvim/gettext_defs.h" #include "nvim/globals.h" -#include "nvim/highlight.h" #include "nvim/highlight_defs.h" #include "nvim/highlight_group.h" #include "nvim/keycodes.h" @@ -64,7 +62,6 @@ #include "nvim/option.h" #include "nvim/option_defs.h" #include "nvim/option_vars.h" -#include "nvim/optionstr.h" #include "nvim/os/input.h" #include "nvim/os/os.h" #include "nvim/path.h" @@ -123,7 +120,7 @@ typedef struct { int indent; int c; bool gotesc; // true when <ESC> just typed - int do_abbr; // when true check for abbr. + bool do_abbr; // when true check for abbr. char *lookfor; // string to match int lookforlen; int hiscnt; // current history line in use @@ -131,17 +128,17 @@ typedef struct { // to jump to next match int histype; // history type to be used incsearch_state_T is_state; - int did_wild_list; // did wild_list() recently + bool did_wild_list; // did wild_list() recently int wim_index; // index in wim_flags[] int save_msg_scroll; int save_State; // remember State when called int prev_cmdpos; char *save_p_icm; - int some_key_typed; // one of the keys was typed + bool some_key_typed; // one of the keys was typed // mouse drag and release events are ignored, unless they are // preceded with a mouse down event - int ignore_drag_release; - int break_ctrl_c; + bool ignore_drag_release; + bool break_ctrl_c; expand_T xpc; OptInt *b_im_ptr; buf_T *b_im_ptr_buf; ///< buffer where b_im_ptr is valid @@ -166,6 +163,7 @@ typedef struct { typedef struct { buf_T *buf; OptInt save_b_p_ul; + int save_b_p_ma; int save_b_changed; pos_T save_b_op_start; pos_T save_b_op_end; @@ -403,7 +401,7 @@ static bool do_incsearch_highlighting(int firstc, int *search_delim, incsearch_s parse_cmd_address(&ea, &dummy, true); if (ea.addr_count > 0) { // Allow for reverse match. - search_first_line = MIN(ea.line1, ea.line1); + search_first_line = MIN(ea.line2, ea.line1); search_last_line = MAX(ea.line2, ea.line1); } else if (cmd[0] == 's' && cmd[1] != 'o') { // :s defaults to the current line @@ -681,6 +679,15 @@ static void init_ccline(int firstc, int indent) } } +static void ui_ext_cmdline_hide(bool abort) +{ + if (ui_has(kUICmdline)) { + cmdline_was_last_drawn = false; + ccline.redraw_state = kCmdRedrawNone; + ui_call_cmdline_hide(ccline.level, abort); + } +} + /// Internal entry point for cmdline mode. /// /// @param count only used for incremental search @@ -787,9 +794,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear setmouse(); setcursor(); - TryState tstate; Error err = ERROR_INIT; - bool tl_ret = true; char firstcbuf[2]; firstcbuf[0] = (char)(firstc > 0 ? firstc : '-'); firstcbuf[1] = 0; @@ -802,20 +807,19 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear tv_dict_add_str(dict, S_LEN("cmdtype"), firstcbuf); tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level); tv_dict_set_keys_readonly(dict); - try_enter(&tstate); - - apply_autocmds(EVENT_CMDLINEENTER, firstcbuf, firstcbuf, false, curbuf); - restore_v_event(dict, &save_v_event); + TRY_WRAP(&err, { + apply_autocmds(EVENT_CMDLINEENTER, firstcbuf, firstcbuf, false, curbuf); + restore_v_event(dict, &save_v_event); + }); - tl_ret = try_leave(&tstate, &err); - if (!tl_ret && ERROR_SET(&err)) { + if (ERROR_SET(&err)) { msg_putchar('\n'); msg_scroll = true; msg_puts_hl(err.msg, HLF_E, true); api_clear_error(&err); redrawcmd(); } - tl_ret = true; + err = ERROR_INIT; } may_trigger_modechanged(); @@ -847,6 +851,10 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear found_one = true; } + if (redraw_custom_title_later()) { + found_one = true; + } + if (found_one) { redraw_statuslines(); } @@ -869,10 +877,10 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear // not readonly: tv_dict_add_bool(dict, S_LEN("abort"), s->gotesc ? kBoolVarTrue : kBoolVarFalse); - try_enter(&tstate); - apply_autocmds(EVENT_CMDLINELEAVE, firstcbuf, firstcbuf, false, curbuf); - // error printed below, to avoid redraw issues - tl_ret = try_leave(&tstate, &err); + TRY_WRAP(&err, { + apply_autocmds(EVENT_CMDLINELEAVE, firstcbuf, firstcbuf, false, curbuf); + // error printed below, to avoid redraw issues + }); if (tv_dict_get_number(dict, "abort") != 0) { s->gotesc = true; } @@ -925,7 +933,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear msg_scroll = s->save_msg_scroll; redir_off = false; - if (!tl_ret && ERROR_SET(&err)) { + if (ERROR_SET(&err)) { msg_putchar('\n'); emsg(err.msg); did_emsg = false; @@ -933,7 +941,7 @@ static uint8_t *command_line_enter(int firstc, int count, int indent, bool clear } // When the command line was typed, no need for a wait-return prompt. - if (s->some_key_typed && tl_ret) { + if (s->some_key_typed && !ERROR_SET(&err)) { need_wait_return = false; } @@ -955,10 +963,11 @@ theend: char *p = ccline.cmdbuff; if (ui_has(kUICmdline)) { - ui_call_cmdline_hide(ccline.level); + ui_ext_cmdline_hide(s->gotesc); msg_ext_clear_later(); } if (!cmd_silent) { + redraw_custom_title_later(); status_redraw_all(); // redraw to show mode change } @@ -1070,23 +1079,23 @@ static int command_line_wildchar_complete(CommandLineState *s) { int res; int options = WILD_NO_BEEP; - if (wim_flags[s->wim_index] & WIM_BUFLASTUSED) { + if (wim_flags[s->wim_index] & kOptWimFlagLastused) { options |= WILD_BUFLASTUSED; } if (s->xpc.xp_numfiles > 0) { // typed p_wc at least twice // if 'wildmode' contains "list" may still need to list if (s->xpc.xp_numfiles > 1 && !s->did_wild_list - && ((wim_flags[s->wim_index] & WIM_LIST) - || (p_wmnu && (wim_flags[s->wim_index] & WIM_FULL) != 0))) { - showmatches(&s->xpc, p_wmnu && ((wim_flags[s->wim_index] & WIM_LIST) == 0)); + && ((wim_flags[s->wim_index] & kOptWimFlagList) + || (p_wmnu && (wim_flags[s->wim_index] & kOptWimFlagFull) != 0))) { + showmatches(&s->xpc, p_wmnu && ((wim_flags[s->wim_index] & kOptWimFlagList) == 0)); redrawcmd(); s->did_wild_list = true; } - if (wim_flags[s->wim_index] & WIM_LONGEST) { + if (wim_flags[s->wim_index] & kOptWimFlagLongest) { res = nextwild(&s->xpc, WILD_LONGEST, options, s->firstc != '@'); - } else if (wim_flags[s->wim_index] & WIM_FULL) { + } else if (wim_flags[s->wim_index] & kOptWimFlagFull) { res = nextwild(&s->xpc, WILD_NEXT, options, s->firstc != '@'); } else { res = OK; // don't insert 'wildchar' now @@ -1097,7 +1106,7 @@ static int command_line_wildchar_complete(CommandLineState *s) // if 'wildmode' first contains "longest", get longest // common part - if (wim_flags[0] & WIM_LONGEST) { + if (wim_flags[0] & kOptWimFlagLongest) { res = nextwild(&s->xpc, WILD_LONGEST, options, s->firstc != '@'); } else { res = nextwild(&s->xpc, WILD_EXPAND_KEEP, options, s->firstc != '@'); @@ -1118,12 +1127,12 @@ static int command_line_wildchar_complete(CommandLineState *s) if (res == OK && s->xpc.xp_numfiles > 1) { // a "longest" that didn't do anything is skipped (but not // "list:longest") - if (wim_flags[0] == WIM_LONGEST && ccline.cmdpos == j) { + if (wim_flags[0] == kOptWimFlagLongest && ccline.cmdpos == j) { s->wim_index = 1; } - if ((wim_flags[s->wim_index] & WIM_LIST) - || (p_wmnu && (wim_flags[s->wim_index] & WIM_FULL) != 0)) { - if (!(wim_flags[0] & WIM_LONGEST)) { + if ((wim_flags[s->wim_index] & kOptWimFlagList) + || (p_wmnu && (wim_flags[s->wim_index] & kOptWimFlagFull) != 0)) { + if (!(wim_flags[0] & kOptWimFlagLongest)) { int p_wmnu_save = p_wmnu; p_wmnu = 0; // remove match @@ -1131,17 +1140,17 @@ static int command_line_wildchar_complete(CommandLineState *s) p_wmnu = p_wmnu_save; } - showmatches(&s->xpc, p_wmnu && ((wim_flags[s->wim_index] & WIM_LIST) == 0)); + showmatches(&s->xpc, p_wmnu && ((wim_flags[s->wim_index] & kOptWimFlagList) == 0)); redrawcmd(); s->did_wild_list = true; - if (wim_flags[s->wim_index] & WIM_LONGEST) { + if (wim_flags[s->wim_index] & kOptWimFlagLongest) { nextwild(&s->xpc, WILD_LONGEST, options, s->firstc != '@'); - } else if (wim_flags[s->wim_index] & WIM_FULL) { + } else if (wim_flags[s->wim_index] & kOptWimFlagFull) { nextwild(&s->xpc, WILD_NEXT, options, s->firstc != '@'); } } else { - vim_beep(BO_WILD); + vim_beep(kOptBoFlagWildmode); } } else if (s->xpc.xp_numfiles == -1) { s->xpc.xp_context = EXPAND_NOTHING; @@ -1380,9 +1389,9 @@ static int command_line_execute(VimState *state, int key) if (s->c == K_S_TAB && KeyTyped) { if (nextwild(&s->xpc, WILD_EXPAND_KEEP, 0, s->firstc != '@') == OK) { if (s->xpc.xp_numfiles > 1 - && ((!s->did_wild_list && (wim_flags[s->wim_index] & WIM_LIST)) || p_wmnu)) { + && ((!s->did_wild_list && (wim_flags[s->wim_index] & kOptWimFlagList)) || p_wmnu)) { // Trigger the popup menu when wildoptions=pum - showmatches(&s->xpc, p_wmnu && ((wim_flags[s->wim_index] & WIM_LIST) == 0)); + showmatches(&s->xpc, p_wmnu && ((wim_flags[s->wim_index] & kOptWimFlagList) == 0)); } nextwild(&s->xpc, WILD_PREV, 0, s->firstc != '@'); nextwild(&s->xpc, WILD_PREV, 0, s->firstc != '@'); @@ -1511,7 +1520,7 @@ static int may_do_command_line_next_incsearch(int firstc, int count, incsearch_s redrawcmdline(); curwin->w_cursor = s->match_end; } else { - vim_beep(BO_ERROR); + vim_beep(kOptBoFlagError); } restore_last_search_pattern(); return FAIL; @@ -1849,6 +1858,12 @@ static int command_line_browse_history(CommandLineState *s) static int command_line_handle_key(CommandLineState *s) { + // For one key prompt, avoid putting ESC and Ctrl_C onto cmdline. + // For all other keys, just put onto cmdline and exit. + if (ccline.one_key && s->c != ESC && s->c != Ctrl_C) { + goto end; + } + // Big switch for a typed command line character. switch (s->c) { case K_BS: @@ -1999,6 +2014,12 @@ static int command_line_handle_key(CommandLineState *s) } FALLTHROUGH; case K_LEFTMOUSE: + // Return on left click above number prompt + if (ccline.mouse_used && mouse_row < cmdline_row) { + *ccline.mouse_used = true; + return 0; + } + FALLTHROUGH; case K_RIGHTMOUSE: command_line_left_right_mouse(s); return command_line_not_changed(s); @@ -2156,6 +2177,14 @@ static int command_line_handle_key(CommandLineState *s) } return command_line_not_changed(s); + case 'q': + // Number prompts use the mouse and return on 'q' press + if (ccline.mouse_used) { + *ccline.cmdbuff = NUL; + return 0; + } + FALLTHROUGH; + default: // Normal character with no special meaning. Just set mod_mask // to 0x0 so that typing Shift-Space in the GUI doesn't enter @@ -2176,6 +2205,7 @@ static int command_line_handle_key(CommandLineState *s) return command_line_changed(s); } +end: // put the character in the command line if (IS_SPECIAL(s->c) || mod_mask != 0) { put_on_cmdline(get_special_key_name(s->c, mod_mask), -1, true); @@ -2184,17 +2214,22 @@ static int command_line_handle_key(CommandLineState *s) IObuff[j] = NUL; // exclude composing chars put_on_cmdline(IObuff, j, true); } - return command_line_changed(s); + return ccline.one_key ? 0 : command_line_changed(s); } -static int command_line_not_changed(CommandLineState *s) +/// Trigger CursorMovedC autocommands. +static void may_trigger_cursormovedc(CommandLineState *s) { - // Trigger CursorMovedC autocommands. if (ccline.cmdpos != s->prev_cmdpos) { trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC); s->prev_cmdpos = ccline.cmdpos; + ccline.redraw_state = MAX(ccline.redraw_state, kCmdRedrawPos); } +} +static int command_line_not_changed(CommandLineState *s) +{ + may_trigger_cursormovedc(s); // Incremental searches for "/" and "?": // Enter command_line_not_changed() when a character has been read but the // command line did not change. Then we only search and redraw if something @@ -2310,11 +2345,13 @@ static win_T *cmdpreview_open_win(buf_T *cmdpreview_buf) win_T *preview_win = curwin; Error err = ERROR_INIT; + int result = OK; // Switch to preview buffer - try_start(); - int result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, cmdpreview_buf->handle, 0); - if (try_end(&err) || result == FAIL) { + TRY_WRAP(&err, { + result = do_buffer(DOBUF_GOTO, DOBUF_FIRST, FORWARD, cmdpreview_buf->handle, 0); + }); + if (ERROR_SET(&err) || result == FAIL) { api_clear_error(&err); return NULL; } @@ -2396,6 +2433,7 @@ static void cmdpreview_prepare(CpInfo *cpinfo) if (!set_has(ptr_t, &saved_bufs, buf)) { CpBufInfo cp_bufinfo; cp_bufinfo.buf = buf; + cp_bufinfo.save_b_p_ma = buf->b_p_ma; cp_bufinfo.save_b_p_ul = buf->b_p_ul; cp_bufinfo.save_b_changed = buf->b_changed; cp_bufinfo.save_b_op_start = buf->b_op_start; @@ -2486,6 +2524,7 @@ static void cmdpreview_restore_state(CpInfo *cpinfo) } buf->b_p_ul = cp_bufinfo.save_b_p_ul; // Restore 'undolevels' + buf->b_p_ma = cp_bufinfo.save_b_p_ma; // Restore 'modifiable' } for (size_t i = 0; i < cpinfo->win_info.size; i++) { @@ -2554,7 +2593,7 @@ static bool cmdpreview_may_show(CommandLineState *s) // Place it there in case preview callback flushes it. #30696 cursorcmd(); // Flush now: external cmdline may itself wish to update the screen which is - // currently disallowed during cmdpreview(no longer needed in case that changes). + // currently disallowed during cmdpreview (no longer needed in case that changes). cmdline_ui_flush(); // Swap invalid command range if needed @@ -2595,9 +2634,10 @@ static bool cmdpreview_may_show(CommandLineState *s) // open the preview window. The preview callback also handles doing the changes and highlights for // the preview. Error err = ERROR_INIT; - try_start(); - cmdpreview_type = execute_cmd(&ea, &cmdinfo, true); - if (try_end(&err)) { + TRY_WRAP(&err, { + cmdpreview_type = execute_cmd(&ea, &cmdinfo, true); + }); + if (ERROR_SET(&err)) { api_clear_error(&err); cmdpreview_type = 0; } @@ -2638,7 +2678,6 @@ end: static void do_autocmd_cmdlinechanged(int firstc) { if (has_event(EVENT_CMDLINECHANGED)) { - TryState tstate; Error err = ERROR_INIT; save_v_event_T save_v_event; dict_T *dict = get_v_event(&save_v_event); @@ -2651,13 +2690,11 @@ static void do_autocmd_cmdlinechanged(int firstc) tv_dict_add_str(dict, S_LEN("cmdtype"), firstcbuf); tv_dict_add_nr(dict, S_LEN("cmdlevel"), ccline.level); tv_dict_set_keys_readonly(dict); - try_enter(&tstate); - - apply_autocmds(EVENT_CMDLINECHANGED, firstcbuf, firstcbuf, false, curbuf); - restore_v_event(dict, &save_v_event); - - bool tl_ret = try_leave(&tstate, &err); - if (!tl_ret && ERROR_SET(&err)) { + TRY_WRAP(&err, { + apply_autocmds(EVENT_CMDLINECHANGED, firstcbuf, firstcbuf, false, curbuf); + restore_v_event(dict, &save_v_event); + }); + if (ERROR_SET(&err)) { msg_putchar('\n'); msg_scroll = true; msg_puts_hl(err.msg, HLF_E, true); @@ -2672,18 +2709,13 @@ static int command_line_changed(CommandLineState *s) // Trigger CmdlineChanged autocommands. do_autocmd_cmdlinechanged(s->firstc > 0 ? s->firstc : '-'); - // Trigger CursorMovedC autocommands. - if (ccline.cmdpos != s->prev_cmdpos) { - trigger_cmd_autocmd(get_cmdline_type(), EVENT_CURSORMOVEDC); - s->prev_cmdpos = ccline.cmdpos; - } + may_trigger_cursormovedc(s); const bool prev_cmdpreview = cmdpreview; if (s->firstc == ':' && current_sctx.sc_sid == 0 // only if interactive && *p_icm != NUL // 'inccommand' is set && !exmode_active // not in ex mode - && curbuf->b_p_ma // buffer is modifiable && cmdline_star == 0 // not typing a password && !vpeekc_any() && cmdpreview_may_show(s)) { @@ -2718,12 +2750,14 @@ static int command_line_changed(CommandLineState *s) static void abandon_cmdline(void) { dealloc_cmdbuff(); - ccline.redraw_state = kCmdRedrawNone; if (msg_scrolled == 0) { compute_cmdrow(); } - msg("", 0); - redraw_cmdline = true; + // Avoid overwriting key prompt + if (!ccline.one_key) { + msg("", 0); + redraw_cmdline = true; + } } /// getcmdline() - accept a command line starting with firstc. @@ -2762,11 +2796,13 @@ char *getcmdline(int firstc, int count, int indent, bool do_concat FUNC_ATTR_UNU /// @param[in] xp_context Type of expansion. /// @param[in] xp_arg User-defined expansion argument. /// @param[in] highlight_callback Callback used for highlighting user input. +/// @param[in] one_key Return after one key press for button prompt. +/// @param[in] mouse_used Set to true when returning after right mouse click. /// /// @return [allocated] Command line or NULL. char *getcmdline_prompt(const int firstc, const char *const prompt, const int hl_id, const int xp_context, const char *const xp_arg, - const Callback highlight_callback) + const Callback highlight_callback, bool one_key, bool *mouse_used) FUNC_ATTR_WARN_UNUSED_RESULT FUNC_ATTR_MALLOC { const int msg_col_save = msg_col; @@ -2787,16 +2823,22 @@ char *getcmdline_prompt(const int firstc, const char *const prompt, const int hl ccline.xp_arg = (char *)xp_arg; ccline.input_fn = (firstc == '@'); ccline.highlight_callback = highlight_callback; + ccline.one_key = one_key; + ccline.mouse_used = mouse_used; + const bool cmd_silent_saved = cmd_silent; int msg_silent_saved = msg_silent; msg_silent = 0; + cmd_silent = false; // Want to see the prompt. char *const ret = (char *)command_line_enter(firstc, 1, 0, false); + ccline.redraw_state = kCmdRedrawNone; if (did_save_ccline) { restore_cmdline(&save_ccline); } msg_silent = msg_silent_saved; + cmd_silent = cmd_silent_saved; // Restore msg_col, the prompt from input() may have changed it. // But only if called recursively and the commandline is therefore being // restored to an old one; if not, the input() prompt stays on the screen, @@ -2820,19 +2862,19 @@ int check_opt_wim(void) } for (char *p = p_wim; *p; p++) { - // Note: Keep this in sync with p_wim_values. + // Note: Keep this in sync with opt_wim_values. for (i = 0; ASCII_ISALPHA(p[i]); i++) {} if (p[i] != NUL && p[i] != ',' && p[i] != ':') { return FAIL; } if (i == 7 && strncmp(p, "longest", 7) == 0) { - new_wim_flags[idx] |= WIM_LONGEST; + new_wim_flags[idx] |= kOptWimFlagLongest; } else if (i == 4 && strncmp(p, "full", 4) == 0) { - new_wim_flags[idx] |= WIM_FULL; + new_wim_flags[idx] |= kOptWimFlagFull; } else if (i == 4 && strncmp(p, "list", 4) == 0) { - new_wim_flags[idx] |= WIM_LIST; + new_wim_flags[idx] |= kOptWimFlagList; } else if (i == 8 && strncmp(p, "lastused", 8) == 0) { - new_wim_flags[idx] |= WIM_BUFLASTUSED; + new_wim_flags[idx] |= kOptWimFlagLastused; } else { return FAIL; } @@ -3140,8 +3182,9 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) #define PRINT_ERRMSG(...) \ do { \ + msg_scroll = true; \ msg_putchar('\n'); \ - msg_printf_hl(HLF_E, __VA_ARGS__); \ + smsg(HLF_E, __VA_ARGS__); \ printed_errmsg = true; \ } while (0) bool ret = true; @@ -3174,11 +3217,9 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) static int prev_prompt_errors = 0; Callback color_cb = CALLBACK_NONE; bool can_free_cb = false; - TryState tstate; Error err = ERROR_INIT; const char *err_errmsg = e_intern2; bool dgc_ret = true; - bool tl_ret = true; if (colored_ccline->prompt_id != prev_prompt_id) { prev_prompt_errors = 0; @@ -3191,16 +3232,16 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) assert(colored_ccline->input_fn); color_cb = colored_ccline->highlight_callback; } else if (colored_ccline->cmdfirstc == ':') { - try_enter(&tstate); - err_errmsg = N_("E5408: Unable to get g:Nvim_color_cmdline callback: %s"); - dgc_ret = tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_cmdline"), - &color_cb); - tl_ret = try_leave(&tstate, &err); + TRY_WRAP(&err, { + err_errmsg = N_("E5408: Unable to get g:Nvim_color_cmdline callback: %s"); + dgc_ret = tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_cmdline"), + &color_cb); + }); can_free_cb = true; } else if (colored_ccline->cmdfirstc == '=') { color_expr_cmdline(colored_ccline, ccline_colors); } - if (!tl_ret || !dgc_ret) { + if (ERROR_SET(&err) || !dgc_ret) { goto color_cmdline_error; } @@ -3221,20 +3262,22 @@ static bool color_cmdline(CmdlineInfo *colored_ccline) // correct, with msg_col it just misses leading `:`. Since `redraw!` in // callback lags this is least of the user problems. // - // Also using try_enter() because error messages may overwrite typed + // Also using TRY_WRAP because error messages may overwrite typed // command-line which is not expected. getln_interrupted_highlight = false; - try_enter(&tstate); - err_errmsg = N_("E5407: Callback has thrown an exception: %s"); - const int saved_msg_col = msg_col; - msg_silent++; - const bool cbcall_ret = callback_call(&color_cb, 1, &arg, &tv); - msg_silent--; - msg_col = saved_msg_col; - if (got_int) { - getln_interrupted_highlight = true; - } - if (!try_leave(&tstate, &err) || !cbcall_ret) { + bool cbcall_ret = true; + TRY_WRAP(&err, { + err_errmsg = N_("E5407: Callback has thrown an exception: %s"); + const int saved_msg_col = msg_col; + msg_silent++; + cbcall_ret = callback_call(&color_cb, 1, &arg, &tv); + msg_silent--; + msg_col = saved_msg_col; + if (got_int) { + getln_interrupted_highlight = true; + } + }); + if (ERROR_SET(&err) || !cbcall_ret) { goto color_cmdline_error; } if (tv.v_type != VAR_LIST) { @@ -3350,7 +3393,7 @@ color_cmdline_error: // when cmdline_star is true. static void draw_cmdline(int start, int len) { - if (!color_cmdline(&ccline)) { + if (ccline.cmdbuff == NULL || !color_cmdline(&ccline)) { return; } @@ -3420,8 +3463,7 @@ static void ui_ext_cmdline_show(CmdlineInfo *line) ui_call_cmdline_show(content, line->cmdpos, cstr_as_string(charbuf), cstr_as_string((line->cmdprompt)), - line->cmdindent, - line->level); + line->cmdindent, line->level, line->hl_id); if (line->special_char) { charbuf[0] = line->special_char; ui_call_cmdline_special_char(cstr_as_string(charbuf), @@ -3457,8 +3499,7 @@ void ui_ext_cmdline_block_leave(void) ui_call_cmdline_block_hide(); } -/// Extra redrawing needed for redraw! and on ui_attach -/// assumes "redrawcmdline()" will already be invoked +/// Extra redrawing needed for redraw! and on ui_attach. void cmdline_screen_cleared(void) { if (!ui_has(kUICmdline)) { @@ -3481,6 +3522,7 @@ void cmdline_screen_cleared(void) } line = line->prev_ccline; } + redrawcmd(); } /// called by ui_flush, do what redraws necessary to keep cmdline updated. @@ -3493,12 +3535,14 @@ void cmdline_ui_flush(void) CmdlineInfo *line = &ccline; while (level > 0 && line) { if (line->level == level) { - if (line->redraw_state == kCmdRedrawAll) { + CmdRedraw redraw_state = line->redraw_state; + line->redraw_state = kCmdRedrawNone; + if (redraw_state == kCmdRedrawAll) { + cmdline_was_last_drawn = true; ui_ext_cmdline_show(line); - } else if (line->redraw_state == kCmdRedrawPos) { + } else if (redraw_state == kCmdRedrawPos && cmdline_was_last_drawn) { ui_call_cmdline_pos(line->cmdpos, line->level); } - line->redraw_state = kCmdRedrawNone; level--; } line = line->prev_ccline; @@ -3866,12 +3910,7 @@ void compute_cmdrow(void) void cursorcmd(void) { - if (cmd_silent) { - return; - } - - if (ui_has(kUICmdline)) { - ccline.redraw_state = MAX(ccline.redraw_state, kCmdRedrawPos); + if (cmd_silent || ui_has(kUICmdline)) { return; } @@ -4473,10 +4512,7 @@ static int open_cmdwin(void) curwin->w_cursor.col = ccline.cmdpos; changed_line_abv_curs(); invalidate_botline(curwin); - if (ui_has(kUICmdline)) { - ccline.redraw_state = kCmdRedrawNone; - ui_call_cmdline_hide(ccline.level); - } + ui_ext_cmdline_hide(false); redraw_later(curwin, UPD_SOME_VALID); // No Ex mode here! @@ -4764,9 +4800,6 @@ void get_user_input(const typval_T *const argvars, typval_T *const rettv, const } } - const bool cmd_silent_save = cmd_silent; - - cmd_silent = false; // Want to see the prompt. // Only the part of the message after the last NL is considered as // prompt for the command line, unlsess cmdline is externalized const char *p = prompt; @@ -4788,7 +4821,7 @@ void get_user_input(const typval_T *const argvars, typval_T *const rettv, const const int save_ex_normal_busy = ex_normal_busy; ex_normal_busy = 0; rettv->vval.v_string = getcmdline_prompt(secret ? NUL : '@', p, get_echo_hl_id(), - xp_type, xp_arg, input_callback); + xp_type, xp_arg, input_callback, false, NULL); ex_normal_busy = save_ex_normal_busy; callback_free(&input_callback); @@ -4801,5 +4834,4 @@ void get_user_input(const typval_T *const argvars, typval_T *const rettv, const // Since the user typed this, no need to wait for return. need_wait_return = false; msg_didout = false; - cmd_silent = cmd_silent_save; } |