Skip to content

Commit

Permalink
feat(find): added find feature
Browse files Browse the repository at this point in the history
  • Loading branch information
metiftikci committed Oct 23, 2023
1 parent e38dac0 commit 26062ea
Show file tree
Hide file tree
Showing 19 changed files with 326 additions and 107 deletions.
14 changes: 6 additions & 8 deletions src/buffer.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
pub mod find;
pub mod helper;
pub mod highlight;
pub mod maps;
Expand All @@ -14,15 +15,12 @@ use std::collections::HashMap;
use crate::{
buffer::{
highlight::Highlight,
maps::{
get_default_command_maps, get_default_insert_maps, get_default_normal_maps,
get_default_visual_maps,
},
maps::{get_default_insert_maps, get_default_normal_maps, get_default_visual_maps},
mode::BufferMode,
options::BufferOptions,
visual_mode::Selection,
},
core::{point::Point, rectangle::Rectangle, style::Style},
core::{point::Point, rectangle::Rectangle, style::Style, text_position::TextPosition},
editor::Editor,
};

Expand All @@ -38,7 +36,6 @@ pub struct Buffer {
pub cursor: Point<usize>,
pub lines: Vec<String>,
pub selection: Selection,
pub actions_command: ActionMap,
pub actions_insert: ActionMap,
pub actions_normal: ActionMap,
pub actions_visual: ActionMap,
Expand All @@ -47,6 +44,7 @@ pub struct Buffer {
pub options: BufferOptions,
pub styles: HashMap<&'static str, Style>,
pub highlights: Vec<Highlight>,
pub finds: Vec<TextPosition>,
}

impl Buffer {
Expand All @@ -63,7 +61,6 @@ impl Buffer {
selection: Selection {
start: Point { x: 0, y: 0 },
},
actions_command: get_default_command_maps(),
actions_insert: get_default_insert_maps(),
actions_normal: get_default_normal_maps(),
actions_visual: get_default_visual_maps(),
Expand All @@ -72,8 +69,9 @@ impl Buffer {
options: BufferOptions::default(),
styles: HashMap::new(),
highlights: vec![],
finds: vec![],
};

buffer.set_static_highlights();
buffer.set_size(area);
buffer
}
Expand Down
121 changes: 121 additions & 0 deletions src/buffer/find.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,121 @@
use crate::{
buffer::{
highlight::{Highlight, HL_FIND_TEXT},
Buffer,
},
core::text_position::TextPosition,
};

impl Buffer {
pub fn find(&mut self, text: &str) {
self.clear_highlight(HL_FIND_TEXT);
self.finds.clear();

for row in 0..self.get_line_count() {
let line = self.get_line(row).clone();
if text.len() <= line.len() {
let column_end = line.len() - text.len() + 1;
for column in 0..column_end {
if &line[column..(column + text.len())] == text {
self.finds.push(TextPosition {
row,
start: column,
end: column + text.len() - 1,
});
self.highlights.push(Highlight {
name: HL_FIND_TEXT,
row,
start: column,
end: column + text.len() - 1,
});
}
}
}
}
}

pub fn clear_finds(&mut self) {
self.finds.clear();
self.clear_highlight(HL_FIND_TEXT);
}

pub fn move_to_next_find(&mut self) {
if self.finds.len() == 0 {
return;
}

let mut pos: Option<TextPosition> = None;
for find in self.finds.iter() {
if find.row < self.cursor.y {
continue;
} else if find.row == self.cursor.y && find.start <= self.cursor.x {
continue;
} else {
pos = Some(find.clone());
break;
}
}
if let Some(p) = pos {
self.move_cursor(p.row, p.start);
} else {
let p = self.finds.get(0).unwrap();
self.move_cursor(p.row, p.start);
}
}

pub fn move_to_previous_find(&mut self) {
if self.finds.len() == 0 {
return;
}

let mut pos: Option<TextPosition> = None;
for find in self.finds.iter().rev() {
if self.cursor.y < find.row {
continue;
} else if find.row == self.cursor.y && self.cursor.x <= find.start {
continue;
} else {
pos = Some(find.clone());
break;
}
}
if let Some(p) = pos {
self.move_cursor(p.row, p.start);
} else {
let p = self.finds.last().unwrap();
self.move_cursor(p.row, p.start);
}
}
}

#[cfg(test)]
mod tests {
use crate::{buffer::Buffer, core::rectangle::Rectangle};

#[test]
fn test() {
let mut buffer = Buffer::new(Rectangle {
x: 0,
y: 0,
width: 10,
height: 10,
});

buffer.lines.clear();
buffer.lines.push(String::from("123 567 90"));
buffer.lines.push(String::from("qwer yuiio"));
buffer.lines.push(String::from(""));
buffer.lines.push(String::from("1 3 56"));
buffer.lines.push(String::from(""));

buffer.find("56");

assert_eq!(2, buffer.finds.len());
assert_eq!(0, buffer.finds.get(0).unwrap().row);
assert_eq!(4, buffer.finds.get(0).unwrap().start);
assert_eq!(5, buffer.finds.get(0).unwrap().end);
assert_eq!(3, buffer.finds.get(1).unwrap().row);
assert_eq!(5, buffer.finds.get(1).unwrap().start);
assert_eq!(6, buffer.finds.get(1).unwrap().end);
}
}
61 changes: 57 additions & 4 deletions src/buffer/highlight.rs
Original file line number Diff line number Diff line change
@@ -1,4 +1,8 @@
use crate::{buffer::Buffer, core::rectangle::Rectangle};
use crate::{
buffer::Buffer,
core::{rectangle::Rectangle, style::Style},
theme::THEME_ONE as T,
};

pub struct Highlight {
pub name: &'static str,
Expand All @@ -7,6 +11,10 @@ pub struct Highlight {
pub end: usize,
}

pub const HL_CURRENT_LINE: &str = "CurrentLine";
pub const HL_CURRENT_LINE_TEXT: &str = "CurrentLineText";
pub const HL_FIND_TEXT: &str = "FindText";

impl Highlight {
pub fn is_visible_in_area(&self, area: Rectangle<usize>) -> bool {
!(self.row < area.y
Expand All @@ -17,19 +25,24 @@ impl Highlight {
}

impl Buffer {
pub fn set_static_highlights(&mut self) {
self.styles
.insert(HL_FIND_TEXT, Style::new(T.text_finded_fg, T.text_finded_bg));
}

pub fn get_dynamic_highlights(&self) -> Vec<Highlight> {
let mut list: Vec<Highlight> = vec![];

list.push(Highlight {
name: "CurrentLine",
name: HL_CURRENT_LINE,
row: self.cursor.x,
start: self.scroll.x,
end: self.text_area.width as usize,
});

if let Some(end) = self.get_current_line_last_char_index() {
list.push(Highlight {
name: "CurrentLineText",
name: HL_CURRENT_LINE_TEXT,
row: self.cursor.y,
start: 0,
end,
Expand All @@ -38,11 +51,18 @@ impl Buffer {

list
}

pub fn clear_highlight(&mut self, name: &str) {
self.highlights.retain(|h| h.name != name);
}
}

#[cfg(test)]
mod tests {
use crate::{buffer::Highlight, core::rectangle::Rectangle};
use crate::{
buffer::{Buffer, Highlight},
core::rectangle::Rectangle,
};

fn test1(row: usize, start: usize, end: usize) -> bool {
let area = Rectangle {
Expand Down Expand Up @@ -71,4 +91,37 @@ mod tests {
assert_eq!(false, test1(0, 10, 10));
assert_eq!(false, test1(10, 0, 1));
}

#[test]
fn clear_highlight_test() {
let mut buffer = Buffer::new(Rectangle {
x: 0,
y: 0,
width: 10,
height: 10,
});

buffer.highlights.push(Highlight {
name: "Foo",
row: 0,
start: 0,
end: 1,
});
buffer.highlights.push(Highlight {
name: "Bar",
row: 0,
start: 0,
end: 1,
});
buffer.highlights.push(Highlight {
name: "Baz",
row: 0,
start: 0,
end: 1,
});

buffer.clear_highlight("Foo");

assert_eq!(2, buffer.highlights.len());
}
}
54 changes: 27 additions & 27 deletions src/buffer/maps.rs
Original file line number Diff line number Diff line change
Expand Up @@ -33,42 +33,42 @@ pub fn get_default_insert_maps() -> ActionMap {
pub fn get_default_normal_maps() -> ActionMap {
let mut map: ActionMap = HashMap::new();
map.insert("left", |editor| {
editor.get_active_buffer_or_popup_mut().move_left()
editor.get_active_buffer_or_popup_mut().move_left();
});
map.insert("down", |editor| {
editor.get_active_buffer_or_popup_mut().move_down()
editor.get_active_buffer_or_popup_mut().move_down();
});
map.insert("up", |editor| {
editor.get_active_buffer_or_popup_mut().move_up()
editor.get_active_buffer_or_popup_mut().move_up();
});
map.insert("right", |editor| {
editor.get_active_buffer_or_popup_mut().move_right()
editor.get_active_buffer_or_popup_mut().move_right();
});

map.insert("h", |editor| {
editor.get_active_buffer_or_popup_mut().move_left()
editor.get_active_buffer_or_popup_mut().move_left();
});
map.insert("j", |editor| {
editor.get_active_buffer_or_popup_mut().move_down()
editor.get_active_buffer_or_popup_mut().move_down();
});
map.insert("k", |editor| {
editor.get_active_buffer_or_popup_mut().move_up()
editor.get_active_buffer_or_popup_mut().move_up();
});
map.insert("l", |editor| {
editor.get_active_buffer_or_popup_mut().move_right()
editor.get_active_buffer_or_popup_mut().move_right();
});

map.insert("g", |editor| {
editor.get_active_buffer_or_popup_mut().move_first_row()
editor.get_active_buffer_or_popup_mut().move_first_row();
});
map.insert("G", |editor| {
editor.get_active_buffer_or_popup_mut().move_last_row()
editor.get_active_buffer_or_popup_mut().move_last_row();
});
map.insert("0", |editor| {
editor.get_active_buffer_or_popup_mut().move_first_column()
editor.get_active_buffer_or_popup_mut().move_first_column();
});
map.insert("$", |editor| {
editor.get_active_buffer_or_popup_mut().move_last_column()
editor.get_active_buffer_or_popup_mut().move_last_column();
});

map.insert("w", |editor| {
Expand All @@ -95,7 +95,7 @@ pub fn get_default_normal_maps() -> ActionMap {
});

map.insert("x", |editor| {
editor.get_active_buffer_or_popup_mut().delete_char()
editor.get_active_buffer_or_popup_mut().delete_char();
});

map.insert("I", |editor| {
Expand Down Expand Up @@ -128,24 +128,24 @@ pub fn get_default_normal_maps() -> ActionMap {
buffer.enter_insert_mode();
});
map.insert(":", |editor| {
editor.command.reset();
editor.get_active_buffer_or_popup_mut().enter_command_mode()
editor.input.reset();
editor.get_active_buffer_or_popup_mut().enter_command_mode();
});
map.insert("v", |editor| {
editor.get_active_buffer_or_popup_mut().enter_visual_mode()
editor.get_active_buffer_or_popup_mut().enter_visual_mode();
});
return map;
}

pub fn get_default_command_maps() -> ActionMap {
let mut map: ActionMap = HashMap::new();
map.insert("esc", |editor| {
editor.get_active_buffer_or_popup_mut().enter_normal_mode()
map.insert("/", |editor| {
editor.input.reset();
editor.get_active_buffer_or_popup_mut().enter_find_mode();
});
map.insert("n", |editor| {
editor.get_active_buffer_or_popup_mut().move_to_next_find();
});
map.insert("N", |editor| {
editor
.get_active_buffer_or_popup_mut()
.move_to_previous_find();
});
map.insert("enter", |editor| editor.run_command());
map.insert("backspace", |editor| editor.command.delete_char());
map.insert("left", |editor| editor.command.move_left());
map.insert("right", |editor| editor.command.move_right());
return map;
}

Expand Down
Loading

0 comments on commit 26062ea

Please sign in to comment.