aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/api/vim.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/api/vim.c')
-rw-r--r--src/nvim/api/vim.c163
1 files changed, 136 insertions, 27 deletions
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index d6f95c7a5f..876b052a8e 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -203,10 +203,10 @@ Integer nvim_get_hl_id_by_name(String name)
/// flags. This is a blocking call, unlike |nvim_input()|.
///
/// On execution error: does not fail, but updates v:errmsg.
-//
-// If you need to input sequences like <C-o> use nvim_replace_termcodes
-// to replace the termcodes and then pass the resulting string to
-// nvim_feedkeys. You'll also want to enable escape_csi.
+///
+/// If you need to input sequences like <C-o> use |nvim_replace_termcodes| to
+/// replace the termcodes and then pass the resulting string to nvim_feedkeys.
+/// You'll also want to enable escape_csi.
///
/// Example:
/// <pre>
@@ -475,7 +475,7 @@ Object nvim_execute_lua(String code, Array args, Error *err)
FUNC_API_DEPRECATED_SINCE(7)
FUNC_API_REMOTE_ONLY
{
- return executor_exec_lua_api(code, args, err);
+ return nlua_exec(code, args, err);
}
/// Execute Lua code. Parameters (if any) are available as `...` inside the
@@ -494,7 +494,7 @@ Object nvim_exec_lua(String code, Array args, Error *err)
FUNC_API_SINCE(7)
FUNC_API_REMOTE_ONLY
{
- return executor_exec_lua_api(code, args, err);
+ return nlua_exec(code, args, err);
}
/// Calls a VimL function.
@@ -2477,7 +2477,7 @@ Array nvim_get_proc_children(Integer pid, Error *err)
Array a = ARRAY_DICT_INIT;
ADD(a, INTEGER_OBJ(pid));
String s = cstr_to_string("return vim._os_proc_children(select(1, ...))");
- Object o = nvim_exec_lua(s, a, err);
+ Object o = nlua_exec(s, a, err);
api_free_string(s);
api_free_array(a);
if (o.type == kObjectTypeArray) {
@@ -2523,7 +2523,7 @@ Object nvim_get_proc(Integer pid, Error *err)
Array a = ARRAY_DICT_INIT;
ADD(a, INTEGER_OBJ(pid));
String s = cstr_to_string("return vim._os_proc_info(select(1, ...))");
- Object o = nvim_exec_lua(s, a, err);
+ Object o = nlua_exec(s, a, err);
api_free_string(s);
api_free_array(a);
if (o.type == kObjectTypeArray && o.data.array.size == 0) {
@@ -2604,26 +2604,135 @@ Array nvim__inspect_cell(Integer grid, Integer row, Integer col, Error *err)
return ret;
}
-/// Set attrs in nvim__buf_set_lua_hl callbacks
-///
-/// TODO(bfredl): This is rather pedestrian. The final
-/// interface should probably be derived from a reformed
-/// bufhl/virttext interface with full support for multi-line
-/// ranges etc
-void nvim__put_attr(Integer id, Integer start_row, Integer start_col,
- Integer end_row, Integer end_col)
- FUNC_API_LUA_ONLY
+void nvim__screenshot(String path)
+ FUNC_API_FAST
{
- if (!lua_attr_active) {
- return;
- }
- if (id == 0 || syn_get_final_id((int)id) == 0) {
- return;
+ 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;
+ }
}
- int attr = syn_id2attr((int)id);
- if (attr == 0) {
- return;
+
+ 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);
+ NLUA_CLEAR_REF(p->redraw_buf);
+ NLUA_CLEAR_REF(p->redraw_win);
+ NLUA_CLEAR_REF(p->redraw_line);
+ NLUA_CLEAR_REF(p->redraw_end);
+ p->active = false;
+}
+
+/// Set or change decoration provider for a namespace
+///
+/// This is a very general purpose interface for having lua callbacks
+/// being triggered during the redraw code.
+///
+/// The expected usage is to set extmarks for the currently
+/// redrawn buffer. |nvim_buf_set_extmark| can be called to add marks
+/// on a per-window or per-lines basis. Use the `ephemeral` key to only
+/// use the mark for the current screen redraw (the callback will be called
+/// again for the next redraw ).
+///
+/// Note: this function should not be called often. Rather, the callbacks
+/// themselves can be used to throttle unneeded callbacks. the `on_start`
+/// callback can return `false` to disable the provider until the next redraw.
+/// Similarily, return `false` in `on_win` will skip the `on_lines` calls
+/// for that window (but any extmarks set in `on_win` will still be used).
+/// A plugin managing multiple sources of decorations should ideally only set
+/// one provider, and merge the sources internally. You can use multiple `ns_id`
+/// for the extmarks set/modified inside the callback anyway.
+///
+/// Note: doing anything other than setting extmarks is considered experimental.
+/// Doing things like changing options are not expliticly forbidden, but is
+/// likely to have unexpected consequences (such as 100% CPU consumption).
+/// doing `vim.rpcnotify` should be OK, but `vim.rpcrequest` is quite dubious
+/// for the moment.
+///
+/// @param ns_id Namespace id from |nvim_create_namespace()|
+/// @param opts Callbacks invoked during redraw:
+/// - on_start: called first on each screen redraw
+/// ["start", tick]
+/// - on_buf: called for each buffer being redrawn (before window
+/// callbacks)
+/// ["buf", bufnr, tick]
+/// - on_win: called when starting to redraw a specific window.
+/// ["win", winid, bufnr, topline, botline_guess]
+/// - on_line: called for each buffer line being redrawn. (The
+/// interation with fold lines is subject to change)
+/// ["win", winid, bufnr, row]
+/// - on_end: called at the end of a redraw cycle
+/// ["end", tick]
+void nvim_set_decoration_provider(Integer ns_id, DictionaryOf(LuaRef) opts,
+ Error *err)
+ FUNC_API_SINCE(7) FUNC_API_LUA_ONLY
+{
+ DecorationProvider *p = get_provider((NS)ns_id, true);
+ clear_provider(p);
+
+ // regardless of what happens, it seems good idea to redraw
+ redraw_later(NOT_VALID); // TODO(bfredl): too soon?
+
+ struct {
+ const char *name;
+ LuaRef *dest;
+ } cbs[] = {
+ { "on_start", &p->redraw_start },
+ { "on_buf", &p->redraw_buf },
+ { "on_win", &p->redraw_win },
+ { "on_line", &p->redraw_line },
+ { "on_end", &p->redraw_end },
+ { NULL, NULL },
+ };
+
+ for (size_t i = 0; i < opts.size; i++) {
+ String k = opts.items[i].key;
+ Object *v = &opts.items[i].value;
+ size_t j;
+ for (j = 0; cbs[j].name; j++) {
+ if (strequal(cbs[j].name, k.data)) {
+ if (v->type != kObjectTypeLuaRef) {
+ api_set_error(err, kErrorTypeValidation,
+ "%s is not a function", cbs[j].name);
+ goto error;
+ }
+ *(cbs[j].dest) = v->data.luaref;
+ v->data.luaref = LUA_NOREF;
+ break;
+ }
+ }
+ if (!cbs[j].name) {
+ api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
+ goto error;
+ }
}
- decorations_add_luahl_attr(attr, (int)start_row, (colnr_T)start_col,
- (int)end_row, (colnr_T)end_col);
+
+ p->active = true;
+ return;
+error:
+ clear_provider(p);
}