aboutsummaryrefslogtreecommitdiff
path: root/src/nvim
diff options
context:
space:
mode:
authorLewis Russell <lewis6991@gmail.com>2022-08-16 12:27:07 +0100
committerLewis Russell <lewis6991@gmail.com>2022-08-19 10:01:40 +0100
commit51063a90df4cc8af4e1111dd50194ae487e8097e (patch)
tree9aa73fc53a6db22068e7ebc9761c81ca38feaa25 /src/nvim
parenta5ed89c972a23c46eb3988fe8c2c8ae0d7ed844f (diff)
downloadrneovim-51063a90df4cc8af4e1111dd50194ae487e8097e.tar.gz
rneovim-51063a90df4cc8af4e1111dd50194ae487e8097e.tar.bz2
rneovim-51063a90df4cc8af4e1111dd50194ae487e8097e.zip
vim-patch:8.1.2057: the screen.c file is much too big
Problem: The screen.c file is much too big. Solution: Split it in three parts. (Yegappan Lakshmanan, closes vim/vim#4943) https://github.com/vim/vim/commit/7528d1f6b5422750eb778dfb550cfd0b0e540964 This is an approximation vim-patch 8.1.2057. Applying the patch directly isn't feasible since our version of screen.c has diverged too much, however we still introduce drawscreen.c and drawline.c: - screen.c is now a much smaller file used for low level screen functions - drawline.c contains everything needed for win_line() - drawscreen.c contains everything needed for update_screen() Co-authored-by: zeertzjq <zeertzjq@outlook.com>
Diffstat (limited to 'src/nvim')
-rw-r--r--src/nvim/api/buffer.c2
-rw-r--r--src/nvim/api/extmark.c2
-rw-r--r--src/nvim/api/vim.c2
-rw-r--r--src/nvim/api/win_config.c2
-rw-r--r--src/nvim/api/window.c2
-rw-r--r--src/nvim/autocmd.c2
-rw-r--r--src/nvim/buffer.c2
-rw-r--r--src/nvim/change.c2
-rw-r--r--src/nvim/cursor.c2
-rw-r--r--src/nvim/debugger.c2
-rw-r--r--src/nvim/decoration.c2
-rw-r--r--src/nvim/diff.c2
-rw-r--r--src/nvim/digraph.c2
-rw-r--r--src/nvim/drawline.c2706
-rw-r--r--src/nvim/drawline.h24
-rw-r--r--src/nvim/drawscreen.c2325
-rw-r--r--src/nvim/drawscreen.h25
-rw-r--r--src/nvim/edit.c2
-rw-r--r--src/nvim/eval/vars.c1
-rw-r--r--src/nvim/ex_cmds.c2
-rw-r--r--src/nvim/ex_docmd.c2
-rw-r--r--src/nvim/ex_getln.c2
-rw-r--r--src/nvim/fileio.c2
-rw-r--r--src/nvim/fold.c2
-rw-r--r--src/nvim/getchar.c2
-rw-r--r--src/nvim/grid.c131
-rw-r--r--src/nvim/grid.h3
-rw-r--r--src/nvim/highlight.c2
-rw-r--r--src/nvim/highlight_group.c2
-rw-r--r--src/nvim/insexpand.c2
-rw-r--r--src/nvim/lua/executor.c2
-rw-r--r--src/nvim/main.c2
-rw-r--r--src/nvim/match.c2
-rw-r--r--src/nvim/mbyte.c2
-rw-r--r--src/nvim/memline.c2
-rw-r--r--src/nvim/message.c2
-rw-r--r--src/nvim/mouse.c2
-rw-r--r--src/nvim/move.c2
-rw-r--r--src/nvim/normal.c2
-rw-r--r--src/nvim/ops.c2
-rw-r--r--src/nvim/option.c2
-rw-r--r--src/nvim/popupmenu.c2
-rw-r--r--src/nvim/quickfix.c2
-rw-r--r--src/nvim/screen.c5211
-rw-r--r--src/nvim/screen.h32
-rw-r--r--src/nvim/search.c2
-rw-r--r--src/nvim/sign.c2
-rw-r--r--src/nvim/spell.c2
-rw-r--r--src/nvim/spellfile.c2
-rw-r--r--src/nvim/state.c2
-rw-r--r--src/nvim/syntax.c2
-rw-r--r--src/nvim/tag.c2
-rw-r--r--src/nvim/terminal.c2
-rw-r--r--src/nvim/ui.c2
-rw-r--r--src/nvim/undo.c2
-rw-r--r--src/nvim/version.c2
-rw-r--r--src/nvim/window.c2
57 files changed, 5302 insertions, 5252 deletions
diff --git a/src/nvim/api/buffer.c b/src/nvim/api/buffer.c
index 9bb3c680aa..5e90e40dd3 100644
--- a/src/nvim/api/buffer.c
+++ b/src/nvim/api/buffer.c
@@ -18,6 +18,7 @@
#include "nvim/change.h"
#include "nvim/cursor.h"
#include "nvim/decoration.h"
+#include "nvim/drawscreen.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h"
#include "nvim/extmark.h"
@@ -28,7 +29,6 @@
#include "nvim/memory.h"
#include "nvim/move.h"
#include "nvim/ops.h"
-#include "nvim/screen.h"
#include "nvim/undo.h"
#include "nvim/vim.h"
#include "nvim/window.h"
diff --git a/src/nvim/api/extmark.c b/src/nvim/api/extmark.c
index b8295601c1..933aa85530 100644
--- a/src/nvim/api/extmark.c
+++ b/src/nvim/api/extmark.c
@@ -10,11 +10,11 @@
#include "nvim/api/private/helpers.h"
#include "nvim/charset.h"
#include "nvim/decoration_provider.h"
+#include "nvim/drawscreen.h"
#include "nvim/extmark.h"
#include "nvim/highlight_group.h"
#include "nvim/lua/executor.h"
#include "nvim/memline.h"
-#include "nvim/screen.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
# include "api/extmark.c.generated.h"
diff --git a/src/nvim/api/vim.c b/src/nvim/api/vim.c
index 53ffac1474..e4dc219e9a 100644
--- a/src/nvim/api/vim.c
+++ b/src/nvim/api/vim.c
@@ -23,6 +23,7 @@
#include "nvim/context.h"
#include "nvim/decoration.h"
#include "nvim/decoration_provider.h"
+#include "nvim/drawscreen.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/typval.h"
@@ -55,7 +56,6 @@
#include "nvim/os/process.h"
#include "nvim/popupmenu.h"
#include "nvim/runtime.h"
-#include "nvim/screen.h"
#include "nvim/state.h"
#include "nvim/types.h"
#include "nvim/ui.h"
diff --git a/src/nvim/api/win_config.c b/src/nvim/api/win_config.c
index a153f746b6..6c37df6af8 100644
--- a/src/nvim/api/win_config.c
+++ b/src/nvim/api/win_config.c
@@ -10,9 +10,9 @@
#include "nvim/api/private/helpers.h"
#include "nvim/api/win_config.h"
#include "nvim/ascii.h"
+#include "nvim/drawscreen.h"
#include "nvim/highlight_group.h"
#include "nvim/option.h"
-#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/syntax.h"
#include "nvim/ui.h"
diff --git a/src/nvim/api/window.c b/src/nvim/api/window.c
index d0a2ff766e..580dfd8639 100644
--- a/src/nvim/api/window.c
+++ b/src/nvim/api/window.c
@@ -12,12 +12,12 @@
#include "nvim/ascii.h"
#include "nvim/buffer.h"
#include "nvim/cursor.h"
+#include "nvim/drawscreen.h"
#include "nvim/ex_docmd.h"
#include "nvim/globals.h"
#include "nvim/lua/executor.h"
#include "nvim/move.h"
#include "nvim/option.h"
-#include "nvim/screen.h"
#include "nvim/syntax.h"
#include "nvim/vim.h"
#include "nvim/window.h"
diff --git a/src/nvim/autocmd.c b/src/nvim/autocmd.c
index 218aad0099..b5b2a73be1 100644
--- a/src/nvim/autocmd.c
+++ b/src/nvim/autocmd.c
@@ -11,6 +11,7 @@
#include "nvim/buffer.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/drawscreen.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/eval/userfunc.h"
@@ -29,7 +30,6 @@
#include "nvim/profile.h"
#include "nvim/regexp.h"
#include "nvim/runtime.h"
-#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/state.h"
#include "nvim/ui_compositor.h"
diff --git a/src/nvim/buffer.c b/src/nvim/buffer.c
index 08c2746d7b..f9bce2476f 100644
--- a/src/nvim/buffer.c
+++ b/src/nvim/buffer.c
@@ -38,6 +38,7 @@
#include "nvim/decoration.h"
#include "nvim/diff.h"
#include "nvim/digraph.h"
+#include "nvim/drawscreen.h"
#include "nvim/eval.h"
#include "nvim/eval/vars.h"
#include "nvim/ex_cmds.h"
@@ -73,7 +74,6 @@
#include "nvim/quickfix.h"
#include "nvim/regexp.h"
#include "nvim/runtime.h"
-#include "nvim/screen.h"
#include "nvim/sign.h"
#include "nvim/spell.h"
#include "nvim/strings.h"
diff --git a/src/nvim/change.c b/src/nvim/change.c
index f0ca5f3af3..5184dc0689 100644
--- a/src/nvim/change.c
+++ b/src/nvim/change.c
@@ -10,6 +10,7 @@
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
+#include "nvim/drawscreen.h"
#include "nvim/edit.h"
#include "nvim/eval.h"
#include "nvim/extmark.h"
@@ -23,7 +24,6 @@
#include "nvim/move.h"
#include "nvim/option.h"
#include "nvim/plines.h"
-#include "nvim/screen.h"
#include "nvim/search.h"
#include "nvim/state.h"
#include "nvim/ui.h"
diff --git a/src/nvim/cursor.c b/src/nvim/cursor.c
index 1446257f7e..d4670dedc7 100644
--- a/src/nvim/cursor.c
+++ b/src/nvim/cursor.c
@@ -9,6 +9,7 @@
#include "nvim/change.h"
#include "nvim/charset.h"
#include "nvim/cursor.h"
+#include "nvim/drawscreen.h"
#include "nvim/extmark.h"
#include "nvim/fold.h"
#include "nvim/mark.h"
@@ -17,7 +18,6 @@
#include "nvim/move.h"
#include "nvim/option.h"
#include "nvim/plines.h"
-#include "nvim/screen.h"
#include "nvim/state.h"
#include "nvim/vim.h"
diff --git a/src/nvim/debugger.c b/src/nvim/debugger.c
index 72d776d1e4..a061bd961b 100644
--- a/src/nvim/debugger.c
+++ b/src/nvim/debugger.c
@@ -8,6 +8,7 @@
#include "nvim/ascii.h"
#include "nvim/charset.h"
#include "nvim/debugger.h"
+#include "nvim/drawscreen.h"
#include "nvim/eval.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
@@ -18,7 +19,6 @@
#include "nvim/pos.h"
#include "nvim/regexp.h"
#include "nvim/runtime.h"
-#include "nvim/screen.h"
#include "nvim/types.h"
#include "nvim/vim.h"
diff --git a/src/nvim/decoration.c b/src/nvim/decoration.c
index ef4162a143..a93fb599c4 100644
--- a/src/nvim/decoration.c
+++ b/src/nvim/decoration.c
@@ -4,12 +4,12 @@
#include "nvim/api/ui.h"
#include "nvim/buffer.h"
#include "nvim/decoration.h"
+#include "nvim/drawscreen.h"
#include "nvim/extmark.h"
#include "nvim/highlight.h"
#include "nvim/highlight_group.h"
#include "nvim/lua/executor.h"
#include "nvim/move.h"
-#include "nvim/screen.h"
#include "nvim/vim.h"
#ifdef INCLUDE_GENERATED_DECLARATIONS
diff --git a/src/nvim/diff.c b/src/nvim/diff.c
index d483e22a30..c1fdbc1b9a 100644
--- a/src/nvim/diff.c
+++ b/src/nvim/diff.c
@@ -20,6 +20,7 @@
#include "nvim/charset.h"
#include "nvim/cursor.h"
#include "nvim/diff.h"
+#include "nvim/drawscreen.h"
#include "nvim/eval.h"
#include "nvim/ex_cmds.h"
#include "nvim/ex_docmd.h"
@@ -36,7 +37,6 @@
#include "nvim/os/os.h"
#include "nvim/os/shell.h"
#include "nvim/path.h"
-#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/ui.h"
#include "nvim/undo.h"
diff --git a/src/nvim/digraph.c b/src/nvim/digraph.c
index c4e5f25719..0f511bd37c 100644
--- a/src/nvim/digraph.c
+++ b/src/nvim/digraph.c
@@ -12,6 +12,7 @@
#include "nvim/ascii.h"
#include "nvim/charset.h"
#include "nvim/digraph.h"
+#include "nvim/drawscreen.h"
#include "nvim/eval/typval.h"
#include "nvim/ex_docmd.h"
#include "nvim/ex_getln.h"
@@ -24,7 +25,6 @@
#include "nvim/normal.h"
#include "nvim/os/input.h"
#include "nvim/runtime.h"
-#include "nvim/screen.h"
#include "nvim/strings.h"
#include "nvim/vim.h"
diff --git a/src/nvim/drawline.c b/src/nvim/drawline.c
new file mode 100644
index 0000000000..95026ff8ed
--- /dev/null
+++ b/src/nvim/drawline.c
@@ -0,0 +1,2706 @@
+// 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
+
+// drawline.c: Functions for drawing window lines on the screen.
+// This is the middle level, drawscreen.c is the top and grid.c/screen.c the lower level.
+
+#include <assert.h>
+#include <inttypes.h>
+#include <stdbool.h>
+#include <string.h>
+
+#include "nvim/arabic.h"
+#include "nvim/buffer.h"
+#include "nvim/charset.h"
+#include "nvim/cursor.h"
+#include "nvim/cursor_shape.h"
+#include "nvim/diff.h"
+#include "nvim/drawline.h"
+#include "nvim/fold.h"
+#include "nvim/grid.h"
+#include "nvim/highlight.h"
+#include "nvim/highlight_group.h"
+#include "nvim/indent.h"
+#include "nvim/match.h"
+#include "nvim/move.h"
+#include "nvim/option.h"
+#include "nvim/plines.h"
+#include "nvim/quickfix.h"
+#include "nvim/search.h"
+#include "nvim/sign.h"
+#include "nvim/spell.h"
+#include "nvim/state.h"
+#include "nvim/syntax.h"
+#include "nvim/undo.h"
+#include "nvim/window.h"
+
+#define MB_FILLER_CHAR '<' // character used when a double-width character
+ // doesn't fit.
+
+/// for line_putchar. Contains the state that needs to be remembered from
+/// putting one character to the next.
+typedef struct {
+ const char *p;
+ int prev_c; ///< previous Arabic character
+ int prev_c1; ///< first composing char for prev_c
+} LineState;
+#define LINE_STATE(p) { p, 0, 0 }
+
+#ifdef INCLUDE_GENERATED_DECLARATIONS
+# include "drawline.c.generated.h"
+#endif
+
+/// Advance **color_cols
+///
+/// @return true when there are columns to draw.
+static bool advance_color_col(int vcol, int **color_cols)
+{
+ while (**color_cols >= 0 && vcol > **color_cols) {
+ (*color_cols)++;
+ }
+ return **color_cols >= 0;
+}
+
+/// Used when 'cursorlineopt' contains "screenline": compute the margins between
+/// which the highlighting is used.
+static void margin_columns_win(win_T *wp, int *left_col, int *right_col)
+{
+ // cache previous calculations depending on w_virtcol
+ static int saved_w_virtcol;
+ static win_T *prev_wp;
+ static int prev_left_col;
+ static int prev_right_col;
+ static int prev_col_off;
+
+ int cur_col_off = win_col_off(wp);
+ int width1;
+ int width2;
+
+ if (saved_w_virtcol == wp->w_virtcol && prev_wp == wp
+ && prev_col_off == cur_col_off) {
+ *right_col = prev_right_col;
+ *left_col = prev_left_col;
+ return;
+ }
+
+ width1 = wp->w_width - cur_col_off;
+ width2 = width1 + win_col_off2(wp);
+
+ *left_col = 0;
+ *right_col = width1;
+
+ if (wp->w_virtcol >= (colnr_T)width1) {
+ *right_col = width1 + ((wp->w_virtcol - width1) / width2 + 1) * width2;
+ }
+ if (wp->w_virtcol >= (colnr_T)width1 && width2 > 0) {
+ *left_col = (wp->w_virtcol - width1) / width2 * width2 + width1;
+ }
+
+ // cache values
+ prev_left_col = *left_col;
+ prev_right_col = *right_col;
+ prev_wp = wp;
+ saved_w_virtcol = wp->w_virtcol;
+ prev_col_off = cur_col_off;
+}
+
+/// Put a single char from an UTF-8 buffer into a line buffer.
+///
+/// Handles composing chars and arabic shaping state.
+static int line_putchar(buf_T *buf, LineState *s, schar_T *dest, int maxcells, bool rl, int vcol)
+{
+ const char_u *p = (char_u *)s->p;
+ int cells = utf_ptr2cells((char *)p);
+ int c_len = utfc_ptr2len((char *)p);
+ int u8c, u8cc[MAX_MCO];
+ if (cells > maxcells) {
+ return -1;
+ }
+ u8c = utfc_ptr2char(p, u8cc);
+ if (*p == TAB) {
+ cells = MIN(tabstop_padding(vcol, buf->b_p_ts, buf->b_p_vts_array), maxcells);
+ for (int c = 0; c < cells; c++) {
+ schar_from_ascii(dest[c], ' ');
+ }
+ goto done;
+ } else if (*p < 0x80 && u8cc[0] == 0) {
+ schar_from_ascii(dest[0], (char)(*p));
+ s->prev_c = u8c;
+ } else {
+ if (p_arshape && !p_tbidi && ARABIC_CHAR(u8c)) {
+ // Do Arabic shaping.
+ int pc, pc1, nc;
+ int pcc[MAX_MCO];
+ int firstbyte = *p;
+
+ // The idea of what is the previous and next
+ // character depends on 'rightleft'.
+ if (rl) {
+ pc = s->prev_c;
+ pc1 = s->prev_c1;
+ nc = utf_ptr2char((char *)p + c_len);
+ s->prev_c1 = u8cc[0];
+ } else {
+ pc = utfc_ptr2char(p + c_len, pcc);
+ nc = s->prev_c;
+ pc1 = pcc[0];
+ }
+ s->prev_c = u8c;
+
+ u8c = arabic_shape(u8c, &firstbyte, &u8cc[0], pc, pc1, nc);
+ } else {
+ s->prev_c = u8c;
+ }
+ schar_from_cc(dest[0], u8c, u8cc);
+ }
+ if (cells > 1) {
+ dest[1][0] = 0;
+ }
+done:
+ s->p += c_len;
+ return cells;
+}
+
+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 = err,
+ .hl_id = hl_err }));
+ err_decor.virt_text_width = (int)mb_string2cells(err);
+ decor_add_ephemeral(lnum - 1, 0, lnum - 1, 0, &err_decor, 0, 0);
+}
+
+static void draw_virt_text(win_T *wp, buf_T *buf, int col_off, int *end_col, int max_col,
+ int win_row)
+{
+ DecorState *state = &decor_state;
+ int right_pos = max_col;
+ bool do_eol = state->eol_col > -1;
+ for (size_t i = 0; i < kv_size(state->active); i++) {
+ DecorRange *item = &kv_A(state->active, i);
+ if (!(item->start_row == state->row
+ && (kv_size(item->decor.virt_text) || item->decor.ui_watched))) {
+ continue;
+ }
+ if (item->win_col == -1) {
+ if (item->decor.virt_text_pos == kVTRightAlign) {
+ right_pos -= item->decor.virt_text_width;
+ item->win_col = right_pos;
+ } else if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) {
+ item->win_col = state->eol_col;
+ } else if (item->decor.virt_text_pos == kVTWinCol) {
+ item->win_col = MAX(item->decor.col + col_off, 0);
+ }
+ }
+ if (item->win_col < 0) {
+ continue;
+ }
+ int col;
+ if (item->decor.ui_watched) {
+ // send mark position to UI
+ col = item->win_col;
+ WinExtmark m = { (NS)item->ns_id, item->mark_id, win_row, col };
+ kv_push(win_extmark_arr, m);
+ }
+ if (kv_size(item->decor.virt_text)) {
+ col = draw_virt_text_item(buf, item->win_col, item->decor.virt_text,
+ item->decor.hl_mode, max_col, item->win_col - col_off);
+ }
+ item->win_col = -2; // deactivate
+ if (item->decor.virt_text_pos == kVTEndOfLine && do_eol) {
+ state->eol_col = col + 1;
+ }
+
+ *end_col = MAX(*end_col, col);
+ }
+}
+
+static int draw_virt_text_item(buf_T *buf, int col, VirtText vt, HlMode hl_mode, int max_col,
+ int vcol)
+{
+ LineState s = LINE_STATE("");
+ int virt_attr = 0;
+ size_t virt_pos = 0;
+
+ while (col < max_col) {
+ if (!*s.p) {
+ if (virt_pos >= kv_size(vt)) {
+ break;
+ }
+ virt_attr = 0;
+ do {
+ s.p = kv_A(vt, virt_pos).text;
+ int hl_id = kv_A(vt, virt_pos).hl_id;
+ virt_attr = hl_combine_attr(virt_attr,
+ hl_id > 0 ? syn_id2attr(hl_id) : 0);
+ virt_pos++;
+ } while (!s.p && virt_pos < kv_size(vt));
+ if (!s.p) {
+ break;
+ }
+ }
+ if (!*s.p) {
+ continue;
+ }
+ int attr;
+ bool through = false;
+ if (hl_mode == kHlModeCombine) {
+ attr = hl_combine_attr(linebuf_attr[col], virt_attr);
+ } else if (hl_mode == kHlModeBlend) {
+ through = (*s.p == ' ');
+ attr = hl_blend_attrs(linebuf_attr[col], virt_attr, &through);
+ } else {
+ attr = virt_attr;
+ }
+ schar_T dummy[2];
+ int cells = line_putchar(buf, &s, through ? dummy : &linebuf_char[col],
+ max_col - col, false, vcol);
+ // if we failed to emit a char, we still need to advance
+ cells = MAX(cells, 1);
+
+ for (int c = 0; c < cells; c++) {
+ linebuf_attr[col++] = attr;
+ }
+ vcol += cells;
+ }
+ return col;
+}
+
+/// Return true if CursorLineSign highlight is to be used.
+static bool use_cursor_line_sign(win_T *wp, linenr_T lnum)
+{
+ return wp->w_p_cul
+ && lnum == wp->w_cursor.lnum
+ && (wp->w_p_culopt_flags & CULOPT_NBR);
+}
+
+// Get information needed to display the sign in line 'lnum' in window 'wp'.
+// If 'nrcol' is TRUE, the sign is going to be displayed in the number column.
+// Otherwise the sign is going to be displayed in the sign column.
+//
+// @param count max number of signs
+// @param[out] n_extrap number of characters from pp_extra to display
+// @param sign_idxp Index of the displayed sign
+static void get_sign_display_info(bool nrcol, win_T *wp, linenr_T lnum, SignTextAttrs sattrs[],
+ int row, int startrow, int filler_lines, int filler_todo,
+ int *c_extrap, int *c_finalp, char_u *extra, size_t extra_size,
+ char_u **pp_extra, int *n_extrap, int *char_attrp, int sign_idx,
+ int cul_attr)
+{
+ // Draw cells with the sign value or blank.
+ *c_extrap = ' ';
+ *c_finalp = NUL;
+ if (nrcol) {
+ *n_extrap = number_width(wp) + 1;
+ } else {
+ if (use_cursor_line_sign(wp, lnum)) {
+ *char_attrp = win_hl_attr(wp, HLF_CLS);
+ } else {
+ *char_attrp = win_hl_attr(wp, HLF_SC);
+ }
+ *n_extrap = win_signcol_width(wp);
+ }
+
+ if (row == startrow + filler_lines && filler_todo <= 0) {
+ SignTextAttrs *sattr = sign_get_attr(sign_idx, sattrs, wp->w_scwidth);
+ if (sattr != NULL) {
+ *pp_extra = sattr->text;
+ if (*pp_extra != NULL) {
+ *c_extrap = NUL;
+ *c_finalp = NUL;
+
+ if (nrcol) {
+ int n, width = number_width(wp) - 2;
+ for (n = 0; n < width; n++) {
+ extra[n] = ' ';
+ }
+ extra[n] = NUL;
+ STRCAT(extra, *pp_extra);
+ STRCAT(extra, " ");
+ *pp_extra = extra;
+ *n_extrap = (int)STRLEN(*pp_extra);
+ } else {
+ size_t symbol_blen = STRLEN(*pp_extra);
+
+ // TODO(oni-link): Is sign text already extended to
+ // full cell width?
+ assert((size_t)win_signcol_width(wp) >= mb_string2cells((char *)(*pp_extra)));
+ // symbol(s) bytes + (filling spaces) (one byte each)
+ *n_extrap = (int)symbol_blen + win_signcol_width(wp) -
+ (int)mb_string2cells((char *)(*pp_extra));
+
+ assert(extra_size > symbol_blen);
+ memset(extra, ' ', extra_size);
+ memcpy(extra, *pp_extra, symbol_blen);
+
+ *pp_extra = extra;
+ (*pp_extra)[*n_extrap] = NUL;
+ }
+ }
+
+ if (use_cursor_line_sign(wp, lnum) && cul_attr > 0) {
+ *char_attrp = cul_attr;
+ } else {
+ *char_attrp = sattr->hl_attr_id;
+ }
+ }
+ }
+}
+
+static int get_sign_attrs(buf_T *buf, linenr_T lnum, SignTextAttrs *sattrs, int *line_attr,
+ int *num_attr, int *cul_attr)
+{
+ HlPriAttr line_attrs = { *line_attr, 0 };
+ HlPriAttr num_attrs = { *num_attr, 0 };
+ HlPriAttr cul_attrs = { *cul_attr, 0 };
+
+ // TODO(bfredl, vigoux): line_attr should not take priority over decoration!
+ int num_signs = buf_get_signattrs(buf, lnum, sattrs, &num_attrs, &line_attrs, &cul_attrs);
+ decor_redraw_signs(buf, lnum - 1, &num_signs, sattrs, &num_attrs, &line_attrs, &cul_attrs);
+
+ *line_attr = line_attrs.attr_id;
+ *num_attr = num_attrs.attr_id;
+ *cul_attr = cul_attrs.attr_id;
+
+ return num_signs;
+}
+
+/// Return true if CursorLineNr highlight is to be used for the number column.