diff options
| author | Jakob Schnitzer <mail@jakobschnitzer.de> | 2017-06-28 16:52:04 +0200 |
|---|---|---|
| committer | Jakob Schnitzer <mail@jakobschnitzer.de> | 2017-06-28 16:52:04 +0200 |
| commit | e8829710bc5f38208499e0ad38402eac24a67ac2 (patch) | |
| tree | 4e1ae954c2e301adadbfa7038b823ea9ea2fb08e /src/nvim/api | |
| parent | ff8b2eb435c518f0eafd0e509afe1f5ee4a81fd1 (diff) | |
| parent | f0dafa89c2b7602cfedf0bd3409858e4c212b0a2 (diff) | |
| download | rneovim-e8829710bc5f38208499e0ad38402eac24a67ac2.tar.gz rneovim-e8829710bc5f38208499e0ad38402eac24a67ac2.tar.bz2 rneovim-e8829710bc5f38208499e0ad38402eac24a67ac2.zip | |
Merge branch 'master' into option-fixes
Diffstat (limited to 'src/nvim/api')
| -rw-r--r-- | src/nvim/api/buffer.c | 105 | ||||
| -rw-r--r-- | src/nvim/api/private/defs.h | 34 | ||||
| -rw-r--r-- | src/nvim/api/private/helpers.c | 99 | ||||
| -rw-r--r-- | src/nvim/api/private/helpers.h | 2 | ||||
| -rw-r--r-- | src/nvim/api/tabpage.c | 14 | ||||
| -rw-r--r-- | src/nvim/api/ui.c | 207 | ||||
| -rw-r--r-- | src/nvim/api/ui_events.in.h | 71 | ||||
| -rw-r--r-- | src/nvim/api/vim.c | 198 | ||||
| -rw-r--r-- | src/nvim/api/window.c | 40 |
9 files changed, 471 insertions, 299 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c index ae5728ee21..82de8fd4a2 100644 --- a/src/nvim/api/buffer.c +++ b/src/nvim/api/buffer.c @@ -35,7 +35,7 @@ /// @param[out] err Error details, if any /// @return Line count Integer nvim_buf_line_count(Buffer buffer, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -157,7 +157,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id, Integer end, Boolean strict_indexing, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { Array rv = ARRAY_DICT_INIT; buf_T *buf = find_buffer_by_handle(buffer, err); @@ -195,7 +195,7 @@ ArrayOf(String) nvim_buf_get_lines(uint64_t channel_id, Object str = STRING_OBJ(cstr_to_string(bufstr)); // Vim represents NULs as NLs, but this may confuse clients. - if (channel_id != INTERNAL_CALL) { + if (channel_id != VIML_INTERNAL_CALL) { strchrsub(str.data.string.data, '\n', '\0'); } @@ -270,7 +270,7 @@ void nvim_buf_set_lines(uint64_t channel_id, Boolean strict_indexing, ArrayOf(String) replacement, // NOLINT Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -295,6 +295,24 @@ void nvim_buf_set_lines(uint64_t channel_id, return; } + for (size_t i = 0; i < replacement.size; i++) { + if (replacement.items[i].type != kObjectTypeString) { + api_set_error(err, + kErrorTypeValidation, + "All items in the replacement array must be strings"); + return; + } + // Disallow newlines in the middle of the line. + if (channel_id != VIML_INTERNAL_CALL) { + const String l = replacement.items[i].data.string; + if (memchr(l.data, NL, l.size)) { + api_set_error(err, kErrorTypeValidation, + "String cannot contain newlines"); + return; + } + } + } + win_T *save_curwin = NULL; tabpage_T *save_curtab = NULL; size_t new_len = replacement.size; @@ -303,31 +321,16 @@ void nvim_buf_set_lines(uint64_t channel_id, char **lines = (new_len != 0) ? xcalloc(new_len, sizeof(char *)) : NULL; for (size_t i = 0; i < new_len; i++) { - if (replacement.items[i].type != kObjectTypeString) { - api_set_error(err, - kErrorTypeValidation, - "All items in the replacement array must be strings"); - goto end; - } - - String l = replacement.items[i].data.string; + const String l = replacement.items[i].data.string; - // Fill lines[i] with l's contents. Disallow newlines in the middle of a - // line and convert NULs to newlines to avoid truncation. - lines[i] = xmallocz(l.size); - for (size_t j = 0; j < l.size; j++) { - if (l.data[j] == '\n' && channel_id != INTERNAL_CALL) { - api_set_error(err, kErrorTypeException, - "String cannot contain newlines"); - new_len = i + 1; - goto end; - } - lines[i][j] = (char) (l.data[j] == '\0' ? '\n' : l.data[j]); - } + // Fill lines[i] with l's contents. Convert NULs to newlines as required by + // NL-used-for-NUL. + lines[i] = xmemdupz(l.data, l.size); + memchrsub(lines[i], NUL, NL, l.size); } try_start(); - bufref_T save_curbuf = { NULL, 0 }; + bufref_T save_curbuf = { NULL, 0, 0 }; switch_to_win_for_buf(buf, &save_curwin, &save_curtab, &save_curbuf); if (u_save((linenr_T)(start - 1), (linenr_T)end) == FAIL) { @@ -396,7 +399,7 @@ void nvim_buf_set_lines(uint64_t channel_id, // Only adjust marks if we managed to switch to a window that holds // the buffer, otherwise line numbers will be invalid. if (save_curbuf.br_buf == NULL) { - mark_adjust((linenr_T)start, (linenr_T)(end - 1), MAXLNUM, extra); + mark_adjust((linenr_T)start, (linenr_T)(end - 1), MAXLNUM, extra, false); } changed_lines((linenr_T)start, 0, (linenr_T)end, (long)extra); @@ -422,7 +425,7 @@ end: /// @param[out] err Error details, if any /// @return Variable value Object nvim_buf_get_var(Buffer buffer, String name, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -439,7 +442,7 @@ Object nvim_buf_get_var(Buffer buffer, String name, Error *err) /// /// @return `b:changedtick` value. Integer nvim_buf_get_changedtick(Buffer buffer, Error *err) - FUNC_API_SINCE(2) + FUNC_API_SINCE(2) { const buf_T *const buf = find_buffer_by_handle(buffer, err); @@ -450,6 +453,26 @@ Integer nvim_buf_get_changedtick(Buffer buffer, Error *err) return buf->b_changedtick; } +/// Get a list of dictionaries describing buffer-local mappings +/// Note that the buffer key in the dictionary will represent the buffer +/// handle where the mapping is present +/// +/// @param mode The abbreviation for the mode +/// @param buffer_id Buffer handle +/// @param[out] err Error details, if any +/// @returns An array of maparg() like dictionaries describing mappings +ArrayOf(Dictionary) nvim_buf_get_keymap(Buffer buffer, String mode, Error *err) + FUNC_API_SINCE(3) +{ + buf_T *buf = find_buffer_by_handle(buffer, err); + + if (!buf) { + return (Array)ARRAY_DICT_INIT; + } + + return keymap_array(mode, buf); +} + /// Sets a buffer-scoped (b:) variable /// /// @param buffer Buffer handle @@ -457,7 +480,7 @@ Integer nvim_buf_get_changedtick(Buffer buffer, Error *err) /// @param value Variable value /// @param[out] err Error details, if any void nvim_buf_set_var(Buffer buffer, String name, Object value, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -474,7 +497,7 @@ void nvim_buf_set_var(Buffer buffer, String name, Object value, Error *err) /// @param name Variable name /// @param[out] err Error details, if any void nvim_buf_del_var(Buffer buffer, String name, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -535,7 +558,7 @@ Object buffer_del_var(Buffer buffer, String name, Error *err) /// @param[out] err Error details, if any /// @return Option value Object nvim_buf_get_option(Buffer buffer, String name, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -554,7 +577,7 @@ Object nvim_buf_get_option(Buffer buffer, String name, Error *err) /// @param value Option value /// @param[out] err Error details, if any void nvim_buf_set_option(Buffer buffer, String name, Object value, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -567,11 +590,15 @@ void nvim_buf_set_option(Buffer buffer, String name, Object value, Error *err) /// Gets the buffer number /// +/// @deprecated The buffer number now is equal to the object id, +/// so there is no need to use this function. +/// /// @param buffer Buffer handle /// @param[out] err Error details, if any /// @return Buffer number Integer nvim_buf_get_number(Buffer buffer, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) + FUNC_API_DEPRECATED_SINCE(2) { Integer rv = 0; buf_T *buf = find_buffer_by_handle(buffer, err); @@ -589,7 +616,7 @@ Integer nvim_buf_get_number(Buffer buffer, Error *err) /// @param[out] err Error details, if any /// @return Buffer name String nvim_buf_get_name(Buffer buffer, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { String rv = STRING_INIT; buf_T *buf = find_buffer_by_handle(buffer, err); @@ -607,7 +634,7 @@ String nvim_buf_get_name(Buffer buffer, Error *err) /// @param name Buffer name /// @param[out] err Error details, if any void nvim_buf_set_name(Buffer buffer, String name, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); @@ -637,7 +664,7 @@ void nvim_buf_set_name(Buffer buffer, String name, Error *err) /// @param buffer Buffer handle /// @return true if the buffer is valid, false otherwise Boolean nvim_buf_is_valid(Buffer buffer) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { Error stub = ERROR_INIT; Boolean ret = find_buffer_by_handle(buffer, &stub) != NULL; @@ -671,7 +698,7 @@ void buffer_insert(Buffer buffer, /// @param[out] err Error details, if any /// @return (row, col) tuple ArrayOf(Integer, 2) nvim_buf_get_mark(Buffer buffer, String name, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { Array rv = ARRAY_DICT_INIT; buf_T *buf = find_buffer_by_handle(buffer, err); @@ -747,7 +774,7 @@ Integer nvim_buf_add_highlight(Buffer buffer, Integer col_start, Integer col_end, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); if (!buf) { @@ -788,7 +815,7 @@ void nvim_buf_clear_highlight(Buffer buffer, Integer line_start, Integer line_end, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { buf_T *buf = find_buffer_by_handle(buffer, err); if (!buf) { diff --git a/src/nvim/api/private/defs.h b/src/nvim/api/private/defs.h index 60bf38265f..2144c80d6a 100644 --- a/src/nvim/api/private/defs.h +++ b/src/nvim/api/private/defs.h @@ -5,6 +5,8 @@ #include <stdbool.h> #include <string.h> +#include "nvim/func_attr.h" + #define ARRAY_DICT_INIT {.size = 0, .capacity = 0, .items = NULL} #define STRING_INIT {.data = NULL, .size = 0} #define OBJECT_INIT { .type = kObjectTypeNil } @@ -36,8 +38,27 @@ typedef enum { /// Used as the message ID of notifications. #define NO_RESPONSE UINT64_MAX -/// Used as channel_id when the call is local. -#define INTERNAL_CALL UINT64_MAX +/// Mask for all internal calls +#define INTERNAL_CALL_MASK (((uint64_t)1) << (sizeof(uint64_t) * 8 - 1)) + +/// Internal call from VimL code +#define VIML_INTERNAL_CALL INTERNAL_CALL_MASK + +/// Internal call from lua code +#define LUA_INTERNAL_CALL (VIML_INTERNAL_CALL + 1) + +static inline bool is_internal_call(uint64_t channel_id) + REAL_FATTR_ALWAYS_INLINE REAL_FATTR_CONST; + +/// Check whether call is internal +/// +/// @param[in] channel_id Channel id. +/// +/// @return true if channel_id refers to internal channel. +static inline bool is_internal_call(const uint64_t channel_id) +{ + return !!(channel_id & INTERNAL_CALL_MASK); +} typedef struct { ErrorType type; @@ -78,16 +99,17 @@ typedef struct { } Dictionary; typedef enum { - kObjectTypeBuffer, - kObjectTypeWindow, - kObjectTypeTabpage, - kObjectTypeNil, + kObjectTypeNil = 0, kObjectTypeBoolean, kObjectTypeInteger, kObjectTypeFloat, kObjectTypeString, kObjectTypeArray, kObjectTypeDictionary, + // EXT types, cannot be split or reordered, see #EXT_OBJECT_TYPE_SHIFT + kObjectTypeBuffer, + kObjectTypeWindow, + kObjectTypeTabpage, } ObjectType; struct object { diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c index 69cb19c14f..d401ae52a0 100644 --- a/src/nvim/api/private/helpers.c +++ b/src/nvim/api/private/helpers.c @@ -24,6 +24,7 @@ #include "nvim/option_defs.h" #include "nvim/version.h" #include "nvim/lib/kvec.h" +#include "nvim/getchar.h" /// Helper structure for vim_to_object typedef struct { @@ -33,6 +34,7 @@ typedef struct { #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/private/helpers.c.generated.h" # include "api/private/funcs_metadata.generated.h" +# include "api/private/ui_events_metadata.generated.h" #endif /// Start block that may cause vimscript exceptions @@ -353,7 +355,7 @@ void set_option_to(void *to, int type, String name, Object value, Error *err) #define TYPVAL_ENCODE_CONV_UNSIGNED_NUMBER TYPVAL_ENCODE_CONV_NUMBER #define TYPVAL_ENCODE_CONV_FLOAT(tv, flt) \ - kv_push(edata->stack, FLOATING_OBJ((Float)(flt))) + kv_push(edata->stack, FLOAT_OBJ((Float)(flt))) #define TYPVAL_ENCODE_CONV_STRING(tv, str, len) \ do { \ @@ -820,6 +822,7 @@ Dictionary api_metadata(void) if (!metadata.size) { PUT(metadata, "version", DICTIONARY_OBJ(version_dict())); init_function_metadata(&metadata); + init_ui_event_metadata(&metadata); init_error_type_metadata(&metadata); init_type_metadata(&metadata); } @@ -843,6 +846,22 @@ static void init_function_metadata(Dictionary *metadata) PUT(*metadata, "functions", functions); } +static void init_ui_event_metadata(Dictionary *metadata) +{ + msgpack_unpacked unpacked; + msgpack_unpacked_init(&unpacked); + if (msgpack_unpack_next(&unpacked, + (const char *)ui_events_metadata, + sizeof(ui_events_metadata), + NULL) != MSGPACK_UNPACK_SUCCESS) { + abort(); + } + Object ui_events; + msgpack_rpc_to_object(&unpacked.data, &ui_events); + msgpack_unpacked_destroy(&unpacked); + PUT(*metadata, "ui_events", ui_events); +} + static void init_error_type_metadata(Dictionary *metadata) { Dictionary types = ARRAY_DICT_INIT; @@ -864,15 +883,18 @@ static void init_type_metadata(Dictionary *metadata) Dictionary types = ARRAY_DICT_INIT; Dictionary buffer_metadata = ARRAY_DICT_INIT; - PUT(buffer_metadata, "id", INTEGER_OBJ(kObjectTypeBuffer)); + PUT(buffer_metadata, "id", + INTEGER_OBJ(kObjectTypeBuffer - EXT_OBJECT_TYPE_SHIFT)); PUT(buffer_metadata, "prefix", STRING_OBJ(cstr_to_string("nvim_buf_"))); Dictionary window_metadata = ARRAY_DICT_INIT; - PUT(window_metadata, "id", INTEGER_OBJ(kObjectTypeWindow)); + PUT(window_metadata, "id", + INTEGER_OBJ(kObjectTypeWindow - EXT_OBJECT_TYPE_SHIFT)); PUT(window_metadata, "prefix", STRING_OBJ(cstr_to_string("nvim_win_"))); Dictionary tabpage_metadata = ARRAY_DICT_INIT; - PUT(tabpage_metadata, "id", INTEGER_OBJ(kObjectTypeTabpage)); + PUT(tabpage_metadata, "id", + INTEGER_OBJ(kObjectTypeTabpage - EXT_OBJECT_TYPE_SHIFT)); PUT(tabpage_metadata, "prefix", STRING_OBJ(cstr_to_string("nvim_tabpage_"))); PUT(types, "Buffer", DICTIONARY_OBJ(buffer_metadata)); @@ -882,6 +904,24 @@ static void init_type_metadata(Dictionary *metadata) PUT(*metadata, "types", DICTIONARY_OBJ(types)); } +String copy_string(String str) +{ + if (str.data != NULL) { + return (String){ .data = xmemdupz(str.data, str.size), .size = str.size }; + } else { + return (String)STRING_INIT; + } +} + +Array copy_array(Array array) +{ + Array rv = ARRAY_DICT_INIT; + for (size_t i = 0; i < array.size; i++) { + ADD(rv, copy_object(array.items[i])); + } + return rv; +} + /// Creates a deep clone of an object Object copy_object(Object obj) { @@ -893,15 +933,10 @@ Object copy_object(Object obj) return obj; case kObjectTypeString: - return STRING_OBJ(cstr_to_string(obj.data.string.data)); + return STRING_OBJ(copy_string(obj.data.string)); - case kObjectTypeArray: { - Array rv = ARRAY_DICT_INIT; - for (size_t i = 0; i < obj.data.array.size; i++) { - ADD(rv, copy_object(obj.data.array.items[i])); - } - return ARRAY_OBJ(rv); - } + case kObjectTypeArray: + return ARRAY_OBJ(copy_array(obj.data.array)); case kObjectTypeDictionary: { Dictionary rv = ARRAY_DICT_INIT; @@ -926,7 +961,7 @@ static void set_option_value_for(char *key, { win_T *save_curwin = NULL; tabpage_T *save_curtab = NULL; - bufref_T save_curbuf = { NULL, 0 }; + bufref_T save_curbuf = { NULL, 0, 0 }; try_start(); switch (opt_type) @@ -1000,3 +1035,41 @@ void api_set_error(Error *err, ErrorType errType, const char *format, ...) err->type = errType; } + +/// Get an array containing dictionaries describing mappings +/// based on mode and buffer id +/// +/// @param mode The abbreviation for the mode +/// @param buf The buffer to get the mapping array. NULL for global +/// @returns An array of maparg() like dictionaries describing mappings +ArrayOf(Dictionary) keymap_array(String mode, buf_T *buf) +{ + Array mappings = ARRAY_DICT_INIT; + dict_T *const dict = tv_dict_alloc(); + + // Convert the string mode to the integer mode + // that is stored within each mapblock + char_u *p = (char_u *)mode.data; + int int_mode = get_map_mode(&p, 0); + + // Determine the desired buffer value + long buffer_value = (buf == NULL) ? 0 : buf->handle; + + for (int i = 0; i < MAX_MAPHASH; i++) { + for (const mapblock_T *current_maphash = get_maphash(i, buf); + current_maphash; + current_maphash = current_maphash->m_next) { + // Check for correct mode + if (int_mode & current_maphash->m_mode) { + mapblock_fill_dict(dict, current_maphash, buffer_value, false); + ADD(mappings, vim_to_object( + (typval_T[]) { { .v_type = VAR_DICT, .vval.v_dict = dict } })); + + tv_dict_clear(dict); + } + } + } + tv_dict_free(dict); + + return mappings; +} diff --git a/src/nvim/api/private/helpers.h b/src/nvim/api/private/helpers.h index 681945ac9c..159b9d5c2a 100644 --- a/src/nvim/api/private/helpers.h +++ b/src/nvim/api/private/helpers.h @@ -18,7 +18,7 @@ .type = kObjectTypeInteger, \ .data.integer = i }) -#define FLOATING_OBJ(f) ((Object) { \ +#define FLOAT_OBJ(f) ((Object) { \ .type = kObjectTypeFloat, \ .data.floating = f }) diff --git a/src/nvim/api/tabpage.c b/src/nvim/api/tabpage.c index 6f2f9e1d2a..b6830d9fcf 100644 --- a/src/nvim/api/tabpage.c +++ b/src/nvim/api/tabpage.c @@ -18,7 +18,7 @@ /// @param[out] err Error details, if any /// @return List of windows in `tabpage` ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { Array rv = ARRAY_DICT_INIT; tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -48,7 +48,7 @@ ArrayOf(Window) nvim_tabpage_list_wins(Tabpage tabpage, Error *err) /// @param[out] err Error details, if any /// @return Variable value Object nvim_tabpage_get_var(Tabpage tabpage, String name, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -69,7 +69,7 @@ void nvim_tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -86,7 +86,7 @@ void nvim_tabpage_set_var(Tabpage tabpage, /// @param name Variable name /// @param[out] err Error details, if any void nvim_tabpage_del_var(Tabpage tabpage, String name, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -145,7 +145,7 @@ Object tabpage_del_var(Tabpage tabpage, String name, Error *err) /// @param[out] err Error details, if any /// @return Window handle Window nvim_tabpage_get_win(Tabpage tabpage, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { Window rv = 0; tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -173,7 +173,7 @@ Window nvim_tabpage_get_win(Tabpage tabpage, Error *err) /// @param[out] err Error details, if any /// @return Tabpage number Integer nvim_tabpage_get_number(Tabpage tabpage, Error *err) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { Integer rv = 0; tabpage_T *tab = find_tab_by_handle(tabpage, err); @@ -190,7 +190,7 @@ Integer nvim_tabpage_get_number(Tabpage tabpage, Error *err) /// @param tabpage Tabpage handle /// @return true if the tabpage is valid, false otherwise Boolean nvim_tabpage_is_valid(Tabpage tabpage) - FUNC_API_SINCE(1) + FUNC_API_SINCE(1) { Error stub = ERROR_INIT; Boolean ret = find_tab_by_handle(tabpage, &stub) != NULL; diff --git a/src/nvim/api/ui.c b/src/nvim/api/ui.c index f0da0d1812..573be23d8e 100644 --- a/src/nvim/api/ui.c +++ b/src/nvim/api/ui.c @@ -19,6 +19,7 @@ #ifdef INCLUDE_GENERATED_DECLARATIONS # include "api/ui.c.generated.h" +# include "ui_events_remote.generated.h" #endif typedef struct { @@ -29,13 +30,13 @@ typedef struct { static PMap(uint64_t) *connected_uis = NULL; void remote_ui_init(void) - FUNC_API_NOEXPORT + FUNC_API_NOEXPORT { connected_uis = pmap_new(uint64_t)(); } void remote_ui_disconnect(uint64_t channel_id) - FUNC_API_NOEXPORT + FUNC_API_NOEXPORT { UI *ui = pmap_get(uint64_t)(connected_uis, channel_id); if (!ui) { @@ -52,7 +53,7 @@ void remote_ui_disconnect(uint64_t channel_id) void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, Dictionary options, Error *err) - FUNC_API_SINCE(1) FUNC_API_NOEVAL + FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY { if (pmap_has(uint64_t)(connected_uis, channel_id)) { api_set_error(err, kErrorTypeException, "UI already attached for channel"); @@ -68,7 +69,6 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, ui->width = (int)width; ui->height = (int)height; ui->rgb = true; - ui->pum_external = false; ui->resize = remote_ui_resize; ui->clear = remote_ui_clear; ui->eol_clear = remote_ui_eol_clear; @@ -95,6 +95,8 @@ void nvim_ui_attach(uint64_t channel_id, Integer width, Integer height, ui->set_icon = remote_ui_set_icon; ui->event = remote_ui_event; + memset(ui->ui_ext, 0, sizeof(ui->ui_ext)); + for (size_t i = 0; i < options.size; i++) { ui_set_option(ui, options.items[i].key, options.items[i].value, err); if (ERROR_SET(err)) { @@ -123,7 +125,7 @@ void ui_attach(uint64_t channel_id, Integer width, Integer height, } void nvim_ui_detach(uint64_t channel_id, Error *err) - FUNC_API_SINCE(1) FUNC_API_NOEVAL + FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { api_set_error(err, kErrorTypeException, "UI is not attached for channel"); @@ -135,7 +137,7 @@ void nvim_ui_detach(uint64_t channel_id, Error *err) void nvim_ui_try_resize(uint64_t channel_id, Integer width, Integer height, Error *err) - FUNC_API_SINCE(1) FUNC_API_NOEVAL + FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { api_set_error(err, kErrorTypeException, "UI is not attached for channel"); @@ -156,7 +158,7 @@ void nvim_ui_try_resize(uint64_t channel_id, Integer width, void nvim_ui_set_option(uint64_t channel_id, String name, Object value, Error *error) - FUNC_API_SINCE(1) FUNC_API_NOEVAL + FUNC_API_SINCE(1) FUNC_API_REMOTE_ONLY { if (!pmap_has(uint64_t)(connected_uis, channel_id)) { api_set_error(error, kErrorTypeException, "UI is not attached for channel"); @@ -170,23 +172,47 @@ void nvim_ui_set_option(uint64_t channel_id, String name, } } -static void ui_set_option(UI *ui, String name, Object value, Error *error) { - if (strcmp(name.data, "rgb") == 0) { +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 (value.type != kObjectTypeBoolean) { api_set_error(error, kErrorTypeValidation, "rgb must be a Boolean"); return; } ui->rgb = value.data.boolean; - } else if (strcmp(name.data, "popupmenu_external") == 0) { + 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. if (value.type != kObjectTypeBoolean) { api_set_error(error, kErrorTypeValidation, "popupmenu_external must be a Boolean"); return; } - ui->pum_external = value.data.boolean; - } else { - api_set_error(error, kErrorTypeValidation, "No such ui option"); + ui->ui_ext[kUIPopupmenu] = value.data.boolean; + return; } + + api_set_error(error, kErrorTypeValidation, "No such ui option"); +#undef UI_EXT_OPTION } static void push_call(UI *ui, char *name, Array args) @@ -211,100 +237,6 @@ static void push_call(UI *ui, char *name, Array args) kv_A(data->buffer, kv_size(data->buffer) - 1).data.array = call; } -static void remote_ui_resize(UI *ui, int width, int height) -{ - Array args = ARRAY_DICT_INIT; - ADD(args, INTEGER_OBJ(width)); - ADD(args, INTEGER_OBJ(height)); - push_call(ui, "resize", args); -} - -static void remote_ui_clear(UI *ui) -{ - Array args = ARRAY_DICT_INIT; - push_call(ui, "clear", args); -} - -static void remote_ui_eol_clear(UI *ui) -{ - Array args = ARRAY_DICT_INIT; - push_call(ui, "eol_clear", args); -} - -static void remote_ui_cursor_goto(UI *ui, int row, int col) -{ - Array args = ARRAY_DICT_INIT; - ADD(args, INTEGER_OBJ(row)); - ADD(args, INTEGER_OBJ(col)); - push_call(ui, "cursor_goto", args); -} - -static void remote_ui_update_menu(UI *ui) -{ - Array args = ARRAY_DICT_INIT; - push_call(ui, "update_menu", args); -} - -static void remote_ui_busy_start(UI *ui) -{ - Array args = ARRAY_DICT_INIT; - push_call(ui, "busy_start", args); -} - -static void remote_ui_busy_stop(UI *ui) -{ - Array args = ARRAY_DICT_INIT; - push_call(ui, "busy_stop", args); -} - -static void remote_ui_mouse_on(UI *ui) -{ - Array args = ARRAY_DICT_INIT; - push_call(ui, "mouse_on", args); -} - -static void remote_ui_mouse_off(UI *ui) -{ - Array args = ARRAY_DICT_INIT; - push_call(ui, "mouse_off", args); -} - -static void remote_ui_mode_change(UI *ui, int mode_idx) -{ - Array args = ARRAY_DICT_INIT; - - char *full_name = shape_table[mode_idx].full_name; - ADD(args, STRING_OBJ(cstr_to_string(full_name))); - - ADD(args, INTEGER_OBJ(mode_idx)); - push_call(ui, "mode_change", args); -} - -static void remote_ui_set_scroll_region(UI *ui, int top, int bot, int left, - int right) -{ - Array args = ARRAY_DICT_INIT; - ADD(args, INTEGER_OBJ(top)); - ADD(args, INTEGER_OBJ(bot)); - ADD(args, INTEGER_OBJ(left)); - ADD(args, INTEGER_OBJ(right)); - push_call(ui, "set_scroll_region", args); -} - -static void remote_ui_scroll(UI *ui, int count) -{ - Array args = ARRAY_DICT_INIT; - ADD(args, INTEGER_OBJ(count)); - push_call(ui, "scroll", args); -} - -static void remote_ui_mode_info_set(UI *ui, bool guicursor_enabled, Array data) -{ - Array args = ARRAY_DICT_INIT; - ADD(args, BOOLEAN_OBJ(guicursor_enabled)); - ADD(args, copy_object(ARRAY_OBJ(data))); - push_call(ui, "mode_info_set", args); -} static void remote_ui_highlight_set(UI *ui, HlAttrs attrs) { @@ -347,47 +279,6 @@ static void remote_ui_highlight_set(UI *ui, HlAttrs attrs) push_call(ui, "highlight_set", args); } -static void remote_ui_put(UI *ui, uint8_t *data, size_t size) -{ - Array args = ARRAY_DICT_INIT; - String str = { .data = xmemdupz(data, size), .size = size }; - ADD(args, STRING_OBJ(str)); - push_call(ui, "put", args); -} - -static void remote_ui_bell(UI *ui) -{ - Array args = ARRAY_DICT_INIT; - push_call(ui, "bell", args); -} - -static void remote_ui_visual_bell(UI *ui) -{ - Array args = ARRAY_DICT_INIT; - push_call(ui, "visual_bell", args); -} - -static void remote_ui_update_fg(UI *ui, int fg) -{ - Array args = ARRAY_DICT_INIT; - ADD(args, INTEGER_OBJ(fg)); - push_call(ui, "update_fg", args); -} - -static void remote_ui_update_bg(UI *ui, int bg) -{ - Array args = ARRAY_DICT_INIT; - ADD(args, INTEGER_OBJ(bg)); - push_call(ui, "update_bg", args); -} - -static void remote_ui_update_sp(UI *ui, int sp) -{ - Array args = ARRAY_DICT_INIT; - ADD(args, INTEGER_OBJ(sp)); - push_call(ui, "update_sp", args); -} - static void remote_ui_flush(UI *ui) { UIData *data = ui->data; @@ -397,26 +288,6 @@ static void remote_ui_flush(UI *ui) } } -static void remote_ui_suspend(UI *ui) -{ - Array args = ARRAY_DICT_INIT; - push_call(ui, "suspend", args); -} - -static void remote_ui_set_title(UI *ui, char *title) -{ - Array args = ARRAY_DICT_INIT; - ADD(args, STRING_OBJ(cstr_to_string(title))); - push_call(ui, "set_title", args); -} - -static void remote_ui_set_icon(UI *ui, char *icon) -{ - Array args = ARRAY_DICT_INIT; - ADD(args, STRING_OBJ(cstr_to_string(icon))); - push_call(ui, "set_icon", args); -} - static void remote_ui_event(UI *ui, char *name, Array args, bool *args_consumed) { Array my_args = ARRAY_DICT_INIT; diff --git a/src/nvim/api/ui_events.in.h b/src/nvim/api/ui_events.in.h new file mode 100644 index 0000000000..1b5d17584f --- /dev/null +++ b/src/nvim/api/ui_events.in.h @@ -0,0 +1,71 @@ +#ifndef NVIM_API_UI_EVENTS_IN_H +#define NVIM_API_UI_EVENTS_IN_H + +// This file is not compiled, just parsed for definitons +#ifdef INCLUDE_GENERATED_DECLARATIONS +# error "don't include this file, include nvim/ui.h" +#endif + +#include "nvim/api/private/defs.h" +#include "nvim/func_attr.h" +#include "nvim/ui.h" + +void resize(Integer rows, Integer columns) + FUNC_API_SINCE(3); +void clear(void) + FUNC_API_SINCE(3); +void eol_clear(void) + FUNC_API_SINCE(3); +void cursor_goto(Integer row, Integer col) + FUNC_API_SINCE(3); +void mode_info_set(Boolean enabled, Array cursor_styles) + FUNC_API_SINCE(3); +void update_menu(void) + FUNC_API_SINCE(3); +void busy_start(void) + FUNC_API_SINCE(3); +void busy_stop(void) + FUNC_API_SINCE(3); +void mouse_on(void) + FUNC_API_SINCE(3); +void mouse_off(void) + FUNC_API_SINCE(3); +void mode_change(String mode, Integer mode_idx) + FUNC_API_SINCE(3); +void set_scroll_region(Integer top, Integer bot, Integer left, Integer right) + FUNC_API_SINCE(3); +void scroll(Integer count) + FUNC_API_SINCE(3); +void highlight_set(HlAttrs attrs) + FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL FUNC_API_BRIDGE_IMPL; +void put(String str) + FUNC_API_SINCE(3); +void bell(void) + FUNC_API_SINCE(3); +void visual_bell(void) + FUNC_API_SINCE(3); +void flush(void) + FUNC_API_SINCE(3) FUNC_API_REMOTE_IMPL; +void update_fg(Integer fg) + FUNC_API_SINCE(3); +void update_bg(Integer bg) + FUNC_API_SINCE(3); +void update_sp(Integer sp) + FUNC_API_SINCE(3); +void suspend(void) + FUNC_API_SINCE(3) FUNC_API_BRIDGE_IMPL; +void set_title(String title) + FUNC_API_SINCE(3); +void set_icon(String icon) + FUNC_API_SINCE(3); + +void popupmenu_show(Array items, Integer selected, Integer row, Integer col) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; +void popupmenu_hide(void) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; +void popupmenu_select(Integer selected) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; +void tabline_update(Tabpage current, Array tabs) + FUNC_API_SINCE(3) FUNC_API_REMOTE_ONLY; + +#endif // NVIM_API_UI_EVENTS_IN_H |