diff options
author | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 21:52:58 +0000 |
---|---|---|
committer | Josh Rahm <joshuarahm@gmail.com> | 2023-11-29 21:52:58 +0000 |
commit | 931bffbda3668ddc609fc1da8f9eb576b170aa52 (patch) | |
tree | d8c1843a95da5ea0bb4acc09f7e37843d9995c86 /src/nvim/decoration_provider.c | |
parent | 142d9041391780ac15b89886a54015fdc5c73995 (diff) | |
parent | 4a8bf24ac690004aedf5540fa440e788459e5e34 (diff) | |
download | rneovim-userreg.tar.gz rneovim-userreg.tar.bz2 rneovim-userreg.zip |
Merge remote-tracking branch 'upstream/master' into userreguserreg
Diffstat (limited to 'src/nvim/decoration_provider.c')
-rw-r--r-- | src/nvim/decoration_provider.c | 82 |
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 |