mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
refactor(decorations): move provider code
Move decoration provider code to a separate file.
This commit is contained in:
parent
9e9322b222
commit
1b054119ec
@ -8,6 +8,7 @@
|
|||||||
#include "nvim/api/extmark.h"
|
#include "nvim/api/extmark.h"
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
|
#include "nvim/decoration_provider.h"
|
||||||
#include "nvim/extmark.h"
|
#include "nvim/extmark.h"
|
||||||
#include "nvim/lua/executor.h"
|
#include "nvim/lua/executor.h"
|
||||||
#include "nvim/memline.h"
|
#include "nvim/memline.h"
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "nvim/charset.h"
|
#include "nvim/charset.h"
|
||||||
#include "nvim/context.h"
|
#include "nvim/context.h"
|
||||||
#include "nvim/decoration.h"
|
#include "nvim/decoration.h"
|
||||||
|
#include "nvim/decoration_provider.h"
|
||||||
#include "nvim/edit.h"
|
#include "nvim/edit.h"
|
||||||
#include "nvim/eval.h"
|
#include "nvim/eval.h"
|
||||||
#include "nvim/eval/typval.h"
|
#include "nvim/eval/typval.h"
|
||||||
|
@ -523,59 +523,6 @@ void decor_add_ephemeral(int start_row, int start_col, int end_row, int end_col,
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
DecorProvider *get_decor_provider(NS ns_id, bool force)
|
|
||||||
{
|
|
||||||
size_t i;
|
|
||||||
size_t len = kv_size(decor_providers);
|
|
||||||
for (i = 0; i < len; i++) {
|
|
||||||
DecorProvider *item = &kv_A(decor_providers, i);
|
|
||||||
if (item->ns_id == ns_id) {
|
|
||||||
return item;
|
|
||||||
} else if (item->ns_id > ns_id) {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!force) {
|
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
// Adding a new provider, so allocate room in the vector
|
|
||||||
(void)kv_a(decor_providers, len);
|
|
||||||
if (i < len) {
|
|
||||||
// New ns_id needs to be inserted between existing providers to maintain
|
|
||||||
// ordering, so shift other providers with larger ns_id
|
|
||||||
memmove(&kv_A(decor_providers, i + 1),
|
|
||||||
&kv_A(decor_providers, i),
|
|
||||||
(len - i) * sizeof(kv_a(decor_providers, i)));
|
|
||||||
}
|
|
||||||
DecorProvider *item = &kv_a(decor_providers, i);
|
|
||||||
*item = DECORATION_PROVIDER_INIT(ns_id);
|
|
||||||
|
|
||||||
return item;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decor_provider_clear(DecorProvider *p)
|
|
||||||
{
|
|
||||||
if (p == NULL) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
NLUA_CLEAR_REF(p->redraw_start);
|
|
||||||
NLUA_CLEAR_REF(p->redraw_buf);
|
|
||||||
NLUA_CLEAR_REF(p->redraw_win);
|
|
||||||
NLUA_CLEAR_REF(p->redraw_line);
|
|
||||||
NLUA_CLEAR_REF(p->redraw_end);
|
|
||||||
p->active = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
void decor_free_all_mem(void)
|
|
||||||
{
|
|
||||||
for (size_t i = 0; i < kv_size(decor_providers); i++) {
|
|
||||||
decor_provider_clear(&kv_A(decor_providers, i));
|
|
||||||
}
|
|
||||||
kv_destroy(decor_providers);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int decor_virt_lines(win_T *wp, linenr_T lnum, VirtLines *lines)
|
int decor_virt_lines(win_T *wp, linenr_T lnum, VirtLines *lines)
|
||||||
{
|
{
|
||||||
|
@ -82,26 +82,7 @@ typedef struct {
|
|||||||
int eol_col;
|
int eol_col;
|
||||||
} DecorState;
|
} DecorState;
|
||||||
|
|
||||||
typedef struct {
|
|
||||||
NS ns_id;
|
|
||||||
bool active;
|
|
||||||
LuaRef redraw_start;
|
|
||||||
LuaRef redraw_buf;
|
|
||||||
LuaRef redraw_win;
|
|
||||||
LuaRef redraw_line;
|
|
||||||
LuaRef redraw_end;
|
|
||||||
LuaRef hl_def;
|
|
||||||
int hl_valid;
|
|
||||||
} DecorProvider;
|
|
||||||
|
|
||||||
EXTERN kvec_t(DecorProvider) decor_providers INIT(= KV_INITIAL_VALUE);
|
|
||||||
EXTERN DecorState decor_state INIT(= { 0 });
|
EXTERN DecorState decor_state INIT(= { 0 });
|
||||||
EXTERN bool provider_active INIT(= false);
|
|
||||||
|
|
||||||
#define DECORATION_PROVIDER_INIT(ns_id) (DecorProvider) \
|
|
||||||
{ ns_id, false, LUA_NOREF, LUA_NOREF, \
|
|
||||||
LUA_NOREF, LUA_NOREF, LUA_NOREF, \
|
|
||||||
LUA_NOREF, -1 }
|
|
||||||
|
|
||||||
static inline bool decor_has_sign(Decoration *decor)
|
static inline bool decor_has_sign(Decoration *decor)
|
||||||
{
|
{
|
||||||
|
224
src/nvim/decoration_provider.c
Normal file
224
src/nvim/decoration_provider.c
Normal file
@ -0,0 +1,224 @@
|
|||||||
|
// 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 "nvim/api/extmark.h"
|
||||||
|
#include "nvim/api/private/helpers.h"
|
||||||
|
#include "nvim/buffer.h"
|
||||||
|
#include "nvim/decoration.h"
|
||||||
|
#include "nvim/decoration_provider.h"
|
||||||
|
#include "nvim/highlight.h"
|
||||||
|
#include "nvim/lua/executor.h"
|
||||||
|
|
||||||
|
static bool decor_provider_invoke(NS ns_id, const char *name, LuaRef ref,
|
||||||
|
Array args, bool default_true, char **perr)
|
||||||
|
{
|
||||||
|
Error err = ERROR_INIT;
|
||||||
|
|
||||||
|
textlock++;
|
||||||
|
provider_active = true;
|
||||||
|
Object ret = nlua_call_ref(ref, name, args, true, &err);
|
||||||
|
provider_active = false;
|
||||||
|
textlock--;
|
||||||
|
|
||||||
|
if (!ERROR_SET(&err)
|
||||||
|
&& api_object_to_bool(ret, "provider %s retval", default_true, &err)) {
|
||||||
|
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);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
api_free_object(ret);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For each provider invoke the 'start' callback
|
||||||
|
///
|
||||||
|
/// @param[out] providers Decoration providers
|
||||||
|
/// @param[out] err Provider err
|
||||||
|
void decor_providers_start(DecorProviders *providers, int type, char **err)
|
||||||
|
{
|
||||||
|
kvi_init(*providers);
|
||||||
|
|
||||||
|
for (size_t i = 0; i < kv_size(decor_providers); i++) {
|
||||||
|
DecorProvider *p = &kv_A(decor_providers, i);
|
||||||
|
if (!p->active) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool active;
|
||||||
|
if (p->redraw_start != LUA_NOREF) {
|
||||||
|
FIXED_TEMP_ARRAY(args, 2);
|
||||||
|
args.items[0] = INTEGER_OBJ((int)display_tick);
|
||||||
|
args.items[1] = INTEGER_OBJ(type);
|
||||||
|
active = decor_provider_invoke(p->ns_id, "start", p->redraw_start, args, true, err);
|
||||||
|
} else {
|
||||||
|
active = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (active) {
|
||||||
|
kvi_push(*providers, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For each provider run 'win'. If result is not false, then collect the
|
||||||
|
/// 'on_line' callback to call inside win_line
|
||||||
|
///
|
||||||
|
/// @param wp Window
|
||||||
|
/// @param providers Decoration providers
|
||||||
|
/// @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)
|
||||||
|
{
|
||||||
|
kvi_init(*line_providers);
|
||||||
|
|
||||||
|
linenr_T knownmax = ((wp->w_valid & VALID_BOTLINE)
|
||||||
|
? wp->w_botline
|
||||||
|
: (wp->w_topline + wp->w_height_inner));
|
||||||
|
|
||||||
|
for (size_t k = 0; k < kv_size(*providers); k++) {
|
||||||
|
DecorProvider *p = kv_A(*providers, k);
|
||||||
|
if (p && p->redraw_win != LUA_NOREF) {
|
||||||
|
FIXED_TEMP_ARRAY(args, 4);
|
||||||
|
args.items[0] = WINDOW_OBJ(wp->handle);
|
||||||
|
args.items[1] = BUFFER_OBJ(wp->w_buffer->handle);
|
||||||
|
// TODO(bfredl): we are not using this, but should be first drawn line?
|
||||||
|
args.items[2] = INTEGER_OBJ(wp->w_topline-1);
|
||||||
|
args.items[3] = INTEGER_OBJ(knownmax);
|
||||||
|
if (decor_provider_invoke(p->ns_id, "win", p->redraw_win, args, true, err)) {
|
||||||
|
kvi_push(*line_providers, p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
win_check_ns_hl(wp);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// For each provider invoke the 'line' callback for a given window row.
|
||||||
|
///
|
||||||
|
/// @param wp Window
|
||||||
|
/// @param providers Decoration 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 providers_invoke_line(win_T *wp, DecorProviders *providers, int row, bool *has_decor,
|
||||||
|
char **err)
|
||||||
|
{
|
||||||
|
for (size_t k = 0; k < kv_size(*providers); k++) {
|
||||||
|
DecorProvider *p = kv_A(*providers, k);
|
||||||
|
if (p && p->redraw_line != LUA_NOREF) {
|
||||||
|
FIXED_TEMP_ARRAY(args, 3);
|
||||||
|
args.items[0] = WINDOW_OBJ(wp->handle);
|
||||||
|
args.items[1] = BUFFER_OBJ(wp->w_buffer->handle);
|
||||||
|
args.items[2] = INTEGER_OBJ(row);
|
||||||
|
if (decor_provider_invoke(p->ns_id, "line", p->redraw_line, args, true, err)) {
|
||||||
|
*has_decor = true;
|
||||||
|
} else {
|
||||||
|
// return 'false' or error: skip rest of this window
|
||||||
|
kv_A(*providers, k) = NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
win_check_ns_hl(wp);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// For each provider invoke the 'buf' callback for a given buffer.
|
||||||
|
///
|
||||||
|
/// @param buf Buffer
|
||||||
|
/// @param providers Decoration providers
|
||||||
|
/// @param[out] err Provider error
|
||||||
|
void decor_providers_invoke_buf(buf_T *buf, DecorProviders *providers, char **err)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < kv_size(*providers); i++) {
|
||||||
|
DecorProvider *p = kv_A(*providers, i);
|
||||||
|
if (p && p->redraw_buf != LUA_NOREF) {
|
||||||
|
FIXED_TEMP_ARRAY(args, 1);
|
||||||
|
args.items[0] = BUFFER_OBJ(buf->handle);
|
||||||
|
decor_provider_invoke(p->ns_id, "buf", p->redraw_buf, args, true, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// For each provider invoke the 'end' callback
|
||||||
|
///
|
||||||
|
/// @param providers Decoration providers
|
||||||
|
/// @param displaytick Display tick
|
||||||
|
/// @param[out] err Provider error
|
||||||
|
void decor_providers_invoke_end(DecorProviders *providers, char **err)
|
||||||
|
{
|
||||||
|
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) {
|
||||||
|
FIXED_TEMP_ARRAY(args, 1);
|
||||||
|
args.items[0] = INTEGER_OBJ((int)display_tick);
|
||||||
|
decor_provider_invoke(p->ns_id, "end", p->redraw_end, args, true, err);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
DecorProvider *get_decor_provider(NS ns_id, bool force)
|
||||||
|
{
|
||||||
|
size_t i;
|
||||||
|
size_t len = kv_size(decor_providers);
|
||||||
|
for (i = 0; i < len; i++) {
|
||||||
|
DecorProvider *item = &kv_A(decor_providers, i);
|
||||||
|
if (item->ns_id == ns_id) {
|
||||||
|
return item;
|
||||||
|
} else if (item->ns_id > ns_id) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!force) {
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Adding a new provider, so allocate room in the vector
|
||||||
|
(void)kv_a(decor_providers, len);
|
||||||
|
if (i < len) {
|
||||||
|
// New ns_id needs to be inserted between existing providers to maintain
|
||||||
|
// ordering, so shift other providers with larger ns_id
|
||||||
|
memmove(&kv_A(decor_providers, i + 1),
|
||||||
|
&kv_A(decor_providers, i),
|
||||||
|
(len - i) * sizeof(kv_a(decor_providers, i)));
|
||||||
|
}
|
||||||
|
DecorProvider *item = &kv_a(decor_providers, i);
|
||||||
|
*item = DECORATION_PROVIDER_INIT(ns_id);
|
||||||
|
|
||||||
|
return item;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decor_provider_clear(DecorProvider *p)
|
||||||
|
{
|
||||||
|
if (p == NULL) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
NLUA_CLEAR_REF(p->redraw_start);
|
||||||
|
NLUA_CLEAR_REF(p->redraw_buf);
|
||||||
|
NLUA_CLEAR_REF(p->redraw_win);
|
||||||
|
NLUA_CLEAR_REF(p->redraw_line);
|
||||||
|
NLUA_CLEAR_REF(p->redraw_end);
|
||||||
|
p->active = false;
|
||||||
|
}
|
||||||
|
|
||||||
|
void decor_free_all_mem(void)
|
||||||
|
{
|
||||||
|
for (size_t i = 0; i < kv_size(decor_providers); i++) {
|
||||||
|
decor_provider_clear(&kv_A(decor_providers, i));
|
||||||
|
}
|
||||||
|
kv_destroy(decor_providers);
|
||||||
|
}
|
||||||
|
|
33
src/nvim/decoration_provider.h
Normal file
33
src/nvim/decoration_provider.h
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
#ifndef NVIM_DECORATION_PROVIDER_H
|
||||||
|
#define NVIM_DECORATION_PROVIDER_H
|
||||||
|
|
||||||
|
#include "nvim/buffer_defs.h"
|
||||||
|
#include "nvim/extmark_defs.h"
|
||||||
|
|
||||||
|
typedef struct {
|
||||||
|
NS ns_id;
|
||||||
|
bool active;
|
||||||
|
LuaRef redraw_start;
|
||||||
|
LuaRef redraw_buf;
|
||||||
|
LuaRef redraw_win;
|
||||||
|
LuaRef redraw_line;
|
||||||
|
LuaRef redraw_end;
|
||||||
|
LuaRef hl_def;
|
||||||
|
int hl_valid;
|
||||||
|
} DecorProvider;
|
||||||
|
|
||||||
|
#define DECORATION_PROVIDER_INIT(ns_id) (DecorProvider) \
|
||||||
|
{ ns_id, false, LUA_NOREF, LUA_NOREF, \
|
||||||
|
LUA_NOREF, LUA_NOREF, LUA_NOREF, \
|
||||||
|
LUA_NOREF, -1 }
|
||||||
|
|
||||||
|
typedef kvec_withinit_t(DecorProvider *, 4) DecorProviders;
|
||||||
|
|
||||||
|
EXTERN kvec_t(DecorProvider) decor_providers INIT(= KV_INITIAL_VALUE);
|
||||||
|
EXTERN bool provider_active INIT(= false);
|
||||||
|
|
||||||
|
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||||
|
# include "decoration_provider.h.generated.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif // NVIM_DECORATION_PROVIDER_H
|
@ -5,6 +5,7 @@
|
|||||||
|
|
||||||
#include "nvim/api/private/defs.h"
|
#include "nvim/api/private/defs.h"
|
||||||
#include "nvim/api/private/helpers.h"
|
#include "nvim/api/private/helpers.h"
|
||||||
|
#include "nvim/decoration_provider.h"
|
||||||
#include "nvim/highlight.h"
|
#include "nvim/highlight.h"
|
||||||
#include "nvim/highlight_defs.h"
|
#include "nvim/highlight_defs.h"
|
||||||
#include "nvim/lua/executor.h"
|
#include "nvim/lua/executor.h"
|
||||||
|
@ -14,6 +14,7 @@
|
|||||||
#include "nvim/channel.h"
|
#include "nvim/channel.h"
|
||||||
#include "nvim/charset.h"
|
#include "nvim/charset.h"
|
||||||
#include "nvim/decoration.h"
|
#include "nvim/decoration.h"
|
||||||
|
#include "nvim/decoration_provider.h"
|
||||||
#include "nvim/diff.h"
|
#include "nvim/diff.h"
|
||||||
#include "nvim/eval.h"
|
#include "nvim/eval.h"
|
||||||
#include "nvim/ex_cmds.h"
|
#include "nvim/ex_cmds.h"
|
||||||
|
@ -10,7 +10,7 @@
|
|||||||
|
|
||||||
#include "nvim/api/extmark.h"
|
#include "nvim/api/extmark.h"
|
||||||
#include "nvim/context.h"
|
#include "nvim/context.h"
|
||||||
#include "nvim/decoration.h"
|
#include "nvim/decoration_provider.h"
|
||||||
#include "nvim/eval.h"
|
#include "nvim/eval.h"
|
||||||
#include "nvim/highlight.h"
|
#include "nvim/highlight.h"
|
||||||
#include "nvim/lua/executor.h"
|
#include "nvim/lua/executor.h"
|
||||||
|
@ -75,6 +75,7 @@
|
|||||||
#include "nvim/cursor.h"
|
#include "nvim/cursor.h"
|
||||||
#include "nvim/cursor_shape.h"
|
#include "nvim/cursor_shape.h"
|
||||||
#include "nvim/decoration.h"
|
#include "nvim/decoration.h"
|
||||||
|
#include "nvim/decoration_provider.h"
|
||||||
#include "nvim/diff.h"
|
#include "nvim/diff.h"
|
||||||
#include "nvim/edit.h"
|
#include "nvim/edit.h"
|
||||||
#include "nvim/eval.h"
|
#include "nvim/eval.h"
|
||||||
@ -126,8 +127,6 @@
|
|||||||
#define MB_FILLER_CHAR '<' /* character used when a double-width character
|
#define MB_FILLER_CHAR '<' /* character used when a double-width character
|
||||||
* doesn't fit. */
|
* doesn't fit. */
|
||||||
|
|
||||||
typedef kvec_withinit_t(DecorProvider *, 4) Providers;
|
|
||||||
|
|
||||||
// temporary buffer for rendering a single screenline, so it can be
|
// temporary buffer for rendering a single screenline, so it can be
|
||||||
// compared with previous contents to calculate smallest delta.
|
// compared with previous contents to calculate smallest delta.
|
||||||
// Per-cell attributes
|
// Per-cell attributes
|
||||||
@ -168,36 +167,6 @@ static bool resizing = false;
|
|||||||
|
|
||||||
static char *provider_err = NULL;
|
static char *provider_err = NULL;
|
||||||
|
|
||||||
static bool provider_invoke(NS ns_id, const char *name, LuaRef ref, Array args, bool default_true)
|
|
||||||
{
|
|
||||||
Error err = ERROR_INIT;
|
|
||||||
|
|
||||||
textlock++;
|
|
||||||
provider_active = true;
|
|
||||||
Object ret = nlua_call_ref(ref, name, args, true, &err);
|
|
||||||
provider_active = false;
|
|
||||||
textlock--;
|
|
||||||
|
|
||||||
if (!ERROR_SET(&err)
|
|
||||||
&& api_object_to_bool(ret, "provider %s retval", default_true, &err)) {
|
|
||||||
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 && provider_err == NULL) {
|
|
||||||
static char errbuf[IOSIZE];
|
|
||||||
snprintf(errbuf, sizeof errbuf, "%s: %s", ns_name, err.msg);
|
|
||||||
provider_err = xstrdup(errbuf);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
api_free_object(ret);
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/// Redraw a window later, with update_screen(type).
|
/// Redraw a window later, with update_screen(type).
|
||||||
///
|
///
|
||||||
/// Set must_redraw only if not already set to a higher value.
|
/// Set must_redraw only if not already set to a higher value.
|
||||||
@ -501,28 +470,8 @@ int update_screen(int type)
|
|||||||
|
|
||||||
ui_comp_set_screen_valid(true);
|
ui_comp_set_screen_valid(true);
|
||||||
|
|
||||||
Providers providers;
|
DecorProviders providers;
|
||||||
kvi_init(providers);
|
decor_providers_start(&providers, type, &provider_err);
|
||||||
for (size_t i = 0; i < kv_size(decor_providers); i++) {
|
|
||||||
DecorProvider *p = &kv_A(decor_providers, i);
|
|
||||||
if (!p->active) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool active;
|
|
||||||
if (p->redraw_start != LUA_NOREF) {
|
|
||||||
FIXED_TEMP_ARRAY(args, 2);
|
|
||||||
args.items[0] = INTEGER_OBJ(display_tick);
|
|
||||||
args.items[1] = INTEGER_OBJ(type);
|
|
||||||
active = provider_invoke(p->ns_id, "start", p->redraw_start, args, true);
|
|
||||||
} else {
|
|
||||||
active = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (active) {
|
|
||||||
kvi_push(providers, p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// "start" callback could have changed highlights for global elements
|
// "start" callback could have changed highlights for global elements
|
||||||
if (win_check_ns_hl(NULL)) {
|
if (win_check_ns_hl(NULL)) {
|
||||||
@ -591,14 +540,7 @@ int update_screen(int type)
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (buf->b_mod_tick_decor < display_tick) {
|
if (buf->b_mod_tick_decor < display_tick) {
|
||||||
for (size_t i = 0; i < kv_size(providers); i++) {
|
decor_providers_invoke_buf(buf, &providers, &provider_err);
|
||||||
DecorProvider *p = kv_A(providers, i);
|
|
||||||
if (p && p->redraw_buf != LUA_NOREF) {
|
|
||||||
FIXED_TEMP_ARRAY(args, 1);
|
|
||||||
args.items[0] = BUFFER_OBJ(buf->handle);
|
|
||||||
provider_invoke(p->ns_id, "buf", p->redraw_buf, args, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
buf->b_mod_tick_decor = display_tick;
|
buf->b_mod_tick_decor = display_tick;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -668,18 +610,7 @@ int update_screen(int type)
|
|||||||
}
|
}
|
||||||
did_intro = true;
|
did_intro = true;
|
||||||
|
|
||||||
for (size_t i = 0; i < kv_size(providers); i++) {
|
decor_providers_invoke_end(&providers, &provider_err);
|
||||||
DecorProvider *p = kv_A(providers, i);
|
|
||||||
if (!p->active) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (p->redraw_end != LUA_NOREF) {
|
|
||||||
FIXED_TEMP_ARRAY(args, 1);
|
|
||||||
args.items[0] = INTEGER_OBJ(display_tick);
|
|
||||||
provider_invoke(p->ns_id, "end", p->redraw_end, args, true);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
kvi_destroy(providers);
|
kvi_destroy(providers);
|
||||||
|
|
||||||
|
|
||||||
@ -766,7 +697,7 @@ bool win_cursorline_standout(const win_T *wp)
|
|||||||
* mid: from mid_start to mid_end (update inversion or changed text)
|
* mid: from mid_start to mid_end (update inversion or changed text)
|
||||||
* bot: from bot_start to last row (when scrolled up)
|
* bot: from bot_start to last row (when scrolled up)
|
||||||
*/
|
*/
|
||||||
static void win_update(win_T *wp, Providers *providers)
|
static void win_update(win_T *wp, DecorProviders *providers)
|
||||||
{
|
{
|
||||||
buf_T *buf = wp->w_buffer;
|
buf_T *buf = wp->w_buffer;
|
||||||
int type;
|
int type;
|
||||||
@ -1377,30 +1308,8 @@ static void win_update(win_T *wp, Providers *providers)
|
|||||||
|
|
||||||
decor_redraw_reset(buf, &decor_state);
|
decor_redraw_reset(buf, &decor_state);
|
||||||
|
|
||||||
Providers line_providers;
|
DecorProviders line_providers;
|
||||||
kvi_init(line_providers);
|
decor_providers_invoke_win(wp, providers, &line_providers, &provider_err);
|
||||||
|
|
||||||
linenr_T knownmax = ((wp->w_valid & VALID_BOTLINE)
|
|
||||||
? wp->w_botline
|
|
||||||
: (wp->w_topline + wp->w_height_inner));
|
|
||||||
|
|
||||||
for (size_t k = 0; k < kv_size(*providers); k++) {
|
|
||||||
DecorProvider *p = kv_A(*providers, k);
|
|
||||||
if (p && p->redraw_win != LUA_NOREF) {
|
|
||||||
FIXED_TEMP_ARRAY(args, 4);
|
|
||||||
args.items[0] = WINDOW_OBJ(wp->handle);
|
|
||||||
args.items[1] = BUFFER_OBJ(buf->handle);
|
|
||||||
// TODO(bfredl): we are not using this, but should be first drawn line?
|
|
||||||
args.items[2] = INTEGER_OBJ(wp->w_topline-1);
|
|
||||||
args.items[3] = INTEGER_OBJ(knownmax);
|
|
||||||
if (provider_invoke(p->ns_id, "win", p->redraw_win, args, true)) {
|
|
||||||
kvi_push(line_providers, p);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
win_check_ns_hl(wp);
|
|
||||||
|
|
||||||
|
|
||||||
for (;;) {
|
for (;;) {
|
||||||
/* stop updating when reached the end of the window (check for _past_
|
/* stop updating when reached the end of the window (check for _past_
|
||||||
@ -2028,6 +1937,17 @@ static size_t fill_foldcolumn(char_u *p, win_T *wp, foldinfo_T foldinfo, linenr_
|
|||||||
return MAX(char_counter + (fdc-i), (size_t)fdc);
|
return MAX(char_counter + (fdc-i), (size_t)fdc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static inline void provider_err_virt_text(linenr_T lnum, char *err)
|
||||||
|
{
|
||||||
|
Decoration err_decor = DECORATION_INIT;
|
||||||
|
int hl_err = syn_check_group(S_LEN("ErrorMsg"));
|
||||||
|
kv_push(err_decor.virt_text,
|
||||||
|
((VirtTextChunk){ .text = provider_err,
|
||||||
|
.hl_id = hl_err }));
|
||||||
|
err_decor.virt_text_width = mb_string2cells((char_u *)err);
|
||||||
|
decor_add_ephemeral(lnum-1, 0, lnum-1, 0, &err_decor);
|
||||||
|
}
|
||||||
|
|
||||||
/// Display line "lnum" of window 'wp' on the screen.
|
/// Display line "lnum" of window 'wp' on the screen.
|
||||||
/// wp->w_virtcol needs to be valid.
|
/// wp->w_virtcol needs to be valid.
|
||||||
///
|
///
|
||||||
@ -2043,7 +1963,7 @@ static size_t fill_foldcolumn(char_u *p, win_T *wp, foldinfo_T foldinfo, linenr_
|
|||||||
///
|
///
|
||||||
/// @return the number of last row the line occupies.
|
/// @return the number of last row the line occupies.
|
||||||
static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool nochange,
|
||||||
bool number_only, foldinfo_T foldinfo, Providers *providers)
|
bool number_only, foldinfo_T foldinfo, DecorProviders *providers)
|
||||||
{
|
{
|
||||||
int c = 0; // init for GCC
|
int c = 0; // init for GCC
|
||||||
long vcol = 0; // virtual column (for tabs)
|
long vcol = 0; // virtual column (for tabs)
|
||||||
@ -2231,34 +2151,12 @@ static int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, bool noc
|
|||||||
|
|
||||||
has_decor = decor_redraw_line(buf, lnum-1, &decor_state);
|
has_decor = decor_redraw_line(buf, lnum-1, &decor_state);
|
||||||
|
|
||||||
for (size_t k = 0; k < kv_size(*providers); k++) {
|
providers_invoke_line(wp, providers, lnum-1, &has_decor, &provider_err);
|
||||||
DecorProvider *p = kv_A(*providers, k);
|
|
||||||
if (p && p->redraw_line != LUA_NOREF) {
|
|
||||||
FIXED_TEMP_ARRAY(args, 3);
|
|
||||||
args.items[0] = WINDOW_OBJ(wp->handle);
|
|
||||||
args.items[1] = BUFFER_OBJ(buf->handle);
|
|
||||||
args.items[2] = INTEGER_OBJ(lnum-1);
|
|
||||||
if (provider_invoke(p->ns_id, "line", p->redraw_line, args, true)) {
|
|
||||||
has_decor = true;
|
|
||||||
} else {
|
|
||||||
// return 'false' or error: skip rest of this window
|
|
||||||
kv_A(*providers, k) = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
win_check_ns_hl(wp);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (provider_err) {
|
if (provider_err) {
|
||||||
Decoration err_decor = DECORATION_INIT;
|
provider_err_virt_text(lnum, provider_err);
|
||||||
int hl_err = syn_check_group(S_LEN("ErrorMsg"));
|
|
||||||
kv_push(err_decor.virt_text,
|
|
||||||
((VirtTextChunk){ .text = provider_err,
|
|
||||||
.hl_id = hl_err }));
|
|
||||||
err_decor.virt_text_width = mb_string2cells((char_u *)provider_err);
|
|
||||||
decor_add_ephemeral(lnum-1, 0, lnum-1, 0, &err_decor);
|
|
||||||
provider_err = NULL;
|
|
||||||
has_decor = true;
|
has_decor = true;
|
||||||
|
provider_err = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (has_decor) {
|
if (has_decor) {
|
||||||
|
Loading…
Reference in New Issue
Block a user