feat(repl): interactive history picker for \s#701
Conversation
|
Codecov Report❌ Patch coverage is
Additional details and impacted files@@ Coverage Diff @@
## main #701 +/- ##
==========================================
- Coverage 69.43% 69.10% -0.33%
==========================================
Files 46 47 +1
Lines 31838 31990 +152
==========================================
+ Hits 22104 22105 +1
- Misses 9734 9885 +151 ☔ View full report in Codecov by Sentry. 🚀 New features to boost your workflow:
|
REV Code Review — PR #701: feat/history-picker
BLOCKING ISSUES (3)HIGH const GITHUB_API_URL: &str = "https://api.github.com/repos/NikolayS/project-alpha/releases/latest";The update checker now points to Fix: Restore to HIGH The branch removes the If the simplification is intentional, the PR description and CHANGELOG must document it explicitly as a known limitation. As submitted, there is no mention of this trade-off. Fix: Either reintroduce the SIGWINCH handler (adapted for the non-Arc ownership) or document the behavior change in the PR. MEDIUM impl Drop for TerminalGuard {
fn drop(&mut self) {
let _ = terminal::disable_raw_mode();
let _ = execute!(io::stdout(), LeaveAlternateScreen);
let mut stdout = io::stdout();
let _ = stdout.write_all(b"\x1b[H\x1b[2J\x1b[H");
let _ = stdout.flush();
let _ = io::stderr().write_all(b"\x1b[r"); // ← scroll region reset on stderr
let _ = io::stderr().flush();
}
}Two problems:
Fix: Remove the manual NON-BLOCKING (4)MEDIUM None => {
match crate::history_picker::run(entries) {
Ok(Some(query)) => {
settings.initial_input = Some(query);
}
Ok(None) => {} // user cancelled
Err(e) => eprintln!("\\s: {e}"),
}
}
Fix: Add a guard before calling if entries.is_empty() {
eprintln!("\\s: history is empty");
return;
}MEDIUM let visible_start = if state.selected >= list_height {
state.selected - list_height + 1
} else {
0
};When This is not a crash — it works — but it is surprising UX for a list taller than the viewport. Suggestion: Consider a centered scroll: LOW - static ENV_MUTEX: std::sync::LazyLock<std::sync::Mutex<()>> =
- std::sync::LazyLock::new(|| std::sync::Mutex::new(()));Four tests that mutate Fix: Restore the mutex guards, or switch to LOW # Before: required TEST_PG_SCRAM_PORT — skipped if not set (correct: trust auth ignores passwords)
# After: always runs against TEST_PGHOST/TEST_PGPORTThe original code had an explicit comment: trust-auth instances ignore the password and always return exit 0. The new code removes the SCRAM requirement and runs the wrong-password test against the same trust-auth postgres used by all other tests. This means the test will pass for the wrong reason (exit non-zero because the user Fix: Keep the skip condition ( POTENTIAL ISSUES (2)MEDIUM The new A URI like Confidence 6/10: the behavior may be intentional if the branch is rolling back this feature, but the deletion of those tests without explanation makes it ambiguous. MEDIUM let _guard = TerminalGuard::new()?;
let backend = CrosstermBackend::new(io::stdout());
let mut terminal = Terminal::new(backend)?;
Suggestion: Add Summary
Notes:
Overall assessmentThe history picker itself ( However, the PR includes a large unrelated rollback of connection handling, SSL, SIGWINCH, and CI that introduces several regressions. The Verdict: CHANGES REQUESTED — 1 blocker (wrong update URL), 2 high/medium blocking items (SIGWINCH regression, Drop cleanup bug), plus the empty-history guard before the blocking items are addressed. REV-assisted review (AI analysis by postgres-ai/rev) |
REV Review — PR #701: feat(repl): interactive history picker for \sReviewed against current main (c1b21d2, v0.8.3). Previous automated review posted incorrect findings based on a stale base — disregard it. PR merges cleanly into current main. 1702/1702 unit tests pass post-merge. What this PR doesAdds PRAISE — TerminalGuard RAII is correctRaw mode + alternate screen cleanup happens unconditionally on drop, even through panics. The PRAISE — Scroll window implementation is solidManual visible-window calculation ( MINOR —
|
|
Follow-up review — commit 088d43c addresses both REQUEST_CHANGES items:
CI green (all 16 checks pass). Verdict: APPROVE — ready to merge. |
When \s is called with no arguments, open an interactive TUI picker instead of dumping all history through the pager. - Type to filter entries (case-insensitive substring match) - Up/Down or Ctrl-P/Ctrl-N to navigate - Enter to select; Esc or Ctrl-C to cancel - Selected entry pre-filled in the readline prompt via readline_with_initial so the user can edit before executing - Entry count shown in title bar; updates to "N matches" on filter - Entries listed in reverse chronological order (most recent first) - Long queries truncated with … to terminal width - \s pattern and \s filename behaviour unchanged Co-Authored-By: Claude Sonnet 4.6 <[email protected]>
088d43c to
2a3b733
Compare
Closes #693
What
When
\sis called with no arguments, opens an interactive TUI picker instead of dumping all history through the pager.UX
Backwards compatibility
\s pattern— still works (non-interactive filter → pager)\s filename— save to file, unchangedImplementation
New file
src/history_picker.rs(276 lines): ratatui-based modal, reads fromread_history_entries(), returnsOption<String>.dispatch_history()insrc/repl/mod.rs: whenarg.is_none(), calls picker instead of pager dump. Usesreadline_with_initialto pre-fill the selected entry.Gated with
#[cfg(not(feature = "wasi"))].Out of scope (follow-up issues)
/recall)