FileEditToolUpdatedMessage.tsx
1 import { Hunk } from 'diff' 2 import { Box, Text } from 'ink' 3 import * as React from 'react' 4 import { intersperse } from '../utils/array.js' 5 import { StructuredDiff } from './StructuredDiff.js' 6 import { getTheme } from '../utils/theme.js' 7 import { getCwd } from '../utils/state.js' 8 import { relative } from 'path' 9 import { useTerminalSize } from '../hooks/useTerminalSize.js' 10 11 type Props = { 12 filePath: string 13 structuredPatch: Hunk[] 14 verbose: boolean 15 } 16 17 export function FileEditToolUpdatedMessage({ 18 filePath, 19 structuredPatch, 20 verbose, 21 }: Props): React.ReactNode { 22 const { columns } = useTerminalSize() 23 const numAdditions = structuredPatch.reduce( 24 (count, hunk) => count + hunk.lines.filter(_ => _.startsWith('+')).length, 25 0, 26 ) 27 const numRemovals = structuredPatch.reduce( 28 (count, hunk) => count + hunk.lines.filter(_ => _.startsWith('-')).length, 29 0, 30 ) 31 32 return ( 33 <Box flexDirection="column"> 34 <Text> 35 {' '}⎿ Updated{' '} 36 <Text bold>{verbose ? filePath : relative(getCwd(), filePath)}</Text> 37 {numAdditions > 0 || numRemovals > 0 ? ' with ' : ''} 38 {numAdditions > 0 ? ( 39 <> 40 <Text bold>{numAdditions}</Text>{' '} 41 {numAdditions > 1 ? 'additions' : 'addition'} 42 </> 43 ) : null} 44 {numAdditions > 0 && numRemovals > 0 ? ' and ' : null} 45 {numRemovals > 0 ? ( 46 <> 47 <Text bold>{numRemovals}</Text>{' '} 48 {numRemovals > 1 ? 'removals' : 'removal'} 49 </> 50 ) : null} 51 </Text> 52 {intersperse( 53 structuredPatch.map(_ => ( 54 <Box flexDirection="column" paddingLeft={5} key={_.newStart}> 55 <StructuredDiff patch={_} dim={false} width={columns - 12} /> 56 </Box> 57 )), 58 i => ( 59 <Box paddingLeft={5} key={`ellipsis-${i}`}> 60 <Text color={getTheme().secondaryText}>...</Text> 61 </Box> 62 ), 63 )} 64 </Box> 65 ) 66 }