Skip to content

Highlight the active line in the code editor - #266

Open
ArthurArthurArthur0817 wants to merge 1 commit into
sysprog21:mainfrom
ArthurArthurArthur0817:feat/active-line-highlight
Open

ArthurArthurArthur0817 wants to merge 1 commit into
sysprog21:mainfrom
ArthurArthurArthur0817:feat/active-line-highlight

Conversation

@ArthurArthurArthur0817

@ArthurArthurArthur0817 ArthurArthurArthur0817 commented Oct 8, 2026 •

Copy link
Copy Markdown

The code editor lacked an active-line indicator, leaving candidates scanning for a thin caret when navigating long snippets or discussing specific line numbers referenced by the interviewer. This made it harder to quickly locate the current row across the editor and the gutter.

When the editor is focused, paintEditor now computes the 0-based active line from a collapsed selection and exposes it to the .editor-stack as an --active-line custom property. The syntax overlay and gutter read this property to position a subtle linear-gradient background behind the text. Moving the caret or scrolling the textarea updates the scroll and line position variables accordingly.

The CSS approach keeps the syntax layer DOM untouched. Inserting markup for the active row would mutate the code overlay, tripping the MutationObserver that guarantees single-pass rendering, and breaking the plain-text nature of the gutter. The highlight is cleared completely when the editor loses focus or when a selection range is active, ensuring it only tracks a collapsed caret.

Testing:
New tests: the DOM contract test verifies the active line tracks the caret when the editor is focused without a selection, asserting the exact caret conditions in the script and the custom properties in the stylesheet. The test was checked by breaking the strict equality it covers and watching it fail.
node --test tests/browser/dom-contract.test.js was run on Windows; against the baseline (with CRLF checked out to LF via dos2unix) this change adds no failure.

Closes #247


Summary by cubic

Highlights the active line in the code editor so candidates can quickly locate the current row while editing or discussing line numbers.

paintEditor sets a 0-based --active-line custom property on .editor-stack when the editor is focused with a collapsed caret. #editor-lines, #editor-highlight, and .plain-text #editor paint a gradient behind that row, anchored with background-attachment: local so it stays put while scrolling. The highlight clears on blur or while a selection is active. Keeping it in CSS leaves the syntax layer DOM untouched, so the MutationObserver that guarantees single-pass rendering never trips. Both light and dark themes get a --code-active-line color, and the gutter's background shorthand becomes background-color in the same pass.

Adds an end-to-end test in tests/browser/editor-font-size.test.js verifying the highlight tracks the caret, stays anchored while scrolling, and clears on selection or blur.

Closes #247

Written for commit f7db916. Summary will update on new commits.

View guided diff

cubic-dev-ai[bot]

This comment was marked as resolved.

jserv

This comment was marked as duplicate.

Comment thread tests/browser/dom-contract.test.js Outdated
Comment thread web/styles.css Outdated

@cubic-dev-ai cubic-dev-ai Bot left a comment •

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

All reported issues were addressed across 4 files (changes from recent commits).

Tip: Review your code locally with the cubic CLI to iterate faster.

View guided diff | Re-trigger cubic

Comment thread tests/browser/editor-font-size.test.js Outdated
jserv

This comment was marked as outdated.

@ArthurArthurArthur0817
ArthurArthurArthur0817 force-pushed the feat/active-line-highlight branch 2 times, most recently from e3b9a64 to 8539578 Compare October 9, 2026 08:42

@jserv jserv left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Rebase the current branch onto the upstream default branch and rework the series into functionally minimal commits, folding similar ones and enforcing the project's commit message rules.

@jserv

jserv commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

