aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDongdong Zhou <dzhou121@gmail.com>2017-05-11 07:51:10 +0100
committerBjörn Linse <bjorn.linse@gmail.com>2017-10-26 09:35:13 +0200
commit866dadaf753ba3733feb8c22d7da47af757bd35c (patch)
treec96ea0abcdf2fe4856a0f99ccac89d1fc022065e
parentab85999eb7c53e9d2b5bca5f8896ea11cb1df13e (diff)
downloadrneovim-866dadaf753ba3733feb8c22d7da47af757bd35c.tar.gz
rneovim-866dadaf753ba3733feb8c22d7da47af757bd35c.tar.bz2
rneovim-866dadaf753ba3733feb8c22d7da47af757bd35c.zip
ext_cmdline: added cmdline level
add cchar_to_string
-rw-r--r--src/nvim/api/private/helpers.c16
-rw-r--r--src/nvim/api/ui_events.in.h11
-rw-r--r--src/nvim/ex_getln.c40
-rw-r--r--test/functional/ui/cmdline_spec.lua52
4 files changed, 82 insertions, 37 deletions
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index e736e29e2d..f00fbf69ea 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -667,6 +667,22 @@ tabpage_T *find_tab_by_handle(Tabpage tabpage, Error *err)
return rv;
}
+/// Allocates a String consisting of a single char. Does not support multibyte
+/// characters. The resulting string is also NUL-terminated, to facilitate
+/// interoperating with code using C strings.
+///
+/// @param char the char to convert
+/// @return the resulting String, if the input char was NUL, an
+/// empty String is returned
+String cchar_to_string(char c)
+{
+ char buf[] = { c, NUL };
+ return (String) {
+ .data = xmemdupz(buf, 1),
+ .size = (c != NUL) ? 1 : 0
+ };
+}
+
/// Copies a C string into a String (binary safe string, characters + length).
/// The resulting string is also NUL-terminated, to facilitate interoperating
/// with code using C strings.
diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h
index 093251bb00..17eefbe1d6 100644
--- a/src/nvim/api/ui_events.in.h
+++ b/src/nvim/api/ui_events.in.h
@@ -66,17 +66,14 @@ void popupmenu_hide(void)
void popupmenu_select(Integer selected)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
void tabline_update(Tabpage current, Array tabs)
- FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
-
-void cmdline_enter(void)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
-void cmdline_show(Array content, Integer pos, String firstc, String prompt)
+void cmdline_show(Array content, Integer pos, String firstc, String prompt, Integer level)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
-void cmdline_pos(Integer pos)
+void cmdline_pos(Integer pos, Integer level)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
-void cmdline_char(String c, Integer shift)
+void cmdline_char(String c, Integer shift, Integer level)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
-void cmdline_hide(void)
+void cmdline_hide(Integer level)
FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY;
#endif // NVIM_API_UI_EVENTS_IN_H
diff --git a/src/nvim/ex_getln.c b/src/nvim/ex_getln.c
index 0223d9e936..548459a8ce 100644
--- a/src/nvim/ex_getln.c
+++ b/src/nvim/ex_getln.c
@@ -91,6 +91,7 @@ struct cmdline_info {
int input_fn; // when TRUE Invoked for input() function
unsigned prompt_id; ///< Prompt number, used to disable coloring on errors.
Callback highlight_callback; ///< Callback used for coloring user input.
+ int level; // current cmdline level
};
/// Last value of prompt_id, incremented when doing new prompt
static unsigned last_prompt_id = 0;
@@ -238,7 +239,9 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
cmd_hkmap = 0;
}
+ // TODO(bfredl): can these be combined?
ccline.prompt_id = last_prompt_id++;
+ ccline.level++;
ccline.overstrike = false; // always start in insert mode
clearpos(&s->match_end);
s->save_cursor = curwin->w_cursor; // may be restored later
@@ -414,6 +417,11 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
// Make ccline empty, getcmdline() may try to use it.
ccline.cmdbuff = NULL;
+
+ if (ui_is_external(kUICmdline)) {
+ ui_call_cmdline_hide(ccline.level);
+ }
+ ccline.level--;
return p;
}
}
@@ -1830,14 +1838,7 @@ getcmdline (
int indent // indent for inside conditionals
)
{
- if (ui_is_external(kUICmdline)) {
- ui_call_cmdline_enter();
- }
- char_u *p = command_line_enter(firstc, count, indent);
- if (ui_is_external(kUICmdline)) {
- ui_call_cmdline_hide();
- }
- return p;
+ return command_line_enter(firstc, count, indent);
}
/// Get a command line with a prompt
@@ -2720,17 +2721,12 @@ draw_cmdline_no_arabicshape:
void ui_ext_cmdline_show(void)
{
- Array content = ARRAY_DICT_INIT;
- Array text = ARRAY_DICT_INIT;
- ADD(text, STRING_OBJ(cstr_to_string("Normal")));
- ADD(text, STRING_OBJ(cstr_to_string((char *)(ccline.cmdbuff))));
- ADD(content, ARRAY_OBJ(text));
- char *firstc = (char []) { (char)ccline.cmdfirstc };
- String str = (String) {
- .data = xmemdupz(firstc, 1),
- .size = 1
- };
- ui_call_cmdline_show(content, ccline.cmdpos, str, cstr_to_string((char *)(ccline.cmdprompt)));
+ Array content = ARRAY_DICT_INIT;
+ Array text = ARRAY_DICT_INIT;
+ ADD(text, STRING_OBJ(cstr_to_string("Normal")));
+ ADD(text, STRING_OBJ(cstr_to_string((char *)(ccline.cmdbuff))));
+ ADD(content, ARRAY_OBJ(text));
+ ui_call_cmdline_show(content, ccline.cmdpos, cchar_to_string((char)ccline.cmdfirstc), cstr_to_string((char *)(ccline.cmdprompt)), ccline.level);
}
/*
@@ -2750,7 +2746,7 @@ void putcmdline(int c, int shift)
draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
msg_no_more = FALSE;
} else {
- ui_call_cmdline_char(cstr_to_string((char *)(&c)), shift);
+ ui_call_cmdline_char(cchar_to_string((char)(c)), shift, ccline.level);
}
cursorcmd();
ui_cursor_shape();
@@ -3178,7 +3174,7 @@ static void cursorcmd(void)
return;
if (ui_is_external(kUICmdline)) {
- ui_call_cmdline_pos(ccline.cmdpos);
+ ui_call_cmdline_pos(ccline.cmdpos, ccline.level);
return;
}
@@ -3200,7 +3196,7 @@ static void cursorcmd(void)
void gotocmdline(int clr)
{
if (ui_is_external(kUICmdline)) {
- return;
+ return;
}
msg_start();
if (cmdmsg_rl)
diff --git a/test/functional/ui/cmdline_spec.lua b/test/functional/ui/cmdline_spec.lua
index 479f5c3b7d..479d40e959 100644
--- a/test/functional/ui/cmdline_spec.lua
+++ b/test/functional/ui/cmdline_spec.lua
@@ -7,19 +7,19 @@ if helpers.pending_win32(pending) then return end
describe('External command line completion', function()
local screen
local shown = false
- local firstc, prompt, content, pos, char, shift
+ local firstc, prompt, content, pos, char, shift, level, current_hide_level
before_each(function()
clear()
screen = Screen.new(25, 5)
screen:attach({rgb=true, ext_cmdline=true})
screen:set_on_event_handler(function(name, data)
- if name == "cmdline_enter" then
- shown = true
- elseif name == "cmdline_hide" then
+ if name == "cmdline_hide" then
shown = false
+ current_hide_level = data[1]
elseif name == "cmdline_show" then
- content, pos, firstc, prompt = unpack(data)
+ shown = true
+ content, pos, firstc, prompt, level = unpack(data)
elseif name == "cmdline_char" then
char, shift = unpack(data)
elseif name == "cmdline_pos" then
@@ -107,9 +107,9 @@ describe('External command line completion', function()
eq("input", prompt)
eq({{'Normal', 'default'}}, content)
end)
-
feed('<cr>')
- feed(':<C-R>=1+2<cr>')
+
+ feed(':')
screen:expect([[
^ |
~ |
@@ -117,9 +117,45 @@ describe('External command line completion', function()
~ |
|
]], nil, nil, function()
- eq({{'Normal', '3'}}, content)
+ eq(1, level)
+ end)
+
+ feed('<C-R>=1+2')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{'Normal', '1+2'}}, content)
eq("\"", char)
eq(1, shift)
+ eq(2, level)
+ end)
+
+ feed('<cr>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq({{'Normal', '3'}}, content)
+ eq(2, current_hide_level)
+ eq(1, level)
+ end)
+
+ feed('<esc>')
+ screen:expect([[
+ ^ |
+ ~ |
+ ~ |
+ ~ |
+ |
+ ]], nil, nil, function()
+ eq(1, current_hide_level)
end)
end)