All files / webview/components BashResult.tsx

18.18% Statements 2/11
0% Branches 0/6
33.33% Functions 1/3
18.18% Lines 2/11

Press n or j to go to the next uncovered block, b, p or k for the previous block.

1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42      4x   26x                                                                        
import { cn } from '../lib/utils'
 
// biome-ignore lint/suspicious/noControlCharactersInRegex: needed for ANSI stripping
const ANSI_RE = /[\x1b\x9b][[()#;?]*(?:[0-9]{1,4}(?:;[0-9]{0,4})*)?[0-9A-ORZcf-nqry=><~]/g
export function stripAnsi(s: string): string {
  return s.replace(ANSI_RE, '')
}
 
export function BashResult({ output, isError }: { output: string; isError?: boolean }) {
  const lines = output.trimEnd().split('\n')
  const isLong = lines.length > 10
  const previewLines = lines.slice(0, 3)
  const baseClass =
    'mt-1 font-mono text-xs whitespace-pre-wrap wrap-break-word rounded px-2 py-1.5 bg-(--vscode-terminal-background,--vscode-editor-background)'
  const textClass = isError
    ? 'text-(--vscode-errorForeground)'
    : 'text-(--vscode-terminal-foreground,--vscode-foreground)'
 
  if (!isLong) {
    return <pre className={cn(baseClass, textClass)}>{output.trimEnd()}</pre>
  }
 
  return (
    <div className="mt-1">
      <div className="text-[10px] opacity-50 font-mono truncate">
        {previewLines
          .map((l) => l.trim())
          .filter(Boolean)
          .slice(0, 3)
          .join(' / ')}
        {lines.length > 3 ? '…' : ''}
      </div>
      <details>
        <summary className="cursor-pointer opacity-50 hover:opacity-80 select-none text-[10px]">
          Show output ({lines.length} lines)
        </summary>
        <pre className={cn(baseClass, textClass)}>{output.trimEnd()}</pre>
      </details>
    </div>
  )
}