use crate::buffer::Buffer;
pub enum TextObjectType {
Inside,
Around,
}
pub type TOBounds = Option<(usize, usize)>;
pub struct TextObject<'a> {
pub name: &'a str,
command: fn(buffer: &Buffer) -> TOBounds,
}
impl<'a> TextObject<'a> {
pub fn new(name: &'a str, command: fn(buffer: &Buffer) -> TOBounds) -> Self {
TextObject { name, command }
}
pub fn around(&self, buffer: &Buffer) -> TOBounds {
(self.command)(buffer)
}
pub fn inside(&self, buffer: &Buffer) -> TOBounds {
let (i, j) = (self.command)(buffer)?;
if i == j {
return Some((i, j));
}
Some((i + 1, j - 1))
}
}
pub fn find_matching(buffer: &Buffer, start: char, end: char) -> TOBounds {
if buffer.get_curr_char() == start {
let second = buffer.find_next_on_line(end)?;
Some((buffer.cursor, second))
} else if let Some(first) = buffer.find_prev_on_line(start) {
let second = buffer.find_next_on_line_from(end, first)?;
Some((first, second))
} else if buffer.get_curr_char() == end {
let first = buffer.find_prev_on_line(start)?;
Some((first, buffer.cursor))
} else {
let first = buffer.find_next_on_line(start)?;
let second = buffer.find_next_on_line_from(end, first)?;
Some((first, second))
}
}
pub fn parentheses(buffer: &Buffer) -> TOBounds {
find_matching(buffer, '(', ')')
}
pub fn curly_braces(buffer: &Buffer) -> TOBounds {
find_matching(buffer, '{', '}')
}
pub fn square_braces(buffer: &Buffer) -> TOBounds {
find_matching(buffer, '[', ']')
}
pub fn quotations(buffer: &Buffer) -> TOBounds {
find_matching(buffer, '\"', '\"')
}
pub fn single_quotations(buffer: &Buffer) -> TOBounds {
find_matching(buffer, '\'', '\'')
}
pub fn grav(buffer: &Buffer) -> TOBounds {
find_matching(buffer, '`', '`')
}