@ArthurArthurArthur0817 The check run on 8539578 failed in two ways, and only one of them goes away with the rebase.

  1. The new test fails on its first assertion: "highlight tracks a collapsed caret moved by the keyboard" expected --active-line to be 2 and got 1199, the caret line fillLongBuffer left behind. A caret move reaches paintEditor through selectionchange and scheduleEditorPaint (web/interview.js:828 and :3274), which paints on the next animation frame, so reading the property right after keyboard.press sees the previous paint. Wait for the value instead, for example with page.waitForFunction on --active-line, in every assertion that follows a caret move or a scroll.
  2. The theme assertions ("system theme, no stored choice" and the editor colors) fail because the branch predates Let the candidate switch the editor theme #251, which added the light editor theme. After rebasing, check the highlight in that theme too: a fixed rgba(255, 255, 255, 0.06) band is invisible on the light background, so the color needs to come from the theme's own variables.

Also restore the final newline that the diff removes from tests/browser/dom-contract.test.js.

@ArthurArthurArthur0817
ArthurArthurArthur0817 force-pushed the feat/active-line-highlight branch 2 times, most recently from ec02814 to 59220fe Compare October 10, 2026 08:28
@ArthurArthurArthur0817

Copy link
Copy Markdown
Author

I have rebased onto the latest upstream/main (resolving conflicts with the new indent guides and scroll tests) and addressed all feedback:

Async Paint Timing in Tests: Integrated page.waitForFunction in editor-font-size.test.js to wait for --active-line to match the expected value before asserting. This resolves the race condition caused by async paint timing after cursor movements and scrolling.

Editor Theme Variable Integration: Replaced hardcoded highlight colors with --code-active-line scoped across themes (#ffffff0f for dark mode, #0000000d for light mode under .editor-stack[data-theme="light"] and the prefers-color-scheme: light media query) to align with PR #251.

I also restored the final newline in tests/browser/dom-contract.test.js.Thanks for the reminder.

@jserv

jserv commented Oct 10, 2026

Copy link
Copy Markdown
Contributor

I have rebased onto the latest upstream/main (resolving conflicts with the new indent guides and scroll tests) and addressed all feedback:

Don't make statements too early. Continue resolving.

jserv

This comment was marked as outdated.

@ArthurArthurArthur0817
ArthurArthurArthur0817 force-pushed the feat/active-line-highlight branch 4 times, most recently from 7c9c642 to a906f9b Compare October 12, 2026 05:03
@jserv
jserv requested review from ColtenOuO and alanhc October 12, 2026 05:31
Comment thread web/styles.css Outdated
Comment thread web/styles.css
overflow: hidden;
color: var(--code-gutter-ink);
background: var(--code-gutter);
background-color: var(--code-gutter);

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

The description says the gutter reads --active-line too, but the only gutter change is background becoming background-color; #editor-lines gets no gradient, so the caret's line number is not marked. Add the same background-image, background-size and background-position to #editor-lines (it is scrolled from the same scrollTop and has the same 1rem top padding, so background-attachment: local lines up there too), or drop the gutter claim from the description.

Comment thread tests/browser/editor-font-size.test.js
jserv

This comment was marked as outdated.

During an interview, candidates often navigate long snippets or
discuss specific line numbers referenced by the interviewer.
Tracking the caret across the editor and gutter without an
active-line indicator makes it harder to locate the current row.

Set a 0-based --active-line CSS custom property on .editor-stack
during paintEditor when the editor is focused with a collapsed
selection, and render a linear-gradient across #editor-highlight
and #editor-lines without mutating the syntax layer DOM.
@jserv

jserv commented Oct 16, 2026

Copy link
Copy Markdown
Contributor

@ArthurArthurArthur0817 The check run on f7db916 fails in tests/recording_contract.rs (contract_duplicate_webhook and contract_invalid_signature, both BodyMismatch), while main passes them. The cause is in this branch. Besides web/interview.js, web/styles.css and the new editor test, it rewrites 15 files the highlight has no reason to touch: the recording webhook fixtures, whose signature is checked against their exact bytes; the goldens under tests/golden/; the other files under tests/fixtures/; the generated web/problem-topics.json; and web/recording/recording.css. Restore them with git checkout origin/main -- tests/fixtures tests/golden web/problem-topics.json web/recording/recording.css, keep the commit to the highlight and its test, and force-push.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

Highlight the active line in the code editor

2 participants