review(p9-fb-22): 회차 1 nit 반영 — input.rs 빈줄, HOTFIXES/spec 카운트, library helper

회차 1 review (PR #96 회차 1) 의 4 건 actionable nit 모두 수렴.

- `crates/kebab-tui/src/input.rs`: `impl InputBuffer { ... }` 닫힘과
  `#[cfg(test)]` 사이의 잉여 빈 줄 1 개 제거 (1 → 2 → 1).
- `tasks/HOTFIXES.md`, `tasks/p9/p9-fb-22-tui-cursor-and-autoscroll.md`:
  신규 테스트 카운트 정정 — 12 → 11 (InputBuffer unit), 5/6 → 10
  (Ask integration), 30 → 38 (기존 backwards-compat 통과 카운트).
  영속 기록이라 정확한 숫자가 의미 있음.
- `crates/kebab-tui/src/library.rs`: `FilterEdit::active_buf_mut(&mut self)
  -> &mut InputBuffer` helper 추가, filter overlay 의 7 개 key arm
  (Backspace + Left/Right/Home/End/Delete + Char) 이 모두 helper 한 줄로
  통일. 동일 `match edit.field { ... }` 디스패치 7번 반복 → 1 곳.

코드/문서 수렴. 카운트는 `cargo test -p kebab-tui` 으로 재확인:
input.rs unit 18 → 29 (+11), tests/ask.rs 21 → 31 (+10).

Co-Authored-By: Claude Opus 4.7 (1M context) <noreply@anthropic.com>
This commit is contained in:
2026-05-04 15:34:28 +00:00
parent 294b1ed00c
commit f1dcdc34b0
4 changed files with 22 additions and 40 deletions

View File

@@ -234,7 +234,6 @@ impl InputBuffer {
}
}
#[cfg(test)]
mod tests {
use super::*;

View File

@@ -74,6 +74,17 @@ pub(crate) enum FilterField {
}
impl FilterEdit {
/// Borrow the buffer for the currently-focused field. Centralizes
/// the `match edit.field` pick so the key-handler arms (Backspace
/// / arrows / Delete / typed Char) don't each re-spell the same
/// 3-line dispatch.
fn active_buf_mut(&mut self) -> &mut crate::input::InputBuffer {
match self.field {
FilterField::Tags => &mut self.tags_buf,
FilterField::Lang => &mut self.lang_buf,
}
}
pub fn from_filter(filter: &DocFilter) -> Self {
let mut tags_buf = crate::input::InputBuffer::new();
tags_buf.push_str(&filter.tags_any.join(","));
@@ -362,62 +373,34 @@ fn handle_filter_edit_key(state: &mut App, key: KeyEvent) -> KeyOutcome {
KeyOutcome::Refresh
}
KeyCode::Backspace => {
let buf = match edit.field {
FilterField::Tags => &mut edit.tags_buf,
FilterField::Lang => &mut edit.lang_buf,
};
buf.pop_char();
edit.active_buf_mut().pop_char();
KeyOutcome::Continue
}
// p9-fb-22: cursor navigation + Delete inside the active filter
// field. Tab still cycles between Tags / Lang fields; arrows
// only move within the focused buffer.
KeyCode::Left => {
let buf = match edit.field {
FilterField::Tags => &mut edit.tags_buf,
FilterField::Lang => &mut edit.lang_buf,
};
buf.move_left();
edit.active_buf_mut().move_left();
KeyOutcome::Continue
}
KeyCode::Right => {
let buf = match edit.field {
FilterField::Tags => &mut edit.tags_buf,
FilterField::Lang => &mut edit.lang_buf,
};
buf.move_right();
edit.active_buf_mut().move_right();
KeyOutcome::Continue
}
KeyCode::Home => {
let buf = match edit.field {
FilterField::Tags => &mut edit.tags_buf,
FilterField::Lang => &mut edit.lang_buf,
};
buf.move_home();
edit.active_buf_mut().move_home();
KeyOutcome::Continue
}
KeyCode::End => {
let buf = match edit.field {
FilterField::Tags => &mut edit.tags_buf,
FilterField::Lang => &mut edit.lang_buf,
};
buf.move_end();
edit.active_buf_mut().move_end();
KeyOutcome::Continue
}
KeyCode::Delete => {
let buf = match edit.field {
FilterField::Tags => &mut edit.tags_buf,
FilterField::Lang => &mut edit.lang_buf,
};
buf.delete_after();
edit.active_buf_mut().delete_after();
KeyOutcome::Continue
}
KeyCode::Char(c) => {
let buf = match edit.field {
FilterField::Tags => &mut edit.tags_buf,
FilterField::Lang => &mut edit.lang_buf,
};
buf.push_char(c);
edit.active_buf_mut().push_char(c);
KeyOutcome::Continue
}
_ => KeyOutcome::Continue,

View File

@@ -33,7 +33,7 @@ git history.
**Spec contract impact**: p9-fb-10 frozen spec 의 "v1 is append-only; mid-string editing... is out of scope" 문구와 충돌. p9-fb-10 의 frozen 텍스트는 그대로 두고 본 HOTFIXES 항목이 InputBuffer 의 live cursor 모델 source of truth. p9-3 frozen spec 에는 follow-tail 동작이 명시되지 않았음 — 본 항목이 추가 동작 기록.
**Tests added**: 12 신규 InputBuffer unit (move_left/right ASCII/Hangul, home/end, mid-string insert, backspace at cursor, delete_after, mixed-width cursor invariant), 5 신규 Ask integration (left/right/home/end/Delete on Ask input, Hangul left arrow, follow_tail default, k disengages, Shift-G re-engages, Ctrl-L resets, follow-tail rendering bottom of long transcript). 기존 30 개 InputBuffer + Ask 테스트는 backwards-compat 으로 그대로 통과 (cursor 가 끝에 있을 때 push_char/pop_char 의미 동일).
**Tests added**: 11 신규 InputBuffer unit (move_left/right ASCII/Hangul, home/end, mid-string insert, backspace at cursor + at home no-op, delete_after at cursor + at end no-op, mixed-width cursor invariant, take 후 cursor reset), 10 신규 Ask integration (left/right/home/end/Delete on Ask input, Hangul left arrow, follow_tail default, k disengages, Shift-G re-engages, Ctrl-L resets, follow-tail rendering bottom of long transcript). 기존 38 개 InputBuffer + Ask 테스트는 backwards-compat 으로 그대로 통과 (cursor 가 끝에 있을 때 push_char/pop_char 의미 동일).
**Known limitation (deferred)**: cheatsheet popup body 가 Search +3 row, Ask +4 row 로 늘어나 75% height 한계가 더 빡빡해짐. p9-fb-21 의 deferred 한계와 같은 후속 task (popup scroll 또는 multi-column layout) 가 점점 더 필요함.

View File

@@ -64,9 +64,9 @@ source_feedback: 사용자 도그푸딩 2026-05-04 — Gitea #94 (입력 후 커
## Tests
- 12 신규 InputBuffer unit (move_left/right ASCII/Hangul, home/end, mid-string insert, backspace at cursor, delete_after, mixed-width cursor invariant, take 후 cursor reset).
- 6 신규 Ask integration (Left/Right/Home/End/Delete on Ask input, Hangul left arrow, follow_tail default, k disengages, Shift-G re-engages, Ctrl-L resets, follow-tail rendering bottom of long transcript).
- 기존 30+ 테스트는 그대로 통과 (cursor 가 끝일 때 backwards-compat).
- 11 신규 InputBuffer unit (move_left/right ASCII/Hangul, home/end, mid-string insert, backspace at cursor + at home no-op, delete_after at cursor + at end no-op, mixed-width cursor invariant, take 후 cursor reset).
- 10 신규 Ask integration (Left/Right/Home/End/Delete on Ask input, Hangul left arrow, follow_tail default, k disengages, Shift-G re-engages, Ctrl-L resets, follow-tail rendering bottom of long transcript).
- 기존 38 개 테스트는 그대로 통과 (cursor 가 끝일 때 backwards-compat).
## Risks / notes