api: nvim_ui_attach(): Flatten ext_* options.

This commit is contained in:
Justin M. Keyes
2017-04-25 10:14:29 +02:00
parent 00843902d3
commit c8e1af93de
5 changed files with 34 additions and 61 deletions

View File

@@ -264,13 +264,11 @@ a dictionary with these (optional) keys:
colors. colors.
Set to false to use terminal color codes (at Set to false to use terminal color codes (at
most 256 different colors). most 256 different colors).
`ui_ext` String array of "externalized" widgets. `ext_popupmenu` Externalize the popupmenu. |ui-ext-popupmenu|
Widgets in this list will not be drawn by `ext_tabline` Externalize the tabline. |ui-ext-tabline|
Externalized widgets will not be drawn by
Nvim; only high-level data will be published Nvim; only high-level data will be published
in new UI event kinds. Valid names: in new UI event kinds.
popupmenu |ui-ext-popupmenu|
tabline |ui-ext-tabline|
Defaults to empty.
Nvim will then send msgpack-rpc notifications, with the method name "redraw" Nvim will then send msgpack-rpc notifications, with the method name "redraw"
and a single argument, an array of screen updates (described below). These and a single argument, an array of screen updates (described below). These

View File

@@ -173,13 +173,33 @@ void nvim_ui_set_option(uint64_t channel_id, String name,
static void ui_set_option(UI *ui, String name, Object value, Error *error) static void ui_set_option(UI *ui, String name, Object value, Error *error)
{ {
#define UI_EXT_OPTION(o, e) \
do { \
if (strequal(name.data, #o)) { \
if (value.type != kObjectTypeBoolean) { \
api_set_error(error, kErrorTypeValidation, #o " must be a Boolean"); \
return; \
} \
ui->ui_ext[(e)] = value.data.boolean; \
return; \
} \
} while (0)
if (strequal(name.data, "rgb")) { if (strequal(name.data, "rgb")) {
if (value.type != kObjectTypeBoolean) { if (value.type != kObjectTypeBoolean) {
api_set_error(error, kErrorTypeValidation, "rgb must be a Boolean"); api_set_error(error, kErrorTypeValidation, "rgb must be a Boolean");
return; return;
} }
ui->rgb = value.data.boolean; ui->rgb = value.data.boolean;
} else if (strequal(name.data, "popupmenu_external")) { return;
}
UI_EXT_OPTION(ext_cmdline, kUICmdline);
UI_EXT_OPTION(ext_popupmenu, kUIPopupmenu);
UI_EXT_OPTION(ext_tabline, kUITabline);
UI_EXT_OPTION(ext_wildmenu, kUIWildmenu);
if (strequal(name.data, "popupmenu_external")) {
// LEGACY: Deprecated option, use `ui_ext` instead. // LEGACY: Deprecated option, use `ui_ext` instead.
if (value.type != kObjectTypeBoolean) { if (value.type != kObjectTypeBoolean) {
api_set_error(error, kErrorTypeValidation, api_set_error(error, kErrorTypeValidation,
@@ -187,38 +207,11 @@ static void ui_set_option(UI *ui, String name, Object value, Error *error)
return; return;
} }
ui->ui_ext[kUIPopupmenu] = value.data.boolean; ui->ui_ext[kUIPopupmenu] = value.data.boolean;
} else if (strequal(name.data, "ui_ext")) { return;
if (value.type != kObjectTypeArray) {
api_set_error(error, kErrorTypeValidation,
"ui_ext must be an Array");
return;
}
for (size_t i = 0; i < value.data.array.size; i++) {
Object item = value.data.array.items[i];
if (item.type != kObjectTypeString) {
api_set_error(error, kErrorTypeValidation,
"ui_ext: item must be a String");
return;
}
char *name = item.data.string.data;
if (strequal(name, "cmdline")) {
ui->ui_ext[kUICmdline] = true;
} else if (strequal(name, "popupmenu")) {
ui->ui_ext[kUIPopupmenu] = true;
} else if (strequal(name, "tabline")) {
ui->ui_ext[kUITabline] = true;
} else if (strequal(name, "wildmenu")) {
ui->ui_ext[kUIWildmenu] = true;
} else {
api_set_error(error, kErrorTypeValidation,
"ui_ext: unknown widget: %s", name);
return;
}
}
} else {
api_set_error(error, kErrorTypeValidation, "No such ui option");
} }
api_set_error(error, kErrorTypeValidation, "No such ui option");
#undef UI_EXT_OPTION
} }
static void push_call(UI *ui, char *name, Array args) static void push_call(UI *ui, char *name, Array args)

View File

@@ -577,28 +577,10 @@ describe('nvim_ui_attach()', function()
eq(999, eval('&lines')) eq(999, eval('&lines'))
eq(999, eval('&columns')) eq(999, eval('&columns'))
end) end)
it('"ui_ext" widgets', function() it('invalid option returns error', function()
local screen = Screen.new() local screen = Screen.new()
screen:attach({ui_ext={ local status, rv = pcall(function() screen:attach({foo={'foo'}}) end)
'cmdline',
'popupmenu',
'tabline',
'wildmenu',
}})
end)
it('invalid "ui_ext" returns error', function()
local screen = Screen.new()
local status, rv = pcall(function() screen:attach({ui_ext={'foo'}}) end)
eq(false, status) eq(false, status)
eq('ui_ext: unknown widget: foo', rv:match("ui_ext:.*")) eq('No such ui option', rv:match("No such .*"))
status, rv = pcall(function() screen:attach({ui_ext={'cmdline','foo'}}) end)
eq(false, status)
eq('ui_ext: unknown widget: foo', rv:match("ui_ext:.*"))
status, rv = pcall(function() screen:attach({ui_ext={'cmdline',1}}) end)
eq(false, status)
eq('ui_ext: item must be a String', rv:match("ui_ext:.*"))
end) end)
end) end)

View File

@@ -9,7 +9,7 @@ describe('ui/tabline', function()
before_each(function() before_each(function()
clear() clear()
screen = Screen.new(25, 5) screen = Screen.new(25, 5)
screen:attach({rgb=true, ui_ext={'tabline'}}) screen:attach({rgb=true, ext_tabline=true})
screen:set_on_event_handler(function(name, data) screen:set_on_event_handler(function(name, data)
if name == "tabline_update" then if name == "tabline_update" then
curtab, tabs = unpack(data) curtab, tabs = unpack(data)

View File

@@ -874,7 +874,7 @@ describe('ui/externalized/popupmenu', function()
before_each(function() before_each(function()
clear() clear()
screen = Screen.new(60, 8) screen = Screen.new(60, 8)
screen:attach({rgb=true, ui_ext={'popupmenu'}}) screen:attach({rgb=true, ext_popupmenu=true})
screen:set_default_attr_ids({ screen:set_default_attr_ids({
[1] = {bold=true, foreground=Screen.colors.Blue}, [1] = {bold=true, foreground=Screen.colors.Blue},
[2] = {bold = true}, [2] = {bold = true},