Skip to content

Add auto indentation to the current code editor - #59

Open
CX330Blake wants to merge 1 commit into
sysprog21:mainfrom
CX330Blake:c-branch-1
Open

CX330Blake wants to merge 1 commit into
sysprog21:mainfrom
CX330Blake:c-branch-1

Conversation

@CX330Blake

@CX330Blake CX330Blake commented Sep 17, 2026

Copy link
Copy Markdown

Summary

Reduce manual formatting during interviews by preserving the current
line indentation and adding one level after opening delimiters and
Python block statements.

Keep delimiter pairs readable by moving matching closing delimiters onto
a separate line when appropriate. Avoid treating comment-only lines as
block openers so comments do not introduce unexpected indentation.

Add regression tests to cover indentation behavior, comments, and C++
preprocessor directives.

Known Limitations

  • Trailing comments are not parsed syntax-aware, so block openers before
    a trailing comment like int func() { // may not trigger the expected
    indentation.
  • Continuation lines inside multi-line block comments are not detected
    as comment-only lines.

These cases are intentionally left for a follow-up to keep this change
lightweight.

@CX330Blake
CX330Blake marked this pull request as ready for review September 17, 2026 11:00
cubic-dev-ai[bot]

This comment was marked as resolved.

Comment thread web/editor.js Outdated
Comment thread tests/browser/editor.test.js Outdated
cubic-dev-ai[bot]

This comment was marked as resolved.

@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.

Read https://chris.beams.io/git-commit carefully and enforce the rules.

@ColtenOuO ColtenOuO left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Overall, I think this is heading in the right direction, just left a few small suggestions and minor issues to address.

Comment thread web/editor.js
const lineStart = start === 0 ? 0 : value.lastIndexOf("\n", start - 1) + 1;
const before = value.slice(lineStart, start);
const indentation = before.match(/^[ \t]*/)[0];
const opener = before.trimEnd().slice(-1);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

This is fine to handle as a follow-up, but I'd suggest mentioning it in the PR description for future reference.

Comment thread web/editor.js Outdated
);
}
});

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I'd suggest adding some tests for the newly added comment handling.

ex.

["    # Steps:", "python"]
["    // setup {", "javascript"]
["if ready: # explain", "python"]
["run(); // setup {", "javascript"]

@ColtenOuO ColtenOuO left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

By the way, some of the intermediate review commits can be squashed together.

@ColtenOuO ColtenOuO left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

Would it be worth adding a browser integration test (actually interact with the textarea via Playwright)? Right now, we can only verify whether individual methods work correctly, but we can't validate if the full end-to-end user behavior in the browser matches our expectations.

It might be worth adding because the entire flow actually involves multiple steps. Testing just one part of those steps might not give us comprehensive coverage.

Comment thread web/editor.js
Reduce manual formatting during interviews by preserving the current
line indentation and adding one level after opening delimiters and
Python block statements.

Keep delimiter pairs readable by moving matching closing delimiters
onto a separate line when appropriate. Avoid treating comment-only
lines as block openers so comments do not introduce unexpected
indentation.

Add regression tests to cover indentation behavior, comments, and C++
preprocessor directives.
@CX330Blake

Copy link
Copy Markdown
Author

Would it be worth adding a browser integration test (actually interact with the textarea via Playwright)? Right now, we can only verify whether individual methods work correctly, but we can't validate if the full end-to-end user behavior in the browser matches our expectations.

It might be worth adding because the entire flow actually involves multiple steps. Testing just one part of those steps might not give us comprehensive coverage.

Added Playwright integration tests that interact with the actual editor textarea, press Enter, and verify indentation and caret position across nine cases. They also check syntax highlighting, line numbers, undo/redo, and code retention when switching languages.

@ColtenOuO ColtenOuO left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

I think we are almost there.

Comment thread web/editor.js
if (language === "python") {
return /^[ \t]*#/.test(line);
}
return /^[ \t]*(\/\/|\/\*)/.test(line);

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

isCommentOnlyLine() treats any C-like line starting with /* as comment-only, even when the comment closes and code follows.

For example, pressing Enter after /* guard */ if (ready) { preserves the current indentation instead of adding one level.

Could we either handle text after */ or explicitly track this case in #61?

Copy link
Copy Markdown
Author

Choose a reason for hiding this comment

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

Since this is not a common case people are likely to encounter in normal coding, I think we can leave it as a follow-up. I've added this case to #61 for tracking. Thanks for reviewing!

@ColtenOuO ColtenOuO left a comment

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

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

LGTM, thanks for your contribution and patience!

@ColtenOuO
ColtenOuO requested a review from jserv September 18, 2026 16:41
Comment thread web/editor.js
@@ -1,5 +1,41 @@
const INDENT = " ";

// TODO: The current implementation cannot handle cases like:

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 repository carries no other TODO in first-party code, and this one records a limitation the pull request description already states, so once this merges it is a marker nothing tracks. Say what isCommentOnlyLine actually does instead: it classifies on the first token of a single line and carries no block comment state, which is why a continuation line inside /* ... */ reads as code.

Comment thread web/editor.js
if (language === "python") {
return /^[ \t]*#/.test(line);
}
return /^[ \t]*(\/\/|\/\*)/.test(line);

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.

This matches any line whose first token opens a block comment, even when the comment closes and real code follows, so /* seed */ if (ready) { is classified as a comment and the next line loses its level. Requiring the comment to stay open on the line keeps the intended cases and drops this one.

Suggested change
return /^[ \t]*(\/\/|\/\*)/.test(line);
return /^[ \t]*(\/\/|\/\*(?!.*\*\/))/.test(line);

Comment thread web/editor.js
const lineStart = start === 0 ? 0 : value.lastIndexOf("\n", start - 1) + 1;
const before = value.slice(lineStart, start);
const indentation = before.match(/^[ \t]*/)[0];
const opener = before.trimEnd().slice(-1);

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.

opener reads the raw line, so a trailing comment that ends in a delimiter or a colon adds a level the code never opened: work(); // { in JavaScript and value = 1 # note: in Python both indent the next line. The description covers the opposite direction (a real opener hidden before a trailing comment); this direction costs the candidate a deletion on every such line, so cutting the comment tail before reading the last token is worth doing here rather than in a follow-up.

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.

3 participants