From d5a60d17fbca33ca96124288e69937a276d3abda Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Sun, 7 Sep 2014 18:48:10 -0300 Subject: api/msgpack-rpc: Remove specialized array types Specialized array types(BufferArray, WindowArray, etc) were added to the API for two main reasons: - msgpack used to lack a way of serializing appliaction-specific types and there was no obvious way of making an API function accept/return arrays of custom objects such as buffers(which are represented as integers, so clients didn't have a way to distinguish from normal numbers) - Let clients in statically-typed languages that support generics have a better typed API With msgpack 2.0 EXT type the first item is no longer a factor and this commit starts by removing the specialized array types. The second item will be addressed in the future by making the API metadata return extra useful information for statically-typed languages. --- src/nvim/api/vim.c | 37 +++++++++++++++++++------------------ 1 file changed, 19 insertions(+), 18 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index a2c50b4c81..b1d5a067b4 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -149,9 +149,9 @@ Integer vim_strwidth(String str, Error *err) /// Returns a list of paths contained in 'runtimepath' /// /// @return The list of paths -StringArray vim_list_runtime_paths(void) +Array vim_list_runtime_paths(void) { - StringArray rv = ARRAY_DICT_INIT; + Array rv = ARRAY_DICT_INIT; uint8_t *rtp = p_rtp; if (*rtp == NUL) { @@ -168,19 +168,20 @@ StringArray vim_list_runtime_paths(void) } // Allocate memory for the copies - rv.items = xmalloc(sizeof(String) * rv.size); + rv.items = xmalloc(sizeof(Object) * rv.size); // reset the position rtp = p_rtp; // Start copying for (size_t i = 0; i < rv.size && *rtp != NUL; i++) { - rv.items[i].data = xmalloc(MAXPATHL); + rv.items[i].type = kObjectTypeString; + rv.items[i].data.string.data = xmalloc(MAXPATHL); // Copy the path from 'runtimepath' to rv.items[i] int length = copy_option_part(&rtp, - (char_u *)rv.items[i].data, + (char_u *)rv.items[i].data.string.data, MAXPATHL, ","); assert(length >= 0); - rv.items[i].size = (size_t)length; + rv.items[i].data.string.size = (size_t)length; } return rv; @@ -310,9 +311,9 @@ void vim_err_write(String str) /// Gets the current list of buffer handles /// /// @return The number of buffers -BufferArray vim_get_buffers(void) +Array vim_get_buffers(void) { - BufferArray rv = ARRAY_DICT_INIT; + Array rv = ARRAY_DICT_INIT; buf_T *b = firstbuf; while (b) { @@ -320,12 +321,12 @@ BufferArray vim_get_buffers(void) b = b->b_next; } - rv.items = xmalloc(sizeof(Buffer) * rv.size); + rv.items = xmalloc(sizeof(Object) * rv.size); size_t i = 0; b = firstbuf; while (b) { - rv.items[i++] = b->handle; + rv.items[i++] = BUFFER_OBJ(b->handle); b = b->b_next; } @@ -370,9 +371,9 @@ void vim_set_current_buffer(Buffer buffer, Error *err) /// Gets the current list of window handles /// /// @return The number of windows -WindowArray vim_get_windows(void) +Array vim_get_windows(void) { - WindowArray rv = ARRAY_DICT_INIT; + Array rv = ARRAY_DICT_INIT; tabpage_T *tp; win_T *wp; @@ -380,11 +381,11 @@ WindowArray vim_get_windows(void) rv.size++; } - rv.items = xmalloc(sizeof(Window) * rv.size); + rv.items = xmalloc(sizeof(Object) * rv.size); size_t i = 0; FOR_ALL_TAB_WINDOWS(tp, wp) { - rv.items[i++] = wp->handle; + rv.items[i++] = WINDOW_OBJ(wp->handle); } return rv; @@ -426,9 +427,9 @@ void vim_set_current_window(Window window, Error *err) /// Gets the current list of tabpage handles /// /// @return The number of tab pages -TabpageArray vim_get_tabpages(void) +Array vim_get_tabpages(void) { - TabpageArray rv = ARRAY_DICT_INIT; + Array rv = ARRAY_DICT_INIT; tabpage_T *tp = first_tabpage; while (tp) { @@ -436,12 +437,12 @@ TabpageArray vim_get_tabpages(void) tp = tp->tp_next; } - rv.items = xmalloc(sizeof(Tabpage) * rv.size); + rv.items = xmalloc(sizeof(Object) * rv.size); size_t i = 0; tp = first_tabpage; while (tp) { - rv.items[i++] = tp->handle; + rv.items[i++] = TABPAGE_OBJ(tp->handle); tp = tp->tp_next; } -- cgit From a1ce3a3acc9f5e617e9d7e9542d58953d2e9546f Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Wed, 10 Sep 2014 10:11:45 -0300 Subject: provider: Major refactor - Providers for features are now registered as a unit. For example, instead of calling `register_provider("clipboard_get")` and `register_provider("clipboard_set")`, clients call `register_provider("clipboard")` and nvim will assume it implements all methods of the "clipboard" feature - Bootstrapping code was removed. With the `api_spawn` function exposed to vimscript, it's no longer necessary and will be handled by plugins distributed with nvim. - Now the `has` function will return true if there's a live channel that has registered as a provider for the feature. - 'initpython'/'initclipboard' options were removed - A new API function was exposed: `vim_discover_features` which returns an object with information about pluggable features such as 'python' or 'clipboard' --- src/nvim/api/vim.c | 18 ++++++++++++------ 1 file changed, 12 insertions(+), 6 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index b1d5a067b4..e14c427dc1 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -502,22 +502,28 @@ void vim_unsubscribe(uint64_t channel_id, String event) channel_unsubscribe(channel_id, e); } -/// Registers the channel as the provider for `method`. This fails if -/// a provider for `method` is already registered. +/// Registers the channel as the provider for `feature`. This fails if +/// a provider for `feature` is already provided by another channel. /// /// @param channel_id The channel id -/// @param method The method name +/// @param feature The feature name /// @param[out] err Details of an error that may have occurred -void vim_register_provider(uint64_t channel_id, String method, Error *err) +void vim_register_provider(uint64_t channel_id, String feature, Error *err) { char buf[METHOD_MAXLEN]; - xstrlcpy(buf, method.data, sizeof(buf)); + xstrlcpy(buf, feature.data, sizeof(buf)); if (!provider_register(buf, channel_id)) { - set_api_error("Provider already registered", err); + set_api_error("Feature doesn't exist", err); } } +/// Returns a feature->method list dictionary for all pluggable features +Dictionary vim_discover_features(void) +{ + return provider_get_all(); +} + /// Writes a message to vim output or error buffer. The string is split /// and flushed after each newline. Incomplete lines are kept for writing /// later. -- cgit From 15ca58d79f8cc8565c1a2b2581029cf7901b5fbd Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Thu, 11 Sep 2014 10:35:52 -0300 Subject: api: Implement `vim_report_error` function This function is used to report errors caused by remote functions called by channel_send_call --- src/nvim/api/vim.c | 10 ++++++++++ 1 file changed, 10 insertions(+) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index e14c427dc1..25454761ea 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -308,6 +308,16 @@ void vim_err_write(String str) write_msg(str, true); } +/// Higher level error reporting function that ensures all str contents +/// are written by sending a trailing linefeed to `vim_wrr_write` +/// +/// @param str The message +void vim_report_error(String str) +{ + vim_err_write(str); + vim_err_write((String) {.data = "\n", .size = 1}); +} + /// Gets the current list of buffer handles /// /// @return The number of buffers -- cgit From cd2e46c0785d40b9ea15f6d722a3fad54c007b9b Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Thu, 11 Sep 2014 21:56:52 -0300 Subject: api/msgpack-rpc: Refactor metadata object construction Instead of building all metadata from msgpack-gen.lua, we now merge the generated part with manual information(such as types and features). The metadata is accessible through the api method `vim_get_api_info`. This was done to simplify the generator while also increasing flexibility(by being able to add more metadata) --- src/nvim/api/vim.c | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index 25454761ea..c0a9fe3410 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -528,10 +528,15 @@ void vim_register_provider(uint64_t channel_id, String feature, Error *err) } } -/// Returns a feature->method list dictionary for all pluggable features -Dictionary vim_discover_features(void) +Array vim_get_api_info(uint64_t channel_id) { - return provider_get_all(); + Array rv = ARRAY_DICT_INIT; + + assert(channel_id <= INT64_MAX); + ADD(rv, INTEGER_OBJ((int64_t)channel_id)); + ADD(rv, DICTIONARY_OBJ(api_metadata())); + + return rv; } /// Writes a message to vim output or error buffer. The string is split -- cgit From 545acf2024ea2653ae6937d570a37aa0340caa5e Mon Sep 17 00:00:00 2001 From: Thiago de Arruda Date: Fri, 12 Sep 2014 11:24:01 -0300 Subject: api metadata: Allow typed container information in api functions Adapt gendeclarations.lua/msgpack-gen.lua to allow the `ArrayOf(...)` and `DictionaryOf(...)` types in function headers. These are simple macros that expand to Array and Dictionary respectively, but the information is kept in the metadata object, which is useful for building clients in statically typed languages. --- src/nvim/api/vim.c | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) (limited to 'src/nvim/api/vim.c') diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c index c0a9fe3410..43f2aafdc8 100644 --- a/src/nvim/api/vim.c +++ b/src/nvim/api/vim.c @@ -149,7 +149,7 @@ Integer vim_strwidth(String str, Error *err) /// Returns a list of paths contained in 'runtimepath' /// /// @return The list of paths -Array vim_list_runtime_paths(void) +ArrayOf(String) vim_list_runtime_paths(void) { Array rv = ARRAY_DICT_INIT; uint8_t *rtp = p_rtp; @@ -321,7 +321,7 @@ void vim_report_error(String str) /// Gets the current list of buffer handles /// /// @return The number of buffers -Array vim_get_buffers(void) +ArrayOf(Buffer) vim_get_buffers(void) { Array rv = ARRAY_DICT_INIT; buf_T *b = firstbuf; @@ -381,7 +381,7 @@ void vim_set_current_buffer(Buffer buffer, Error *err) /// Gets the current list of window handles /// /// @return The number of windows -Array vim_get_windows(void) +ArrayOf(Window) vim_get_windows(void) { Array rv = ARRAY_DICT_INIT; tabpage_T *tp; @@ -437,7 +437,7 @@ void vim_set_current_window(Window window, Error *err) /// Gets the current list of tabpage handles /// /// @return The number of tab pages -Array vim_get_tabpages(void) +ArrayOf(Tabpage) vim_get_tabpages(void) { Array rv = ARRAY_DICT_INIT; tabpage_T *tp = first_tabpage; -- cgit