Skip to main content

codetether_agent/tui/app/
file_preview.rs

1//! File preview: reads the first N bytes/lines of a file for picker display.
2
3use std::io::{Read, Seek, SeekFrom};
4use std::path::Path;
5
6use crate::tui::utils::helpers::truncate_with_ellipsis;
7
8/// Read up to `max_bytes` bytes, returning up to `max_lines` lines.
9///
10/// Returns `(lines, was_truncated, is_binary)`.
11pub fn read_file_preview_lines(
12    path: &Path,
13    max_bytes: usize,
14    max_lines: usize,
15) -> Result<(Vec<String>, bool, bool), std::io::Error> {
16    let mut file = std::fs::File::open(path)?;
17    let mut buffer = vec![0_u8; max_bytes.saturating_add(1)];
18    let bytes_read = file.read(&mut buffer)?;
19
20    let truncated_by_bytes = bytes_read > max_bytes;
21    buffer.truncate(bytes_read.min(max_bytes));
22
23    if buffer.contains(&0) {
24        return Ok((Vec::new(), truncated_by_bytes, true));
25    }
26
27    let text = String::from_utf8_lossy(&buffer).to_string();
28    let mut lines: Vec<String> = text
29        .lines()
30        .map(|line| truncate_with_ellipsis(line, 220))
31        .collect();
32
33    if lines.is_empty() {
34        lines.push("(empty file)".to_string());
35    }
36
37    let mut truncated = truncated_by_bytes;
38    if lines.len() > max_lines {
39        lines.truncate(max_lines);
40        truncated = true;
41    }
42
43    Ok((lines, truncated, false))
44}