Skip to content

feat(web): honor EditorConfig tab widths and show whitespace - #15286

Closed
AndreiShenets wants to merge 19 commits into
pingdotgg:mainfrom
AndreiShenets:feat/editorconfig-whitespace
Closed

AndreiShenets wants to merge 19 commits into
pingdotgg:mainfrom
AndreiShenets:feat/editorconfig-whitespace

Conversation

@AndreiShenets

@AndreiShenets AndreiShenets commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Problem

Code viewers use a fixed tab width of 2 instead of the file's EditorConfig settings, and invisible whitespace makes mixed indentation and trailing spaces difficult to inspect.

Fixes #11076.

Change

  • Resolve tab widths per file from .editorconfig: tab_width takes precedence over indent_size, with a fallback of 2. Honor inherited sections, root, and unset.
  • Add a default-off, searchable and resettable whitespace setting to the shared file, working-tree, checkpoint and PR viewers. Marks are display-only; tabs and spaces are not rewritten.
  • Reuse existing workspace reads, caching and refresh signals. Include repositoryRoot in existing Git status/preview responses so EditorConfig lookup uses the correct base for nested projects, repositories without remotes and worktrees.
  • Read PR configuration through the existing hosted content API at the reviewed revision, independent of the local checkout. Keep checkpoint paths repository-relative even with diff.relative=true.

Scope and approval

juliusmarminge approved this direction and scope. This covers the shared web viewers used by web and desktop; mobile is deferred per that approval.

Verification

Focused checks on Windows with Node 24.21.0. Upstream main at 71dbaf1f9 merged without conflicts in 388aff13a:

  • Latest parser and EditorConfig hook run — 155 passed. Covers literal/slash-containing glob classes, ** traversal, adjacent numeric ranges and one-megabyte bounds without numeric expansion or backtracking.
  • Post-merge integration run: parser, EditorConfig hook, PR query runtime, whitespace decoration, editor focus and shared diff viewer suites — 230 passed, including revision-scoped PR config caching/refresh.
  • Focused editor and decoration tests passed: fileEditorFocus.test.tsx, fileEditorVirtualization.test.ts, codeWhitespace.test.ts and codeViewTabWidths.test.ts, including selection/caret, draft/focus and decoration geometry coverage.
  • vp test run apps/server/src/vcs/GitVcsDriverCore.test.ts apps/server/src/git/GitManager.test.ts -t "returns the diff path root without a remote|local status exposes the repository root|loads repository-relative files from a nested project directory" — 4 passed.
  • Focused checkpoint diff/summary run — 10 passed, including real-Git regressions for nested paths with diff.relative on/off in patch and numstat output.
  • Post-merge web, server and client-runtime typechecks passed. Targeted formatting/lint checks reported only existing warnings; the PR diff's whitespace check passed.

An isolated Edge pass at d85210779 verified computed tab widths of 2, 4 and 8 for the same source/layout, settings search and off/on behavior in file and split-diff views. Native editing and saving of a grammarless file retained actual tabs, repeated spaces and trailing spaces with marks both off and on, without marker-glyph substitutions.

Selection/caret across toggles and draft/focus across config changes are covered by automated tests, not established by this browser pass. Native desktop, checkpoint/PR viewers and remote/relay connections were not manually exercised. No video was captured.

Screenshots

Matching off/on pairs captured at d85210779:

Same-source, same-layout configuration comparison at d85210779, not an old-checkout baseline:

Evidence is hosted on GitHub; no PR-only assets are committed.

Models: GPT-6 Astra and GPT-6.1 Sol. Harness: OpenCode.

Closes discussions

@github-actions github-actions Bot added vouch:unvouched Author is not yet trusted in the VOUCHED list. size:XL 500-999 changed lines (additions + deletions). labels Oct 3, 2026
Comment thread apps/web/src/lib/editorConfig.ts Resolved
Comment thread apps/web/src/components/DiffPanel.tsx Resolved
Comment thread apps/web/src/lib/editorConfig.ts Resolved
@macroscopeapp

macroscopeapp Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Approvability

Verdict: Not approved

Macroscope's review found this PR not approvable — This PR adds a substantial cross-layer code-view feature rather than a small isolated change, including new EditorConfig parsing, hosted configuration reads, DOM decoration, editor remount behavior, and Git path metadata plumbing. It also introduces a new persisted product setting with a default, so human review is required.

You can add or adjust custom eligibility rules. Learn more.

@juliusmarminge juliusmarminge added the macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews label Oct 3, 2026 — with ChatGPT Codex Connector
@coderabbitai

coderabbitai Bot commented Oct 3, 2026 •

Copy link
Copy Markdown
Contributor

