diff --git a/crates/ui-egui/src/app.rs b/crates/ui-egui/src/app.rs index a132dbe..1b68ce1 100644 --- a/crates/ui-egui/src/app.rs +++ b/crates/ui-egui/src/app.rs @@ -7393,6 +7393,16 @@ impl NoteCraftApp { // press made them together. self.undo(); } + // Ctrl+F, and OneNote's Ctrl+E, go to the search box. Taken before the page sees + // them: with the caret in the page, the key went nowhere and the words typed to find + // something were written into the note (issue #134). The code view has a Find of its + // own for the file it shows, so it keeps Ctrl+F while it is open. + if !self.show_source && ctx.input_mut(|i| i.consume_key(Modifiers::COMMAND, Key::F) || i.consume_key(Modifiers::COMMAND, Key::E)) { + if let Some(caret) = self.editor.as_mut().and_then(|ed| ed.caret.as_mut()) { + caret.focus = false; + } + self.focus_search = true; + } self.nav_keys(ctx); self.direction_keys(ctx); self.hierarchy_keys(ctx); diff --git a/crates/ui-egui/tests/ui.rs b/crates/ui-egui/tests/ui.rs index dd44b9c..5ce9068 100644 --- a/crates/ui-egui/tests/ui.rs +++ b/crates/ui-egui/tests/ui.rs @@ -607,6 +607,34 @@ fn clicking_a_page_opens_it_and_a_container_toggles() { review(&mut h, "markdown_page"); } +/// Issue #134: Ctrl+F with the caret in the page goes to the search box, and what is typed +/// next is looked for, not written into the note. Ctrl+E, OneNote's key for it, does too. +#[test] +fn ctrl_f_in_the_page_goes_to_search_and_writes_nothing() { + for key in ["F", "E"] { + let (_t, mut app, s) = sample_app("ui-ctrl-f"); + app.open_path(&s.html_page.to_string_lossy()); + let mut h = harness(app, LIGHT); + settle(&mut h); + ask(&mut h, "ui.caret", json!({"block": 1})).expect("caret in the words"); + settle(&mut h); + let before = h.state().body().unwrap_or_default().to_string(); + + ask(&mut h, "ui.key", json!({"key": key, "ctrl": true})).expect("Ctrl+key"); + settle(&mut h); + ask(&mut h, "ui.text", json!({"text": "findneedle"})).expect("type a query"); + settle(&mut h); + + let after = h.state().body().unwrap_or_default().to_string(); + assert!(!after.contains("findneedle"), "Ctrl+{key}: nothing typed went into the note:\n{after}"); + assert_eq!(after, before, "Ctrl+{key}: the page is as it was"); + assert!( + h.get_all_by_role(egui::accesskit::Role::TextInput).any(|node| node.value().as_deref() == Some("findneedle")), + "Ctrl+{key}: the query is in the search box" + ); + } +} + /// The caret lives in the page: clicking a block and typing changes that block, and the page /// is written back in its own format. This is the editor the owner asked for, so it is tested /// for both formats.