mirror of
https://github.com/neovim/neovim.git
synced 2025-02-25 18:55:25 -06:00
Merge pull request #26528 from bfredl/nodrawstate
refactor(drawline): remove LineDrawState and wlv->saved_n_extra
This commit is contained in:
commit
d9d9d94343
@ -665,9 +665,8 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
|
||||
}
|
||||
|
||||
if (HAS_KEY(opts, set_extmark, sign_text)) {
|
||||
sign.text.ptr = NULL;
|
||||
VALIDATE_S(init_sign_text(NULL, &sign.text.ptr, opts->sign_text.data),
|
||||
"sign_text", "", {
|
||||
sign.text[0] = 0;
|
||||
VALIDATE_S(init_sign_text(NULL, sign.text, opts->sign_text.data), "sign_text", "", {
|
||||
goto error;
|
||||
});
|
||||
sign.flags |= kSHIsSign;
|
||||
@ -785,7 +784,7 @@ Integer nvim_buf_set_extmark(Buffer buffer, Integer ns_id, Integer line, Integer
|
||||
uint32_t decor_indexed = DECOR_ID_INVALID;
|
||||
if (sign.flags & kSHIsSign) {
|
||||
decor_indexed = decor_put_sh(sign);
|
||||
if (sign.text.ptr != NULL) {
|
||||
if (sign.text[0]) {
|
||||
decor_flags |= MT_FLAG_DECOR_SIGNTEXT;
|
||||
}
|
||||
if (sign.number_hl_id || sign.line_hl_id || sign.cursorline_hl_id) {
|
||||
|
@ -5,6 +5,7 @@
|
||||
|
||||
#include "nvim/api/extmark.h"
|
||||
#include "nvim/api/private/helpers.h"
|
||||
#include "nvim/ascii_defs.h"
|
||||
#include "nvim/buffer_defs.h"
|
||||
#include "nvim/decoration.h"
|
||||
#include "nvim/drawscreen.h"
|
||||
@ -19,6 +20,7 @@
|
||||
#include "nvim/move.h"
|
||||
#include "nvim/option_vars.h"
|
||||
#include "nvim/pos_defs.h"
|
||||
#include "nvim/sign.h"
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "decoration.c.generated.h"
|
||||
@ -158,7 +160,7 @@ DecorSignHighlight decor_sh_from_inline(DecorHighlightInline item)
|
||||
DecorSignHighlight conv = {
|
||||
.flags = item.flags,
|
||||
.priority = item.priority,
|
||||
.text.sc[0] = item.conceal_char,
|
||||
.text[0] = item.conceal_char,
|
||||
.hl_id = item.hl_id,
|
||||
.number_hl_id = 0,
|
||||
.line_hl_id = 0,
|
||||
@ -207,7 +209,7 @@ void buf_put_decor_sh(buf_T *buf, DecorSignHighlight *sh, int row1, int row2)
|
||||
if (sh->flags & kSHIsSign) {
|
||||
sh->sign_add_id = sign_add_id++;
|
||||
buf->b_signs++;
|
||||
if (sh->text.ptr) {
|
||||
if (sh->text[0]) {
|
||||
buf->b_signs_with_text++;
|
||||
buf_signcols_invalidate_range(buf, row1, row2, 1);
|
||||
}
|
||||
@ -253,7 +255,7 @@ void buf_remove_decor_sh(buf_T *buf, int row1, int row2, DecorSignHighlight *sh)
|
||||
if (sh->flags & kSHIsSign) {
|
||||
assert(buf->b_signs > 0);
|
||||
buf->b_signs--;
|
||||
if (sh->text.ptr) {
|
||||
if (sh->text[0]) {
|
||||
assert(buf->b_signs_with_text > 0);
|
||||
buf->b_signs_with_text--;
|
||||
if (row2 >= row1) {
|
||||
@ -311,9 +313,6 @@ void decor_free_inner(DecorVirtText *vt, uint32_t first_idx)
|
||||
uint32_t idx = first_idx;
|
||||
while (idx != DECOR_ID_INVALID) {
|
||||
DecorSignHighlight *sh = &kv_A(decor_items, idx);
|
||||
if (sh->flags & kSHIsSign) {
|
||||
xfree(sh->text.ptr);
|
||||
}
|
||||
if (sh->flags & kSHIsSign) {
|
||||
xfree(sh->sign_name);
|
||||
}
|
||||
@ -362,8 +361,11 @@ void decor_check_invalid_glyphs(void)
|
||||
{
|
||||
for (size_t i = 0; i < kv_size(decor_items); i++) {
|
||||
DecorSignHighlight *it = &kv_A(decor_items, i);
|
||||
if ((it->flags & kSHConceal) && schar_high(it->text.sc[0])) {
|
||||
it->text.sc[0] = schar_from_char(schar_get_first_codepoint(it->text.sc[0]));
|
||||
int width = (it->flags & kSHIsSign) ? SIGN_WIDTH : ((it->flags & kSHConceal) ? 1 : 0);
|
||||
for (int j = 0; j < width; j++) {
|
||||
if (schar_high(it->text[j])) {
|
||||
it->text[j] = schar_from_char(schar_get_first_codepoint(it->text[j]));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -661,7 +663,7 @@ next_mark:
|
||||
if (item.start_row == state->row && item.start_col == col) {
|
||||
DecorSignHighlight *sh = &item.data.sh;
|
||||
conceal = 2;
|
||||
conceal_char = sh->text.sc[0];
|
||||
conceal_char = sh->text[0];
|
||||
state->col_until = MIN(state->col_until, item.start_col);
|
||||
conceal_attr = item.attr_id;
|
||||
}
|
||||
@ -729,7 +731,7 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[],
|
||||
while (marktree_itr_step_overlap(buf->b_marktree, itr, &pair)) {
|
||||
if (!mt_invalid(pair.start) && mt_decor_sign(pair.start)) {
|
||||
DecorSignHighlight *sh = decor_find_sign(mt_decor(pair.start));
|
||||
num_text += (sh->text.ptr != NULL);
|
||||
num_text += (sh->text[0] != NUL);
|
||||
kv_push(signs, ((SignItem){ sh, pair.start.id }));
|
||||
}
|
||||
}
|
||||
@ -741,7 +743,7 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[],
|
||||
}
|
||||
if (!mt_end(mark) && !mt_invalid(mark) && mt_decor_sign(mark)) {
|
||||
DecorSignHighlight *sh = decor_find_sign(mt_decor(mark));
|
||||
num_text += (sh->text.ptr != NULL);
|
||||
num_text += (sh->text[0] != NUL);
|
||||
kv_push(signs, ((SignItem){ sh, mark.id }));
|
||||
}
|
||||
|
||||
@ -755,8 +757,8 @@ void decor_redraw_signs(win_T *wp, buf_T *buf, int row, SignTextAttrs sattrs[],
|
||||
|
||||
for (size_t i = 0; i < kv_size(signs); i++) {
|
||||
DecorSignHighlight *sh = kv_A(signs, i).sh;
|
||||
if (idx >= 0 && sh->text.ptr) {
|
||||
sattrs[idx].text = sh->text.ptr;
|
||||
if (idx >= 0 && sh->text[0]) {
|
||||
memcpy(sattrs[idx].text, sh->text, SIGN_WIDTH * sizeof(sattr_T));
|
||||
sattrs[idx--].hl_id = sh->hl_id;
|
||||
}
|
||||
if (*num_id == 0) {
|
||||
@ -1033,7 +1035,7 @@ void decor_to_dict_legacy(Dictionary *dict, DecorInline decor, bool hl_name)
|
||||
PUT(*dict, "hl_eol", BOOLEAN_OBJ(sh_hl.flags & kSHHlEol));
|
||||
if (sh_hl.flags & kSHConceal) {
|
||||
char buf[MAX_SCHAR_SIZE];
|
||||
schar_get(buf, sh_hl.text.sc[0]);
|
||||
schar_get(buf, sh_hl.text[0]);
|
||||
PUT(*dict, "conceal", CSTR_TO_OBJ(buf));
|
||||
}
|
||||
|
||||
@ -1081,8 +1083,10 @@ void decor_to_dict_legacy(Dictionary *dict, DecorInline decor, bool hl_name)
|
||||
}
|
||||
|
||||
if (sh_sign.flags & kSHIsSign) {
|
||||
if (sh_sign.text.ptr) {
|
||||
PUT(*dict, "sign_text", CSTR_TO_OBJ(sh_sign.text.ptr));
|
||||
if (sh_sign.text[0]) {
|
||||
char buf[SIGN_WIDTH * MAX_SCHAR_SIZE];
|
||||
describe_sign_text(buf, sh_sign.text);
|
||||
PUT(*dict, "sign_text", CSTR_TO_OBJ(buf));
|
||||
}
|
||||
|
||||
if (sh_sign.sign_name) {
|
||||
|
@ -59,11 +59,7 @@ typedef struct {
|
||||
uint16_t flags;
|
||||
DecorPriority priority;
|
||||
int hl_id; // if sign: highlight of sign text
|
||||
// TODO(bfredl): Later signs should use sc[2] as well.
|
||||
union {
|
||||
char *ptr; // sign
|
||||
schar_T sc[2]; // conceal text (only sc[0] used)
|
||||
} text;
|
||||
schar_T text[SIGN_WIDTH]; // conceal text only uses text[0]
|
||||
// NOTE: if more functionality is added to a Highlight these should be overloaded
|
||||
// or restructured
|
||||
char *sign_name;
|
||||
@ -74,7 +70,7 @@ typedef struct {
|
||||
uint32_t next;
|
||||
} DecorSignHighlight;
|
||||
|
||||
#define DECOR_SIGN_HIGHLIGHT_INIT { 0, DECOR_PRIORITY_BASE, 0, { .ptr = NULL }, NULL, 0, 0, 0, 0, \
|
||||
#define DECOR_SIGN_HIGHLIGHT_INIT { 0, DECOR_PRIORITY_BASE, 0, { 0, 0 }, NULL, 0, 0, 0, 0, \
|
||||
DECOR_ID_INVALID }
|
||||
|
||||
enum {
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -26,6 +26,7 @@
|
||||
#include "nvim/fold.h"
|
||||
#include "nvim/gettext.h"
|
||||
#include "nvim/globals.h"
|
||||
#include "nvim/grid.h"
|
||||
#include "nvim/highlight.h"
|
||||
#include "nvim/highlight_group.h"
|
||||
#include "nvim/macros_defs.h"
|
||||
@ -104,7 +105,7 @@ static void buf_set_sign(buf_T *buf, uint32_t *id, char *group, int prio, linenr
|
||||
DecorSignHighlight sign = DECOR_SIGN_HIGHLIGHT_INIT;
|
||||
|
||||
sign.flags |= kSHIsSign;
|
||||
sign.text.ptr = sp->sn_text ? xstrdup(sp->sn_text) : NULL;
|
||||
memcpy(sign.text, sp->sn_text, SIGN_WIDTH * sizeof(schar_T));
|
||||
sign.sign_name = xstrdup(sp->sn_name);
|
||||
sign.hl_id = sp->sn_text_hl;
|
||||
sign.line_hl_id = sp->sn_line_hl;
|
||||
@ -113,7 +114,7 @@ static void buf_set_sign(buf_T *buf, uint32_t *id, char *group, int prio, linenr
|
||||
sign.priority = (DecorPriority)prio;
|
||||
|
||||
bool has_hl = (sp->sn_line_hl || sp->sn_num_hl || sp->sn_cul_hl);
|
||||
uint16_t decor_flags = (sp->sn_text ? MT_FLAG_DECOR_SIGNTEXT : 0)
|
||||
uint16_t decor_flags = (sp->sn_text[0] ? MT_FLAG_DECOR_SIGNTEXT : 0)
|
||||
| (has_hl ? MT_FLAG_DECOR_SIGNHL : 0);
|
||||
|
||||
DecorInline decor = { .ext = true, .data.ext = { .vt = NULL, .sh_idx = decor_put_sh(sign) } };
|
||||
@ -333,9 +334,24 @@ static int sign_cmd_idx(char *begin_cmd, char *end_cmd)
|
||||
return idx;
|
||||
}
|
||||
|
||||
/// buf must be SIGN_WIDTH * MAX_SCHAR_SIZE (no extra +1 needed)
|
||||
size_t describe_sign_text(char *buf, schar_T *sign_text)
|
||||
{
|
||||
size_t p = 0;
|
||||
for (int i = 0; i < SIGN_WIDTH; i++) {
|
||||
schar_get(buf + p, sign_text[i]);
|
||||
size_t len = strlen(buf + p);
|
||||
if (len == 0) {
|
||||
break;
|
||||
}
|
||||
p += len;
|
||||
}
|
||||
return p;
|
||||
}
|
||||
|
||||
/// Initialize the "text" for a new sign and store in "sign_text".
|
||||
/// "sp" is NULL for signs added through nvim_buf_set_extmark().
|
||||
int init_sign_text(sign_T *sp, char **sign_text, char *text)
|
||||
int init_sign_text(sign_T *sp, schar_T *sign_text, char *text)
|
||||
{
|
||||
char *s;
|
||||
char *endp = text + (int)strlen(text);
|
||||
@ -350,34 +366,29 @@ int init_sign_text(sign_T *sp, char **sign_text, char *text)
|
||||
// Count cells and check for non-printable chars
|
||||
int cells = 0;
|
||||
for (s = text; s < endp; s += utfc_ptr2len(s)) {
|
||||
if (!vim_isprintc(utf_ptr2char(s))) {
|
||||
int c;
|
||||
sign_text[cells] = utfc_ptr2schar(s, &c);
|
||||
if (!vim_isprintc(c)) {
|
||||
break;
|
||||
}
|
||||
cells += utf_ptr2cells(s);
|
||||
int width = utf_char2cells(c);
|
||||
if (width == 2) {
|
||||
sign_text[cells + 1] = 0;
|
||||
}
|
||||
cells += width;
|
||||
}
|
||||
// Currently must be empty, one or two display cells
|
||||
if (s != endp || cells > 2) {
|
||||
if (s != endp || cells > SIGN_WIDTH) {
|
||||
if (sp != NULL) {
|
||||
semsg(_("E239: Invalid sign text: %s"), text);
|
||||
}
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
if (cells < 1) {
|
||||
if (sp != NULL) {
|
||||
sp->sn_text = NULL;
|
||||
}
|
||||
return OK;
|
||||
}
|
||||
|
||||
if (sp != NULL) {
|
||||
xfree(sp->sn_text);
|
||||
}
|
||||
// Allocate one byte more if we need to pad up with a space.
|
||||
size_t len = (size_t)(endp - text + (cells == 1));
|
||||
*sign_text = xstrnsave(text, len);
|
||||
|
||||
if (cells == 1) {
|
||||
STRCPY(*sign_text + len - 1, " ");
|
||||
sign_text[0] = 0;
|
||||
} else if (cells == 1) {
|
||||
sign_text[1] = schar_from_ascii(' ');
|
||||
}
|
||||
|
||||
return OK;
|
||||
@ -411,7 +422,7 @@ static int sign_define_by_name(char *name, char *icon, char *text, char *linehl,
|
||||
backslash_halve((*sp)->sn_icon);
|
||||
}
|
||||
|
||||
if (text != NULL && (init_sign_text(*sp, &(*sp)->sn_text, text) == FAIL)) {
|
||||
if (text != NULL && (init_sign_text(*sp, (*sp)->sn_text, text) == FAIL)) {
|
||||
return FAIL;
|
||||
}
|
||||
|
||||
@ -436,7 +447,6 @@ static int sign_undefine_by_name(const char *name)
|
||||
}
|
||||
|
||||
xfree(sp->sn_name);
|
||||
xfree(sp->sn_text);
|
||||
xfree(sp->sn_icon);
|
||||
xfree(sp);
|
||||
return OK;
|
||||
@ -451,9 +461,11 @@ static void sign_list_defined(sign_T *sp)
|
||||
msg_outtrans(sp->sn_icon, 0);
|
||||
msg_puts(_(" (not supported)"));
|
||||
}
|
||||
if (sp->sn_text != NULL) {
|
||||
if (sp->sn_text[0]) {
|
||||
msg_puts(" text=");
|
||||
msg_outtrans(sp->sn_text, 0);
|
||||
char buf[SIGN_WIDTH * MAX_SCHAR_SIZE];
|
||||
describe_sign_text(buf, sp->sn_text);
|
||||
msg_outtrans(buf, 0);
|
||||
}
|
||||
static char *arg[] = { " linehl=", " texthl=", " culhl=", " numhl=" };
|
||||
int hl[] = { sp->sn_line_hl, sp->sn_text_hl, sp->sn_cul_hl, sp->sn_num_hl };
|
||||
@ -880,8 +892,10 @@ static dict_T *sign_get_info_dict(sign_T *sp)
|
||||
if (sp->sn_icon != NULL) {
|
||||
tv_dict_add_str(d, S_LEN("icon"), sp->sn_icon);
|
||||
}
|
||||
if (sp->sn_text != NULL) {
|
||||
tv_dict_add_str(d, S_LEN("text"), sp->sn_text);
|
||||
if (sp->sn_text[0]) {
|
||||
char buf[SIGN_WIDTH * MAX_SCHAR_SIZE];
|
||||
describe_sign_text(buf, sp->sn_text);
|
||||
tv_dict_add_str(d, S_LEN("text"), buf);
|
||||
}
|
||||
static char *arg[] = { "linehl", "texthl", "culhl", "numhl" };
|
||||
int hl[] = { sp->sn_line_hl, sp->sn_text_hl, sp->sn_cul_hl, sp->sn_num_hl };
|
||||
|
@ -1,8 +1,10 @@
|
||||
#pragma once
|
||||
|
||||
#include "nvim/types_defs.h"
|
||||
|
||||
/// Sign attributes. Used by the screen refresh routines.
|
||||
typedef struct {
|
||||
char *text;
|
||||
schar_T text[SIGN_WIDTH];
|
||||
int hl_id;
|
||||
} SignTextAttrs;
|
||||
|
||||
@ -10,13 +12,12 @@ typedef struct {
|
||||
typedef struct sign {
|
||||
char *sn_name; // name of sign
|
||||
char *sn_icon; // name of pixmap
|
||||
char *sn_text; // text used instead of pixmap
|
||||
schar_T sn_text[SIGN_WIDTH]; // text used instead of pixmap
|
||||
int sn_line_hl; // highlight ID for line
|
||||
int sn_text_hl; // highlight ID for text
|
||||
int sn_cul_hl; // highlight ID for text on current line when 'cursorline' is set
|
||||
int sn_num_hl; // highlight ID for line number
|
||||
} sign_T;
|
||||
|
||||
enum { SIGN_WIDTH = 2, }; ///< Number of display cells for a sign in the signcolumn
|
||||
enum { SIGN_SHOW_MAX = 9, }; ///< Maximum number of signs shown on a single line
|
||||
enum { SIGN_DEF_PRIO = 10, }; ///< Default sign highlight priority
|
||||
|
@ -1640,20 +1640,32 @@ int build_stl_str_hl(win_T *wp, char *out, size_t outlen, char *fmt, OptIndex op
|
||||
|
||||
char *p = NULL;
|
||||
if (fold) {
|
||||
size_t n = fill_foldcolumn(out_p, wp, stcp->foldinfo,
|
||||
(linenr_T)get_vim_var_nr(VV_LNUM), NULL);
|
||||
schar_T fold_buf[10];
|
||||
size_t n = fill_foldcolumn(NULL, wp, stcp->foldinfo,
|
||||
(linenr_T)get_vim_var_nr(VV_LNUM), 0, fold_buf);
|
||||
stl_items[curitem].minwid = -((stcp->use_cul ? HLF_CLF : HLF_FC) + 1);
|
||||
size_t buflen = 0;
|
||||
// TODO(bfredl): this is very backwards. we must support schar_T
|
||||
// being used directly in 'statuscol'
|
||||
for (size_t i = 0; i < n; i++) {
|
||||
schar_get(out_p + buflen, fold_buf[i]);
|
||||
buflen += strlen(out_p + buflen);
|
||||
}
|
||||
p = out_p;
|
||||
p[n] = NUL;
|
||||
}
|
||||
|
||||
char buf[SIGN_WIDTH * MAX_SCHAR_SIZE];
|
||||
size_t buflen = 0;
|
||||
varnumber_T virtnum = get_vim_var_nr(VV_VIRTNUM);
|
||||
for (int i = 0; i < width; i++) {
|
||||
if (!fold) {
|
||||
SignTextAttrs *sattr = virtnum ? NULL : &stcp->sattrs[i];
|
||||
p = sattr && sattr->text ? sattr->text : " ";
|
||||
stl_items[curitem].minwid = -(sattr && sattr->text
|
||||
p = " ";
|
||||
if (sattr && sattr->text[0]) {
|
||||
describe_sign_text(buf, sattr->text);
|
||||
p = buf;
|
||||
}
|
||||
stl_items[curitem].minwid = -(sattr && sattr->text[0]
|
||||
? (stcp->sign_cul_id ? stcp->sign_cul_id : sattr->hl_id)
|
||||
: (stcp->use_cul ? HLF_CLS : HLF_SC) + 1);
|
||||
}
|
||||
|
@ -56,6 +56,8 @@ typedef struct {
|
||||
} SignRange;
|
||||
#define SIGNRANGE_INIT { 0, 0 }
|
||||
|
||||
enum { SIGN_WIDTH = 2, }; ///< Number of display cells for a sign in the signcolumn
|
||||
|
||||
typedef struct file_buffer buf_T;
|
||||
typedef struct loop Loop;
|
||||
typedef struct regprog regprog_T;
|
||||
|
@ -415,8 +415,8 @@ describe('Signs', function()
|
||||
feed('gg100aa<Esc>')
|
||||
screen:expect([[
|
||||
{1: >> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
aa^a |
|
||||
{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{8: }aa^a |
|
||||
{8: 2 }b |
|
||||
{6: 3 }c |
|
||||
{6: 4 } |
|
||||
@ -430,10 +430,10 @@ describe('Signs', function()
|
||||
feed('<C-Y>')
|
||||
-- number column on virtual lines should be empty
|
||||
screen:expect([[
|
||||
VIRT LINES |
|
||||
{6: }VIRT LINES |
|
||||
{1: >> }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
aa^a |
|
||||
{8: }aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa|
|
||||
{8: }aa^a |
|
||||
{8: 2 }b |
|
||||
{6: 3 }c |
|
||||
{6: 4 } |
|
||||
|
Loading…
Reference in New Issue
Block a user