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
| 1 | import Git from '../../../git' |
| 2 | import { HUNK_DIVIDER } from '../hunk-divider' |
| 3 | import { HUNK_DIVIDER_NODES } from '../hunk-divider-nodes' |
| 4 | import { hunkSourceOf } from '../hunk-source-of' |
| 5 | import { leadingHunkOf } from '../leading-hunk-of' |
| 6 | import { MAX_BODY_CHARS } from '../max-body-chars' |
| 7 | import { MAX_BODY_NODES } from '../max-body-nodes' |
| 8 | import { MAX_CODE_CHARS } from '../max-code-chars' |
| 9 | import { subHunksOf } from '../sub-hunks-of' |
| 10 | import type Types from '../types' |
| 11 | import { 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 | */ |
| 24 | export 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 | } |