Repository: vscode-neovim/vscode-neovim
Pull request #1988 (2024-05-19 16:58:50)

fix(highlight): fix eol highlight not displaying
Close #1987


Patch:
diff --git a/src/utils/text.ts b/src/utils/text.ts
index 9b6c779..9fefc5a 100644
--- a/src/utils/text.ts
+++ b/src/utils/text.ts
@@ -17,10 +17,14 @@ export function expandTabs(line: string, tabWidth: number): string {
     return expanded;
 }
 
+/**
+ * Note: This function is for use by the highlight module only.
+ */
 export function calculateEditorColFromVimScreenCol(line: string, screenCol: number, tabSize: number): number {
     if (screenCol === 0 || !line) {
         return 0;
     }
+
     let currentCharIdx = 0;
     let currentVimCol = 0;
     while (currentVimCol < screenCol) {
@@ -33,7 +37,18 @@ export function calculateEditorColFromVimScreenCol(line: string, screenCol: numb
         }
 
         if (currentCharIdx >= line.length) {
-            return currentCharIdx;
+            //  The basic logic of highlighting is to store them according
+            //  to the editor column. For EOL highlights, the end-of-line position
+            //  is always used as the decoration position, use CSS
+            //  position offset for display.
+
+            //  Typically, the starting vim column in the grid_line event only exceeds the
+            //  line text length when there are EOL highlights, so the offset
+            //  needs to be added directly here. Otherwise, the parts exceeding the
+            //  line text length will use the same editor column, causing EOL highlights
+            //  to be incorrectly covered.
+            const eolCol = Math.max(screenCol - currentVimCol, 0);
+            return currentCharIdx + eolCol;
         }
     }
     return currentCharIdx;


Test patch:
diff --git a/src/test/unit/highlights/highlight_grid.test.ts b/src/test/unit/highlights/highlight_grid.test.ts
index 30e1ed0..364b403 100644
--- a/src/test/unit/highlights/highlight_grid.test.ts
+++ b/src/test/unit/highlights/highlight_grid.test.ts
@@ -630,6 +630,46 @@ describe("processHighlightCellsEvent", () => {
                 },
             ],
         },
+        {
+            testName: "virtual highlights can exceed line length",
+            events: [
+                {
+                    row: 2,
+                    vimCol: 6,
+                    validCells: [{ hlId: 2, text: "!" }],
+                    lineText: "hello",
+                    tabSize: 4,
+                },
+            ],
+            expectedRanges: [
+                {
+                    textType: "virtual" as const,
+                    highlights: [{ hlId: 2, text: "!", virtText: "!" }],
+                    line: 12,
+                    col: 6,
+                },
+            ],
+        },
+        {
+            testName: "calculateEditorColFromVimScreenCol eolCol >= 0",
+            events: [
+                {
+                    row: 2,
+                    vimCol: 3,
+                    validCells: [{ hlId: 2, text: "!" }],
+                    lineText: "\t你",
+                    tabSize: 2,
+                },
+            ],
+            expectedRanges: [
+                {
+                    textType: "virtual" as const,
+                    highlights: [{ hlId: 2, text: "!", virtText: "!" }],
+                    line: 12,
+                    col: 1,
+                },
+            ],
+        },
     ].forEach(
         ({
             testName,