Files
openidea/templates/theme-plugin/themes/harbor-night.theme.json
ad09a76212 feat(vcs): IntelliJ's diff algorithm and change colouring in the diff viewer (#242)
* feat(vcs): IDEA's diff algorithm and change colouring in the diff viewer

Port IntelliJ's text comparison to TypeScript (src/features/vcs/comparison):
Myers/patience LCS with unique-element discarding, ByLine (smart matching
that skips unimportant lines, chunk optimizer, second-step correction),
ByWord (word chunks, punctuation matching, whitespace policies, line block
splitting) and ComparisonManager's compareLinesInner / processBlocks. The
port runs IntelliJ's own LineComparisonUtilTest, WordComparisonUtilTest and
SplitComparisonUtilTest cases (459 runs), converted to ideaCases.json.

MergeView chunks now come straight from these line fragments, with the
inner word fragments as chunk changes, instead of @codemirror/merge's
presentable diff. Revert and >> / << replace lines as
DiffUtil.applyModification does.

Colour changes as IDEA does: modified (blue), inserted (green) and deleted
(grey) by chunk type, a lighter line background for chunks whose words were
compared, each word fragment in its own type at full line height, a thin
bar for a fragment empty on one side, and the colours carried into the
gutters and the divider bands. New --diff-modified / --diff-inserted /
--diff-deleted theme tokens, imported from .icls DIFF_* attributes.

Add a Playwright suite over a generated git repository of diff cases,
including 10,000-line files, in every viewer mode.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>

* fix(vcs): preserve unified revert boundaries and bound large diffs

---------

Co-authored-by: Claude Opus 5.5 <noreply@anthropic.com>
Co-authored-by: l0ng-ai <24760907+l0ng-ai@users.noreply.github.com>
2026-10-29 19:59:57 +08:00

147 lines
4.6 KiB
JSON

