spacehub

surshar / claude-code

Claude Code is an agentic coding tool that lives in your terminal, understands your codebase, and helps you code faster by executing routine tasks, explaining complex code, and handling git workflows - all through natural language commands.

Built by Anthropic · github.com/anthropics

claude-code / mods / diff / hooks / views / current-pane / current-pane.tsx
130 lines · 4.3 KBRaw
1/* @jsxRuntime classic */
2/* @jsx h */
3/* @jsxFrag Fragment */
4import type { RenderElement } from 'claude-code'
5
6import type Git from '../../git'
7import Names from '../../names'
8import PaneState from '../../pane-state'
9import Detail from '../detail'
10import type { Kit } from '../kit'
11import Layout from '../layout'
12import Sections from '../sections'
13import { fileRowOf } from './file-row-of'
14import { listBodyOf } from './list-body-of'
15
16/**
17 * The pane over the repository's diff now (ReplDiffSidebarBody, one file's
18 * body at a time): header, base line, todo bar, pickers, rows, detail.
19 *
20 * The tests-and-generated toggle sits above the rows; the elision count, the
21 * withheld-untracked note, the pre-session line and rows below them; the
22 * selected file last.
23 *
24 * @param kit the elements, the handlers, the width
25 * @param model the pane's state
26 * @returns the pane's tree
27 */
28export function currentPane(
29 kit: Kit,
30 model: PaneState.PaneModel,
31): RenderElement {
32 const { Box } = kit.ui
33 const { data } = model
34
35 if (model.isOutsideRepository) {
36 return <Box>{Sections.dimNote(kit, Names.NOT_IN_REPOSITORY_TEXT)}</Box>
37 }
38
39 if (!data && !model.hasSettled) {
40 return <Box>{Sections.dimNote(kit, 'Loading diff…')}</Box>
41 }
42
43 const noise = model.isNoiseShown ? 'shown' : 'hidden'
44 const preSession = model.isPreSessionShown ? 'shown' : 'hidden'
45 const partition = PaneState.partitionOf(data?.files ?? [], noise)
46 const totals = data
47 ? PaneState.headerTotalsOf(data, partition)
48 : PaneState.ZERO_TOTALS
49 const empty = PaneState.emptyStateOf(data, totals.filesCount, model.words)
50 const baseLabel = PaneState.baseLabelOf(
51 model.requestedMode,
52 data,
53 totals.filesCount,
54 model.words,
55 )
56 const selected = PaneState.selectionOf(
57 PaneState.listedOf(partition, preSession),
58 model.selectedPath,
59 )
60 const rowOf = (file: Git.FileStat): RenderElement =>
61 Sections.fileRow(kit, fileRowOf(file, selected?.path ?? null), () =>
62 kit.actions.selectFile(file.path),
63 )
64 const noteOf = (text: string | null): RenderElement | null =>
65 text === null ? null : Sections.dimNote(kit, Layout.sanitizeName(text))
66 const noiseFace = model.isNoiseShown ? 'hide' : 'show'
67 const noiseCount = Layout.plural(partition.noiseCount, 'test')
68 const hasNoise = partition.noiseCount > 0
69 const noiseToggle = hasNoise
70 ? Sections.toggleRow(kit, 'noise', {
71 label: `${noiseCount}/generated (${noiseFace})`,
72 onPress: kit.actions.toggleNoise,
73 })
74 : null
75 const earlierFace = model.isPreSessionShown ? 'hide' : 'show'
76 const earlierCount = Layout.plural(partition.preSession.length, 'file')
77 const hasEarlier = partition.preSession.length > 0
78 const earlierToggle = hasEarlier
79 ? Sections.toggleRow(kit, 'presession', {
80 label: `+${earlierCount} edited before this session (${earlierFace})`,
81 onPress: kit.actions.togglePreSession,
82 })
83 : null
84 const earlierRows = model.isPreSessionShown ? partition.preSession : []
85 const isUntrackedNoted = data?.isUntrackedWithheld === true && !empty
86 const listed = listBodyOf(kit, { data, partition, totals, empty })
87 const detail = selected
88 ? [
89 Sections.divider(kit),
90 Detail.detailView(
91 kit,
92 {
93 words: model.words,
94 path: selected.path,
95 renamedFrom: selected.renamedFrom,
96 isUntracked: selected.isUntracked,
97 isBinary: selected.isBinary,
98 body: model.body,
99 bodyState: model.bodyState,
100 isArmed: model.armedPath === selected.path,
101 },
102 () => kit.actions.toggleAsk(selected.path),
103 ),
104 ]
105 : []
106
107 return (
108 <Box flexDirection="column">
109 {Sections.present([
110 Sections.headerView(kit, empty?.headline ?? null, totals),
111 noteOf(baseLabel),
112 Sections.todoBar(kit, model.todos),
113 Sections.controlsView(kit, model),
114 noiseToggle,
115 ...listed.map(line =>
116 typeof line === 'string' ? noteOf(line) : rowOf(line),
117 ),
118 noteOf(totals.notShown > 0 ? `${totals.notShown} not shown` : null),
119 noteOf(
120 isUntrackedNoted
121 ? Names.untrackedWithheldTextOf(model.words.lister)
122 : null,
123 ),
124 earlierToggle,
125 ...earlierRows.map(rowOf),
126 ...detail,
127 ])}
128 </Box>
129 )
130}