api: add API for themes

co-author: hlpr98 <hlpr98@gmail.com> (dict2hlattrs function)

orange is sus??

NOVEMBER DAWN

erase the lie that is redraw_later()
This commit is contained in:
Björn Linse
2020-09-08 09:47:10 +02:00
parent 037ffd54dc
commit c146eddc8b
43 changed files with 690 additions and 203 deletions

View File

@@ -974,9 +974,9 @@ void nvim_buf_delete(Buffer buffer, Dictionary opts, Error *err)
String k = opts.items[i].key;
Object v = opts.items[i].value;
if (strequal("force", k.data)) {
force = api_coerce_to_bool(v, "force", false, err);
force = api_object_to_bool(v, "force", false, err);
} else if (strequal("unload", k.data)) {
unload = api_coerce_to_bool(v, "unload", false, err);
unload = api_object_to_bool(v, "unload", false, err);
} else {
api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
return;
@@ -1441,7 +1441,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id,
goto error;
}
} else if (strequal("ephemeral", k.data)) {
ephemeral = api_coerce_to_bool(*v, "ephemeral", false, err);
ephemeral = api_object_to_bool(*v, "ephemeral", false, err);
if (ERROR_SET(err)) {
goto error;
}

View File

@@ -1625,11 +1625,8 @@ free_exit:
/// @param what The name of the object, used for error message
/// @param nil_value What to return if the type is nil.
/// @param err Set if there was an error in converting to a bool
bool api_coerce_to_bool(
Object obj,
const char *what,
bool nil_value,
Error *err)
bool api_object_to_bool(Object obj, const char *what,
bool nil_value, Error *err)
{
if (obj.type == kObjectTypeBoolean) {
return obj.data.boolean;
@@ -1654,3 +1651,30 @@ const char *describe_ns(NS ns_id)
})
return "(UNKNOWN PLUGIN)";
}
DecorationProvider *get_provider(NS ns_id, bool force)
{
ssize_t i;
for (i = 0; i < (ssize_t)kv_size(decoration_providers); i++) {
DecorationProvider *item = &kv_A(decoration_providers, i);
if (item->ns_id == ns_id) {
return item;
} else if (item->ns_id > ns_id) {
break;
}
}
if (!force) {
return NULL;
}
for (ssize_t j = (ssize_t)kv_size(decoration_providers)-1; j >= i; j++) {
// allocates if needed:
(void)kv_a(decoration_providers, (size_t)j+1);
kv_A(decoration_providers, (size_t)j+1) = kv_A(decoration_providers, j);
}
DecorationProvider *item = &kv_a(decoration_providers, (size_t)i);
*item = DECORATION_PROVIDER_INIT(ns_id);
return item;
}

View File

@@ -199,6 +199,69 @@ Integer nvim_get_hl_id_by_name(String name)
return syn_check_group((const char_u *)name.data, (int)name.size);
}
Dictionary nvim__get_hl_defs(Integer ns_id, Error *err)
{
if (ns_id == 0) {
return get_global_hl_defs();
}
abort();
}
/// Set a highlight group.
///
/// @param ns_id number of namespace for this highlight
/// @param name highlight group name, like ErrorMsg
/// @param val highlight definiton map, like |nvim_get_hl_by_name|.
/// @param[out] err Error details, if any
///
/// TODO: ns_id = 0, should modify :highlight namespace
/// TODO val should take update vs reset flag
void nvim_set_hl(Integer ns_id, String name, Dictionary val, Error *err)
FUNC_API_SINCE(7)
{
int hl_id = syn_check_group( (char_u *)(name.data), (int)name.size);
int link_id = -1;
HlAttrs attrs = dict2hlattrs(val, true, &link_id, err);
if (!ERROR_SET(err)) {
ns_hl_def((NS)ns_id, hl_id, attrs, link_id);
}
}
/// Set active namespace for highlights.
///
/// NB: this function can be called from async contexts, but the
/// semantics are not yet well-defined. To start with
/// |nvim_set_decoration_provider| on_win and on_line callbacks
/// are explicitly allowed to change the namespace during a redraw cycle.
///
/// @param ns_id the namespace to activate
/// @param[out] err Error details, if any
void nvim_set_hl_ns(Integer ns_id, Error *err)
FUNC_API_SINCE(7)
FUNC_API_FAST
{
if (ns_id >= 0) {
ns_hl_active = (NS)ns_id;
}
// TODO(bfredl): this is a little bit hackish. Eventually we want a standard
// event path for redraws caused by "fast" events. This could tie in with
// better throttling of async events causing redraws, such as non-batched
// nvim_buf_set_extmark calls from async contexts.
if (!updating_screen && !ns_hl_changed) {
multiqueue_put(main_loop.events, on_redraw_event, 0);
}
ns_hl_changed = true;
}
static void on_redraw_event(void **argv)
FUNC_API_NOEXPORT
{
redraw_all_later(NOT_VALID);
}
/// Sends input-keys to Nvim, subject to various quirks controlled by `mode`
/// flags. This is a blocking call, unlike |nvim_input()|.
///
@@ -1477,7 +1540,7 @@ void nvim_unsubscribe(uint64_t channel_id, String event)
Integer nvim_get_color_by_name(String name)
FUNC_API_SINCE(1)
{
return name_to_color((char_u *)name.data);
return name_to_color(name.data);
}
/// Returns a map of color names and RGB values.
@@ -2610,33 +2673,6 @@ void nvim__screenshot(String path)
ui_call_screenshot(path);
}
static DecorationProvider *get_provider(NS ns_id, bool force)
{
ssize_t i;
for (i = 0; i < (ssize_t)kv_size(decoration_providers); i++) {
DecorationProvider *item = &kv_A(decoration_providers, i);
if (item->ns_id == ns_id) {
return item;
} else if (item->ns_id > ns_id) {
break;
}
}
if (!force) {
return NULL;
}
for (ssize_t j = (ssize_t)kv_size(decoration_providers)-1; j >= i; j++) {
// allocates if needed:
(void)kv_a(decoration_providers, (size_t)j+1);
kv_A(decoration_providers, (size_t)j+1) = kv_A(decoration_providers, j);
}
DecorationProvider *item = &kv_a(decoration_providers, (size_t)i);
*item = DECORATION_PROVIDER_INIT(ns_id);
return item;
}
static void clear_provider(DecorationProvider *p)
{
NLUA_CLEAR_REF(p->redraw_start);
@@ -2695,7 +2731,7 @@ void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts,
clear_provider(p);
// regardless of what happens, it seems good idea to redraw
redraw_later(NOT_VALID); // TODO(bfredl): too soon?
redraw_all_later(NOT_VALID); // TODO(bfredl): too soon?
struct {
const char *name;
@@ -2706,6 +2742,7 @@ void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts,
{ "on_win", &p->redraw_win },
{ "on_line", &p->redraw_line },
{ "on_end", &p->redraw_end },
{ "_on_hl_def", &p->hl_def },
{ NULL, NULL },
};

View File

@@ -142,7 +142,7 @@ void nvim_win_set_cursor(Window window, ArrayOf(Integer, 2) pos, Error *err)
// make sure cursor is in visible range even if win != curwin
update_topline_win(win);
redraw_win_later(win, VALID);
redraw_later(win, VALID);
}
/// Gets the window height
@@ -471,7 +471,7 @@ void nvim_win_set_config(Window window, Dictionary config, Error *err)
if (!win_new_float(win, fconfig, err)) {
return;
}
redraw_later(NOT_VALID);
redraw_later(win, NOT_VALID);
} else {
win_config_float(win, fconfig);
win->w_pos_changed = true;