Files
statusline/src/preview.rs
T
chuan 4d3956b097 refactor: optimize git/transcript sources, centralize colors, add tests
- git: fetch branch and changed files in one `git status --porcelain --branch` (3 subprocesses -> 2)
- transcript: read only the last 1 MB from the file tail instead of parsing the whole jsonl
- color: add a shared palette and route heat() and every widget through it
- widgets: drop the preview bridge functions; preview now calls the component fns directly
- add unit tests for the pure helpers (parse_branch, interval merge, heat, percentages, formatting)
2026-06-25 19:48:22 +08:00

126 lines
3.9 KiB
Rust
Raw Blame History

This file contains ambiguous Unicode characters
This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.
//! `statusline test <目标>` 子命令:在终端预览各组件效果。
use crate::sources::git::GitInfo;
use crate::sources::transcript::Speed;
use crate::widgets;
/// `test`:依次显示所有组件的预览。
pub fn run() {
header("usage");
usage();
header("git");
git();
header("speed");
speed();
header("model");
model();
header("rate");
rate();
header("dir");
dir();
}
/// 打印分节标题。
fn header(name: &str) {
println!("\n=== {name} ===");
}
/// 预览上下文百分比 1% → 100% 的渐变色,每行 10 个。
fn usage() {
for pct in 1..=100 {
print!("{} ", widgets::context::colored(pct as f64));
if pct % 10 == 0 {
println!();
}
}
}
/// 用合成数据预览 git 段的所有显示情况与配色。
fn git() {
// 非仓库时 render 直接返回 "-",这里单列。
println!("{} -", pad("非仓库", 12));
let samples = [
("干净", GitInfo { branch: "main".into(), changed_files: 0, insertions: 0, deletions: 0 }),
("仅改文件", GitInfo { branch: "main".into(), changed_files: 3, insertions: 0, deletions: 0 }),
("改文件+增", GitInfo { branch: "dev".into(), changed_files: 3, insertions: 128, deletions: 0 }),
("改文件+删", GitInfo { branch: "hotfix".into(), changed_files: 2, insertions: 0, deletions: 42 }),
("增删都有", GitInfo { branch: "feature/login".into(), changed_files: 5, insertions: 128, deletions: 17 }),
];
for (label, info) in &samples {
println!("{} {}", pad(label, 12), widgets::git::format_info(info));
}
}
/// 用合成数据预览 token 速度的各种情况。
fn speed() {
let samples = [
("正常", Speed { input_per_sec: Some(2.7), output_per_sec: Some(134.4) }),
("高速(k)", Speed { input_per_sec: Some(1234.0), output_per_sec: Some(3456.0) }),
("缺输入", Speed { input_per_sec: None, output_per_sec: Some(88.5) }),
("无数据", Speed::EMPTY),
];
for (label, speed) in &samples {
println!("{} {}", pad(label, 12), widgets::speed::display(speed));
}
}
/// 预览模型(思考) 合并格式。
fn model() {
println!("思考等级(模型固定 Opus 4.8:");
for (label, level) in [
("low", "low"),
("medium", "medium"),
("high", "high"),
("xhigh", "xhigh"),
("缺失/未知", ""),
] {
println!(" {} {}", pad(label, 10), widgets::model::combined("Opus 4.8 (1M context)", level));
}
println!("模型名(思考固定 high:");
for (label, name) in [
("Opus", "Opus 4.8 (1M context)"),
("Sonnet", "Sonnet 4.6"),
("Haiku", "Haiku 4.5"),
("Fable", "Fable 5"),
("缺失", "-"),
] {
println!(" {} {}", pad(label, 10), widgets::model::combined(name, "high"));
}
}
/// 用合成数据预览额度的各种情况。
fn rate() {
let samples = [
("正常", Some(10.0), Some(40.0), Some(6300i64)),
("接近满", Some(92.0), Some(78.0), Some(900)),
("无倒计时", Some(10.0), Some(40.0), None),
("缺数据", None, None, None),
];
for (label, five, seven, secs) in samples {
println!("{} {}", pad(label, 10), widgets::rate::display(five, seven, secs));
}
}
/// 用合成数据预览目录显示。
fn dir() {
let samples = [
("项目根", "/path/to/project", true),
("子目录", "/path/to/project/src/widgets", false),
("非项目", "/some/other/dir", false),
];
for (label, path, at_root) in samples {
println!("{} {}", pad(label, 10), widgets::dir::format_dir(path, at_root));
}
}
/// 把文本按显示列宽右侧补空格对齐(中文字符算 2 列)。
fn pad(text: &str, width: usize) -> String {
let shown: usize = text
.chars()
.map(|c| if (c as u32) >= 0x1100 { 2 } else { 1 })
.sum();
format!("{text}{}", " ".repeat(width.saturating_sub(shown)))
}