mirror of
https://github.com/neovim/neovim.git
synced 2025-09-16 16:28:17 +00:00
eval,ex_getln: Add support for coloring input() prompts
This commit is contained in:
@@ -4699,6 +4699,7 @@ input({opts})
|
|||||||
cancelreturn "" Same as {cancelreturn} from
|
cancelreturn "" Same as {cancelreturn} from
|
||||||
|inputdialog()|. Also works with
|
|inputdialog()|. Also works with
|
||||||
input().
|
input().
|
||||||
|
highlight nothing Highlight handler: |Funcref|.
|
||||||
|
|
||||||
The highlighting set with |:echohl| is used for the prompt.
|
The highlighting set with |:echohl| is used for the prompt.
|
||||||
The input is entered just like a command-line, with the same
|
The input is entered just like a command-line, with the same
|
||||||
@@ -4722,6 +4723,22 @@ input({opts})
|
|||||||
more information. Example: >
|
more information. Example: >
|
||||||
let fname = input("File: ", "", "file")
|
let fname = input("File: ", "", "file")
|
||||||
<
|
<
|
||||||
|
The optional highlight key allows specifying function which
|
||||||
|
will be used for highlighting. This function receives user
|
||||||
|
input as its only argument and must return a list of 3-tuples
|
||||||
|
[hl_start_byte, hl_end_byte + 1, hl_group] where
|
||||||
|
hl_start_byte is the first highlighted byte,
|
||||||
|
hl_end_byte is the last highlighted byte (+ 1!),
|
||||||
|
hl_group is |:hl| group used for highlighting.
|
||||||
|
*E5403* *E5404* *E5405* *E5406*
|
||||||
|
Both hl_start_byte and hl_end_byte + 1 must point to the start
|
||||||
|
of the multibyte character (highlighting must not break
|
||||||
|
multibyte characters), hl_end_byte + 1 may be equal to the
|
||||||
|
input length. Start column must be in range [0, len(input)),
|
||||||
|
end column must be in range (hl_start_byte, len(input)],
|
||||||
|
sections must be ordered so that next hl_start_byte is greater
|
||||||
|
then or equal to previous hl_end_byte.
|
||||||
|
|
||||||
NOTE: This function must not be used in a startup file, for
|
NOTE: This function must not be used in a startup file, for
|
||||||
the versions that only run in GUI mode (e.g., the Win32 GUI).
|
the versions that only run in GUI mode (e.g., the Win32 GUI).
|
||||||
Note: When input() is called from within a mapping it will
|
Note: When input() is called from within a mapping it will
|
||||||
|
@@ -11010,6 +11010,7 @@ void get_user_input(const typval_T *const argvars,
|
|||||||
const char *defstr = "";
|
const char *defstr = "";
|
||||||
const char *cancelreturn = NULL;
|
const char *cancelreturn = NULL;
|
||||||
const char *xp_name = NULL;
|
const char *xp_name = NULL;
|
||||||
|
Callback input_callback = { .type = kCallbackNone };
|
||||||
char prompt_buf[NUMBUFLEN];
|
char prompt_buf[NUMBUFLEN];
|
||||||
char defstr_buf[NUMBUFLEN];
|
char defstr_buf[NUMBUFLEN];
|
||||||
char cancelreturn_buf[NUMBUFLEN];
|
char cancelreturn_buf[NUMBUFLEN];
|
||||||
@@ -11019,7 +11020,7 @@ void get_user_input(const typval_T *const argvars,
|
|||||||
emsgf(_("E5050: {opts} must be the only argument"));
|
emsgf(_("E5050: {opts} must be the only argument"));
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
const dict_T *const dict = argvars[0].vval.v_dict;
|
dict_T *const dict = argvars[0].vval.v_dict;
|
||||||
prompt = tv_dict_get_string_buf_chk(dict, S_LEN("prompt"), prompt_buf, "");
|
prompt = tv_dict_get_string_buf_chk(dict, S_LEN("prompt"), prompt_buf, "");
|
||||||
if (prompt == NULL) {
|
if (prompt == NULL) {
|
||||||
return;
|
return;
|
||||||
@@ -11045,6 +11046,9 @@ void get_user_input(const typval_T *const argvars,
|
|||||||
if (xp_name == def) { // default to NULL
|
if (xp_name == def) { // default to NULL
|
||||||
xp_name = NULL;
|
xp_name = NULL;
|
||||||
}
|
}
|
||||||
|
if (!tv_dict_get_callback(dict, S_LEN("highlight"), &input_callback)) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
prompt = tv_get_string_buf_chk(&argvars[0], prompt_buf);
|
prompt = tv_get_string_buf_chk(&argvars[0], prompt_buf);
|
||||||
if (prompt == NULL) {
|
if (prompt == NULL) {
|
||||||
@@ -11103,12 +11107,16 @@ void get_user_input(const typval_T *const argvars,
|
|||||||
|
|
||||||
stuffReadbuffSpec(defstr);
|
stuffReadbuffSpec(defstr);
|
||||||
|
|
||||||
int save_ex_normal_busy = ex_normal_busy;
|
const int save_ex_normal_busy = ex_normal_busy;
|
||||||
|
const Callback save_getln_input_callback = getln_input_callback;
|
||||||
ex_normal_busy = 0;
|
ex_normal_busy = 0;
|
||||||
|
getln_input_callback = input_callback;
|
||||||
rettv->vval.v_string =
|
rettv->vval.v_string =
|
||||||
getcmdline_prompt(inputsecret_flag ? NUL : '@', (char_u *)p, echo_attr,
|
getcmdline_prompt(inputsecret_flag ? NUL : '@', (char_u *)p, echo_attr,
|
||||||
xp_type, (char_u *)xp_arg);
|
xp_type, (char_u *)xp_arg);
|
||||||
|
getln_input_callback = save_getln_input_callback;
|
||||||
ex_normal_busy = save_ex_normal_busy;
|
ex_normal_busy = save_ex_normal_busy;
|
||||||
|
callback_free(&input_callback);
|
||||||
|
|
||||||
if (rettv->vval.v_string == NULL && cancelreturn != NULL) {
|
if (rettv->vval.v_string == NULL && cancelreturn != NULL) {
|
||||||
rettv->vval.v_string = (char_u *)xstrdup(cancelreturn);
|
rettv->vval.v_string = (char_u *)xstrdup(cancelreturn);
|
||||||
|
@@ -70,23 +70,26 @@
|
|||||||
* structure.
|
* structure.
|
||||||
*/
|
*/
|
||||||
struct cmdline_info {
|
struct cmdline_info {
|
||||||
char_u *cmdbuff; /* pointer to command line buffer */
|
char_u *cmdbuff; // pointer to command line buffer
|
||||||
int cmdbufflen; /* length of cmdbuff */
|
int cmdbufflen; // length of cmdbuff
|
||||||
int cmdlen; /* number of chars in command line */
|
int cmdlen; // number of chars in command line
|
||||||
int cmdpos; /* current cursor position */
|
int cmdpos; // current cursor position
|
||||||
int cmdspos; /* cursor column on screen */
|
int cmdspos; // cursor column on screen
|
||||||
int cmdfirstc; /* ':', '/', '?', '=', '>' or NUL */
|
int cmdfirstc; // ':', '/', '?', '=', '>' or NUL
|
||||||
int cmdindent; /* number of spaces before cmdline */
|
int cmdindent; // number of spaces before cmdline
|
||||||
char_u *cmdprompt; /* message in front of cmdline */
|
char_u *cmdprompt; // message in front of cmdline
|
||||||
int cmdattr; /* attributes for prompt */
|
int cmdattr; // attributes for prompt
|
||||||
int overstrike; /* Typing mode on the command line. Shared by
|
int overstrike; // Typing mode on the command line. Shared by
|
||||||
getcmdline() and put_on_cmdline(). */
|
// getcmdline() and put_on_cmdline().
|
||||||
expand_T *xpc; /* struct being used for expansion, xp_pattern
|
expand_T *xpc; // struct being used for expansion, xp_pattern
|
||||||
may point into cmdbuff */
|
// may point into cmdbuff
|
||||||
int xp_context; /* type of expansion */
|
int xp_context; // type of expansion
|
||||||
char_u *xp_arg; /* user-defined expansion arg */
|
char_u *xp_arg; // user-defined expansion arg
|
||||||
int input_fn; /* when TRUE Invoked for input() function */
|
int input_fn; // when TRUE Invoked for input() function
|
||||||
|
unsigned prompt_id; ///< Prompt number, used to disable coloring on errors.
|
||||||
};
|
};
|
||||||
|
/// Last value of prompt_id, incremented when doing new prompt
|
||||||
|
static unsigned last_prompt_id = 0;
|
||||||
|
|
||||||
typedef struct command_line_state {
|
typedef struct command_line_state {
|
||||||
VimState state;
|
VimState state;
|
||||||
@@ -135,6 +138,9 @@ typedef struct {
|
|||||||
int attr; ///< Highlight attr.
|
int attr; ///< Highlight attr.
|
||||||
} ColoredCmdlineChunk;
|
} ColoredCmdlineChunk;
|
||||||
|
|
||||||
|
/// Callback used for coloring input() prompts
|
||||||
|
Callback getln_input_callback = { .type = kCallbackNone };
|
||||||
|
|
||||||
kvec_t(ColoredCmdlineChunk) ccline_colors;
|
kvec_t(ColoredCmdlineChunk) ccline_colors;
|
||||||
|
|
||||||
/* The current cmdline_info. It is initialized in getcmdline() and after that
|
/* The current cmdline_info. It is initialized in getcmdline() and after that
|
||||||
@@ -188,6 +194,7 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
|
|||||||
cmd_hkmap = 0;
|
cmd_hkmap = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ccline.prompt_id = last_prompt_id++;
|
||||||
ccline.overstrike = false; // always start in insert mode
|
ccline.overstrike = false; // always start in insert mode
|
||||||
s->old_cursor = curwin->w_cursor; // needs to be restored later
|
s->old_cursor = curwin->w_cursor; // needs to be restored later
|
||||||
s->old_curswant = curwin->w_curswant;
|
s->old_curswant = curwin->w_curswant;
|
||||||
@@ -1703,6 +1710,7 @@ getcmdline_prompt (
|
|||||||
int msg_col_save = msg_col;
|
int msg_col_save = msg_col;
|
||||||
|
|
||||||
save_cmdline(&save_ccline);
|
save_cmdline(&save_ccline);
|
||||||
|
ccline.prompt_id = last_prompt_id++;
|
||||||
ccline.cmdprompt = prompt;
|
ccline.cmdprompt = prompt;
|
||||||
ccline.cmdattr = attr;
|
ccline.cmdattr = attr;
|
||||||
ccline.xp_context = xp_context;
|
ccline.xp_context = xp_context;
|
||||||
@@ -2178,7 +2186,7 @@ void free_cmdline_buf(void)
|
|||||||
|
|
||||||
# endif
|
# endif
|
||||||
|
|
||||||
enum { MAX_CB_ERRORS = 5 };
|
enum { MAX_CB_ERRORS = 1 };
|
||||||
|
|
||||||
/// Color command-line
|
/// Color command-line
|
||||||
///
|
///
|
||||||
@@ -2195,9 +2203,6 @@ static bool color_cmdline(void)
|
|||||||
{
|
{
|
||||||
bool ret = true;
|
bool ret = true;
|
||||||
kv_size(ccline_colors) = 0;
|
kv_size(ccline_colors) = 0;
|
||||||
if (ccline.cmdfirstc != ':') {
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
const int saved_force_abort = force_abort;
|
const int saved_force_abort = force_abort;
|
||||||
force_abort = true;
|
force_abort = true;
|
||||||
@@ -2208,24 +2213,32 @@ static bool color_cmdline(void)
|
|||||||
};
|
};
|
||||||
typval_T tv = { .v_type = VAR_UNKNOWN };
|
typval_T tv = { .v_type = VAR_UNKNOWN };
|
||||||
|
|
||||||
static Callback prev_cb = { .type = kCallbackNone };
|
static unsigned prev_prompt_id = UINT_MAX;
|
||||||
static int prev_cb_errors = 0;
|
static int prev_prompt_errors = 0;
|
||||||
Callback color_cb;
|
Callback color_cb = { .type = kCallbackNone };
|
||||||
if (!tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_cmdline"),
|
bool can_free_cb = false;
|
||||||
&color_cb)) {
|
|
||||||
goto color_cmdline_error;
|
if (ccline.input_fn) {
|
||||||
|
color_cb = getln_input_callback;
|
||||||
|
} else if (ccline.cmdfirstc == ':') {
|
||||||
|
if (!tv_dict_get_callback(&globvardict, S_LEN("Nvim_color_cmdline"),
|
||||||
|
&color_cb)) {
|
||||||
|
goto color_cmdline_error;
|
||||||
|
}
|
||||||
|
can_free_cb = true;
|
||||||
|
} else {
|
||||||
|
goto color_cmdline_end;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (color_cb.type == kCallbackNone) {
|
if (color_cb.type == kCallbackNone) {
|
||||||
goto color_cmdline_end;
|
goto color_cmdline_end;
|
||||||
}
|
}
|
||||||
if (!tv_callback_equal(&prev_cb, &color_cb)) {
|
if (ccline.prompt_id != prev_prompt_id) {
|
||||||
prev_cb_errors = 0;
|
prev_prompt_errors = 0;
|
||||||
} else if (prev_cb_errors >= MAX_CB_ERRORS) {
|
prev_prompt_id = ccline.prompt_id;
|
||||||
callback_free(&color_cb);
|
} else if (prev_prompt_errors >= MAX_CB_ERRORS) {
|
||||||
goto color_cmdline_end;
|
goto color_cmdline_end;
|
||||||
}
|
}
|
||||||
callback_free(&prev_cb);
|
|
||||||
prev_cb = color_cb;
|
|
||||||
if (ccline.cmdbuff[ccline.cmdlen] != NUL) {
|
if (ccline.cmdbuff[ccline.cmdlen] != NUL) {
|
||||||
arg_allocated = true;
|
arg_allocated = true;
|
||||||
arg.vval.v_string = xmemdupz((const char *)ccline.cmdbuff,
|
arg.vval.v_string = xmemdupz((const char *)ccline.cmdbuff,
|
||||||
@@ -2329,8 +2342,11 @@ static bool color_cmdline(void)
|
|||||||
.attr = 0,
|
.attr = 0,
|
||||||
}));
|
}));
|
||||||
}
|
}
|
||||||
prev_cb_errors = 0;
|
prev_prompt_errors = 0;
|
||||||
color_cmdline_end:
|
color_cmdline_end:
|
||||||
|
if (can_free_cb) {
|
||||||
|
callback_free(&color_cb);
|
||||||
|
}
|
||||||
force_abort = saved_force_abort;
|
force_abort = saved_force_abort;
|
||||||
if (arg_allocated) {
|
if (arg_allocated) {
|
||||||
tv_clear(&arg);
|
tv_clear(&arg);
|
||||||
@@ -2338,7 +2354,7 @@ color_cmdline_end:
|
|||||||
tv_clear(&tv);
|
tv_clear(&tv);
|
||||||
return ret;
|
return ret;
|
||||||
color_cmdline_error:
|
color_cmdline_error:
|
||||||
prev_cb_errors++;
|
prev_prompt_errors++;
|
||||||
const bool do_redraw = (did_emsg || got_int);
|
const bool do_redraw = (did_emsg || got_int);
|
||||||
got_int = false;
|
got_int = false;
|
||||||
did_emsg = false;
|
did_emsg = false;
|
||||||
@@ -2350,9 +2366,9 @@ color_cmdline_error:
|
|||||||
}
|
}
|
||||||
kv_size(ccline_colors) = 0;
|
kv_size(ccline_colors) = 0;
|
||||||
if (do_redraw) {
|
if (do_redraw) {
|
||||||
prev_cb_errors += MAX_CB_ERRORS;
|
prev_prompt_errors += MAX_CB_ERRORS;
|
||||||
redrawcmdline();
|
redrawcmdline();
|
||||||
prev_cb_errors -= MAX_CB_ERRORS;
|
prev_prompt_errors -= MAX_CB_ERRORS;
|
||||||
ret = false;
|
ret = false;
|
||||||
}
|
}
|
||||||
goto color_cmdline_end;
|
goto color_cmdline_end;
|
||||||
|
@@ -52,6 +52,8 @@ typedef struct hist_entry {
|
|||||||
list_T *additional_elements; ///< Additional entries from ShaDa file.
|
list_T *additional_elements; ///< Additional entries from ShaDa file.
|
||||||
} histentry_T;
|
} histentry_T;
|
||||||
|
|
||||||
|
extern Callback getln_input_callback;
|
||||||
|
|
||||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
# include "ex_getln.h.generated.h"
|
# include "ex_getln.h.generated.h"
|
||||||
#endif
|
#endif
|
||||||
|
@@ -23,10 +23,41 @@ before_each(function()
|
|||||||
function CustomListCompl(...)
|
function CustomListCompl(...)
|
||||||
return ['FOO']
|
return ['FOO']
|
||||||
endfunction
|
endfunction
|
||||||
|
|
||||||
|
highlight RBP1 guibg=Red
|
||||||
|
highlight RBP2 guibg=Yellow
|
||||||
|
highlight RBP3 guibg=Green
|
||||||
|
highlight RBP4 guibg=Blue
|
||||||
|
let g:NUM_LVLS = 4
|
||||||
|
function Redraw()
|
||||||
|
redraw!
|
||||||
|
return ''
|
||||||
|
endfunction
|
||||||
|
cnoremap <expr> {REDRAW} Redraw()
|
||||||
|
function RainBowParens(cmdline)
|
||||||
|
let ret = []
|
||||||
|
let i = 0
|
||||||
|
let lvl = 0
|
||||||
|
while i < len(a:cmdline)
|
||||||
|
if a:cmdline[i] is# '('
|
||||||
|
call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)])
|
||||||
|
let lvl += 1
|
||||||
|
elseif a:cmdline[i] is# ')'
|
||||||
|
let lvl -= 1
|
||||||
|
call add(ret, [i, i + 1, 'RBP' . ((lvl % g:NUM_LVLS) + 1)])
|
||||||
|
endif
|
||||||
|
let i += 1
|
||||||
|
endwhile
|
||||||
|
return ret
|
||||||
|
endfunction
|
||||||
]])
|
]])
|
||||||
screen:set_default_attr_ids({
|
screen:set_default_attr_ids({
|
||||||
EOB={bold = true, foreground = Screen.colors.Blue1},
|
EOB={bold = true, foreground = Screen.colors.Blue1},
|
||||||
T={foreground=Screen.colors.Red},
|
T={foreground=Screen.colors.Red},
|
||||||
|
RBP1={background=Screen.colors.Red},
|
||||||
|
RBP2={background=Screen.colors.Yellow},
|
||||||
|
RBP3={background=Screen.colors.Green},
|
||||||
|
RBP4={background=Screen.colors.Blue},
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -196,6 +227,19 @@ describe('input()', function()
|
|||||||
eq('Vim(call):E118: Too many arguments for function: input',
|
eq('Vim(call):E118: Too many arguments for function: input',
|
||||||
exc_exec('call input("prompt> ", "default", "file", "extra")'))
|
exc_exec('call input("prompt> ", "default", "file", "extra")'))
|
||||||
end)
|
end)
|
||||||
|
it('supports highlighting', function()
|
||||||
|
feed([[:call input({"highlight": "RainBowParens"})<CR>]])
|
||||||
|
wait()
|
||||||
|
feed('(())')
|
||||||
|
wait()
|
||||||
|
screen:expect([[
|
||||||
|
{EOB:~ }|
|
||||||
|
{EOB:~ }|
|
||||||
|
{EOB:~ }|
|
||||||
|
|
|
||||||
|
{RBP1:(}{RBP2:()}{RBP1:)}^ |
|
||||||
|
]])
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
describe('inputdialog()', function()
|
describe('inputdialog()', function()
|
||||||
it('works with multiline prompts', function()
|
it('works with multiline prompts', function()
|
||||||
@@ -363,4 +407,17 @@ describe('inputdialog()', function()
|
|||||||
eq('Vim(call):E118: Too many arguments for function: inputdialog',
|
eq('Vim(call):E118: Too many arguments for function: inputdialog',
|
||||||
exc_exec('call inputdialog("prompt> ", "default", "file", "extra")'))
|
exc_exec('call inputdialog("prompt> ", "default", "file", "extra")'))
|
||||||
end)
|
end)
|
||||||
|
it('supports highlighting', function()
|
||||||
|
feed([[:call inputdialog({"highlight": "RainBowParens"})<CR>]])
|
||||||
|
wait()
|
||||||
|
feed('(())')
|
||||||
|
wait()
|
||||||
|
screen:expect([[
|
||||||
|
{EOB:~ }|
|
||||||
|
{EOB:~ }|
|
||||||
|
{EOB:~ }|
|
||||||
|
|
|
||||||
|
{RBP1:(}{RBP2:()}{RBP1:)}^ |
|
||||||
|
]])
|
||||||
|
end)
|
||||||
end)
|
end)
|
||||||
|
@@ -15,10 +15,10 @@ before_each(function()
|
|||||||
screen = Screen.new(40, 8)
|
screen = Screen.new(40, 8)
|
||||||
screen:attach()
|
screen:attach()
|
||||||
source([[
|
source([[
|
||||||
highlight RBP1 guifg=Red
|
highlight RBP1 guibg=Red
|
||||||
highlight RBP2 guifg=Yellow
|
highlight RBP2 guibg=Yellow
|
||||||
highlight RBP3 guifg=Green
|
highlight RBP3 guibg=Green
|
||||||
highlight RBP4 guifg=Blue
|
highlight RBP4 guibg=Blue
|
||||||
let g:NUM_LVLS = 4
|
let g:NUM_LVLS = 4
|
||||||
function Redraw()
|
function Redraw()
|
||||||
redraw!
|
redraw!
|
||||||
@@ -103,12 +103,13 @@ before_each(function()
|
|||||||
endfunction
|
endfunction
|
||||||
]])
|
]])
|
||||||
screen:set_default_attr_ids({
|
screen:set_default_attr_ids({
|
||||||
RBP1={foreground = Screen.colors.Red},
|
RBP1={background = Screen.colors.Red},
|
||||||
RBP2={foreground = Screen.colors.Yellow},
|
RBP2={background = Screen.colors.Yellow},
|
||||||
RBP3={foreground = Screen.colors.Green},
|
RBP3={background = Screen.colors.Green},
|
||||||
RBP4={foreground = Screen.colors.Blue},
|
RBP4={background = Screen.colors.Blue},
|
||||||
EOB={bold = true, foreground = Screen.colors.Blue1},
|
EOB={bold = true, foreground = Screen.colors.Blue1},
|
||||||
ERR={foreground = Screen.colors.Grey100, background = Screen.colors.Red},
|
ERR={foreground = Screen.colors.Grey100, background = Screen.colors.Red},
|
||||||
|
SK={foreground = Screen.colors.Blue},
|
||||||
})
|
})
|
||||||
end)
|
end)
|
||||||
|
|
||||||
@@ -237,40 +238,50 @@ describe('Command-line coloring', function()
|
|||||||
meths.set_var('Nvim_color_cmdline', 'SplittedMultibyteStart')
|
meths.set_var('Nvim_color_cmdline', 'SplittedMultibyteStart')
|
||||||
feed(':echo "«')
|
feed(':echo "«')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
|
{EOB:~ }|
|
||||||
|
{EOB:~ }|
|
||||||
|
{EOB:~ }|
|
||||||
{EOB:~ }|
|
{EOB:~ }|
|
||||||
:echo " |
|
:echo " |
|
||||||
{ERR:E5405: Chunk 0 start 7 splits multibyte }|
|
{ERR:E5405: Chunk 0 start 7 splits multibyte }|
|
||||||
{ERR:character} |
|
{ERR:character} |
|
||||||
:echo "« |
|
|
||||||
{ERR:E5405: Chunk 0 start 7 splits multibyte }|
|
|
||||||
{ERR:character} |
|
|
||||||
:echo "«^ |
|
:echo "«^ |
|
||||||
]])
|
]])
|
||||||
feed('»')
|
feed('»')
|
||||||
-- FIXME Does not work well with too much error messages: they overwrite
|
screen:expect([[
|
||||||
-- cmdline.
|
{EOB:~ }|
|
||||||
|
{EOB:~ }|
|
||||||
|
{EOB:~ }|
|
||||||
|
{EOB:~ }|
|
||||||
|
:echo " |
|
||||||
|
{ERR:E5405: Chunk 0 start 7 splits multibyte }|
|
||||||
|
{ERR:character} |
|
||||||
|
:echo "«»^ |
|
||||||
|
]])
|
||||||
end)
|
end)
|
||||||
it('does the right thing when hl end appears to split multibyte char',
|
it('does the right thing when hl end appears to split multibyte char',
|
||||||
function()
|
function()
|
||||||
meths.set_var('Nvim_color_cmdline', 'SplittedMultibyteEnd')
|
meths.set_var('Nvim_color_cmdline', 'SplittedMultibyteEnd')
|
||||||
feed(':echo "«')
|
feed(':echo "«')
|
||||||
screen:expect([[
|
screen:expect([[
|
||||||
|
{EOB:~ }|
|
||||||
|
{EOB:~ }|
|
||||||
|
{EOB:~ }|
|
||||||
{EOB:~ }|
|
{EOB:~ }|
|
||||||
:echo " |
|
:echo " |
|
||||||
{ERR:E5406: Chunk 0 end 7 splits multibyte ch}|
|
{ERR:E5406: Chunk 0 end 7 splits multibyte ch}|
|
||||||
{ERR:aracter} |
|
{ERR:aracter} |
|
||||||
:echo "« |
|
|
||||||
{ERR:E5406: Chunk 0 end 7 splits multibyte ch}|
|
|
||||||
{ERR:aracter} |
|
|
||||||
:echo "«^ |
|
:echo "«^ |
|
||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
it('does the right thing when errorring', function()
|
it('does the right thing when errorring', function()
|
||||||
|
if true then return pending('echoerr does not work well now') end
|
||||||
meths.set_var('Nvim_color_cmdline', 'Echoerring')
|
meths.set_var('Nvim_color_cmdline', 'Echoerring')
|
||||||
feed(':e')
|
feed(':e')
|
||||||
-- FIXME Does not work well with :echoerr: error message overwrites cmdline.
|
-- FIXME Does not work well with :echoerr: error message overwrites cmdline.
|
||||||
end)
|
end)
|
||||||
it('does the right thing when throwing', function()
|
it('does the right thing when throwing', function()
|
||||||
|
if true then return pending('Throwing does not work well now') end
|
||||||
meths.set_var('Nvim_color_cmdline', 'Throwing')
|
meths.set_var('Nvim_color_cmdline', 'Throwing')
|
||||||
feed(':e')
|
feed(':e')
|
||||||
-- FIXME Does not work well with :throw: error message overwrites cmdline.
|
-- FIXME Does not work well with :throw: error message overwrites cmdline.
|
||||||
@@ -280,16 +291,17 @@ describe('Command-line coloring', function()
|
|||||||
feed(':let x = "«"\n')
|
feed(':let x = "«"\n')
|
||||||
eq('«', meths.get_var('x'))
|
eq('«', meths.get_var('x'))
|
||||||
local msg = 'E5405: Chunk 0 start 10 splits multibyte character'
|
local msg = 'E5405: Chunk 0 start 10 splits multibyte character'
|
||||||
eq('\n'..msg..'\n'..msg, funcs.execute('messages'))
|
eq('\n'..msg, funcs.execute('messages'))
|
||||||
end)
|
end)
|
||||||
it('stops executing callback after a number of errors', function()
|
it('stops executing callback after a number of errors', function()
|
||||||
meths.set_var('Nvim_color_cmdline', 'SplittedMultibyteStart')
|
meths.set_var('Nvim_color_cmdline', 'SplittedMultibyteStart')
|
||||||
feed(':let x = "«»«»«»«»«»"\n')
|
feed(':let x = "«»«»«»«»«»"\n')
|
||||||
eq('«»«»«»«»«»', meths.get_var('x'))
|
eq('«»«»«»«»«»', meths.get_var('x'))
|
||||||
local msg = '\nE5405: Chunk 0 start 10 splits multibyte character'
|
local msg = '\nE5405: Chunk 0 start 10 splits multibyte character'
|
||||||
eq(msg:rep(5), funcs.execute('messages'))
|
eq(msg:rep(1), funcs.execute('messages'))
|
||||||
end)
|
end)
|
||||||
it('allows interrupting callback with <C-c>', function()
|
it('allows interrupting callback with <C-c>', function()
|
||||||
|
if true then return pending('<C-c> does not work well enough now') end
|
||||||
meths.set_var('Nvim_color_cmdline', 'Halting')
|
meths.set_var('Nvim_color_cmdline', 'Halting')
|
||||||
feed(':echo 42')
|
feed(':echo 42')
|
||||||
for i = 1, 6 do
|
for i = 1, 6 do
|
||||||
@@ -338,7 +350,7 @@ describe('Command-line coloring', function()
|
|||||||
{EOB:~ }|
|
{EOB:~ }|
|
||||||
{EOB:~ }|
|
{EOB:~ }|
|
||||||
{EOB:~ }|
|
{EOB:~ }|
|
||||||
:echo {RBP1:(}"{RBP4:^M^@^@}"{RBP1:)}^ |
|
:echo {RBP1:(}"{SK:^M^@^@}"{RBP1:)}^ |
|
||||||
]])
|
]])
|
||||||
end)
|
end)
|
||||||
-- TODO Check for all other errors
|
-- TODO Check for all other errors
|
||||||
|
Reference in New Issue
Block a user