aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/ui_client.c
diff options
context:
space:
mode:
authorhlpr98 <hlpr98@gmail.com>2022-03-12 21:08:29 +0100
committerbfredl <bjorn.linse@gmail.com>2022-03-15 19:55:34 +0100
commit794d2744f33562326172801ddd729853e7135347 (patch)
tree539b34d053bdc4b5a23bb5e2824042c211ced2dc /src/nvim/ui_client.c
parentaa35d15a0db8a5a2a0b06aca7b7161c5e35b57b1 (diff)
downloadrneovim-794d2744f33562326172801ddd729853e7135347.tar.gz
rneovim-794d2744f33562326172801ddd729853e7135347.tar.bz2
rneovim-794d2744f33562326172801ddd729853e7135347.zip
feat(ui): implement ui_client event handlers
Diffstat (limited to 'src/nvim/ui_client.c')
-rw-r--r--src/nvim/ui_client.c114
1 files changed, 114 insertions, 0 deletions
diff --git a/src/nvim/ui_client.c b/src/nvim/ui_client.c
index 4a435aac4d..b23ceefb6f 100644
--- a/src/nvim/ui_client.c
+++ b/src/nvim/ui_client.c
@@ -6,11 +6,22 @@
#include <assert.h>
#include "nvim/vim.h"
+#include "nvim/log.h"
+#include "nvim/map.h"
#include "nvim/ui_client.h"
#include "nvim/api/private/helpers.h"
#include "nvim/msgpack_rpc/channel.h"
#include "nvim/api/private/dispatch.h"
#include "nvim/ui.h"
+#include "nvim/highlight.h"
+#include "nvim/screen.h"
+
+static Map(String, ApiRedrawWrapper) redraw_methods = MAP_INIT;
+
+static void add_redraw_event_handler(String method, ApiRedrawWrapper handler)
+{
+ map_put(String, ApiRedrawWrapper)(&redraw_methods, method, handler);
+}
void ui_client_init(uint64_t chan)
{
@@ -68,3 +79,106 @@ void ui_client_execute(uint64_t chan)
getout(0);
}
+
+/// @param name Redraw method name
+/// @param name_len name size (includes terminating NUL)
+ApiRedrawWrapper get_redraw_event_handler(const char *name, size_t name_len, Error *error)
+{
+ String m = { .data = (char *)name, .size = name_len };
+ ApiRedrawWrapper rv =
+ map_get(String, ApiRedrawWrapper)(&redraw_methods, m);
+
+ if (!rv) {
+ api_set_error(error, kErrorTypeException, "Invalid method: %.*s",
+ m.size > 0 ? (int)m.size : (int)sizeof("<empty>"),
+ m.size > 0 ? m.data : "<empty>");
+ }
+ return rv;
+}
+
+static HlAttrs redraw_dict2hlattrs(Dictionary redraw_dict, bool rgb)
+{
+ Error err = ERROR_INIT;
+ Dict(highlight) dict = { 0 };
+ if (!api_dict_to_keydict(&dict, KeyDict_highlight_get_field, redraw_dict, &err)) {
+ // TODO(bfredl): log "err"
+ return HLATTRS_INIT;
+ }
+ return dict2hlattrs(&dict, true, NULL, &err);
+}
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+#include "ui_events_redraw.generated.h"
+#endif
+
+void ui_redraw_event_grid_line(Array args)
+{
+ Integer grid = args.items[0].data.integer;
+ Integer row = args.items[1].data.integer;
+ Integer startcol = args.items[2].data.integer;
+ Array cells = args.items[3].data.array;
+ Integer endcol, clearcol, clearattr;
+ // TODO(hlpr98): Accomodate other LineFlags when included in grid_line
+ LineFlags lineflags = 0;
+ schar_T *chunk;
+ sattr_T *attrs;
+ size_t size_of_cells = cells.size;
+ size_t no_of_cells = size_of_cells;
+ endcol = startcol;
+
+ // checking if clearcol > endcol
+ if (!STRCMP(cells.items[size_of_cells-1].data.array
+ .items[0].data.string.data, " ")
+ && cells.items[size_of_cells-1].data.array.size == 3) {
+ no_of_cells = size_of_cells - 1;
+ }
+
+ // getting endcol
+ for (size_t i = 0; i < no_of_cells; i++) {
+ endcol++;
+ if (cells.items[i].data.array.size == 3) {
+ endcol += cells.items[i].data.array.items[2].data.integer - 1;
+ }
+ }
+
+ if (!STRCMP(cells.items[size_of_cells-1].data.array
+ .items[0].data.string.data, " ")
+ && cells.items[size_of_cells-1].data.array.size == 3) {
+ clearattr = cells.items[size_of_cells-1].data.array.items[1].data.integer;
+ clearcol = endcol + cells.items[size_of_cells-1].data.array
+ .items[2].data.integer;
+ } else {
+ clearattr = 0;
+ clearcol = endcol;
+ }
+
+ size_t ncells = (size_t)(endcol - startcol);
+ chunk = xmalloc(ncells * sizeof(schar_T) + 1);
+ attrs = xmalloc(ncells * sizeof(sattr_T) + 1);
+
+ size_t j = 0;
+ size_t k = 0;
+ for (size_t i = 0; i < no_of_cells; i++) {
+ STRCPY(chunk[j++], cells.items[i].data.array.items[0].data.string.data);
+ if (cells.items[i].data.array.size == 3) {
+ // repeat present
+ for (size_t i_intr = 1;
+ i_intr < (size_t)cells.items[i].data.array.items[2].data.integer;
+ i_intr++) {
+ STRCPY(chunk[j++], cells.items[i].data.array.items[0].data.string.data);
+ attrs[k++] = (sattr_T)cells.items[i].data.array.items[1].data.integer;
+ }
+ } else if (cells.items[i].data.array.size == 2) {
+ // repeat = 1 but attrs != last_hl
+ attrs[k++] = (sattr_T)cells.items[i].data.array.items[1].data.integer;
+ }
+ if (j > k) {
+ // attrs == last_hl
+ attrs[k] = attrs[k-1];
+ k++;
+ }
+ }
+
+ ui_call_raw_line(grid, row, startcol, endcol, clearcol, clearattr, lineflags,
+ (const schar_T *)chunk, (const sattr_T *)attrs);
+}