Skip to content

Commit 52e67be

Browse files
zippoxerclaude
andcommitted
Fix Windows: double key input and empty session list
- Filter for KeyEventKind::Press to avoid double input on Windows (crossterm sends both Press and Release events on Windows) - Default search scope to "everywhere" instead of current folder (fixes empty list when run from directory with no sessions) - Handle both / and \ path separators in scope display - Use USERPROFILE env var fallback for Windows home directory 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude <noreply@anthropic.com>
1 parent ea4cb97 commit 52e67be

File tree

4 files changed

+17
-9
lines changed

4 files changed

+17
-9
lines changed

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "recall"
3-
version = "0.1.2"
3+
version = "0.1.3"
44
edition = "2021"
55
description = "Search and resume Claude Code and Codex CLI conversations"
66

src/app.rs

Lines changed: 11 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -98,7 +98,7 @@ impl App {
9898
total_sessions: 0,
9999
index_rx: Some(rx),
100100
indexing: true,
101-
search_scope: SearchScope::Folder(launch_cwd.clone()),
101+
search_scope: SearchScope::Everything,
102102
launch_cwd,
103103
};
104104

@@ -192,7 +192,10 @@ impl App {
192192
pub fn scope_folder_name(&self) -> Option<&str> {
193193
match &self.search_scope {
194194
SearchScope::Everything => None,
195-
SearchScope::Folder(path) => path.rsplit('/').next(),
195+
SearchScope::Folder(path) => {
196+
// Handle both Unix (/) and Windows (\) path separators
197+
path.rsplit(['/', '\\']).next()
198+
}
196199
}
197200
}
198201

@@ -206,8 +209,10 @@ impl App {
206209
SearchScope::Folder(path) => path.as_str(),
207210
};
208211

209-
// Replace home dir with ~
210-
let home = std::env::var("HOME").unwrap_or_default();
212+
// Replace home dir with ~ (HOME on Unix, USERPROFILE on Windows)
213+
let home = std::env::var("HOME")
214+
.or_else(|_| std::env::var("USERPROFILE"))
215+
.unwrap_or_default();
211216
let display_path = if !home.is_empty() && path.starts_with(&home) {
212217
format!("~{}", &path[home.len()..])
213218
} else {
@@ -221,7 +226,8 @@ impl App {
221226
}
222227

223228
// Otherwise show prefix/.../<last_dir>
224-
let last_component = path.rsplit('/').next().unwrap_or(path);
229+
// Handle both Unix (/) and Windows (\) path separators
230+
let last_component = path.rsplit(['/', '\\']).next().unwrap_or(path);
225231
let prefix = if display_path.starts_with('~') { "~" } else { "" };
226232
Some(format!("{}/.../{}", prefix, last_component))
227233
}

src/main.rs

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,7 +8,7 @@ mod ui;
88

99
use anyhow::Result;
1010
use app::App;
11-
use crossterm::event::{self, Event, KeyCode, KeyModifiers, MouseEventKind};
11+
use crossterm::event::{self, Event, KeyCode, KeyEventKind, KeyModifiers, MouseEventKind};
1212
use std::time::Duration;
1313

1414
const VERSION: &str = env!("CARGO_PKG_VERSION");
@@ -67,7 +67,9 @@ fn run(terminal: &mut tui::Tui, app: &mut App) -> Result<()> {
6767
// Handle all pending events (drain queue to prevent mouse event flooding)
6868
while event::poll(Duration::from_millis(0))? {
6969
match event::read()? {
70-
Event::Key(key) => match key.code {
70+
// On Windows, crossterm sends both Press and Release events.
71+
// Only handle Press to avoid double input.
72+
Event::Key(key) if key.kind == KeyEventKind::Press => match key.code {
7173
KeyCode::Char('c') if key.modifiers.contains(KeyModifiers::CONTROL) => {
7274
app.should_quit = true;
7375
}

0 commit comments

Comments
 (0)