martanne / vis

A vi-like editor based on Plan 9's structural regular expressions
Other
4.19k stars 260 forks source link

Extra terminal cells styled after end of file #1176

Open git-bruh opened 2 months ago

git-bruh commented 2 months ago

Problem

For markdown files containing a hyperlink at the end (no newlines), the underlining style overflows over to the empty cells:

image

I've not investigated much but there might be an off by one error around this logic (as lua is one indexed): https://github.com/martanne/vis/blob/6f537f300b0b4d7e4a729e28cce7be9241e829a3/lua/vis-std.lua#L67

Seems similar to https://github.com/martanne/vis/issues/1147

Steps to reproduce

No response

vis version (vis -v)

vis 95bf9f5-dirty +curses +lua +lpeg

Terminal name/version

foot 1.16.2

$TERM environment variable

foot

acidrums4 commented 2 months ago

Not sure if it's related, but if for example I set a different background color for a certain type of string in the theme file (say, lexers.STYLE_FUNCTION), the background color will overflow over the neighboring empty cells too.

git-bruh commented 2 months ago
diff --git a/view.c b/view.c
index df7906b..6a723a4 100644
--- a/view.c
+++ b/view.c
@@ -1432,10 +1432,10 @@ void view_style(View *view, enum UiStyle style, size_t start, size_t end) {
        col++;

    do {
-       while (pos <= end && col < width) {
+       while (pos < end && col < width) {
            pos += line->cells[col].len;
            view->ui->style_set(view->ui, &line->cells[col++], style);
        }
        col = 0;
-   } while (pos <= end && (line = line->next));
+   } while (pos < end && (line = line->next));
 }

This works, the end position passed from lua is equal to view->end, and we should only iterate till view->end - 1

Otherwise we reach view->end which has empty columns, and adding line->cells[col].len to pos keeps the loop running as length of an empty cell is 0

@acidrums4 could you see if this fixes your issue as well?

EDIT: nvm, this breaks regular highlighting at the last character as well, in case there is more text after it , eg [a](b) xyz, the ) isn't highlighted

git-bruh commented 2 months ago

This might be a more reasonable fix:

diff --git a/lua/vis-std.lua b/lua/vis-std.lua
index 8b5715b..1ccef0d 100644
--- a/lua/vis-std.lua
+++ b/lua/vis-std.lua
@@ -75,7 +75,7 @@ vis.events.subscribe(vis.events.WIN_HIGHLIGHT, function(win)
    local data = win.file:content(viewport)
    local token_styles = lexer._TOKENSTYLES
    local tokens = lexer:lex(data, 1)
-   local token_end = lex_start + (tokens[#tokens] or 1) - 1
+   local token_end = lex_start + ((tokens[#tokens] and tokens[#tokens] - 1) or 1) - 1

    for i = #tokens - 1, 1, -2 do
        local token_start = lex_start + (tokens[i-1] or 1) - 1

Not sure if I'm missing any edge case here