diff options
author | Thiago de Arruda <tpadilha84@gmail.com> | 2014-05-07 17:59:16 -0300 |
---|---|---|
committer | Thiago de Arruda <tpadilha84@gmail.com> | 2014-05-12 19:28:30 -0300 |
commit | b3268d071277c8967b3e3ecb60430718e1f36472 (patch) | |
tree | 37fbdeb52835cd3fff0648301292aec12f25bb12 /src | |
parent | fc22317389fa8713f27f5a754ee142ae003f5871 (diff) | |
download | rneovim-b3268d071277c8967b3e3ecb60430718e1f36472.tar.gz rneovim-b3268d071277c8967b3e3ecb60430718e1f36472.tar.bz2 rneovim-b3268d071277c8967b3e3ecb60430718e1f36472.zip |
Refactor API types and prototypes
- Split functions with multiple files in the 'api' subdirectory
- Move/Add more types in the 'api/defs.h' header
- Add more prototypes
- Refactor scripts/msgpack-gen.lua
- Move msgpack modules to 'os' subdirectory
Diffstat (limited to 'src')
-rw-r--r-- | src/CMakeLists.txt | 11 | ||||
-rw-r--r-- | src/api.c | 112 | ||||
-rw-r--r-- | src/api.h | 114 | ||||
-rw-r--r-- | src/api/buffer.c | 87 | ||||
-rw-r--r-- | src/api/buffer.h | 135 | ||||
-rw-r--r-- | src/api/defs.h | 74 | ||||
-rw-r--r-- | src/api/tabpage.c | 32 | ||||
-rw-r--r-- | src/api/tabpage.h | 46 | ||||
-rw-r--r-- | src/api/vim.c | 140 | ||||
-rw-r--r-- | src/api/vim.h | 172 | ||||
-rw-r--r-- | src/api/window.c | 73 | ||||
-rw-r--r-- | src/api/window.h | 105 | ||||
-rw-r--r-- | src/msgpack_rpc.c | 156 | ||||
-rw-r--r-- | src/msgpack_rpc.h | 30 | ||||
-rw-r--r-- | src/os/msgpack_rpc.c | 409 | ||||
-rw-r--r-- | src/os/msgpack_rpc.h | 107 |
16 files changed, 1386 insertions, 417 deletions
diff --git a/src/CMakeLists.txt b/src/CMakeLists.txt index 2d761ee79c..8ee6739a34 100644 --- a/src/CMakeLists.txt +++ b/src/CMakeLists.txt @@ -2,16 +2,16 @@ include(CheckLibraryExists) set(GENERATED_DIR ${PROJECT_BINARY_DIR}/src/auto) set(DISPATCH_GENERATOR ${PROJECT_SOURCE_DIR}/scripts/msgpack-gen.lua) -set(API_HEADER ${PROJECT_SOURCE_DIR}/src/api.h) -set(MSGPACK_RPC_HEADER ${PROJECT_SOURCE_DIR}/src/msgpack_rpc.h) +file(GLOB API_HEADERS api/*.h) +set(MSGPACK_RPC_HEADER ${PROJECT_SOURCE_DIR}/src/os/msgpack_rpc.h) set(MSGPACK_DISPATCH ${GENERATED_DIR}/msgpack_dispatch.c) file(MAKE_DIRECTORY ${GENERATED_DIR}) add_custom_command(OUTPUT ${MSGPACK_DISPATCH} - COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${API_HEADER} ${MSGPACK_DISPATCH} + COMMAND ${LUA_PRG} ${DISPATCH_GENERATOR} ${API_HEADERS} ${MSGPACK_DISPATCH} DEPENDS - ${API_HEADER} + ${API_HEADERS} ${MSGPACK_RPC_HEADER} ${DISPATCH_GENERATOR} ) @@ -30,6 +30,7 @@ list(APPEND NEOVIM_SOURCES "${PROJECT_BINARY_DIR}/config/auto/pathdef.c") list(APPEND NEOVIM_SOURCES "${MSGPACK_DISPATCH}") file( GLOB OS_SOURCES os/*.c ) +file( GLOB API_SOURCES api/*.c ) set(CONV_SRCS api.c @@ -90,7 +91,7 @@ list(APPEND NVIM_LINK_LIBRARIES ${CMAKE_THREAD_LIBS_INIT}) if(NOT DEFINED ENV{SKIP_EXEC}) - add_executable(nvim ${NEOVIM_SOURCES} ${OS_SOURCES}) + add_executable(nvim ${NEOVIM_SOURCES} ${OS_SOURCES} ${API_SOURCES}) target_link_libraries(nvim ${NVIM_LINK_LIBRARIES}) install(TARGETS nvim RUNTIME DESTINATION bin) endif() diff --git a/src/api.c b/src/api.c deleted file mode 100644 index 93aee546c6..0000000000 --- a/src/api.c +++ /dev/null @@ -1,112 +0,0 @@ -#include <stdint.h> -#include <stdlib.h> - -#include "api.h" - -void api_push_keys(char *str) -{ - abort(); -} - -void api_command(char *str) -{ - abort(); -} - -void api_eval(char *str) -{ - abort(); -} - -uint32_t api_bind_eval(char *str) -{ - abort(); -} - -char **api_list_runtime_paths() -{ - abort(); -} - -char **api_list_buffers(void) -{ - abort(); - return NULL; -} - -char **api_list_windows(void) -{ - abort(); - return NULL; -} - -char **api_list_tabpages(void) -{ - abort(); - return NULL; -} - -char *api_get_current_line(void) -{ - abort(); - return NULL; -} - -uint32_t api_get_current_buffer(void) -{ - abort(); - return 0; -} - -uint32_t api_get_current_window(void) -{ - abort(); - return 0; -} - -uint32_t api_get_current_tabpage(void) -{ - abort(); - return 0; -} - -void api_set_current_line(char *line) -{ - abort(); -} - -void api_set_current_buffer(uint32_t id) -{ - abort(); -} - -void api_set_current_window(uint32_t id) -{ - abort(); -} - -void api_set_current_tabpage(uint32_t id) -{ - abort(); -} - -char *api_get_option(char *name) -{ - abort(); - return NULL; -} - -void api_set_option(char *name, char *value) -{ - abort(); -} - -void api_out_write(char *str) -{ - abort(); -} - -void api_err_write(char *str) -{ - abort(); -} diff --git a/src/api.h b/src/api.h deleted file mode 100644 index 39a51b9157..0000000000 --- a/src/api.h +++ /dev/null @@ -1,114 +0,0 @@ -#ifndef NEOVIM_API_H -#define NEOVIM_API_H - -#include <stdint.h> - -/// Send keys to vim input buffer, simulating user input. -/// -/// @param str The keys to send -void api_push_keys(char *str); - -/// Executes an ex-mode command str -/// -/// @param str The command str -void api_command(char *str); - -/// Evaluates the expression str using the vim internal expression -/// evaluator (see |expression|). Returns the expression result as: -/// - a string if the Vim expression evaluates to a string or number -/// - a list if the Vim expression evaluates to a Vim list -/// - a dictionary if the Vim expression evaluates to a Vim dictionary -/// Dictionaries and lists are recursively expanded. -/// -/// @param str The expression str -void api_eval(char *str); - -/// Like eval, but returns special object ids that can be used to interact -/// with the real objects remotely. -// -/// @param str The expression str -uint32_t api_bind_eval(char *str); - -/// Returns a list of paths contained in 'runtimepath' -/// -/// @return The list of paths -char **api_list_runtime_paths(void); - -/// Return a list of buffers -/// -/// @return the list of buffers -char **api_list_buffers(void); - -/// Return a list of windows -/// -/// @return the list of windows -char **api_list_windows(void); - -/// Return a list of tabpages -/// -/// @return the list of tabpages -char **api_list_tabpages(void); - -/// Return the current line -/// -/// @return The current line -char *api_get_current_line(void); - -/// Return the current buffer -/// -/// @return The current buffer -uint32_t api_get_current_buffer(void); - -/// Return the current window -/// -/// @return The current window -uint32_t api_get_current_window(void); - -/// Return the current tabpage -/// -/// @return The current tabpage -uint32_t api_get_current_tabpage(void); - -/// Sets the current line -/// -/// @param line The line contents -void api_set_current_line(char *line); - -/// Sets the current buffer -/// -/// @param id The buffer id -void api_set_current_buffer(uint32_t id); - -/// Sets the current window -/// -/// @param id The window id -void api_set_current_window(uint32_t id); - -/// Sets the current tabpage -/// -/// @param id The tabpage id -void api_set_current_tabpage(uint32_t id); - -/// Get an option value string -/// -/// @param name The option name -char *api_get_option(char *name); - -/// Get an option value string -/// -/// @param name The option name -/// @param value The new option value -void api_set_option(char *name, char *value); - -/// Write a message to vim output buffer -/// -/// @param str The message -void api_out_write(char *str); - -/// Write a message to vim error buffer -/// -/// @param str The message -void api_err_write(char *str); - -#endif // NEOVIM_API_H - diff --git a/src/api/buffer.c b/src/api/buffer.c new file mode 100644 index 0000000000..743d8c4729 --- /dev/null +++ b/src/api/buffer.c @@ -0,0 +1,87 @@ +#include <stdint.h> +#include <stdlib.h> + +#include "api/buffer.h" +#include "api/defs.h" + +int64_t buffer_get_length(Buffer buffer, Error *err) +{ + abort(); +} + +String buffer_get_line(Buffer buffer, int64_t index, Error *err) +{ + abort(); +} + +void buffer_set_line(Buffer buffer, int64_t index, String line, Error *err) +{ + abort(); +} + +StringArray buffer_get_slice(Buffer buffer, + int64_t start, + int64_t end, + Error *err) +{ + abort(); +} + +void buffer_set_slice(Buffer buffer, + int64_t start, + int64_t end, + StringArray lines, + Error *err) +{ + abort(); +} + +Object buffer_get_var(Buffer buffer, String name, Error *err) +{ + abort(); +} + +void buffer_set_var(Buffer buffer, String name, Object value, Error *err) +{ + abort(); +} + +String buffer_get_option(Buffer buffer, String name, Error *err) +{ + abort(); +} + +void buffer_set_option(Buffer buffer, String name, String value, Error *err) +{ + abort(); +} + +void buffer_del_option(Buffer buffer, String name, Error *err) +{ + abort(); +} + +String buffer_get_name(Buffer buffer, Error *err) +{ + abort(); +} + +void buffer_set_name(Buffer buffer, String name, Error *err) +{ + abort(); +} + +bool buffer_is_valid(Buffer buffer) +{ + abort(); +} + +void buffer_insert(Buffer buffer, StringArray lines, int64_t lnum, Error *err) +{ + abort(); +} + +Position buffer_mark(Buffer buffer, String name, Error *err) +{ + abort(); +} diff --git a/src/api/buffer.h b/src/api/buffer.h new file mode 100644 index 0000000000..14e91c6382 --- /dev/null +++ b/src/api/buffer.h @@ -0,0 +1,135 @@ +#ifndef NEOVIM_API_BUFFER_H +#define NEOVIM_API_BUFFER_H + +#include <stdint.h> +#include <stdbool.h> + +#include "api/defs.h" + +/// Gets the buffer line count +/// +/// @param buffer The buffer handle +/// @param[out] err Details of an error that may have occurred +/// @return The line count +int64_t buffer_get_length(Buffer buffer, Error *err); + +/// Gets a buffer line +/// +/// @param buffer The buffer handle +/// @param index The line index +/// @param[out] err Details of an error that may have occurred +/// @return The line string +String buffer_get_line(Buffer buffer, int64_t index, Error *err); + +/// Sets a buffer line +/// +/// @param buffer The buffer handle +/// @param index The line index +/// @param line The new line +/// @param[out] err Details of an error that may have occurred +void buffer_set_line(Buffer buffer, int64_t index, String line, Error *err); + +/// Retrieves a line range from the buffer +/// +/// @param buffer The buffer handle +/// @param start The first line index +/// @param end The last line index(exclusive) +/// @param[out] err Details of an error that may have occurred +/// @return An array of lines +StringArray buffer_get_slice(Buffer buffer, + int64_t start, + int64_t end, + Error *err); + +/// Replaces a line range on the buffer +/// +/// @param buffer The buffer handle +/// @param start The first line index +/// @param end The last line index(exclusive) +/// @param lines An array of lines to use as replacement +/// @param[out] err Details of an error that may have occurred +void buffer_set_slice(Buffer buffer, + int64_t start, + int64_t end, + StringArray lines, + Error *err); + +/// Gets a buffer variable +/// +/// @param buffer The buffer handle +/// @param name The variable name +/// @param[out] err Details of an error that may have occurred +/// @return The variable value +Object buffer_get_var(Buffer buffer, String name, Error *err); + +/// Sets a buffer variable +/// +/// @param buffer The buffer handle +/// @param name The variable name +/// @param value The variable value +/// @param[out] err Details of an error that may have occurred +void buffer_set_var(Buffer buffer, String name, Object value, Error *err); + +/// Gets a buffer option value +/// +/// @param buffer The buffer handle +/// @param name The option name +/// @param[out] err Details of an error that may have occurred +/// @return The option value +String buffer_get_option(Buffer buffer, String name, Error *err); + +/// Sets a buffer option value +/// +/// @param buffer The buffer handle +/// @param name The option name +/// @param value The option value +/// @param[out] err Details of an error that may have occurred +void buffer_set_option(Buffer buffer, String name, String value, Error *err); + +/// Deletes a buffer option(falls back to the global value if available) +/// +/// @param buffer The buffer handle +/// @param name The option name +/// @param[out] err Details of an error that may have occurred +void buffer_del_option(Buffer buffer, String name, Error *err); + +/// Gets the full file name for the buffer +/// +/// @param buffer The buffer handle +/// @param[out] err Details of an error that may have occurred +/// @return The buffer name +String buffer_get_name(Buffer buffer, Error *err); + +/// Sets the full file name for a buffer +/// +/// @param buffer The buffer handle +/// @param name The buffer name +/// @param[out] err Details of an error that may have occurred +void buffer_set_name(Buffer buffer, String name, Error *err); + +/// Checks if a buffer is valid +/// +/// @param buffer The buffer handle +/// @return true if the buffer is valid, false otherwise +bool buffer_is_valid(Buffer buffer); + +/// Inserts a sequence of lines to a buffer at a certain index +/// +/// @param buffer The buffer handle +/// @param lines An array of lines +/// @param lnum Insert the lines before `lnum`. If negative, it will append +/// to the end of the buffer. +/// @param[out] err Details of an error that may have occurred +void buffer_insert(Buffer buffer, StringArray lines, int64_t lnum, Error *err); + +/// Creates a mark in the buffer and returns a tuple(row, col) representing +/// the position of the named mark +/// +/// @param buffer The buffer handle +/// @param name The mark's name +/// @param[out] err Details of an error that may have occurred +/// @return The (row, col) tuple +Position buffer_mark(Buffer buffer, String name, Error *err); + +#endif // NEOVIM_API_BUFFER_H + diff --git a/src/api/defs.h b/src/api/defs.h new file mode 100644 index 0000000000..fc1ac655ea --- /dev/null +++ b/src/api/defs.h @@ -0,0 +1,74 @@ +#ifndef NEOVIM_API_DEFS_H +#define NEOVIM_API_DEFS_H + +#include <stdint.h> +#include <string.h> + +// Basic types +typedef struct { + char msg[256]; + bool set; +} Error; + +typedef struct { + char *data; + size_t size; +} String; + +typedef uint16_t Buffer; +typedef uint16_t Window; +typedef uint16_t Tabpage; + +typedef struct object Object; + +typedef struct { + String *items; + size_t size; +} StringArray; + +typedef struct { + uint16_t row, col; +} Position; + +typedef struct { + Object *items; + size_t size; +} Array; + +typedef struct key_value_pair KeyValuePair; + +typedef struct { + KeyValuePair *items; + size_t size; +} Dictionary; + +typedef enum { + kObjectTypeNil, + kObjectTypeBool, + kObjectTypeInt, + kObjectTypeFloat, + kObjectTypeString, + kObjectTypeArray, + kObjectTypeDictionary +} ObjectType; + +struct object { + ObjectType type; + union { + bool boolean; + int64_t integer; + double floating_point; + String string; + Array array; + Dictionary dictionary; + } data; +}; + +struct key_value_pair { + String key; + Object value; +}; + + +#endif // NEOVIM_API_DEFS_H + diff --git a/src/api/tabpage.c b/src/api/tabpage.c new file mode 100644 index 0000000000..1bbde0d986 --- /dev/null +++ b/src/api/tabpage.c @@ -0,0 +1,32 @@ +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +#include "api/tabpage.h" +#include "api/defs.h" + +int64_t tabpage_get_window_count(Tabpage tabpage, Error *err) +{ + abort(); +} + +Object tabpage_get_var(Tabpage tabpage, String name, Error *err) +{ + abort(); +} + +void tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err) +{ + abort(); +} + +Window tabpage_get_buffer(Tabpage tabpage, Error *err) +{ + abort(); +} + +bool tabpage_is_valid(Tabpage tabpage) +{ + abort(); +} + diff --git a/src/api/tabpage.h b/src/api/tabpage.h new file mode 100644 index 0000000000..5bfbf6cda3 --- /dev/null +++ b/src/api/tabpage.h @@ -0,0 +1,46 @@ +#ifndef NEOVIM_API_TABPAGE_H +#define NEOVIM_API_TABPAGE_H + +#include <stdint.h> +#include <stdbool.h> + +#include "api/defs.h" + +/// Gets the number of windows in a tabpage +/// +/// @param tabpage The tabpage +/// @param[out] err Details of an error that may have occurred +/// @return The number of windows in `tabpage` +int64_t tabpage_get_window_count(Tabpage tabpage, Error *err); + +/// Gets a tabpage variable +/// +/// @param tabpage The tab page handle +/// @param name The variable name +/// @param[out] err Details of an error that may have occurred +/// @return The variable value +Object tabpage_get_var(Tabpage tabpage, String name, Error *err); + +/// Sets a tabpage variable +/// +/// @param tabpage andle +/// @param name The variable name +/// @param value The variable value +/// @param[out] err Details of an error that may have occurred +void tabpage_set_var(Tabpage tabpage, String name, Object value, Error *err); + +/// Gets the current window in a tab page +/// +/// @param tabpage The tab page handle +/// @param[out] err Details of an error that may have occurred +/// @return The Window handle +Window tabpage_get_buffer(Tabpage tabpage, Error *err); + +/// Checks if a tab page is valid +/// +/// @param tabpage The tab page handle +/// @return true if the tab page is valid, false otherwise +bool tabpage_is_valid(Tabpage tabpage); + +#endif // NEOVIM_API_TABPAGE_H + diff --git a/src/api/vim.c b/src/api/vim.c new file mode 100644 index 0000000000..aef4276f5b --- /dev/null +++ b/src/api/vim.c @@ -0,0 +1,140 @@ +#include <stdint.h> +#include <stdlib.h> + +#include "api/vim.h" +#include "api/defs.h" + +void vim_push_keys(String str) +{ + abort(); +} + +void vim_command(String str, Error *err) +{ + abort(); +} + +Object vim_eval(String str, Error *err) +{ + abort(); +} + +int64_t vim_strwidth(String str) +{ + abort(); +} + +StringArray vim_list_runtime_paths(void) +{ + abort(); +} + +void vim_change_directory(String dir) +{ + abort(); +} + +String vim_get_current_line(void) +{ + abort(); +} + +void vim_set_current_line(String line) +{ + abort(); +} + +Object vim_get_var(bool special, String name, Error *err) +{ + abort(); +} + +void vim_set_var(bool special, String name, Object value, Error *err) +{ + abort(); +} + +String vim_get_option(String name, Error *err) +{ + abort(); +} + +void vim_set_option(String name, String value, Error *err) +{ + abort(); +} + +void vim_del_option(String name, Error *err) +{ + abort(); +} + +void vim_out_write(String str) +{ + abort(); +} + +void vim_err_write(String str) +{ + abort(); +} + +int64_t vim_get_buffer_count(void) +{ + abort(); +} + +Buffer vim_get_buffer(int64_t num, Error *err) +{ + abort(); +} + +Buffer vim_get_current_buffer(void) +{ + abort(); +} + +void vim_set_current_buffer(Buffer buffer) +{ + abort(); +} + +int64_t vim_get_window_count(void) +{ + abort(); +} + +Window vim_get_window(int64_t num, Error *err) +{ + abort(); +} + +Window vim_get_current_window(void) +{ + abort(); +} + +void vim_set_current_window(Window window) +{ + abort(); +} + +int64_t vim_get_tabpage_count(void) +{ + abort(); +} + +Tabpage vim_get_tabpage(int64_t num, Error *err) +{ + abort(); +} + +Tabpage vim_get_current_tabpage(void) +{ + abort(); +} + +void vim_set_current_tabpage(Tabpage tabpage) +{ + abort(); +} diff --git a/src/api/vim.h b/src/api/vim.h new file mode 100644 index 0000000000..cc373e1cc2 --- /dev/null +++ b/src/api/vim.h @@ -0,0 +1,172 @@ +#ifndef NEOVIM_API_VIM_H +#define NEOVIM_API_VIM_H + +#include <stdint.h> +#include <stdbool.h> + +#include "api/defs.h" + +/// Send keys to vim input buffer, simulating user input. +/// +/// @param str The keys to send +void vim_push_keys(String str); + +/// Executes an ex-mode command str +/// +/// @param str The command str +/// @param[out] err Details of an error that may have occurred +void vim_command(String str, Error *err); + +/// Evaluates the expression str using the vim internal expression +/// evaluator (see |expression|). Returns the expression result as: +/// - a string if the Vim expression evaluates to a string or number +/// - a list if the Vim expression evaluates to a Vim list +/// - a dictionary if the Vim expression evaluates to a Vim dictionary +/// Dictionaries and lists are recursively expanded. +/// +/// @param str The expression str +/// @param[out] err Details of an error that may have occurred +/// @return The expanded object +Object vim_eval(String str, Error *err); + +/// Calculates the number of display cells `str` occupies, tab is counted as +/// one cell. +/// +/// @param str Some text +/// @return The number of cells +int64_t vim_strwidth(String str); + +/// Returns a list of paths contained in 'runtimepath' +/// +/// @return The list of paths +StringArray vim_list_runtime_paths(void); + +/// Changes vim working directory +/// +/// @param dir The new working directory +void vim_change_directory(String dir); + +/// Return the current line +/// +/// @return The current line string +String vim_get_current_line(void); + +/// Sets the current line +/// +/// @param line The line contents +void vim_set_current_line(String line); + +/// Gets a global or special variable +/// +/// @param special If it's a special(:v) variable +/// @param name The variable name +/// @param[out] err Details of an error that may have occurred +/// @return The variable value +Object vim_get_var(bool special, String name, Error *err); + +/// Sets a global or special variable +/// +/// @param special If it's a special(:v) variable +/// @param name The variable name +/// @param value The variable value +/// @param[out] err Details of an error that may have occurred +void vim_set_var(bool special, String name, Object value, Error *err); + +/// Get an option value string +/// +/// @param name The option name +/// @param[out] err Details of an error that may have occurred +/// @return The option value +String vim_get_option(String name, Error *err); + +/// Sets an option value +/// +/// @param name The option name +/// @param value The new option value +/// @param[out] err Details of an error that may have occurred +void vim_set_option(String name, String value, Error *err); + +/// Deletes an option, falling back to the default value +/// +/// @param name The option name +/// @param[out] err Details of an error that may have occurred +void vim_del_option(String name, Error *err); + +/// Write a message to vim output buffer +/// +/// @param str The message +void vim_out_write(String str); + +/// Write a message to vim error buffer +/// +/// @param str The message +void vim_err_write(String str); + +/// Gets the number of buffers +/// +/// @return The number of buffers +int64_t vim_get_buffer_count(void); + +/// Gets a buffer by index +/// +/// @param num The buffer number +/// @param[out] err Details of an error that may have occurred +/// @return The buffer handle +Buffer vim_get_buffer(int64_t num, Error *err); + +/// Return the current buffer +/// +/// @reqturn The buffer handle +Buffer vim_get_current_buffer(void); + +/// Sets the current buffer +/// +/// @param id The buffer handle +void vim_set_current_buffer(Buffer buffer); + +/// Gets the number of windows +/// +/// @return The number of windows +int64_t vim_get_window_count(void); + +/// Gets a window by index +/// +/// @param num The window number +/// @param[out] err Details of an error that may have occurred +/// @return The window handle +Window vim_get_window(int64_t num, Error *err); + +/// Return the current window +/// +/// @return The window handle +Window vim_get_current_window(void); + +/// Sets the current window +/// +/// @param handle The window handle +void vim_set_current_window(Window window); + +/// Gets the number of tab pages +/// +/// @return The number of tab pages +int64_t vim_get_tabpage_count(void); + +/// Gets a tab page by index +/// +/// @param num The tabpage number +/// @param[out] err Details of an error that may have occurred +/// @return The tab page handle +Tabpage vim_get_tabpage(int64_t num, Error *err); + +/// Return the current tab page +/// +/// @return The tab page handle +Tabpage vim_get_current_tabpage(void); + +/// Sets the current tab page +/// +/// @param handle The tab page handle +void vim_set_current_tabpage(Tabpage tabpage); + +#endif // NEOVIM_API_VIM_H + diff --git a/src/api/window.c b/src/api/window.c new file mode 100644 index 0000000000..fe59c2dc8b --- /dev/null +++ b/src/api/window.c @@ -0,0 +1,73 @@ +#include <stdbool.h> +#include <stdint.h> +#include <stdlib.h> + +#include "api/window.h" +#include "api/defs.h" + + +Buffer window_get_buffer(Window window, Error *err) +{ + abort(); +} + +Position window_get_cursor(Window window, Error *err) +{ + abort(); +} + +void window_set_cursor(Window window, Position pos, Error *err) +{ + abort(); +} + +int64_t window_get_height(Window window, Error *err) +{ + abort(); +} + +void window_set_height(Window window, int64_t height, Error *err) +{ + abort(); +} + +int64_t window_get_width(Window window, Error *err) +{ + abort(); +} + +Object window_get_var(Window window, String name, Error *err) +{ + abort(); +} + +void window_set_var(Window window, String name, Object value, Error *err) +{ + abort(); +} + +String window_get_option(Window window, String name, Error *err) +{ + abort(); +} + +void window_set_option(Window window, String name, String value, Error *err) +{ + abort(); +} + +Position window_get_pos(Window window, Error *err) +{ + abort(); +} + +Tabpage window_get_tabpage(Window window, Error *err) +{ + abort(); +} + +bool window_is_valid(Window window) +{ + abort(); +} + diff --git a/src/api/window.h b/src/api/window.h new file mode 100644 index 0000000000..c502b23951 --- /dev/null +++ b/src/api/window.h @@ -0,0 +1,105 @@ +#ifndef NEOVIM_API_WINDOW_H +#define NEOVIM_API_WINDOW_H + +#include <stdint.h> +#include <stdbool.h> + +#include "api/defs.h" + +/// Gets the current buffer in a window +/// +/// @param window The window handle +/// @param[out] err Details of an error that may have occurred +/// @return The buffer handle +Buffer window_get_buffer(Window window, Error *err); + +/// Gets the cursor position in the window +/// +/// @param window The window handle +/// @param[out] err Details of an error that may have occurred +/// @return the (row, col) tuple +Position window_get_cursor(Window window, Error *err); + +/// Sets the cursor position in the window +/// +/// @param window The window handle +/// @param pos the (row, col) tuple representing the new position +/// @param[out] err Details of an error that may have occurred +void window_set_cursor(Window window, Position pos, Error *err); + +/// Gets the window height +/// +/// @param window The window handle +/// @param[out] err Details of an error that may have occurred +/// @return the height in rows +int64_t window_get_height(Window window, Error *err); + +/// Sets the window height. This will only succeed if the screen is split +/// horizontally. +/// +/// @param window The window handle +/// @param height the new height in rows +/// @param[out] err Details of an error that may have occurred +void window_set_height(Window window, int64_t height, Error *err); + +/// Gets the window width +/// +/// @param window The window handle +/// @param[out] err Details of an error that may have occurred +/// @return the width in columns +int64_t window_get_width(Window window, Error *err); + +/// Gets a window variable +/// +/// @param window The window handle +/// @param name The variable name +/// @param[out] err Details of an error that may have occurred +/// @return The variable value +Object window_get_var(Window window, String name, Error *err); + +/// Sets a window variable +/// +/// @param window The window handle +/// @param name The variable name +/// @param value The variable value +/// @param[out] err Details of an error that may have occurred +void window_set_var(Window window, String name, Object value, Error *err); + +/// Gets a window option value +/// +/// @param window The window handle +/// @param name The option name +/// @param[out] err Details of an error that may have occurred +/// @return The option value +String window_get_option(Window window, String name, Error *err); + +/// Sets a window option value +/// +/// @param window The window handle +/// @param name The option name +/// @param value The option value +/// @param[out] err Details of an error that may have occurred +void window_set_option(Window window, String name, String value, Error *err); + +/// Gets the window position in display cells. First position is zero. +/// +/// @param window The window handle +/// @param[out] err Details of an error that may have occurred +/// @return The (row, col) tuple with the window position +Position window_get_pos(Window window, Error *err); + +/// Gets the window tab page +/// +/// @param window The window handle +/// @param[out] err Details of an error that may have occurred +/// @return The tab page that contains the window +Tabpage window_get_tabpage(Window window, Error *err); + +/// Checks if a window is valid +/// +/// @param window The window handle +/// @return true if the window is valid, false otherwise +bool window_is_valid(Window window); + +#endif // NEOVIM_API_WINDOW_H + diff --git a/src/msgpack_rpc.c b/src/msgpack_rpc.c deleted file mode 100644 index 5e36830132..0000000000 --- a/src/msgpack_rpc.c +++ /dev/null @@ -1,156 +0,0 @@ -#include <msgpack.h> - -#include "msgpack_rpc.h" -#include "vim.h" -#include "memory.h" - - -bool msgpack_rpc_call(msgpack_object *req, msgpack_packer *res) -{ - // Validate the basic structure of the msgpack-rpc payload - if (req->type != MSGPACK_OBJECT_ARRAY) { - return msgpack_rpc_error(req, res, "Request is not an array"); - } - - if (req->via.array.size != 4) { - char error_msg[256]; - snprintf(error_msg, - sizeof(error_msg), - "Request array size is %u, it should be 4", - req->via.array.size); - return msgpack_rpc_error(req, res, error_msg); - } - - if (req->via.array.ptr[0].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { - return msgpack_rpc_error(req, res, "Message type must be an integer"); - } - - if (req->via.array.ptr[0].via.u64 != 0) { - return msgpack_rpc_error(req, res, "Message type must be 0"); - } - - if (req->via.array.ptr[1].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { - return msgpack_rpc_error(req, res, "Id must be a positive integer"); - } - - if (req->via.array.ptr[2].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { - return msgpack_rpc_error(req, res, "Method id must be a positive integer"); - } - - if (req->via.array.ptr[3].type != MSGPACK_OBJECT_ARRAY) { - return msgpack_rpc_error(req, res, "Paremeters must be an array"); - } - - // dispatch the message - return msgpack_rpc_dispatch(req, res); -} - -void msgpack_rpc_response(msgpack_object *req, msgpack_packer *res) -{ - // Array of size 4 - msgpack_pack_array(res, 4); - // Response type is 1 - msgpack_pack_int(res, 1); - // Msgid is the same as the request - msgpack_pack_int(res, req->via.array.ptr[1].via.u64); -} - -void msgpack_rpc_success(msgpack_object *req, msgpack_packer *res) -{ - msgpack_rpc_response(req, res); - // Nil error - msgpack_pack_nil(res); -} - -bool msgpack_rpc_error(msgpack_object *req, msgpack_packer *res, char *msg) -{ - size_t len = strlen(msg); - - msgpack_rpc_response(req, res); - msgpack_pack_raw(res, len); - msgpack_pack_raw_body(res, msg, len); - // Nil result - msgpack_pack_nil(res); - - return false; -} - -char **msgpack_rpc_array_argument(msgpack_object *obj) -{ - uint32_t i; - char **rv = xmalloc(obj->via.array.size + 1); - - for (i = 0; i < obj->via.array.size; i++) { - rv[i] = msgpack_rpc_raw_argument(obj->via.array.ptr + i); - } - - rv[i] = NULL; - - return rv; -} - -char *msgpack_rpc_raw_argument(msgpack_object *obj) -{ - char *rv = xmalloc(obj->via.raw.size + 1); - memcpy(rv, obj->via.raw.ptr, obj->via.raw.size); - rv[obj->via.raw.size] = NUL; - - return rv; -} - -uint32_t msgpack_rpc_integer_argument(msgpack_object *obj) -{ - return obj->via.u64; -} - -bool msgpack_rpc_array_result(char **result, - msgpack_object *req, - msgpack_packer *res) -{ - char **ptr; - uint32_t array_size; - - // Count number of items in the array - for (ptr = result; *ptr != NULL; ptr++) continue; - - msgpack_rpc_success(req, res); - // Subtract 1 to exclude the NULL slot - array_size = ptr - result - 1; - msgpack_pack_array(res, array_size); - - // push each string to the array - for (ptr = result; *ptr != NULL; ptr++) { - size_t raw_size = strlen(*ptr); - msgpack_pack_raw(res, raw_size); - msgpack_pack_raw_body(res, *ptr, raw_size); - } - - return true; -} - -bool msgpack_rpc_raw_result(char *result, - msgpack_object *req, - msgpack_packer *res) -{ - size_t raw_size = strlen(result); - msgpack_rpc_success(req, res); - msgpack_pack_raw(res, raw_size); - msgpack_pack_raw_body(res, result, raw_size); - return true; -} - -bool msgpack_rpc_integer_result(uint32_t result, - msgpack_object *req, - msgpack_packer *res) -{ - msgpack_rpc_success(req, res); - msgpack_pack_int(res, result); - return true; -} - -bool msgpack_rpc_void_result(msgpack_object *req, msgpack_packer *res) -{ - msgpack_rpc_success(req, res); - msgpack_pack_nil(res); - return true; -} diff --git a/src/msgpack_rpc.h b/src/msgpack_rpc.h deleted file mode 100644 index f713e5eeb5..0000000000 --- a/src/msgpack_rpc.h +++ /dev/null @@ -1,30 +0,0 @@ -#ifndef NEOVIM_MSGPACK_RPC_H -#define NEOVIM_MSGPACK_RPC_H - -#include <stdint.h> -#include <stdbool.h> - -#include <msgpack.h> - -bool msgpack_rpc_call(msgpack_object *req, msgpack_packer *res); -bool msgpack_rpc_dispatch(msgpack_object *req, msgpack_packer *res); -void msgpack_rpc_response(msgpack_object *req, msgpack_packer *res); -void msgpack_rpc_success(msgpack_object *req, msgpack_packer *res); -bool msgpack_rpc_error(msgpack_object *req, msgpack_packer *res, char *msg); -char **msgpack_rpc_array_argument(msgpack_object *obj); -char *msgpack_rpc_raw_argument(msgpack_object *obj); -uint32_t msgpack_rpc_integer_argument(msgpack_object *obj); -bool msgpack_rpc_array_result(char **result, - msgpack_object *req, - msgpack_packer *res); -bool msgpack_rpc_raw_result(char *result, - msgpack_object *req, - msgpack_packer *res); -bool msgpack_rpc_integer_result(uint32_t result, - msgpack_object *req, - msgpack_packer *res); -bool msgpack_rpc_void_result(msgpack_object *req, msgpack_packer *res); - - -#endif // NEOVIM_MSGPACK_RPC_H - diff --git a/src/os/msgpack_rpc.c b/src/os/msgpack_rpc.c new file mode 100644 index 0000000000..0d5e3ef5da --- /dev/null +++ b/src/os/msgpack_rpc.c @@ -0,0 +1,409 @@ +#include <msgpack.h> + +#include "msgpack_rpc.h" +#include "vim.h" +#include "memory.h" + +static bool msgpack_rpc_to_uint16_t(msgpack_object *obj, uint16_t *arg); + +void msgpack_rpc_call(msgpack_object *req, msgpack_packer *res) +{ + // The initial response structure is the same no matter what happens, + // we set it up here + // Array of size 4 + msgpack_pack_array(res, 4); + // Response type is 1 + msgpack_pack_int(res, 1); + + // Validate the basic structure of the msgpack-rpc payload + if (req->type != MSGPACK_OBJECT_ARRAY) { + msgpack_pack_int(res, 0); // no message id yet + msgpack_rpc_error("Request is not an array", res); + return; + } + + if (req->via.array.size != 4) { + msgpack_pack_int(res, 0); // no message id yet + char error_msg[256]; + snprintf(error_msg, + sizeof(error_msg), + "Request array size is %u, it should be 4", + req->via.array.size); + msgpack_rpc_error(error_msg, res); + } + + if (req->via.array.ptr[1].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { + msgpack_pack_int(res, 0); // no message id yet + msgpack_rpc_error("Id must be a positive integer", res); + } + + // Set the response id, which is the same as the request + msgpack_pack_int(res, req->via.array.ptr[1].via.u64); + + if (req->via.array.ptr[0].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { + msgpack_rpc_error("Message type must be an integer", res); + return; + } + + if (req->via.array.ptr[0].via.u64 != 0) { + msgpack_rpc_error("Message type must be 0", res); + return; + } + + if (req->via.array.ptr[2].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { + msgpack_rpc_error("Method id must be a positive integer", res); + return; + } + + if (req->via.array.ptr[3].type != MSGPACK_OBJECT_ARRAY) { + msgpack_rpc_error("Paremeters must be an array", res); + return; + } + + // dispatch the message + msgpack_rpc_dispatch(req, res); +} + +void msgpack_rpc_error(char *msg, msgpack_packer *res) +{ + size_t len = strlen(msg); + + // error message + msgpack_pack_raw(res, len); + msgpack_pack_raw_body(res, msg, len); + // Nil result + msgpack_pack_nil(res); +} + +bool msgpack_rpc_to_bool(msgpack_object *obj, bool *arg) +{ + *arg = obj->via.boolean; + return obj->type == MSGPACK_OBJECT_BOOLEAN; +} + +bool msgpack_rpc_to_int64_t(msgpack_object *obj, int64_t *arg) +{ + *arg = obj->via.i64; + return obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER + || obj->type == MSGPACK_OBJECT_NEGATIVE_INTEGER; +} + +bool msgpack_rpc_to_double(msgpack_object *obj, double *arg) +{ + *arg = obj->via.dec; + return obj->type == MSGPACK_OBJECT_DOUBLE; +} + +bool msgpack_rpc_to_string(msgpack_object *obj, String *arg) +{ + arg->data = (char *)obj->via.raw.ptr; + arg->size = obj->via.raw.size; + return obj->type == MSGPACK_OBJECT_RAW; +} + +bool msgpack_rpc_to_buffer(msgpack_object *obj, Buffer *arg) +{ + return msgpack_rpc_to_uint16_t(obj, arg); +} + +bool msgpack_rpc_to_window(msgpack_object *obj, Window *arg) +{ + return msgpack_rpc_to_uint16_t(obj, arg); +} + +bool msgpack_rpc_to_tabpage(msgpack_object *obj, Tabpage *arg) +{ + return msgpack_rpc_to_uint16_t(obj, arg); +} + +bool msgpack_rpc_to_object(msgpack_object *obj, Object *arg) +{ + switch (obj->type) { + case MSGPACK_OBJECT_NIL: + arg->type = kObjectTypeNil; + return true; + + case MSGPACK_OBJECT_BOOLEAN: + arg->type = kObjectTypeBool; + return msgpack_rpc_to_bool(obj, &arg->data.boolean); + + case MSGPACK_OBJECT_POSITIVE_INTEGER: + case MSGPACK_OBJECT_NEGATIVE_INTEGER: + arg->type = kObjectTypeInt; + return msgpack_rpc_to_int64_t(obj, &arg->data.integer); + + case MSGPACK_OBJECT_DOUBLE: + arg->type = kObjectTypeFloat; + return msgpack_rpc_to_double(obj, &arg->data.floating_point); + + case MSGPACK_OBJECT_RAW: + arg->type = kObjectTypeString; + return msgpack_rpc_to_string(obj, &arg->data.string); + + case MSGPACK_OBJECT_ARRAY: + arg->type = kObjectTypeArray; + return msgpack_rpc_to_array(obj, &arg->data.array); + + case MSGPACK_OBJECT_MAP: + arg->type = kObjectTypeDictionary; + return msgpack_rpc_to_dictionary(obj, &arg->data.dictionary); + + default: + return false; + } +} + +bool msgpack_rpc_to_stringarray(msgpack_object *obj, StringArray *arg) +{ + if (obj->type != MSGPACK_OBJECT_ARRAY) { + return false; + } + + arg->size = obj->via.array.size; + arg->items = xcalloc(obj->via.array.size, sizeof(String)); + + for (uint32_t i = 0; i < obj->via.array.size; i++) { + if (!msgpack_rpc_to_string(obj->via.array.ptr + i, &arg->items[i])) { + return false; + } + } + + return true; +} + +bool msgpack_rpc_to_position(msgpack_object *obj, Position *arg) +{ + // positions are represented by integer arrays of size 2 + if (obj->type != MSGPACK_OBJECT_ARRAY + || obj->via.array.size != 2 + || obj->via.array.ptr[0].type != MSGPACK_OBJECT_POSITIVE_INTEGER + || obj->via.array.ptr[1].type != MSGPACK_OBJECT_POSITIVE_INTEGER) { + return false; + } + + arg->row = obj->via.array.ptr[0].via.u64; + arg->col = obj->via.array.ptr[1].via.u64; + + return true; +} + + +bool msgpack_rpc_to_array(msgpack_object *obj, Array *arg) +{ + if (obj->type != MSGPACK_OBJECT_ARRAY) { + return false; + } + + arg->size = obj->via.array.size; + arg->items = xcalloc(obj->via.array.size, sizeof(Object)); + + for (uint32_t i = 0; i < obj->via.array.size; i++) { + if (!msgpack_rpc_to_object(obj->via.array.ptr + i, &arg->items[i])) { + return false; + } + } + + return true; +} + +bool msgpack_rpc_to_dictionary(msgpack_object *obj, Dictionary *arg) +{ + if (obj->type != MSGPACK_OBJECT_MAP) { + return false; + } + + arg->size = obj->via.array.size; + arg->items = xcalloc(obj->via.map.size, sizeof(KeyValuePair)); + + + for (uint32_t i = 0; i < obj->via.map.size; i++) { + if (!msgpack_rpc_to_string(&obj->via.map.ptr[i].key, + &arg->items[i].key)) { + return false; + } + + if (!msgpack_rpc_to_object(&obj->via.map.ptr[i].val, + &arg->items[i].value)) { + return false; + } + } + + return true; +} + +void msgpack_rpc_from_bool(bool result, msgpack_packer *res) +{ + if (result) { + msgpack_pack_true(res); + } else { + msgpack_pack_false(res); + } +} + +void msgpack_rpc_from_int64_t(int64_t result, msgpack_packer *res) +{ + msgpack_pack_int64(res, result); +} + +void msgpack_rpc_from_uint64_t(uint64_t result, msgpack_packer *res) +{ + msgpack_pack_uint64(res, result); +} + +void msgpack_rpc_from_double(double result, msgpack_packer *res) +{ + msgpack_pack_double(res, result); +} + +void msgpack_rpc_from_string(String result, msgpack_packer *res) +{ + msgpack_pack_raw(res, result.size); + msgpack_pack_raw_body(res, result.data, result.size); +} + +void msgpack_rpc_from_buffer(Buffer result, msgpack_packer *res) +{ + msgpack_rpc_from_uint64_t(result, res); +} + +void msgpack_rpc_from_window(Window result, msgpack_packer *res) +{ + msgpack_rpc_from_uint64_t(result, res); +} + +void msgpack_rpc_from_tabpage(Tabpage result, msgpack_packer *res) +{ + msgpack_rpc_from_uint64_t(result, res); +} + +void msgpack_rpc_from_object(Object result, msgpack_packer *res) +{ + + switch (result.type) { + case kObjectTypeNil: + msgpack_pack_nil(res); + break; + + case kObjectTypeBool: + msgpack_rpc_from_bool(result.data.boolean, res); + break; + + case kObjectTypeInt: + msgpack_rpc_from_int64_t(result.data.integer, res); + break; + + case kObjectTypeFloat: + msgpack_rpc_from_double(result.data.floating_point, res); + break; + + case kObjectTypeString: + msgpack_rpc_from_string(result.data.string, res); + break; + + case kObjectTypeArray: + msgpack_rpc_from_array(result.data.array, res); + break; + + case kObjectTypeDictionary: + msgpack_rpc_from_dictionary(result.data.dictionary, res); + break; + + default: + abort(); + } +} + +void msgpack_rpc_from_stringarray(StringArray result, msgpack_packer *res) +{ + msgpack_pack_array(res, result.size); + + for (size_t i = 0; i < result.size; i++) { + msgpack_rpc_from_string(result.items[i], res); + } +} + +void msgpack_rpc_from_position(Position result, msgpack_packer *res) +{ + msgpack_pack_array(res, 2);; + msgpack_pack_uint16(res, result.row); + msgpack_pack_uint16(res, result.col); +} + +void msgpack_rpc_from_array(Array result, msgpack_packer *res) +{ + msgpack_pack_array(res, result.size); + + for (size_t i = 0; i < result.size; i++) { + msgpack_rpc_from_object(result.items[i], res); + } +} + +void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res) +{ + msgpack_pack_map(res, result.size); + + for (size_t i = 0; i < result.size; i++) { + msgpack_rpc_from_string(result.items[i].key, res); + msgpack_rpc_from_object(result.items[i].value, res); + } +} + +void msgpack_rpc_free_object(Object value) +{ + switch (value.type) { + case kObjectTypeNil: + case kObjectTypeBool: + case kObjectTypeInt: + case kObjectTypeFloat: + break; + + case kObjectTypeString: + msgpack_rpc_free_string(value.data.string); + break; + + case kObjectTypeArray: + msgpack_rpc_free_array(value.data.array); + break; + + case kObjectTypeDictionary: + msgpack_rpc_free_dictionary(value.data.dictionary); + break; + + default: + abort(); + } +} + +void msgpack_rpc_free_stringarray(StringArray value) { + for (uint32_t i = 0; i < value.size; i++) { + msgpack_rpc_free_string(value.items[i]); + } + + free(value.items); +} + +void msgpack_rpc_free_array(Array value) +{ + for (uint32_t i = 0; i < value.size; i++) { + msgpack_rpc_free_object(value.items[i]); + } + + free(value.items); +} + +void msgpack_rpc_free_dictionary(Dictionary value) +{ + for (uint32_t i = 0; i < value.size; i++) { + msgpack_rpc_free_string(value.items[i].key); + msgpack_rpc_free_object(value.items[i].value); + } + + free(value.items); +} + +static bool msgpack_rpc_to_uint16_t(msgpack_object *obj, uint16_t *arg) +{ + *arg = obj->via.u64; + return obj->type == MSGPACK_OBJECT_POSITIVE_INTEGER; +} + diff --git a/src/os/msgpack_rpc.h b/src/os/msgpack_rpc.h new file mode 100644 index 0000000000..8d2c6e767b --- /dev/null +++ b/src/os/msgpack_rpc.h @@ -0,0 +1,107 @@ +#ifndef NEOVIM_MSGPACK_RPC_H +#define NEOVIM_MSGPACK_RPC_H + +#include <stdint.h> +#include <stdbool.h> + +#include <msgpack.h> + +#include "api/defs.h" + +/// Validates the basic structure of the msgpack-rpc call and fills `res` +/// with the basic response structure. +/// +/// @param req The parsed request object +/// @param res A packer that contains the response +void msgpack_rpc_call(msgpack_object *req, msgpack_packer *res); + +/// Dispatches to the actual API function after basic payload validation by +/// `msgpack_rpc_call`. It is responsible for validating/converting arguments +/// to C types, and converting the return value back to msgpack types. +/// The implementation is generated at compile time with metadata extracted +/// from the api/*.h headers, +/// +/// @param req The parsed request object +/// @param res A packer that contains the response +void msgpack_rpc_dispatch(msgpack_object *req, msgpack_packer *res); + +/// Finishes the msgpack-rpc call with an error message. +/// +/// @param msg The error message +/// @param res A packer that contains the response +void msgpack_rpc_error(char *msg, msgpack_packer *res); + +/// Functions for validating and converting from msgpack types to C types. +/// These are used by `msgpack_rpc_dispatch` to validate and convert each +/// argument. +/// +/// @param obj The object to convert +/// @param[out] arg A pointer to the avalue +/// @return true if the convertion succeeded, false otherwise +bool msgpack_rpc_to_bool(msgpack_object *obj, bool *arg); +bool msgpack_rpc_to_int64_t(msgpack_object *obj, int64_t *arg); +bool msgpack_rpc_to_double(msgpack_object *obj, double *arg); +bool msgpack_rpc_to_position(msgpack_object *obj, Position *arg); +bool msgpack_rpc_to_string(msgpack_object *obj, String *arg); +bool msgpack_rpc_to_buffer(msgpack_object *obj, Buffer *arg); +bool msgpack_rpc_to_window(msgpack_object *obj, Window *arg); +bool msgpack_rpc_to_tabpage(msgpack_object *obj, Tabpage *arg); +bool msgpack_rpc_to_object(msgpack_object *obj, Object *arg); +bool msgpack_rpc_to_stringarray(msgpack_object *obj, StringArray *arg); +bool msgpack_rpc_to_array(msgpack_object *obj, Array *arg); +bool msgpack_rpc_to_dictionary(msgpack_object *obj, Dictionary *arg); + +/// Functions for converting from C types to msgpack types. +/// These are used by `msgpack_rpc_dispatch` to convert return values +/// from the API +/// +/// @param result A pointer to the result +/// @param res A packer that contains the response +void msgpack_rpc_from_bool(bool result, msgpack_packer *res); +void msgpack_rpc_from_int64_t(int64_t result, msgpack_packer *res); +void msgpack_rpc_from_double(double result, msgpack_packer *res); +void msgpack_rpc_from_position(Position result, msgpack_packer *res); +void msgpack_rpc_from_string(String result, msgpack_packer *res); +void msgpack_rpc_from_buffer(Buffer result, msgpack_packer *res); +void msgpack_rpc_from_window(Window result, msgpack_packer *res); +void msgpack_rpc_from_tabpage(Tabpage result, msgpack_packer *res); +void msgpack_rpc_from_object(Object result, msgpack_packer *res); +void msgpack_rpc_from_stringarray(StringArray result, msgpack_packer *res); +void msgpack_rpc_from_array(Array result, msgpack_packer *res); +void msgpack_rpc_from_dictionary(Dictionary result, msgpack_packer *res); + +/// Helpers for initializing types that may be freed later +#define msgpack_rpc_init_bool +#define msgpack_rpc_init_int64_t +#define msgpack_rpc_init_double +#define msgpack_rpc_init_position +#define msgpack_rpc_init_string +#define msgpack_rpc_init_buffer +#define msgpack_rpc_init_window +#define msgpack_rpc_init_tabpage +#define msgpack_rpc_init_object = {.type = kObjectTypeNil} +#define msgpack_rpc_init_stringarray = {.items = NULL, .size = 0} +#define msgpack_rpc_init_array = {.items = NULL, .size = 0} +#define msgpack_rpc_init_dictionary = {.items = NULL, .size = 0} + +/// Helpers for freeing arguments/return value +/// +/// @param value The value to be freed +#define msgpack_rpc_free_bool(value) +#define msgpack_rpc_free_int64_t(value) +#define msgpack_rpc_free_double(value) +#define msgpack_rpc_free_position(value) +// Strings are not copied from msgpack and so don't need to be freed(they +// probably "live" in the msgpack streaming buffer) +#define msgpack_rpc_free_string(value) +#define msgpack_rpc_free_buffer(value) +#define msgpack_rpc_free_window(value) +#define msgpack_rpc_free_tabpage(value) +void msgpack_rpc_free_object(Object value); +void msgpack_rpc_free_stringarray(StringArray value); +void msgpack_rpc_free_array(Array value); +void msgpack_rpc_free_dictionary(Dictionary value); + + +#endif // NEOVIM_MSGPACK_RPC_H + |