diff options
Diffstat (limited to 'src/nvim/api')
-rw-r--r-- | src/nvim/api/buffer.c | 52 | ||||
-rw-r--r-- | src/nvim/api/private/defs.h | 2 | ||||
-rw-r--r-- | src/nvim/api/private/helpers.c | 5 | ||||
-rw-r--r-- | src/nvim/api/private/helpers.h | 4 |
4 files changed, 50 insertions, 13 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index 06d7c1810c..81b3851c53 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -7,6 +7,7 @@ #include <stdint.h> #include <stdlib.h> #include <limits.h> +#include <lauxlib.h> #include "nvim/api/buffer.h" #include "nvim/api/private/helpers.h" @@ -98,37 +99,62 @@ String buffer_get_line(Buffer buffer, Integer index, Error *err) return rv; } -/// Activates buffer-update events on the channel. +/// Activates buffer-update events on a channel, or as lua callbacks. /// /// @param channel_id /// @param buffer Buffer handle, or 0 for current buffer /// @param send_buffer Set to true if the initial notification should contain /// the whole buffer. If so, the first notification will be a /// `nvim_buf_lines_event`. Otherwise, the first notification will be -/// a `nvim_buf_changedtick_event` -/// @param opts Optional parameters. Reserved for future use. +/// a `nvim_buf_changedtick_event`. Not used for lua callbacks. +/// @param opts Optional parameters. +/// `on_lines`: lua callback received on change. +/// `on_changedtick`: lua callback received on changedtick +/// increment without text change. +/// See |api-buffer-updates-lua| for more information /// @param[out] err Error details, if any /// @return False when updates couldn't be enabled because the buffer isn't /// loaded or `opts` contained an invalid key; otherwise True. +/// TODO: LUA_API_NO_EVAL Boolean nvim_buf_attach(uint64_t channel_id, Buffer buffer, Boolean send_buffer, - Dictionary opts, + DictionaryOf(LuaRef) opts, Error *err) - FUNC_API_SINCE(4) FUNC_API_REMOTE_ONLY + FUNC_API_SINCE(4) { - if (opts.size > 0) { - api_set_error(err, kErrorTypeValidation, "dict isn't empty"); - return false; - } - buf_T *buf = find_buffer_by_handle(buffer, err); if (!buf) { return false; } - return buf_updates_register(buf, channel_id, send_buffer); + bool is_lua = (channel_id == LUA_INTERNAL_CALL); + BufUpdateCallbacks cb = BUF_UPDATE_CALLBACKS_INIT; + for (size_t i = 0; i < opts.size; i++) { + String k = opts.items[i].key; + Object *v = &opts.items[i].value; + if (is_lua && strequal("on_lines", k.data)) { + if (v->type != kObjectTypeLuaRef) { + api_set_error(err, kErrorTypeValidation, "callback is not a function"); + return false; + } + cb.on_lines = v->data.luaref; + v->data.integer = LUA_NOREF; + } else if (is_lua && strequal("on_changedtick", k.data)) { + if (v->type != kObjectTypeLuaRef) { + api_set_error(err, kErrorTypeValidation, "callback is not a function"); + return false; + } + cb.on_changedtick = v->data.luaref; + v->data.integer = LUA_NOREF; + } else { + api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data); + return false; + } + } + + return buf_updates_register(buf, channel_id, cb, send_buffer); } /// Deactivates buffer-update events on the channel. @@ -307,7 +333,7 @@ void buffer_set_line_slice(Buffer buffer, Integer end, Boolean include_start, Boolean include_end, - ArrayOf(String) replacement, // NOLINT + ArrayOf(String) replacement, Error *err) { start = convert_index(start) + !include_start; @@ -340,7 +366,7 @@ void nvim_buf_set_lines(uint64_t channel_id, Integer start, Integer end, Boolean strict_indexing, - ArrayOf(String) replacement, // NOLINT + ArrayOf(String) replacement, Error *err) FUNC_API_SINCE(1) { diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index 978c55691b..f0d48bf145 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -104,6 +104,7 @@ typedef enum { kObjectTypeString, kObjectTypeArray, kObjectTypeDictionary, + kObjectTypeLuaRef, // EXT types, cannot be split or reordered, see #EXT_OBJECT_TYPE_SHIFT kObjectTypeBuffer, kObjectTypeWindow, @@ -119,6 +120,7 @@ struct object { String string; Array array; Dictionary dictionary; + LuaRef luaref; } data; }; diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 521ec11906..6b05d1ac0a 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -11,6 +11,7 @@ #include "nvim/api/private/defs.h" #include "nvim/api/private/handle.h" #include "nvim/msgpack_rpc/helpers.h" +#include "nvim/lua/executor.h" #include "nvim/ascii.h" #include "nvim/assert.h" #include "nvim/vim.h" @@ -1147,6 +1148,10 @@ void api_free_object(Object value) api_free_dictionary(value.data.dictionary); break; + case kObjectTypeLuaRef: + executor_free_luaref(value.data.luaref); + break; + default: abort(); } diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index cc74824402..0ea7667428 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -48,6 +48,10 @@ .type = kObjectTypeDictionary, \ .data.dictionary = d }) +#define LUAREF_OBJ(r) ((Object) { \ + .type = kObjectTypeLuaRef, \ + .data.luaref = r }) + #define NIL ((Object) {.type = kObjectTypeNil}) #define PUT(dict, k, v) \ |