mirror of
				https://github.com/neovim/neovim.git
				synced 2025-11-04 01:34:25 +00:00 
			
		
		
		
	api: nvim_ui_attach(): Flatten ext_* options.
This commit is contained in:
		@@ -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
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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)
 | 
				
			||||||
 
 | 
				
			|||||||
@@ -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},
 | 
				
			||||||
 
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user