aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorBjörn Linse <bjorn.linse@gmail.com>2020-09-12 10:29:30 +0200
committerBjörn Linse <bjorn.linse@gmail.com>2020-09-13 07:46:39 +0200
commit4042975df42152a64f4d390ed677013d1c8609c5 (patch)
treed512c959d96451357f152c5c8f3beb12f0c029d6 /src
parent05c68922d35af8db38df594a46c87270b5cac0c8 (diff)
downloadrneovim-4042975df42152a64f4d390ed677013d1c8609c5.tar.gz
rneovim-4042975df42152a64f4d390ed677013d1c8609c5.tar.bz2
rneovim-4042975df42152a64f4d390ed677013d1c8609c5.zip
luahl: global the luahl
Diffstat (limited to 'src')
-rw-r--r--src/nvim/api/buffer.c72
-rw-r--r--src/nvim/api/private/helpers.c12
-rw-r--r--src/nvim/api/vim.c65
-rw-r--r--src/nvim/buffer_defs.h6
-rw-r--r--src/nvim/extmark.c2
-rw-r--r--src/nvim/globals.h6
-rw-r--r--src/nvim/main.c2
-rw-r--r--src/nvim/screen.c23
8 files changed, 103 insertions, 85 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index e58035b6c7..21f7c8e931 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -244,78 +244,6 @@ Boolean nvim_buf_detach(uint64_t channel_id,
return true;
}
-static void buf_clear_luahl(buf_T *buf, bool force)
-{
- if (buf->b_luahl || force) {
- api_free_luaref(buf->b_luahl_start);
- api_free_luaref(buf->b_luahl_window);
- api_free_luaref(buf->b_luahl_line);
- api_free_luaref(buf->b_luahl_end);
- }
- buf->b_luahl_start = LUA_NOREF;
- buf->b_luahl_window = LUA_NOREF;
- buf->b_luahl_line = LUA_NOREF;
- buf->b_luahl_end = LUA_NOREF;
-}
-
-/// Unstabilized interface for defining syntax hl in lua.
-///
-/// This is not yet safe for general use, lua callbacks will need to
-/// be restricted, like textlock and probably other stuff.
-///
-/// The API on_line/nvim__put_attr is quite raw and not intended to be the
-/// final shape. Ideally this should operate on chunks larger than a single
-/// line to reduce interpreter overhead, and generate annotation objects
-/// (bufhl/virttext) on the fly but using the same representation.
-void nvim__buf_set_luahl(uint64_t channel_id, Buffer buffer,
- DictionaryOf(LuaRef) opts, Error *err)
- FUNC_API_LUA_ONLY
-{
- buf_T *buf = find_buffer_by_handle(buffer, err);
-
- if (!buf) {
- return;
- }
-
- redraw_buf_later(buf, NOT_VALID);
- buf_clear_luahl(buf, false);
-
- for (size_t i = 0; i < opts.size; i++) {
- String k = opts.items[i].key;
- Object *v = &opts.items[i].value;
- if (strequal("on_start", k.data)) {
- if (v->type != kObjectTypeLuaRef) {
- api_set_error(err, kErrorTypeValidation, "callback is not a function");
- goto error;
- }
- buf->b_luahl_start = v->data.luaref;
- v->data.luaref = LUA_NOREF;
- } else if (strequal("on_window", k.data)) {
- if (v->type != kObjectTypeLuaRef) {
- api_set_error(err, kErrorTypeValidation, "callback is not a function");
- goto error;
- }
- buf->b_luahl_window = v->data.luaref;
- v->data.luaref = LUA_NOREF;
- } else if (strequal("on_line", k.data)) {
- if (v->type != kObjectTypeLuaRef) {
- api_set_error(err, kErrorTypeValidation, "callback is not a function");
- goto error;
- }
- buf->b_luahl_line = v->data.luaref;
- v->data.luaref = LUA_NOREF;
- } else {
- api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
- goto error;
- }
- }
- buf->b_luahl = true;
- return;
-error:
- buf_clear_luahl(buf, true);
- buf->b_luahl = false;
-}
-
void nvim__buf_redraw_range(Buffer buffer, Integer first, Integer last,
Error *err)
FUNC_API_LUA_ONLY
diff --git a/src/nvim/api/private/helpers.c b/src/nvim/api/private/helpers.c
index f1ecd732ee..e0d5862e02 100644
--- a/src/nvim/api/private/helpers.c
+++ b/src/nvim/api/private/helpers.c
@@ -1618,3 +1618,15 @@ free_exit:
clear_virttext(&virt_text);
return virt_text;
}
+
+bool api_is_truthy(Object obj, const char *what, Error *err)
+{
+ if (obj.type == kObjectTypeBoolean) {
+ return obj.data.boolean;
+ } else if (obj.type == kObjectTypeInteger) {
+ return obj.data.integer; // C semantics: non-zery int is true
+ } else {
+ api_set_error(err, kErrorTypeValidation, "%s is not an boolean", what);
+ return false;
+ }
+}
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index cb5d1e1f77..1de1472fc2 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -2702,3 +2702,68 @@ void nvim__screenshot(String path)
{
ui_call_screenshot(path);
}
+
+static void clear_luahl(bool force)
+{
+ if (luahl_active || force) {
+ api_free_luaref(luahl_start);
+ api_free_luaref(luahl_win);
+ api_free_luaref(luahl_line);
+ api_free_luaref(luahl_end);
+ }
+ luahl_start = LUA_NOREF;
+ luahl_win = LUA_NOREF;
+ luahl_line = LUA_NOREF;
+ luahl_end = LUA_NOREF;
+ luahl_active = false;
+}
+
+/// Unstabilized interface for defining syntax hl in lua.
+///
+/// This is not yet safe for general use, lua callbacks will need to
+/// be restricted, like textlock and probably other stuff.
+///
+/// The API on_line/nvim__put_attr is quite raw and not intended to be the
+/// final shape. Ideally this should operate on chunks larger than a single
+/// line to reduce interpreter overhead, and generate annotation objects
+/// (bufhl/virttext) on the fly but using the same representation.
+void nvim__set_luahl(DictionaryOf(LuaRef) opts, Error *err)
+ FUNC_API_LUA_ONLY
+{
+ redraw_later(NOT_VALID);
+ clear_luahl(false);
+
+ for (size_t i = 0; i < opts.size; i++) {
+ String k = opts.items[i].key;
+ Object *v = &opts.items[i].value;
+ if (strequal("on_start", k.data)) {
+ if (v->type != kObjectTypeLuaRef) {
+ api_set_error(err, kErrorTypeValidation, "callback is not a function");
+ goto error;
+ }
+ luahl_start = v->data.luaref;
+ v->data.luaref = LUA_NOREF;
+ } else if (strequal("on_win", k.data)) {
+ if (v->type != kObjectTypeLuaRef) {
+ api_set_error(err, kErrorTypeValidation, "callback is not a function");
+ goto error;
+ }
+ luahl_win = v->data.luaref;
+ v->data.luaref = LUA_NOREF;
+ } else if (strequal("on_line", k.data)) {
+ if (v->type != kObjectTypeLuaRef) {
+ api_set_error(err, kErrorTypeValidation, "callback is not a function");
+ goto error;
+ }
+ luahl_line = v->data.luaref;
+ v->data.luaref = LUA_NOREF;
+ } else {
+ api_set_error(err, kErrorTypeValidation, "unexpected key: %s", k.data);
+ goto error;
+ }
+ }
+ luahl_active = true;
+ return;
+error:
+ clear_luahl(true);
+}
diff --git a/src/nvim/buffer_defs.h b/src/nvim/buffer_defs.h
index b3c95f9362..bd9cd2f5ec 100644
--- a/src/nvim/buffer_defs.h
+++ b/src/nvim/buffer_defs.h
@@ -842,12 +842,6 @@ struct file_buffer {
// The number for times the current line has been flushed in the memline.
int flush_count;
- bool b_luahl;
- LuaRef b_luahl_start;
- LuaRef b_luahl_window;
- LuaRef b_luahl_line;
- LuaRef b_luahl_end;
-
int b_diff_failed; // internal diff failed for this buffer
};
diff --git a/src/nvim/extmark.c b/src/nvim/extmark.c
index 3a04908ccb..c45714de78 100644
--- a/src/nvim/extmark.c
+++ b/src/nvim/extmark.c
@@ -845,7 +845,7 @@ bool decorations_redraw_reset(buf_T *buf, DecorationRedrawState *state)
{
state->row = -1;
kv_size(state->active) = 0;
- return buf->b_extmark_index || buf->b_luahl;
+ return buf->b_extmark_index;
}
diff --git a/src/nvim/globals.h b/src/nvim/globals.h
index 205be4b811..ddb69fc567 100644
--- a/src/nvim/globals.h
+++ b/src/nvim/globals.h
@@ -405,6 +405,12 @@ EXTERN int sys_menu INIT(= false);
// ('lines' and 'rows') must not be changed.
EXTERN int updating_screen INIT(= 0);
+EXTERN bool luahl_active INIT(= false);
+EXTERN LuaRef luahl_start INIT(= LUA_NOREF);
+EXTERN LuaRef luahl_win INIT(= LUA_NOREF);
+EXTERN LuaRef luahl_line INIT(= LUA_NOREF);
+EXTERN LuaRef luahl_end INIT(= LUA_NOREF);
+
// All windows are linked in a list. firstwin points to the first entry,
// lastwin to the last entry (can be the same as firstwin) and curwin to the
// currently active window.
diff --git a/src/nvim/main.c b/src/nvim/main.c
index 1374c5eb5d..a22df9cc69 100644
--- a/src/nvim/main.c
+++ b/src/nvim/main.c
@@ -7,6 +7,8 @@
#include <string.h>
#include <stdbool.h>
+#include <lua.h>
+#include <lauxlib.h>
#include <msgpack.h>
#include "nvim/ascii.h"
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index ca1c4589f8..7d020432d9 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -158,6 +158,8 @@ static bool msg_grid_invalid = false;
static bool resizing = false;
+static bool do_luahl_line = false;
+
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "screen.c.generated.h"
#endif
@@ -508,12 +510,12 @@ int update_screen(int type)
}
buf_T *buf = wp->w_buffer;
- if (buf->b_luahl && buf->b_luahl_window != LUA_NOREF) {
+ if (luahl_active && luahl_start != LUA_NOREF) {
Error err = ERROR_INIT;
FIXED_TEMP_ARRAY(args, 2);
args.items[0] = BUFFER_OBJ(buf->handle);
args.items[1] = INTEGER_OBJ(display_tick);
- nlua_call_ref(buf->b_luahl_start, "start", args, false, &err);
+ nlua_call_ref(luahl_start, "start", args, false, &err);
if (ERROR_SET(&err)) {
ELOG("error in luahl start: %s", err.msg);
api_clear_error(&err);
@@ -1239,7 +1241,9 @@ static void win_update(win_T *wp)
decorations_active = decorations_redraw_reset(buf, &decorations);
- if (buf->b_luahl && buf->b_luahl_window != LUA_NOREF) {
+ do_luahl_line = false;
+
+ if (luahl_win != LUA_NOREF) {
Error err = ERROR_INIT;
FIXED_TEMP_ARRAY(args, 4);
linenr_T knownmax = ((wp->w_valid & VALID_BOTLINE)
@@ -1252,7 +1256,13 @@ static void win_update(win_T *wp)
args.items[3] = INTEGER_OBJ(knownmax);
// TODO(bfredl): we could allow this callback to change mod_top, mod_bot.
// For now the "start" callback is expected to use nvim__buf_redraw_range.
- nlua_call_ref(buf->b_luahl_window, "window", args, false, &err);
+ Object ret = nlua_call_ref(luahl_win, "win", args, true, &err);
+
+ if (!ERROR_SET(&err) && api_is_truthy(ret, "luahl_window retval", &err)) {
+ do_luahl_line = true;
+ decorations_active = true;
+ }
+
if (ERROR_SET(&err)) {
ELOG("error in luahl window: %s", err.msg);
api_clear_error(&err);
@@ -2349,7 +2359,7 @@ win_line (
}
if (decorations_active) {
- if (buf->b_luahl && buf->b_luahl_line != LUA_NOREF) {
+ if (do_luahl_line && luahl_line != LUA_NOREF) {
Error err = ERROR_INIT;
FIXED_TEMP_ARRAY(args, 3);
args.items[0] = WINDOW_OBJ(wp->handle);
@@ -2357,8 +2367,9 @@ win_line (
args.items[2] = INTEGER_OBJ(lnum-1);
lua_attr_active = true;
extra_check = true;
- nlua_call_ref(buf->b_luahl_line, "line", args, false, &err);
+ nlua_call_ref(luahl_line, "line", args, false, &err);
lua_attr_active = false;
+
if (ERROR_SET(&err)) {
ELOG("error in luahl line: %s", err.msg);
luatext = err.msg;