aboutsummaryrefslogtreecommitdiff
path: root/src/nvim/decoration_provider.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/nvim/decoration_provider.c')
-rw-r--r--src/nvim/decoration_provider.c82
1 files changed, 46 insertions, 36 deletions
diff --git a/src/nvim/decoration_provider.c b/src/nvim/decoration_provider.c
index ed21474935..172eb569c9 100644
--- a/src/nvim/decoration_provider.c
+++ b/src/nvim/decoration_provider.c
@@ -1,33 +1,37 @@
-// This is an open source non-commercial project. Dear PVS-Studio, please check
-// it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
-
#include <assert.h>
-#include <stdio.h>
+#include <lauxlib.h>
#include <string.h>
#include "klib/kvec.h"
-#include "lauxlib.h"
#include "nvim/api/extmark.h"
#include "nvim/api/private/defs.h"
#include "nvim/api/private/helpers.h"
#include "nvim/buffer_defs.h"
+#include "nvim/decoration.h"
#include "nvim/decoration_provider.h"
#include "nvim/globals.h"
#include "nvim/highlight.h"
#include "nvim/log.h"
#include "nvim/lua/executor.h"
-#include "nvim/memory.h"
-#include "nvim/pos.h"
+#include "nvim/message.h"
+#include "nvim/pos_defs.h"
static kvec_t(DecorProvider) decor_providers = KV_INITIAL_VALUE;
#define DECORATION_PROVIDER_INIT(ns_id) (DecorProvider) \
{ ns_id, false, LUA_NOREF, LUA_NOREF, \
LUA_NOREF, LUA_NOREF, LUA_NOREF, \
- LUA_NOREF, -1, false, false }
+ LUA_NOREF, -1, false, false, 0 }
+
+static void decor_provider_error(DecorProvider *provider, const char *name, const char *msg)
+{
+ const char *ns_name = describe_ns(provider->ns_id, "(UNKNOWN PLUGIN)");
+ ELOG("error in provider %s.%s: %s", ns_name, name, msg);
+ msg_schedule_semsg_multiline("Error in decoration provider %s.%s:\n%s", ns_name, name, msg);
+}
-static bool decor_provider_invoke(NS ns_id, const char *name, LuaRef ref, Array args,
- bool default_true, char **perr)
+static bool decor_provider_invoke(DecorProvider *provider, const char *name, LuaRef ref, Array args,
+ bool default_true)
{
Error err = ERROR_INIT;
@@ -39,26 +43,25 @@ static bool decor_provider_invoke(NS ns_id, const char *name, LuaRef ref, Array
if (!ERROR_SET(&err)
&& api_object_to_bool(ret, "provider %s retval", default_true, &err)) {
+ provider->error_count = 0;
return true;
}
if (ERROR_SET(&err)) {
- const char *ns_name = describe_ns(ns_id);
- ELOG("error in provider %s:%s: %s", ns_name, name, err.msg);
- bool verbose_errs = true; // TODO(bfredl):
- if (verbose_errs && perr && *perr == NULL) {
- static char errbuf[IOSIZE];
- snprintf(errbuf, sizeof errbuf, "%s: %s", ns_name, err.msg);
- *perr = xstrdup(errbuf);
+ decor_provider_error(provider, name, err.msg);
+ provider->error_count++;
+
+ if (provider->error_count >= DP_MAX_ERROR) {
+ provider->active = false;
}
}
+ api_clear_error(&err);
api_free_object(ret);
return false;
}
-void decor_providers_invoke_spell(win_T *wp, int start_row, int start_col, int end_row, int end_col,
- char **err)
+void decor_providers_invoke_spell(win_T *wp, int start_row, int start_col, int end_row, int end_col)
{
for (size_t i = 0; i < kv_size(decor_providers); i++) {
DecorProvider *p = &kv_A(decor_providers, i);
@@ -74,7 +77,7 @@ void decor_providers_invoke_spell(win_T *wp, int start_row, int start_col, int e
ADD_C(args, INTEGER_OBJ(start_col));
ADD_C(args, INTEGER_OBJ(end_row));
ADD_C(args, INTEGER_OBJ(end_col));
- decor_provider_invoke(p->ns_id, "spell", p->spell_nav, args, true, err);
+ decor_provider_invoke(p, "spell", p->spell_nav, args, true);
}
}
}
@@ -83,7 +86,7 @@ void decor_providers_invoke_spell(win_T *wp, int start_row, int start_col, int e
///
/// @param[out] providers Decoration providers
/// @param[out] err Provider err
-void decor_providers_start(DecorProviders *providers, char **err)
+void decor_providers_start(DecorProviders *providers)
{
kvi_init(*providers);
@@ -97,7 +100,7 @@ void decor_providers_start(DecorProviders *providers, char **err)
if (p->redraw_start != LUA_NOREF) {
MAXSIZE_TEMP_ARRAY(args, 2);
ADD_C(args, INTEGER_OBJ((int)display_tick));
- active = decor_provider_invoke(p->ns_id, "start", p->redraw_start, args, true, err);
+ active = decor_provider_invoke(p, "start", p->redraw_start, args, true);
} else {
active = true;
}
@@ -116,13 +119,17 @@ void decor_providers_start(DecorProviders *providers, char **err)
/// @param[out] line_providers Enabled line providers to invoke in win_line
/// @param[out] err Provider error
void decor_providers_invoke_win(win_T *wp, DecorProviders *providers,
- DecorProviders *line_providers, char **err)
+ DecorProviders *line_providers)
{
kvi_init(*line_providers);
+ // this might change in the future
+ // then we would need decor_state.running_decor_provider just like "on_line" below
+ assert(kv_size(decor_state.active) == 0);
- linenr_T knownmax = ((wp->w_valid & VALID_BOTLINE)
- ? wp->w_botline
- : (wp->w_topline + wp->w_height_inner));
+ linenr_T knownmax = MIN(wp->w_buffer->b_ml.ml_line_count,
+ ((wp->w_valid & VALID_BOTLINE)
+ ? wp->w_botline
+ : MAX(wp->w_topline + wp->w_height_inner, wp->w_botline)));
for (size_t k = 0; k < kv_size(*providers); k++) {
DecorProvider *p = kv_A(*providers, k);
@@ -132,8 +139,8 @@ void decor_providers_invoke_win(win_T *wp, DecorProviders *providers,
ADD_C(args, BUFFER_OBJ(wp->w_buffer->handle));
// TODO(bfredl): we are not using this, but should be first drawn line?
ADD_C(args, INTEGER_OBJ(wp->w_topline - 1));
- ADD_C(args, INTEGER_OBJ(knownmax));
- if (decor_provider_invoke(p->ns_id, "win", p->redraw_win, args, true, err)) {
+ ADD_C(args, INTEGER_OBJ(knownmax - 1));
+ if (decor_provider_invoke(p, "win", p->redraw_win, args, true)) {
kvi_push(*line_providers, p);
}
}
@@ -147,9 +154,9 @@ void decor_providers_invoke_win(win_T *wp, DecorProviders *providers,
/// @param row Row to invoke line callback for
/// @param[out] has_decor Set when at least one provider invokes a line callback
/// @param[out] err Provider error
-void decor_providers_invoke_line(win_T *wp, DecorProviders *providers, int row, bool *has_decor,
- char **err)
+void decor_providers_invoke_line(win_T *wp, DecorProviders *providers, int row, bool *has_decor)
{
+ decor_state.running_decor_provider = true;
for (size_t k = 0; k < kv_size(*providers); k++) {
DecorProvider *p = kv_A(*providers, k);
if (p && p->redraw_line != LUA_NOREF) {
@@ -157,7 +164,7 @@ void decor_providers_invoke_line(win_T *wp, DecorProviders *providers, int row,
ADD_C(args, WINDOW_OBJ(wp->handle));
ADD_C(args, BUFFER_OBJ(wp->w_buffer->handle));
ADD_C(args, INTEGER_OBJ(row));
- if (decor_provider_invoke(p->ns_id, "line", p->redraw_line, args, true, err)) {
+ if (decor_provider_invoke(p, "line", p->redraw_line, args, true)) {
*has_decor = true;
} else {
// return 'false' or error: skip rest of this window
@@ -167,6 +174,7 @@ void decor_providers_invoke_line(win_T *wp, DecorProviders *providers, int row,
hl_check_ns();
}
}
+ decor_state.running_decor_provider = false;
}
/// For each provider invoke the 'buf' callback for a given buffer.
@@ -174,14 +182,15 @@ void decor_providers_invoke_line(win_T *wp, DecorProviders *providers, int row,
/// @param buf Buffer
/// @param providers Decoration providers
/// @param[out] err Provider error
-void decor_providers_invoke_buf(buf_T *buf, DecorProviders *providers, char **err)
+void decor_providers_invoke_buf(buf_T *buf, DecorProviders *providers)
{
for (size_t i = 0; i < kv_size(*providers); i++) {
DecorProvider *p = kv_A(*providers, i);
if (p && p->redraw_buf != LUA_NOREF) {
- MAXSIZE_TEMP_ARRAY(args, 1);
+ MAXSIZE_TEMP_ARRAY(args, 2);
ADD_C(args, BUFFER_OBJ(buf->handle));
- decor_provider_invoke(p->ns_id, "buf", p->redraw_buf, args, true, err);
+ ADD_C(args, INTEGER_OBJ((int64_t)display_tick));
+ decor_provider_invoke(p, "buf", p->redraw_buf, args, true);
}
}
}
@@ -191,16 +200,17 @@ void decor_providers_invoke_buf(buf_T *buf, DecorProviders *providers, char **er
/// @param providers Decoration providers
/// @param displaytick Display tick
/// @param[out] err Provider error
-void decor_providers_invoke_end(DecorProviders *providers, char **err)
+void decor_providers_invoke_end(DecorProviders *providers)
{
for (size_t i = 0; i < kv_size(*providers); i++) {
DecorProvider *p = kv_A(*providers, i);
if (p && p->active && p->redraw_end != LUA_NOREF) {
MAXSIZE_TEMP_ARRAY(args, 1);
ADD_C(args, INTEGER_OBJ((int)display_tick));
- decor_provider_invoke(p->ns_id, "end", p->redraw_end, args, true, err);
+ decor_provider_invoke(p, "end", p->redraw_end, args, true);
}
}
+ decor_check_to_be_deleted();
}
/// Mark all cached state of per-namespace highlights as invalid. Revalidate