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 / detail / code-blocks-of / code-blocks-of.ts
82 lines · 2.6 KBRaw
1import Git from '../../../git'
2import { HUNK_DIVIDER } from '../hunk-divider'
3import { HUNK_DIVIDER_NODES } from '../hunk-divider-nodes'
4import { hunkSourceOf } from '../hunk-source-of'
5import { leadingHunkOf } from '../leading-hunk-of'
6import { MAX_BODY_CHARS } from '../max-body-chars'
7import { MAX_BODY_NODES } from '../max-body-nodes'
8import { MAX_CODE_CHARS } from '../max-code-chars'
9import { subHunksOf } from '../sub-hunks-of'
10import type Types from '../types'
11import { drawnLineOf } from './drawn-line-of'
12
13/**
14 * A file's hunks as the sources of `Code` blocks, each at most
15 * MAX_CODE_CHARS, hunks sharing a block (the engine's ellipsis between).
16 *
17 * A new block at a hunk gets HUNK_DIVIDER; a hunk too long for one is split
18 * (subHunksOf) into blocks stacked with none. The body stops, truncated, at
19 * the whole lines MAX_BODY_CHARS and MAX_BODY_NODES hold, as the host counts.
20 *
21 * @param hunks the file's hunks
22 * @returns the blocks in order, and whether any line was left out or cut
23 */
24export function codeBlocksOf(hunks: readonly Git.Hunk[]): Types.CodeBody {
25 const blocks: Types.CodeBlock[] = []
26
27 let chars = 0
28 let nodes = 0
29 let isTruncated = false
30
31 for (const hunk of hunks) {
32 const lines = hunk.lines.filter(Git.isBodyLine).map(drawnLineOf)
33 const split = subHunksOf({ ...hunk, lines }, MAX_CODE_CHARS)
34 isTruncated ||= split.isTruncated
35
36 for (const [at, piece] of split.hunks.entries()) {
37 const last = blocks.at(-1)
38 const source = hunkSourceOf(piece)
39 const isHunkStart = at === 0
40
41 const isJoining =
42 isHunkStart &&
43 last !== undefined &&
44 last.source.length + 1 + source.length <= MAX_CODE_CHARS
45
46 const hasDivider = isHunkStart && !isJoining && last !== undefined
47 const overhead = isJoining ? 1 : hasDivider ? HUNK_DIVIDER.length : 0
48
49 const addedNodes = isJoining
50 ? 0
51 : 1 + (hasDivider ? HUNK_DIVIDER_NODES : 0)
52
53 const room = MAX_BODY_CHARS - chars - overhead
54 const fitted = source.length <= room ? piece : leadingHunkOf(piece, room)
55 const isOverNodes = nodes + addedNodes > MAX_BODY_NODES
56
57 if (isOverNodes || fitted.lines.length === 0) {
58 return { blocks, isTruncated: true }
59 }
60
61 const text = hunkSourceOf(fitted)
62
63 if (isJoining) {
64 blocks.pop()
65 }
66
67 blocks.push({
68 source: isJoining ? `${last.source}\n${text}` : text,
69 hasDivider: isJoining ? last.hasDivider : hasDivider,
70 })
71
72 chars += overhead + text.length
73 nodes += addedNodes
74
75 if (fitted.lines.length < piece.lines.length) {
76 return { blocks, isTruncated: true }
77 }
78 }
79 }
80
81 return { blocks, isTruncated }
82}