Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
745b951
Update note tag parsing for @ and #
multiplex55 Feb 1, 2026
4421e4d
Fix tag parsing expectations
multiplex55 Feb 1, 2026
365aa3f
Merge pull request #782 from multiplex55/codex/update-tag-parsing-for…
multiplex55 Feb 1, 2026
425921b
Remove note tags from command lists
multiplex55 Feb 1, 2026
6bed97f
Update note root action test for tag alias
multiplex55 Feb 1, 2026
9e09c0b
Merge pull request #783 from multiplex55/codex/remove-note-tags-from-…
multiplex55 Feb 1, 2026
78c6f0d
Expand todo root commands
multiplex55 Feb 1, 2026
f4541e2
Update todo root query test
multiplex55 Feb 1, 2026
6f907e0
Merge pull request #784 from multiplex55/codex/update-todo-query-path…
multiplex55 Feb 1, 2026
040c5cb
Add debounce for note search and improve note matching
multiplex55 Feb 1, 2026
f76b95d
Merge pull request #785 from multiplex55/codex/implement-debounce-for…
multiplex55 Feb 1, 2026
91fb177
Update note link results
multiplex55 Feb 1, 2026
14e4b5c
Update note link results
multiplex55 Feb 1, 2026
e00e455
Merge pull request #786 from multiplex55/codex/revise-note-link-handl…
multiplex55 Feb 1, 2026
c5e14a4
Add tag action coverage for todo and notes
multiplex55 Feb 1, 2026
c46bc59
Merge pull request #787 from multiplex55/codex/update-plugins-for-tag…
multiplex55 Feb 1, 2026
de3d3b5
Adjust todo list scrolling and editing
multiplex55 Feb 1, 2026
9966ed9
Fix todo row label wrapping
multiplex55 Feb 1, 2026
c76da28
Merge pull request #788 from multiplex55/codex/remove-inline-edit-but…
multiplex55 Feb 1, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
65 changes: 64 additions & 1 deletion src/gui/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -120,6 +120,7 @@ const SUBCOMMANDS: &[&str] = &[

/// Prefix used to search user saved applications.
pub const APP_PREFIX: &str = "app";
const NOTE_SEARCH_DEBOUNCE: Duration = Duration::from_secs(1);

fn scale_ui<R>(ui: &mut egui::Ui, scale: f32, add_contents: impl FnOnce(&mut egui::Ui) -> R) -> R {
ui.scope(|ui| {
Expand Down Expand Up @@ -518,6 +519,7 @@ pub struct LauncherApp {
last_results_valid: bool,
last_timer_query: bool,
last_stopwatch_query: bool,
last_note_search_change: Option<Instant>,
pending_query: Option<String>,
confirm_modal: ConfirmationModal,
pending_confirm: Option<PendingConfirmAction>,
Expand Down Expand Up @@ -714,6 +716,39 @@ impl LauncherApp {
}
}

fn is_note_search_query(query: &str) -> bool {
query
.trim_start()
.to_lowercase()
.starts_with("note search")
}

fn note_search_debounce_ready(
last_change: Option<Instant>,
now: Instant,
debounce: Duration,
) -> bool {
last_change
.map(|changed_at| now.duration_since(changed_at) >= debounce)
.unwrap_or(false)
}

fn maybe_run_note_search_debounce(&mut self) {
if !Self::is_note_search_query(&self.query) {
self.last_note_search_change = None;
return;
}

if Self::note_search_debounce_ready(
self.last_note_search_change,
Instant::now(),
NOTE_SEARCH_DEBOUNCE,
) {
self.search();
self.last_note_search_change = None;
}
}

pub fn plugin_enabled(&self, name: &str) -> bool {
match &self.enabled_plugins {
Some(set) => set.contains(name),
Expand Down Expand Up @@ -1315,6 +1350,7 @@ impl LauncherApp {
last_results_valid: false,
last_timer_query: false,
last_stopwatch_query: false,
last_note_search_change: None,
pending_query: None,
confirm_modal: ConfirmationModal::default(),
pending_confirm: None,
Expand Down Expand Up @@ -3477,6 +3513,7 @@ impl eframe::App for LauncherApp {
self.search();
self.focus_input();
}
self.maybe_run_note_search_debounce();
if let (Some(t), Some(_)) = (self.error_time, self.error.as_ref()) {
if t.elapsed().as_secs_f32() >= 3.0 {
self.error = None;
Expand Down Expand Up @@ -3690,7 +3727,12 @@ impl eframe::App for LauncherApp {

if input.changed() {
self.autocomplete_index = 0;
self.search();
if Self::is_note_search_query(&self.query) {
self.last_note_search_change = Some(Instant::now());
} else {
self.last_note_search_change = None;
self.search();
}
}

if self.query_autocomplete && !use_dashboard && !self.suggestions.is_empty() {
Expand Down Expand Up @@ -4854,6 +4896,7 @@ mod tests {
Arc, Mutex,
};
use tempfile::tempdir;
use std::time::{Duration, Instant};

static TEST_MUTEX: Lazy<Mutex<()>> = Lazy::new(|| Mutex::new(()));

Expand Down Expand Up @@ -5148,4 +5191,24 @@ mod tests {

std::env::set_current_dir(orig_dir).unwrap();
}

#[test]
fn note_search_debounce_respects_delay() {
let start = Instant::now();
assert!(!LauncherApp::note_search_debounce_ready(
Some(start),
start,
NOTE_SEARCH_DEBOUNCE,
));
assert!(!LauncherApp::note_search_debounce_ready(
Some(start),
start + Duration::from_millis(999),
NOTE_SEARCH_DEBOUNCE,
));
assert!(LauncherApp::note_search_debounce_ready(
Some(start),
start + NOTE_SEARCH_DEBOUNCE,
NOTE_SEARCH_DEBOUNCE,
));
}
}
29 changes: 18 additions & 11 deletions src/gui/todo_view_dialog.rs
Original file line number Diff line number Diff line change
Expand Up @@ -89,7 +89,9 @@ impl TodoViewDialog {
.sort_by(|a, b| self.entries[*b].priority.cmp(&self.entries[*a].priority));
}
let area_height = ui.available_height();
// Keep horizontal overflow for long todo text without wrapping.
egui::ScrollArea::both()
.auto_shrink([false, false])
.max_height(area_height)
.show(ui, |ui| {
for idx in indices {
Expand Down Expand Up @@ -134,13 +136,15 @@ impl TodoViewDialog {
});
} else {
let entry = &mut self.entries[idx];
ui.horizontal_wrapped(|ui| {
ui.horizontal(|ui| {
if ui.checkbox(&mut entry.done, "").changed() {
save_now = true;
}
let resp = ui.label(entry.text.replace('\n', " "));
let resp = ui.add(
egui::Label::new(entry.text.replace('\n', " ")).wrap(false),
);
let idx_copy = idx;
resp.clone().context_menu(|ui| {
resp.clone().context_menu(|ui: &mut egui::Ui| {
if ui.button("Edit Todo").clicked() {
self.editing_idx = Some(idx_copy);
self.editing_text = entry.text.clone();
Expand All @@ -149,15 +153,18 @@ impl TodoViewDialog {
ui.close_menu();
}
});
ui.label(format!("p{}", entry.priority));
ui.add(
egui::Label::new(format!("p{}", entry.priority))
.wrap(false),
);
if !entry.tags.is_empty() {
ui.label(format!("#{:?}", entry.tags.join(", ")));
}
if ui.button("Edit").clicked() {
self.editing_idx = Some(idx);
self.editing_text = entry.text.clone();
self.editing_priority = entry.priority;
self.editing_tags = entry.tags.join(", ");
ui.add(
egui::Label::new(format!(
"#{:?}",
entry.tags.join(", ")
))
.wrap(false),
);
}
});
}
Expand Down
Loading