mirror of
https://github.com/rowboatlabs/rowboat.git
synced 2026-06-12 19:55:19 +02:00
focus on diff when showing code
This commit is contained in:
parent
b2176435bd
commit
89621b8bf0
2 changed files with 36 additions and 3 deletions
|
|
@ -53,6 +53,18 @@ export function cmBaseExtensions(isDark: boolean): Extension[] {
|
|||
color: isDark ? '#6b7280' : '#9ca3af',
|
||||
},
|
||||
'&.cm-focused': { outline: 'none' },
|
||||
// GitHub-style expander bar for folded unchanged regions (@codemirror/merge).
|
||||
'.cm-collapsedLines': {
|
||||
backgroundColor: isDark ? 'rgba(56, 139, 253, 0.15)' : 'rgba(9, 105, 218, 0.08)',
|
||||
backgroundImage: 'none',
|
||||
color: isDark ? '#79c0ff' : '#0969da',
|
||||
padding: '4px 12px',
|
||||
fontSize: '11px',
|
||||
cursor: 'pointer',
|
||||
},
|
||||
'.cm-collapsedLines:hover': {
|
||||
backgroundColor: isDark ? 'rgba(56, 139, 253, 0.25)' : 'rgba(9, 105, 218, 0.15)',
|
||||
},
|
||||
},
|
||||
{ dark: isDark },
|
||||
),
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
import { useEffect, useRef, useState } from 'react'
|
||||
import { MergeView, unifiedMergeView } from '@codemirror/merge'
|
||||
import { EditorView } from '@codemirror/view'
|
||||
import { Columns2, Rows2, X } from 'lucide-react'
|
||||
import { Columns2, FoldVertical, Rows2, UnfoldVertical, X } from 'lucide-react'
|
||||
import { useTheme } from '@/contexts/theme-context'
|
||||
import { Button } from '@/components/ui/button'
|
||||
import { cmBaseExtensions, cmLanguageFor } from './cm'
|
||||
|
|
@ -22,6 +22,9 @@ export function DiffViewer({
|
|||
const isDark = resolvedTheme === 'dark'
|
||||
const containerRef = useRef<HTMLDivElement>(null)
|
||||
const [mode, setMode] = useState<'split' | 'unified'>('split')
|
||||
// GitHub-style: unchanged regions fold into "⋯ N lines" bars (each clickable
|
||||
// to reveal); "Expand all" rebuilds the view with nothing collapsed.
|
||||
const [collapseUnchanged, setCollapseUnchanged] = useState(true)
|
||||
const [diff, setDiff] = useState<{ oldText: string; newText: string; isBinary: boolean; tooLarge: boolean } | null>(null)
|
||||
const [error, setError] = useState<string | null>(null)
|
||||
|
||||
|
|
@ -44,19 +47,27 @@ export function DiffViewer({
|
|||
void cmLanguageFor(path).then((language) => {
|
||||
if (cancelled || !containerRef.current) return
|
||||
const extensions = [...cmBaseExtensions(isDark), ...(language ? [language] : [])]
|
||||
// Same context margins GitHub uses: keep a few lines around each hunk,
|
||||
// only fold stretches long enough to be worth hiding.
|
||||
const collapse = collapseUnchanged ? { margin: 3, minSize: 6 } : undefined
|
||||
if (mode === 'split') {
|
||||
view = new MergeView({
|
||||
a: { doc: diff.oldText, extensions },
|
||||
b: { doc: diff.newText, extensions },
|
||||
parent,
|
||||
gutter: true,
|
||||
...(collapse ? { collapseUnchanged: collapse } : {}),
|
||||
})
|
||||
} else {
|
||||
view = new EditorView({
|
||||
doc: diff.newText,
|
||||
extensions: [
|
||||
...extensions,
|
||||
unifiedMergeView({ original: diff.oldText, mergeControls: false }),
|
||||
unifiedMergeView({
|
||||
original: diff.oldText,
|
||||
mergeControls: false,
|
||||
...(collapse ? { collapseUnchanged: collapse } : {}),
|
||||
}),
|
||||
],
|
||||
parent,
|
||||
})
|
||||
|
|
@ -67,12 +78,22 @@ export function DiffViewer({
|
|||
cancelled = true
|
||||
view?.destroy()
|
||||
}
|
||||
}, [diff, mode, isDark, path])
|
||||
}, [diff, mode, isDark, path, collapseUnchanged])
|
||||
|
||||
return (
|
||||
<div className="flex h-full min-h-0 flex-col">
|
||||
<div className="flex items-center gap-2 border-b px-3 py-1.5">
|
||||
<span className="min-w-0 flex-1 truncate font-mono text-xs text-foreground/90" title={path}>{path}</span>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
className="h-7 px-2 text-xs text-muted-foreground"
|
||||
onClick={() => setCollapseUnchanged((c) => !c)}
|
||||
title={collapseUnchanged ? 'Show the whole file' : 'Collapse unchanged regions'}
|
||||
>
|
||||
{collapseUnchanged ? <UnfoldVertical className="size-3.5" /> : <FoldVertical className="size-3.5" />}
|
||||
{collapseUnchanged ? 'Expand all' : 'Collapse'}
|
||||
</Button>
|
||||
<Button
|
||||
variant="ghost"
|
||||
size="sm"
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue