Organized the code in buffer/mode.rs a bit more nicely.
This commit is contained in:
parent
8fd1659292
commit
e61149e514
|
@ -33,6 +33,11 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Functions for getting information about the buffer.
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
pub fn grapheme_count(&self) -> usize {
|
pub fn grapheme_count(&self) -> usize {
|
||||||
self.text.grapheme_count
|
self.text.grapheme_count
|
||||||
}
|
}
|
||||||
|
@ -43,101 +48,10 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
pub fn get_grapheme<'a>(&'a self, index: usize) -> &'a str {
|
|
||||||
if index >= self.grapheme_count() {
|
|
||||||
panic!("Buffer::get_grapheme(): index past last grapheme.");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return self.text.get_grapheme_recursive(index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn get_grapheme_width(&self, index: usize, tab_width: usize) -> usize {
|
|
||||||
if index >= self.grapheme_count() {
|
|
||||||
panic!("Buffer::get_grapheme_width(): index past last grapheme.");
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
return self.text.get_grapheme_width_recursive(index, tab_width);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn get_line<'a>(&'a self, index: usize) -> &'a Line {
|
|
||||||
if index >= self.line_count() {
|
|
||||||
panic!("get_line(): index out of bounds.");
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE: this can be done non-recursively, which would be more
|
|
||||||
// efficient. However, it seems likely to require unsafe code
|
|
||||||
// if done that way.
|
|
||||||
return self.text.get_line_recursive(index);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Blindly appends a line to the end of the current text without
|
|
||||||
/// doing any sanity checks. This is primarily for efficient
|
|
||||||
/// file loading.
|
|
||||||
pub fn append_line_unchecked(&mut self, line: Line) {
|
|
||||||
self.text.append_line_unchecked_recursive(line);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
/// Removes the lines in line indices [line_a, line_b).
|
|
||||||
pub fn remove_lines(&mut self, line_a: usize, line_b: usize) {
|
|
||||||
// Nothing to do
|
|
||||||
if line_a == line_b {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
// Bounds error
|
|
||||||
else if line_a > line_b {
|
|
||||||
panic!("Buffer::remove_lines(): line_a must be less than or equal to line_b.");
|
|
||||||
}
|
|
||||||
// Bounds error
|
|
||||||
else if line_b > self.line_count() {
|
|
||||||
panic!("Buffer::remove_lines(): attempt to remove lines past the last line of text.");
|
|
||||||
}
|
|
||||||
// Complete removal of all lines
|
|
||||||
else if line_a == 0 && line_b == self.text.line_count {
|
|
||||||
let mut temp_node = BufferNode::new();
|
|
||||||
mem::swap(&mut (self.text), &mut temp_node);
|
|
||||||
}
|
|
||||||
// All other cases
|
|
||||||
else {
|
|
||||||
self.text.remove_lines_recursive(line_a, line_b);
|
|
||||||
self.text.set_last_line_ending_recursive();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn pos_2d_to_closest_1d(&self, pos: (usize, usize)) -> usize {
|
|
||||||
return self.text.pos_2d_to_closest_1d_recursive(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn pos_vis_2d_to_closest_1d(&self, pos: (usize, usize), tab_width: usize) -> usize {
|
|
||||||
if pos.0 >= self.line_count() {
|
|
||||||
return self.grapheme_count();
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
let gs = self.pos_2d_to_closest_1d((pos.0, 0));
|
|
||||||
let h = self.get_line(pos.0).vis_pos_to_closest_grapheme_index(pos.1, tab_width);
|
|
||||||
return gs + h;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn pos_1d_to_closest_2d(&self, pos: usize) -> (usize, usize) {
|
|
||||||
return self.text.pos_1d_to_closest_2d_recursive(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
pub fn pos_1d_to_closest_vis_2d(&self, pos: usize, tab_width: usize) -> (usize, usize) {
|
|
||||||
let (v, h) = self.text.pos_1d_to_closest_2d_recursive(pos);
|
|
||||||
let vis_h = self.get_line(v).grapheme_index_to_closest_vis_pos(h, tab_width);
|
|
||||||
return (v, vis_h);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Editing operations
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Insert 'text' at grapheme position 'pos'.
|
/// Insert 'text' at grapheme position 'pos'.
|
||||||
pub fn insert_text(&mut self, text: &str, pos: usize) {
|
pub fn insert_text(&mut self, text: &str, pos: usize) {
|
||||||
|
@ -189,6 +103,46 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Removes the lines in line indices [line_a, line_b).
|
||||||
|
pub fn remove_lines(&mut self, line_a: usize, line_b: usize) {
|
||||||
|
// Nothing to do
|
||||||
|
if line_a == line_b {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
// Bounds error
|
||||||
|
else if line_a > line_b {
|
||||||
|
panic!("Buffer::remove_lines(): line_a must be less than or equal to line_b.");
|
||||||
|
}
|
||||||
|
// Bounds error
|
||||||
|
else if line_b > self.line_count() {
|
||||||
|
panic!("Buffer::remove_lines(): attempt to remove lines past the last line of text.");
|
||||||
|
}
|
||||||
|
// Complete removal of all lines
|
||||||
|
else if line_a == 0 && line_b == self.text.line_count {
|
||||||
|
let mut temp_node = BufferNode::new();
|
||||||
|
mem::swap(&mut (self.text), &mut temp_node);
|
||||||
|
}
|
||||||
|
// All other cases
|
||||||
|
else {
|
||||||
|
self.text.remove_lines_recursive(line_a, line_b);
|
||||||
|
self.text.set_last_line_ending_recursive();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// Blindly appends a line to the end of the current text without
|
||||||
|
/// doing any sanity checks. This is primarily for efficient
|
||||||
|
/// file loading.
|
||||||
|
pub fn append_line_unchecked(&mut self, line: Line) {
|
||||||
|
self.text.append_line_unchecked_recursive(line);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Undo/redo functionality
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Undoes operations that were pushed to the undo stack, and returns a
|
/// Undoes operations that were pushed to the undo stack, and returns a
|
||||||
/// cursor position that the cursor should jump to, if any.
|
/// cursor position that the cursor should jump to, if any.
|
||||||
pub fn undo(&mut self) -> Option<usize> {
|
pub fn undo(&mut self) -> Option<usize> {
|
||||||
|
@ -212,6 +166,77 @@ impl Buffer {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Position conversions
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub fn pos_2d_to_closest_1d(&self, pos: (usize, usize)) -> usize {
|
||||||
|
return self.text.pos_2d_to_closest_1d_recursive(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn pos_vis_2d_to_closest_1d(&self, pos: (usize, usize), tab_width: usize) -> usize {
|
||||||
|
if pos.0 >= self.line_count() {
|
||||||
|
return self.grapheme_count();
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
let gs = self.pos_2d_to_closest_1d((pos.0, 0));
|
||||||
|
let h = self.get_line(pos.0).vis_pos_to_closest_grapheme_index(pos.1, tab_width);
|
||||||
|
return gs + h;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn pos_1d_to_closest_2d(&self, pos: usize) -> (usize, usize) {
|
||||||
|
return self.text.pos_1d_to_closest_2d_recursive(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn pos_1d_to_closest_vis_2d(&self, pos: usize, tab_width: usize) -> (usize, usize) {
|
||||||
|
let (v, h) = self.text.pos_1d_to_closest_2d_recursive(pos);
|
||||||
|
let vis_h = self.get_line(v).grapheme_index_to_closest_vis_pos(h, tab_width);
|
||||||
|
return (v, vis_h);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Text reading functions
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
|
pub fn get_grapheme<'a>(&'a self, index: usize) -> &'a str {
|
||||||
|
if index >= self.grapheme_count() {
|
||||||
|
panic!("Buffer::get_grapheme(): index past last grapheme.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return self.text.get_grapheme_recursive(index);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn get_grapheme_width(&self, index: usize, tab_width: usize) -> usize {
|
||||||
|
if index >= self.grapheme_count() {
|
||||||
|
panic!("Buffer::get_grapheme_width(): index past last grapheme.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return self.text.get_grapheme_width_recursive(index, tab_width);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
pub fn get_line<'a>(&'a self, index: usize) -> &'a Line {
|
||||||
|
if index >= self.line_count() {
|
||||||
|
panic!("get_line(): index out of bounds.");
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE: this can be done non-recursively, which would be more
|
||||||
|
// efficient. However, it seems likely to require unsafe code
|
||||||
|
// if done that way.
|
||||||
|
return self.text.get_line_recursive(index);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
/// Creates a String from the buffer text in grapheme range [pos_a, posb).
|
/// Creates a String from the buffer text in grapheme range [pos_a, posb).
|
||||||
fn string_from_range(&self, pos_a: usize, pos_b: usize) -> String {
|
fn string_from_range(&self, pos_a: usize, pos_b: usize) -> String {
|
||||||
// Bounds checks
|
// Bounds checks
|
||||||
|
@ -241,6 +266,12 @@ impl Buffer {
|
||||||
return s;
|
return s;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
// Iterator creators
|
||||||
|
//------------------------------------------------------------------------
|
||||||
|
|
||||||
/// Creates an iterator at the first character
|
/// Creates an iterator at the first character
|
||||||
pub fn grapheme_iter<'a>(&'a self) -> BufferGraphemeIter<'a> {
|
pub fn grapheme_iter<'a>(&'a self) -> BufferGraphemeIter<'a> {
|
||||||
BufferGraphemeIter {
|
BufferGraphemeIter {
|
||||||
|
|
8
todo.md
8
todo.md
|
@ -13,8 +13,8 @@
|
||||||
a 2d representation of the text, for which it needs that information to
|
a 2d representation of the text, for which it needs that information to
|
||||||
know the relative positions of things.
|
know the relative positions of things.
|
||||||
- Editing (these are undoable):
|
- Editing (these are undoable):
|
||||||
- insert_text
|
//- insert_text
|
||||||
- remove_text
|
//- remove_text
|
||||||
- move_text
|
- move_text
|
||||||
- Undo functionality:
|
- Undo functionality:
|
||||||
- Undo
|
- Undo
|
||||||
|
@ -23,8 +23,8 @@
|
||||||
- Op section end
|
- Op section end
|
||||||
- Info:
|
- Info:
|
||||||
- byte_count (useful when saving the file)
|
- byte_count (useful when saving the file)
|
||||||
- grapheme_count
|
//- grapheme_count
|
||||||
- line_count
|
//- line_count
|
||||||
- Position conversions:
|
- Position conversions:
|
||||||
- index -> line_col
|
- index -> line_col
|
||||||
- line_col -> index
|
- line_col -> index
|
||||||
|
|
Loading…
Reference in New Issue
Block a user