ext_cmdline: allow external ui to draw cmdline

This commit is contained in:
Dongdong Zhou 2017-02-23 05:33:14 +00:00 committed by Björn Linse
parent f0c2f82e90
commit 439c39a2cf
3 changed files with 106 additions and 9 deletions

View File

@ -260,12 +260,23 @@ a dictionary with these (optional) keys:
colors.
Set to false to use terminal color codes (at
most 256 different colors).
`ext_popupmenu` Externalize the popupmenu. |ui-ext-popupmenu|
`ext_tabline` Externalize the tabline. |ui-ext-tabline|
Externalized widgets will not be drawn by
Nvim; only high-level data will be published
in new UI event kinds.
`popupmenu_external`: Instead of drawing the completion popupmenu on
the grid, Nvim will send higher-level events to
the ui and let it draw the popupmenu.
Defaults to false.
cmdline_external: Instead of drawing the cmdline on
the grid, Nvim will send higher-level events to
the ui and let it draw the cmdline.
Defaults to false.
Nvim will then send msgpack-rpc notifications, with the method name "redraw"
and a single argument, an array of screen updates (described below). These
should be processed in order. Preferably the user should only be able to see
@ -441,5 +452,27 @@ states might be represented as separate modes.
curtab: Current Tabpage
tabs: List of Dicts [{ "tab": Tabpage, "name": String }, ...]
["cmdline_enter"]
Enter the cmdline.
["cmdline_leave"]
Leave the cmdline.
["cmdline_firstc", firstc]
The first character of the command, which could be : / ? etc. With
the firstc, you know wheither it's a command or a search.
["cmdline", content, pos]
When cmdline_external is set to true, nvim will not draw the cmdline
on the grad, instead nvim will send ui events of the cmdline content
and cursor position to the remote ui. The content is the full content
that should be displayed in the cmdline, and the pos is the position
of the cursor that in the cmdline. This event will be triggered when
you type in the cmdline.
["cmdline_pos", pos]
When you move your cursor, nvim will send out this event which tells
you the current position of the cursor in the cmdline.
==============================================================================
vim:tw=78:ts=8:noet:ft=help:norl:

View File

@ -185,6 +185,8 @@ static int cmd_showtail; /* Only show path tail in lists ? */
static int new_cmdpos; /* position set by set_cmdline_pos() */
static bool cmdline_external = false;
/*
* Type used by call_user_expand_func
*/
@ -281,7 +283,9 @@ static uint8_t *command_line_enter(int firstc, long count, int indent)
if (!cmd_silent) {
s->i = msg_scrolled;
msg_scrolled = 0; // avoid wait_return message
gotocmdline(true);
if (!cmdline_external) {
gotocmdline(true);
}
msg_scrolled += s->i;
redrawcmdprompt(); // draw prompt or indent
set_cmdspos();
@ -1828,7 +1832,16 @@ getcmdline (
int indent // indent for inside conditionals
)
{
return command_line_enter(firstc, count, indent);
if (cmdline_external) {
Array args = ARRAY_DICT_INIT;
ui_event("cmdline_enter", args);
}
char_u *p = command_line_enter(firstc, count, indent);
if (cmdline_external) {
Array args = ARRAY_DICT_INIT;
ui_event("cmdline_leave", args);
}
return p;
}
/// Get a command line with a prompt
@ -2589,6 +2602,14 @@ static void draw_cmdline(int start, int len)
return;
}
if (cmdline_external) {
Array args = ARRAY_DICT_INIT;
ADD(args, STRING_OBJ(cstr_to_string((char *)(ccline.cmdbuff))));
ADD(args, INTEGER_OBJ(ccline.cmdpos));
ui_event("cmdline", args);
return;
}
if (cmdline_star > 0) {
for (int i = 0; i < len; i++) {
msg_putchar('*');
@ -2713,11 +2734,28 @@ void putcmdline(int c, int shift)
{
if (cmd_silent)
return;
msg_no_more = TRUE;
msg_putchar(c);
if (shift)
draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
msg_no_more = FALSE;
if (!cmdline_external) {
msg_no_more = TRUE;
msg_putchar(c);
if (shift)
draw_cmdline(ccline.cmdpos, ccline.cmdlen - ccline.cmdpos);
msg_no_more = FALSE;
} else {
char_u *p;
if (ccline.cmdpos == ccline.cmdlen || shift) {
p = vim_strnsave(ccline.cmdbuff, ccline.cmdlen + 1);
} else {
p = vim_strsave(ccline.cmdbuff);
}
p[ccline.cmdpos] = c;
if (shift)
STRCPY(p + ccline.cmdpos + 1, ccline.cmdbuff + ccline.cmdpos);
Array args = ARRAY_DICT_INIT;
ADD(args, STRING_OBJ(cstr_to_string((char *)(p))));
ADD(args, INTEGER_OBJ(ccline.cmdpos));
ui_event("cmdline", args);
xfree(p);
}
cursorcmd();
ui_cursor_shape();
}
@ -3066,8 +3104,15 @@ static void redrawcmdprompt(void)
if (cmd_silent)
return;
if (ccline.cmdfirstc != NUL)
msg_putchar(ccline.cmdfirstc);
if (ccline.cmdfirstc != NUL) {
if (cmdline_external) {
Array args = ARRAY_DICT_INIT;
ADD(args, STRING_OBJ(cstr_to_string((char *)(&ccline.cmdfirstc))));
ui_event("cmdline_firstc", args);
} else {
msg_putchar(ccline.cmdfirstc);
}
}
if (ccline.cmdprompt != NULL) {
msg_puts_attr((const char *)ccline.cmdprompt, ccline.cmdattr);
ccline.cmdindent = msg_col + (msg_row - cmdline_row) * Columns;
@ -3087,6 +3132,11 @@ void redrawcmd(void)
if (cmd_silent)
return;
if (cmdline_external) {
draw_cmdline(0, ccline.cmdlen);
return;
}
/* when 'incsearch' is set there may be no command line while redrawing */
if (ccline.cmdbuff == NULL) {
ui_cursor_goto(cmdline_row, 0);
@ -3130,6 +3180,13 @@ static void cursorcmd(void)
if (cmd_silent)
return;
if (cmdline_external) {
Array args = ARRAY_DICT_INIT;
ADD(args, INTEGER_OBJ(ccline.cmdpos));
ui_event("cmdline_pos", args);
return;
}
if (cmdmsg_rl) {
msg_row = cmdline_row + (ccline.cmdspos / (int)(Columns - 1));
msg_col = (int)Columns - (ccline.cmdspos % (int)(Columns - 1)) - 1;
@ -5974,3 +6031,8 @@ static void set_search_match(pos_T *t)
coladvance((colnr_T)MAXCOL);
}
}
void cmdline_set_external(bool external)
{
cmdline_external = external;
}

View File

@ -30,6 +30,7 @@
#include "nvim/os/input.h"
#include "nvim/os/signal.h"
#include "nvim/popupmnu.h"
#include "nvim/ex_getln.h"
#include "nvim/screen.h"
#include "nvim/syntax.h"
#include "nvim/window.h"
@ -280,6 +281,7 @@ void ui_refresh(void)
int save_p_lz = p_lz;
p_lz = false; // convince redrawing() to return true ...
cmdline_set_external(cmdline_external);
screen_resize(width, height);
p_lz = save_p_lz;