fix(editor): keep selections whole over line backgrounds and indent guides (#1568)

* fix(editor): keep selections whole over line backgrounds and indent guides

Multi-line selections could show a 1px seam between their stacked
rectangles, indent guides showed as short dashes inside a selection,
and a breakpoint or execution line hid the selection past its text.

- Snap selection rectangle edges to device pixels so stacked pieces
  share one edge.
- Paint caret-row, breakpoint and execution line backgrounds on a
  pseudo-element below the selection layer.
- Draw indent guides on a pseudo-element above the text.

* test(e2e): check the visible selection layer in the theme flow
Цей коміт міститься в:
l0ng-ai authored and GitHub committed 2026-11-05 23:31:14 +08:00
1 джерело f665beb17e
коміт 1186cdce64
9 files changed
+96 -7

No files matched your search

+18 -2
Переглянути файл
@@ -177,7 +177,17 @@ export const openideaTheme = EditorView.theme({
"&.cm-focused > .cm-scroller > .cm-selectionLayer .cm-selectionBackground": {
background: "var(--editor-selection)",
},
".cm-activeLine": { backgroundColor: "var(--editor-caret-row)" },
// Row backgrounds go on a pseudo-element under the selection layer: on the line itself they would hide it.
".cm-activeLine": { backgroundColor: "transparent", "--openidea-line-bg": "var(--editor-caret-row)" },
".cm-activeLine, .cm-openidea-lineBg": { position: "relative" },
".cm-activeLine::before, .cm-openidea-lineBg::before": {
content: '""',
position: "absolute",
inset: "0",
zIndex: "-1000",
background: "var(--openidea-line-bg)",
pointerEvents: "none",
},
".cm-selectionMatch": {
backgroundColor: "var(--bg-identifier-under-caret, color-mix(in srgb, var(--fg) 9%, transparent))",
},
@@ -263,7 +273,13 @@ export const openideaTheme = EditorView.theme({
".cm-foldPlaceholder:hover": { backgroundColor: "color-mix(in srgb, var(--fg-muted) 24%, transparent)" },
// Indent guides (cm/indentGuides.ts)
".cm-openidea-guides": {
// Above the text so a selection, or a mark's background, never covers part of a guide.
".cm-openidea-guides": { position: "relative" },
".cm-openidea-guides::after": {
content: '""',
position: "absolute",
inset: "0",
pointerEvents: "none",
backgroundImage:
"repeating-linear-gradient(to right, var(--editor-indent-guide) 0 1px, transparent 1px calc(var(--openidea-guide-step) * 1ch))",
backgroundSize: "calc(var(--openidea-guide-levels) * var(--openidea-guide-step) * 1ch) 100%",