[Feature]: Always render created files inline, even when Side by Side is on
- Dominant language
- TypeScript
- Stars
- 69.7k
- Forks
- 4.5k
- Avg merge
- 16h 8m
- Merged PRs (30d)
- 451
Description
### Problem or use case
A created (added) file has no original side: `originalContent` is empty by definition. With the diff toolbar set to **Side by Side**, such a file still renders as two Monaco columns — the left one completely blank for the whole file — so half of the horizontal space shows nothing and every line of the new file is squeezed into the remaining half, wrapping or scrolling horizontally for no reason.
This is the common case when reviewing agent output: a turn that adds several new files is reviewed in the combined diff, where Side by Side is genuinely useful for the *modified* files in the same review, and actively harmful for the *added* ones. Today the only remedy is to flip the global toggle to Inline, read the new files, and flip it back for the modified ones — per review, repeatedly.
The view mode is a single global toggle (`Inline` / `Side by Side`, `combined-diff-toolbar.tsx` → `toggleSideBySide`), so it cannot express "side by side where there are two sides".
### Proposed solution
Make the side-by-side rendering *per section*, overridden to inline whenever the section is an addition — the global toggle stays exactly as it is, this is a render-time override only.
- Combined diff: `DiffSection` already carries `status` (`src/renderer/src/components/editor/diff-section-types.ts`), and `DiffSectionBody.tsx` already receives the section, so the Monaco option becomes `renderSideBySide: sideBySide && !isAdded(section.status)` at the existing `renderSideBySide: sideBySide` call site. `ImageDiffViewer` in the same file takes `sideBySide` too and can take the same override.
- Single-file diff: `DiffViewer.tsx` has the same `renderSideBySide: sideBySide` line but no status in `DiffViewerProps` (`diff-viewer-props.ts`). Either pass the status down from the call sites that know it, or add an explicit `forceInline?: boolean` prop. Deriving it from `originalContent === ''` inside the viewer is tempting but wrong: limited large diffs intentionally blank the text bodies before IPC (see the `largeDiffSaveContentAvailable` comment in the same file), so an added-file heuristic would misfire there.
Acceptance sketch:
- Side by Side on, combined diff containing both added and modified files → added files render as one inline column, modified files render two columns, in the same scroll.
- Inline on → nothing changes anywhere.
- The toolbar button keeps showing the global state and does not flip while scrolling over an added section; toggling it still switches the modified sections.
- Renames with content changes are treated as modified (two real sides), not as additions.
### Alternatives or additional context
- **Deletions.** The mirror case: the modified side is empty for a deleted file, so the same argument applies. Worth covering by the same override, but it is a separate decision — deletions are read far less often than new files.
- **Setting instead of unconditional behavior.** If unconditional is too opinionated, gate it behind something like `settings.diffInlineForAddedFiles`, default on, next to `diffShowWhitespace` / `diffWordWrap`. My preference is unconditional: an empty column is never the thing the user asked for by turning Side by Side on.
- **Per-file manual toggle** (override the mode for one section) — more UI, more state to remember, and it does not remove the repetitive flipping; it only makes it cheaper.
**Environment:** Orca 1.4.196, Windows 11.
Contributor guide
Research direction
Start with DiffSectionBody.tsx and its existing renderSideBySide call, then trace DiffSection.status from diff-section-types.ts and the ImageDiffViewer path. Check DiffViewer.tsx, diff-viewer-props.ts, and the call sites that know file status before choosing how single-file state is passed. Done means added sections render inline while modified and renamed sections remain side by side, with the global toolbar behavior unchanged.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- typescript
- Domain
- frontend
- Issue type
- Feature
- Difficulty
- 3/5
- Estimated time
- 1-2 days
- Activity status
- Active
- Clarity
- Clearly specified
- Newbie friendliness
- 78/100