feat(kebab-tui): p9-fb-10 partial — CJK width helpers + render audit
`kebab-tui::input::{display_width, truncate_to_display_width}` 신규.
unicode-width 위에서 column-단위 width 계산 (ASCII=1, Hangul/CJK/
fullwidth=2, combining=0) + char-boundary 안전 truncate.
library.rs 의 중복 `truncate_to_display_width` private fn 제거 — 단일
source 로 통일. 9 unit tests + 1 integration render test (Korean +
Japanese fixture, TestBackend 80×20).
spec 의 `InputBuffer` struct 도입은 follow-up — Ask/Search/Editor pane
의 String + cursor 일괄 마이그레이션이 회귀 표면이 커서 helper 만
먼저 머지. backspace 는 모든 pane 이 이미 `String::pop()` 사용 → byte-
boundary 안전성 확보. crossterm 0.28 가 native IME composing 미노출 →
preedit handling out of scope.
spec status `planned` → `in_progress`. HOTFIXES.md 에 InputBuffer
struct deferral 사유 기록.
This commit is contained in:
@@ -215,3 +215,45 @@ fn handle_key_library_f_opens_filter_overlay_then_enter_refreshes() {
|
||||
);
|
||||
assert_eq!(o2, KeyOutcome::Refresh);
|
||||
}
|
||||
|
||||
/// p9-fb-10: Library renders Hangul / CJK titles without overflowing
|
||||
/// the title column. Smoke pin — render with a mixed Korean fixture
|
||||
/// and confirm no panic + the truncated width fits the column.
|
||||
#[test]
|
||||
fn library_renders_korean_titles_without_overflow() {
|
||||
let docs = vec![
|
||||
make_doc("ko/한글-노트.md", "러스트로 만드는 지식 베이스", vec!["rust", "한글"]),
|
||||
make_doc("jp/漢字メモ.md", "日本語のテストドキュメント", vec!["jp"]),
|
||||
make_doc("mix/hello-세계.md", "Hello, 세계 mixed title", vec!["mix"]),
|
||||
];
|
||||
let app = app_with_docs(docs);
|
||||
let backend = TestBackend::new(80, 20);
|
||||
let mut terminal = Terminal::new(backend).unwrap();
|
||||
terminal
|
||||
.draw(|f| {
|
||||
let area = Rect::new(0, 0, 80, 20);
|
||||
render_library(f, area, &app);
|
||||
})
|
||||
.expect("render must not panic on CJK titles");
|
||||
let buffer = terminal.backend().buffer().clone();
|
||||
let rendered: String = (0..buffer.area.height)
|
||||
.map(|y| {
|
||||
(0..buffer.area.width)
|
||||
.map(|x| buffer[(x, y)].symbol())
|
||||
.collect::<String>()
|
||||
})
|
||||
.collect::<Vec<_>>()
|
||||
.join("\n");
|
||||
// At least one Hangul / Kanji glyph survives the render path.
|
||||
// TestBackend renders wide chars one-per-cell with the trailing
|
||||
// cell empty, so the joined string has spaces between adjacent
|
||||
// wide chars — assert single glyphs, not multi-char substrings.
|
||||
assert!(
|
||||
rendered.contains('러') || rendered.contains('한'),
|
||||
"expected a Hangul glyph in rendered frame: {rendered}"
|
||||
);
|
||||
assert!(
|
||||
rendered.contains('日') || rendered.contains('漢'),
|
||||
"expected a Kanji glyph in rendered frame: {rendered}"
|
||||
);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user