Review in Change Stack →

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration
  • Configuration used: Repository: pingdotgg/t3code/.coderabbit.yaml
  • Review profile: CHILL
  • Plan: Advanced
  • Run ID: 4ade6ef2-69e5-45ec-9ab2-e7575a95bdc0

📥 Commits

Reviewing files that changed from the base of the PR and between 63ccd23 and c5a4ac2.


⛔ Files ignored due to path filters (1)
  • pnpm-lock.yaml is excluded by !**/pnpm-lock.yaml

📒 Files selected for processing (2)
  • apps/server/src/vcs/GitVcsDriver.ts
  • apps/server/src/vcs/GitVcsDriverCore.ts

Included review availability: This review used your included allowance. Your plan provides up to 10 included reviews per hour; 9 remain after this review.



📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough
📝 Walkthrough

Walkthrough

File and diff views resolve tab widths from applicable .editorconfig files and can display optional markers for spaces and tabs. VCS status and diff previews expose repository roots, and checkpoint diffs use repository-relative paths.

Changes

Repository paths and editor formatting

Layer / File(s) Summary
Repository-root metadata and workspace context
packages/contracts/src/git.ts, packages/contracts/src/review.ts, apps/server/src/vcs/*, apps/server/src/git/GitManager.ts, packages/shared/src/git.ts, apps/web/src/components/DiffPanel.tsx, apps/web/src/components/diffs/AnnotatableCodeView.tsx, apps/server/src/checkpointing/CheckpointStore.test.ts
VCS status and diff-preview results can include the repository root. Checkpoint diffs use paths relative to the repository root. Web diff selections pass workspace paths and repository-root context to code viewers.
EditorConfig tab-width resolution
apps/web/src/lib/editorConfig.ts, apps/web/src/lib/editorConfig.test.ts, apps/web/src/hooks/useEditorConfigTabWidths.ts, apps/web/src/hooks/useEditorConfigTabWidths.test.tsx, packages/client-runtime/src/state/pullRequests.ts, packages/client-runtime/src/state/pullRequests.test.ts, apps/web/package.json
EditorConfig parsing, path matching, and candidate discovery resolve tab widths from tab_width, then indent_size, with a default of two columns. Queries support workspace files and pull-request snapshots, with refresh and scope behavior covered by tests.
Viewer integration and editable file lifecycle
apps/web/src/components/diffs/StyledDiffCodeView.tsx, apps/web/src/components/pullRequest/PullRequestCodeTab.tsx, apps/web/src/components/files/FilePreviewPanel.tsx, apps/web/src/components/files/ReadOnlySourcePreview.tsx, apps/web/src/components/files/fileEditorFocus.ts, apps/web/src/components/files/fileEditorFocus.test.tsx, apps/web/src/components/files/fileEditorVirtualization.test.ts
File and diff viewers apply resolved tab widths using workspace context. Editable views remount when the width changes; tests cover retained edits, undo history, comment drafts, selection, and focus.
Whitespace display setting and markers
packages/contracts/src/settings.ts, packages/contracts/src/settings.test.ts, apps/web/src/components/settings/SettingsPanels.tsx, apps/web/src/components/settings/settingsSearch.ts, apps/web/src/lib/codeWhitespace.ts, apps/web/src/lib/codeWhitespace.test.ts, docs/user/source-control.md
A default-off setting controls visual markers for spaces and tabs. Rendering decorates file and diff views while preserving underlying text and selection mappings. Settings, documentation, and rendering tests cover the behavior.

Priority: ➖ Normal

Estimated code review effort: 4 (Complex) | ~45 minutes

Change: Feature

Sequence Diagram(s)

sequenceDiagram
  participant StyledDiffCodeView
  participant useEditorConfigTabWidths
  participant editorConfigCandidates
  participant WorkspaceFileQueries
  StyledDiffCodeView->>useEditorConfigTabWidths: workspace context and visible file paths
  useEditorConfigTabWidths->>editorConfigCandidates: working directory and file paths
  editorConfigCandidates-->>useEditorConfigTabWidths: ancestor config paths
  useEditorConfigTabWidths->>WorkspaceFileQueries: read config files
  WorkspaceFileQueries-->>useEditorConfigTabWidths: config contents
  useEditorConfigTabWidths-->>StyledDiffCodeView: resolved tab widths
Loading

Suggested reviewers: t3dotgg, juliusmarminge


Merge Risk: ⚪ Minimal · up to c5a4a

Repository-aware tab widths and optional whitespace markers are supported by the supplied path, configuration, and viewer regression coverage. No concrete issue requiring a pre-merge fix is identified.

Architecture Summary

Architecture risk: 🔵 Low · up to c5a4a

The change affects 6 systems.

Changed systems: apps/server, apps/web, packages/contracts, packages/client-runtime, packages/shared, docs

Architecture concerns
No architecture-level concerns identified.

Review details

Systems and components

  • observed — apps/server (service) was modified; 6 changed files map to changed impact.
  • observed — apps/web (ui) was modified; 20 changed files map to changed impact.
  • observed — packages/contracts (library) was modified; 4 changed files map to changed impact.
  • observed — packages/client-runtime (library) was modified; 2 changed files map to changed impact.

Before / after behavior

  • observed — Modified behavior in apps/server/src/git/GitManager.test.ts: Added a test that calls localStatus from a nested directory in a repository without remotes and asserts hasPrimaryRemote is false and repositoryRoot matches the normalized Git top-level path.
  • observed — Modified behavior in apps/server/src/git/GitManager.ts: localStatus now conditionally adds repositoryRoot from Git status details to its result.
  • observed — Modified behavior in apps/server/src/vcs/GitVcsDriverCore.test.ts: Adds coverage for nested and nested-worktree locations without a remote. The test verifies the preview’s working directory, repository root, and repository-relative changed-file path, and checks that status results report the same repository root and no primary remote.
  • observed — Modified behavior in apps/web/src/components/diffs/AnnotatableCodeView.tsx: The contracts import adds EnvironmentId alongside ScopedThreadRef for the new workspace property.

Pre-merge checks | Passed 4 | Failed 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage Warning Docstring coverage is 38.89% which is insufficient. The required threshold is 80.00%. Docstring coverage is scoped to functions touched by this diff. Analyzed 36 functions across 34 files. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Linked Issues check Passed Issue #11076 requires per-file tab widths from applicable .editorconfig sections, with tab_width before indent_size and a fallback of 2. The parser and hook resolve inherited sections, root, `…
Out of Scope Changes check Passed The repository-root propagation, hosted pull-request configuration reads, and repository-relative checkpoint paths support EditorConfig lookup for the viewers in issue #11076. Focus restoration, selec…
Title check Passed The title clearly and concisely describes the primary changes: EditorConfig tab-width support and optional whitespace rendering in the web interface.
Description check Passed The description includes all required sections. It explains the problem, implementation, approved scope, focused verification results, UI screenshots, limitations, and agent details.

✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create a new PR

  • Autopilot · Keep fixing CodeRabbit findings and required CI, and resolving merge conflicts

Comment @coderabbitai help to get the list of available commands.

Comment thread apps/web/src/lib/editorConfig.ts Resolved
Comment thread apps/web/src/lib/editorConfig.ts Resolved
Comment thread apps/web/src/lib/editorConfig.ts Resolved
@maria-rcks

Copy link
Copy Markdown
Collaborator

Note

Written by gpt-6.1-sol on behalf of Maria

Thanks for working on EditorConfig support and whitespace inspection. Although your description links scope approval, this PR changes 2,685 lines across 38 files, beyond the size we can take over from an unvouched contributor under our limited review capacity. Right now we are only taking focused bug fixes from outside contributors. Please preserve the incorrect tab-width report in #11076 and discuss a smaller defect-only fix there for reconsideration.

@maria-rcks maria-rcks closed this Oct 14, 2026
AndreiShenets added a commit to AndreiShenets/t3code that referenced this pull request Oct 15, 2026
Extract the diff.relative correction and its regression coverage from pingdotgg#15286. Related to pingdotgg#11076; this fix is independently cherry-pickable.
AndreiShenets added a commit to AndreiShenets/t3code that referenced this pull request Oct 15, 2026
Extract snapshot read correctness from pingdotgg#15286. Related to pingdotgg#11076; this fix is independently cherry-pickable. Correct the stale test import left by the provider package move.
AndreiShenets added a commit to AndreiShenets/t3code that referenced this pull request Oct 15, 2026
Split EditorConfig resolution and viewer integration from pingdotgg#15286, with its parser, snapshot caching, repository-root plumbing, and editor state regression coverage. Related to pingdotgg#11076. Whitespace markers and their setting are isolated on feat/show-whitespace.
AndreiShenets added a commit to AndreiShenets/t3code that referenced this pull request Oct 15, 2026
Split the default-off display setting and whitespace decorations from pingdotgg#15286. Preserve text, native selection, and editable-row updates. Move the native editor selection regression cases into a whitespace-only suite. Related to pingdotgg#11076; independent of EditorConfig support.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

macroscope-review Opt PRs made by unvouched contributors in for Macroscope review. Vouched contributors auto-reviews size:XL 500-999 changed lines (additions + deletions). vouch:unvouched Author is not yet trusted in the VOUCHED list.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Feature]: Honor .editorconfig tab width and optionally render whitespace in file and diff views

3 participants