// Harbor Night: UI theme. Keys are the CSS variables of src/styles/tokens.css,
// grouped like its Islands Light block. Delete a line to keep the built-in value
// of the base named by "kind". Comments are allowed (// and /* */).
// Full reference: docs/plugins/themes.md.
{
"id": "harbor-night",
"name": "Harbor Night",
"kind": "dark",
"tokens": {
// Surfaces
"--bg-app": "#14171c",
"--bg-elev": "#1b2027",
"--bg-popup": "#1f252e",
"--bg-hover": "#262c33",
"--bg-selected": "#22484b",
"--bg-selected-strong": "#285a5d",
"--bg-current-line": "#191e25",
"--bg-debug-line": "#245a5c",
"--bg-backdrop": "#1f252e",
"--bg-input": "#14171c",
// Lines
"--border": "#1f252e",
"--border-popup": "#2a333f",
"--border-strong": "#36414f",
"--border-window": "#36414f",
"--control-off": "#515f72",
// Text
"--fg-strong": "#d9dfe6",
"--fg-emphasis": "#c9d1dc",
"--fg": "#c9d1dc",
"--fg-secondary": "#919fb1",
"--fg-muted": "#7c8ca0",
"--fg-subtle": "#637287",
"--fg-faint": "#515f72",
"--fg-gutter": "#3f4d60",
"--fg-icon": "#c6ced9",
// Accent
"--accent": "#2b9e93",
"--link": "#5cc8bd",
"--link-hover": "#8adcd3",
// Charts
"--chart-series": "#e07a7c",
// Status
"--danger": "#f57e84",
"--warning": "#d59637",
"--success": "#6db083",
"--db-connected": "#2fe02f",
"--db-connected-ring": "#1d6b1d",
"--info": "#4fb0d0",
// Vcs
"--vcs-modified": "#82ede6",
"--vcs-added": "#73bd79",
"--vcs-deleted": "#5f6f85",
"--vcs-untracked": "#e88f89",
"--vcs-ignored": "#d69a6b",
"--vcs-conflict": "#de6a66",
"--gutter-modified": "#469e98",
"--gutter-added": "#549159",
"--gutter-deleted": "#75869d",
"--diff-modified": "#2f4f63",
"--diff-inserted": "#294436",
"--diff-deleted": "#43494f",
// Shadows and window controls
"--shadow-popup": "0 6px 20px rgba(0, 0, 0, 0.45)",
"--shadow-dialog": "0 0 0 0.5px rgba(0, 0, 0, 0.6), 0 10px 24px rgba(0, 0, 0, 0.35), 0 24px 72px rgba(0, 0, 0, 0.45)",
"--traffic-close": "#ff5f57",
"--traffic-close-border": "#e0443e",
"--traffic-close-pressed": "#bf4942",
"--traffic-glyph": "#4d0000",
"--traffic-off": "#404955",
"--traffic-off-border": "#363e49",
// Additive
"--bg-tooltip": "#2a333f",
"--fg-tooltip": "#c9d1dc",
"--border-tooltip": "#2a333f",
"--bg-control": "#1f252e",
"--bg-control-hover": "#2a333f",
"--bg-active": "#36414f",
"--bg-scrim": "rgba(0, 0, 0, 0.45)",
"--fg-on-accent": "#ffffff",
"--shadow-tooltip": "0 4px 12px rgba(0, 0, 0, 0.4)",
"--shadow-balloon": "0 8px 24px rgba(0, 0, 0, 0.45)",
// Islands contract
"--bg-frame": "#1f252e",
"--bg-island": "#14171c",
"--bg-stripe-hover": "#ffffff17",
"--bg-stripe-selected": "#ffffff29",
"--fg-stripe-selected-active": "#ffffff",
"--fg-stripe-label": "#919fb1",
"--bg-tab-selected": "#1e3d40",
"--border-tab-selected": "#2b9e93",
"--bg-tab-selected-inactive": "#1f252e",
"--border-tab-selected-inactive": "#36414f",
"--bg-tab-hover": "#ffffff17",
"--border-editor-tabs": "#1f252e",
"--bg-tree-selected": "#22484b",
"--bg-tree-selected-inactive": "#2a333f",
"--bg-tree-hover": "#ffffff10",
"--bg-toolbar-hover": "#ffffff17",
"--bg-toolbar-pressed": "#ffffff29",
"--bg-toolbar-selected": "#285a5d",
"--bg-toolbar-selected-hover": "#2f6b6e",
"--bg-button-primary-hover": "#40a8a1",
"--fg-button-primary": "#ffffff",
"--bg-button": "transparent",
"--border-button": "#36414f",
"--bg-field": "#14171c",
"--bg-checkbox": "#14171c",
"--border-checkbox": "#515f72",
"--bg-toggle-on": "#338555",
"--fg-toggle-on": "#ffffff",
"--bg-toggle-off": "#14171c",
"--fg-toggle-off": "#637287",
"--border-toggle": "#515f72",
"--bg-toggle-knob": "#515f72",
"--focus-ring-soft": "#467c78",
"--scrollbar-thumb": "#ffffff33",
"--scrollbar-thumb-hover": "#ffffff59",
"--bg-search-match": "#ba9752",
"--bg-search-match-current": "#f2c55c",
"--fg-search-match": "#14171c",
"--bg-dialog": "#14171c",
"--bg-popup-inline": "#1f252e",
"--bg-popup-advertiser": "#1f252e",
"--bg-feedback-info": "#2a514f",
"--border-feedback-info": "#397e79",
"--bg-feedback-error": "#56272b",
"--border-feedback-error": "#80383e",
"--bg-feedback-warning": "#44321d",
"--border-feedback-warning": "#694820",
"--bg-feedback-success": "#203b2a",
"--border-feedback-success": "#29583c",
"--bg-counter": "#637287",
"--fg-counter": "#000000",
"--bg-progress-track": "#36414f"
}
}