Basic search mechanism in editor

This commit is contained in:
2026-01-26 01:25:40 +01:00
parent 4ae8e28b2f
commit bde64e7dc5
4 changed files with 141 additions and 17 deletions

View File

@@ -5,4 +5,5 @@ edition = "2021"
[dependencies]
ratatui = "0.29"
tui-textarea = "0.7"
regex = "1"
tui-textarea = { version = "0.7", features = ["search"] }

View File

@@ -40,9 +40,24 @@ impl CompletionState {
}
}
struct SearchState {
query: String,
active: bool,
}
impl SearchState {
fn new() -> Self {
Self {
query: String::new(),
active: false,
}
}
}
pub struct Editor {
text: TextArea<'static>,
completion: CompletionState,
search: SearchState,
}
impl Default for Editor {
@@ -56,12 +71,15 @@ impl Editor {
Self {
text: TextArea::default(),
completion: CompletionState::new(),
search: SearchState::new(),
}
}
pub fn set_content(&mut self, lines: Vec<String>) {
self.text = TextArea::new(lines);
self.completion.active = false;
self.search.query.clear();
self.search.active = false;
}
pub fn set_candidates(&mut self, candidates: Vec<CompletionCandidate>) {
@@ -99,6 +117,62 @@ impl Editor {
}
}
pub fn activate_search(&mut self) {
self.search.active = true;
self.completion.active = false;
}
pub fn search_active(&self) -> bool {
self.search.active
}
pub fn search_query(&self) -> &str {
&self.search.query
}
pub fn search_input(&mut self, c: char) {
self.search.query.push(c);
self.apply_search_pattern();
}
pub fn search_backspace(&mut self) {
self.search.query.pop();
self.apply_search_pattern();
}
pub fn search_confirm(&mut self) {
self.search.active = false;
}
pub fn search_clear(&mut self) {
self.search.query.clear();
self.search.active = false;
let _ = self.text.set_search_pattern("");
}
pub fn search_next(&mut self) -> bool {
if self.search.query.is_empty() {
return false;
}
self.text.search_forward(false)
}
pub fn search_prev(&mut self) -> bool {
if self.search.query.is_empty() {
return false;
}
self.text.search_back(false)
}
fn apply_search_pattern(&mut self) {
if self.search.query.is_empty() {
let _ = self.text.set_search_pattern("");
} else {
let pattern = format!("(?i){}", regex::escape(&self.search.query));
let _ = self.text.set_search_pattern(&pattern);
}
}
pub fn input(&mut self, input: impl Into<tui_textarea::Input>) {
let input: tui_textarea::Input = input.into();
let has_modifier = input.ctrl || input.alt;