Skip to content

Commit 09ccbe1

Browse files
committed
[tui] Simplify editor buffer post mutation validation
Remove the complexity of having an editor_engine_internal_api.rs apply_changes() function that accepts a closure by using a Drop impl on the struct returned by editor_buffer_struct.rs get_mut(). Also fix this bug: #343 Closes #343
1 parent 57ff54b commit 09ccbe1

File tree

10 files changed

+813
-848
lines changed

10 files changed

+813
-848
lines changed

core/src/stack_alloc_types/make_new.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@
1515
* limitations under the License.
1616
*/
1717

18-
// BOOKM: Clever Rust, use of decl macro w/ `tt` to allow any number of arguments.
18+
// BOOKM: Clever Rust, use of decl macro w/ `tt` to allow any number of arguments.
1919

2020
/// This macro joins a collection of items into a [crate::StringStorage] (which is
2121
/// allocated and returned) with a specified delimiter and format. It iterates over the

core/src/tui_core/dimens/position.rs

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,8 @@ impl Position {
144144
}
145145

146146
pub mod position_math_ops {
147+
use std::ops::Sub;
148+
147149
use super::*;
148150

149151
impl AddAssign<ChUnit> for Position {
@@ -193,6 +195,16 @@ pub mod position_math_ops {
193195
}
194196
}
195197
}
198+
199+
impl Sub<Position> for Position {
200+
type Output = Position;
201+
fn sub(self, other: Position) -> Self {
202+
Self {
203+
col_index: self.col_index - other.col_index,
204+
row_index: self.row_index - other.row_index,
205+
}
206+
}
207+
}
196208
}
197209

198210
pub mod convert_position_to_other_type {

tui/src/tui/editor/editor_buffer/editor_buffer_selection_support.rs

Lines changed: 12 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -51,7 +51,7 @@ impl EditorBufferApi {
5151
end_display_col_index: cmp::max(previous, current),
5252
};
5353

54-
let editor_buffer_mut = editor_buffer.get_mut();
54+
let editor_buffer_mut = editor_buffer.get_mut(ch(0), ch(0));
5555

5656
editor_buffer_mut.selection_map.insert(
5757
row_index,
@@ -119,7 +119,7 @@ impl EditorBufferApi {
119119
let delta = previous - current;
120120
let new_range = range.shrink_end_by(delta);
121121

122-
let editor_buffer_mut = editor_buffer.get_mut();
122+
let editor_buffer_mut = editor_buffer.get_mut(ch(0), ch(0));
123123
editor_buffer_mut.selection_map.insert(
124124
row_index,
125125
new_range,
@@ -138,7 +138,7 @@ impl EditorBufferApi {
138138
let delta = range_start - current;
139139
let new_range = range.grow_start_by(delta);
140140

141-
let editor_buffer_mut = editor_buffer.get_mut();
141+
let editor_buffer_mut = editor_buffer.get_mut(ch(0), ch(0));
142142
editor_buffer_mut.selection_map.insert(
143143
row_index,
144144
new_range,
@@ -157,7 +157,7 @@ impl EditorBufferApi {
157157
let delta = current - range_end;
158158
let new_range = range.grow_end_by(delta);
159159

160-
let editor_buffer_mut = editor_buffer.get_mut();
160+
let editor_buffer_mut = editor_buffer.get_mut(ch(0), ch(0));
161161
editor_buffer_mut.selection_map.insert(
162162
row_index,
163163
new_range,
@@ -177,7 +177,7 @@ impl EditorBufferApi {
177177
let delta = current - range_start;
178178
let new_range = range.shrink_start_by(delta);
179179

180-
let editor_buffer_mut = editor_buffer.get_mut();
180+
let editor_buffer_mut = editor_buffer.get_mut(ch(0), ch(0));
181181
editor_buffer_mut.selection_map.insert(
182182
row_index,
183183
new_range,
@@ -196,7 +196,7 @@ impl EditorBufferApi {
196196
// `handle_selection_multiline_caret_movement`.
197197
if let Some(range) = editor_buffer.get_selection_map().get(row_index) {
198198
if range.start_display_col_index == range.end_display_col_index {
199-
let editor_buffer_mut = editor_buffer.get_mut();
199+
let editor_buffer_mut = editor_buffer.get_mut(ch(0), ch(0));
200200
editor_buffer_mut.selection_map.remove(
201201
row_index,
202202
SelectionRange::caret_movement_direction_left_right(
@@ -498,7 +498,7 @@ impl EditorBufferApi {
498498

499499
let row_index = current.row_index; // Same as previous.row_index.
500500

501-
let editor_buffer_mut = editor_buffer.get_mut();
501+
let editor_buffer_mut = editor_buffer.get_mut(ch(0), ch(0));
502502

503503
call_if_true!(DEBUG_TUI_COPY_PASTE, {
504504
let message = "📜🔼🔽 handle_selection_multiline_caret_movement_hit_top_or_bottom_of_document";
@@ -660,7 +660,7 @@ mod multiline_select_helpers {
660660
SelectionRange::new(start_col, end_col)
661661
};
662662

663-
let editor_buffer_mut = editor_buffer.get_mut();
663+
let editor_buffer_mut = editor_buffer.get_mut(ch(0), ch(0));
664664
editor_buffer_mut.selection_map.insert(
665665
first.row_index,
666666
first_row_range,
@@ -688,7 +688,7 @@ mod multiline_select_helpers {
688688
let first_line_width = editor_buffer.get_line_display_width(first.row_index);
689689

690690
// Mutably borrow the selection map.
691-
let editor_buffer_mut = editor_buffer.get_mut();
691+
let editor_buffer_mut = editor_buffer.get_mut(ch(0), ch(0));
692692

693693
// Extend the existing range (in selection map) for the first row to end of line.
694694
if let Some(first_row_range) =
@@ -735,7 +735,7 @@ mod multiline_select_helpers {
735735
let first_line_width = editor_buffer.get_line_display_width(first.row_index);
736736

737737
// Mutably borrow the selection map.
738-
let editor_buffer_mut = editor_buffer.get_mut();
738+
let editor_buffer_mut = editor_buffer.get_mut(ch(0), ch(0));
739739

740740
// FIRST ROW.
741741
if let Some(first_row_range) =
@@ -808,7 +808,7 @@ mod multiline_select_helpers {
808808
let last = previous;
809809

810810
// Mutably borrow the selection map.
811-
let editor_buffer_mut = editor_buffer.get_mut();
811+
let editor_buffer_mut = editor_buffer.get_mut(ch(0), ch(0));
812812

813813
// Drop the existing range (in selection map) for the last row.
814814
if editor_buffer_mut
@@ -860,7 +860,7 @@ mod multiline_select_helpers {
860860
let last = current;
861861

862862
// Mutably borrow the selection map.
863-
let editor_buffer_mut = editor_buffer.get_mut();
863+
let editor_buffer_mut = editor_buffer.get_mut(ch(0), ch(0));
864864

865865
// Drop the existing range (in selection map) for the first row.
866866
if editor_buffer_mut

tui/src/tui/editor/editor_buffer/editor_buffer_struct.rs

Lines changed: 37 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,6 @@
1414
* See the License for the specific language governing permissions and
1515
* limitations under the License.
1616
*/
17-
1817
use std::{collections::HashMap,
1918
fmt::{Debug, Formatter, Result}};
2019

@@ -40,7 +39,8 @@ use sizing::VecEditorContentLines;
4039
use smallvec::{smallvec, SmallVec};
4140

4241
use super::SelectionList;
43-
use crate::{EditorEngine,
42+
use crate::{validate_editor_buffer_change::EditorBufferMut,
43+
EditorEngine,
4444
EditorEngineApi,
4545
HasFocus,
4646
RenderArgs,
@@ -69,17 +69,16 @@ use crate::{EditorEngine,
6969
///
7070
/// These functions take any one of the following args:
7171
/// 1. [crate::EditorArgsMut]
72-
/// 2. [crate::EditorArgs]
7372
/// 3. [EditorBuffer] and [EditorEngine]
7473
///
7574
/// # Accessing and mutating the fields (w/ validation)
7675
///
7776
/// All the fields in this struct are private. In order to access them you have to use the
7877
/// accessor associated functions. To mutate them, you have to use the
79-
/// [get_mut](EditorBuffer::get_mut) method, which returns a tuple w/ mutable references
80-
/// to the fields. This rather strange design allows for all mutations to be tracked
81-
/// easily and allows for validation operations to be applied post mutation (by
82-
/// [crate::validate_editor_buffer_change::apply_change]).
78+
/// [get_mut](EditorBuffer::get_mut) method, which returns a struct of mutable references
79+
/// to the fields. This struct [EditorBufferMut] implements the [Drop] trait, which allows
80+
/// for validation [crate::validate_editor_buffer_change] operations to be applied post
81+
/// mutation.
8382
///
8483
/// # Different kinds of caret positions
8584
///
@@ -439,16 +438,28 @@ pub mod access_and_mutate {
439438
/// 2. [CaretKind::ScrollAdjusted] -> The caret position adjusted for scrolling using
440439
/// scroll_offset.
441440
pub fn get_caret(&self, kind: CaretKind) -> Position {
441+
Self::get_caret_adjusted(
442+
self.editor_content.caret_display_position,
443+
self.editor_content.scroll_offset,
444+
kind,
445+
)
446+
}
447+
448+
pub fn get_caret_adjusted(
449+
caret_display_position: Position,
450+
scroll_offset: ScrollOffset,
451+
kind: CaretKind,
452+
) -> Position {
442453
match kind {
443-
CaretKind::Raw => self.editor_content.caret_display_position,
454+
CaretKind::Raw => caret_display_position,
444455
CaretKind::ScrollAdjusted => {
445456
let col_index = Self::calc_scroll_adj_caret_col(
446-
&self.editor_content.caret_display_position,
447-
&self.editor_content.scroll_offset,
457+
&caret_display_position,
458+
&scroll_offset,
448459
);
449460
let row_index = Self::calc_scroll_adj_caret_row(
450-
&self.editor_content.caret_display_position,
451-
&self.editor_content.scroll_offset,
461+
&caret_display_position,
462+
&scroll_offset,
452463
);
453464
position!(col_index: col_index, row_index: row_index)
454465
}
@@ -478,15 +489,25 @@ pub mod access_and_mutate {
478489
// REFACTOR: [ ] return struct, not tuple, add drop impl to it, to update lines_us? or drop lines_us?
479490
// REFACTOR: [ ] after mutations to lines, lines_us must be recomputed! consider remove this from the struct & computing it only when needed
480491
/// Even though this struct is mutable by editor_ops.rs, this method is provided
481-
/// to mark when mutable access is made to this struct. This makes it easy to
482-
/// determine what code mutates this struct, since it is necessary to validate
483-
/// things after mutation quite a bit in editor_ops.rs.
484-
pub fn get_mut(&mut self) -> EditorBufferMut<'_> {
492+
/// to mark when mutable access is made to this struct.
493+
///
494+
/// This makes it easy to determine what code mutates this struct, since it is
495+
/// necessary to validate things after mutation quite a bit in editor_ops.rs.
496+
///
497+
/// [EditorBufferMut] implements the [Drop] trait, which ensures that any
498+
/// validation changes are applied after making changes to the [EditorBuffer].
499+
pub fn get_mut(
500+
&mut self,
501+
viewport_width: ChUnit,
502+
viewport_height: ChUnit,
503+
) -> EditorBufferMut<'_> {
485504
EditorBufferMut::new(
486505
&mut self.editor_content.lines,
487506
&mut self.editor_content.caret_display_position,
488507
&mut self.editor_content.scroll_offset,
489508
&mut self.editor_content.selection_list,
509+
viewport_width,
510+
viewport_height,
490511
)
491512
}
492513

@@ -500,37 +521,6 @@ pub mod access_and_mutate {
500521
&self.editor_content.selection_list
501522
}
502523
}
503-
504-
pub struct EditorBufferMut<'a> {
505-
pub lines: &'a mut VecEditorContentLines,
506-
pub caret: &'a mut Position,
507-
pub scroll_offset: &'a mut ScrollOffset,
508-
pub selection_map: &'a mut SelectionList,
509-
}
510-
511-
// BOOKM: Clever Rust, use of Drop to perform transaction close / end.
512-
513-
impl Drop for EditorBufferMut<'_> {
514-
fn drop(&mut self) {
515-
// REFACTOR: [ ] do all the validation here?
516-
}
517-
}
518-
519-
impl<'a> EditorBufferMut<'a> {
520-
pub fn new(
521-
lines: &'a mut VecEditorContentLines,
522-
caret: &'a mut Position,
523-
scroll_offset: &'a mut ScrollOffset,
524-
selection_map: &'a mut SelectionList,
525-
) -> Self {
526-
Self {
527-
lines,
528-
caret,
529-
scroll_offset,
530-
selection_map,
531-
}
532-
}
533-
}
534524
}
535525

536526
pub mod history {

tui/src/tui/editor/editor_buffer/selection_list.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -128,7 +128,7 @@ impl SelectionList {
128128
// Column is the last row of the range.
129129
let indices = self.get_ordered_indices();
130130
let first_row_index = indices.first()?;
131-
let last_row_index = indices.first()?;
131+
let last_row_index = indices.last()?;
132132
Some(position!(
133133
col_index: self.get(*last_row_index)?.start_display_col_index,
134134
row_index: *first_row_index

tui/src/tui/editor/editor_engine/editor_engine_api.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,7 +381,7 @@ impl EditorEngineApi {
381381
unicode_string: string,
382382
..
383383
}) =
384-
EditorEngineInternalApi::string_at_caret(editor_buffer, editor_engine)
384+
EditorEngineInternalApi::string_at_caret(editor_buffer)
385385
{
386386
// PERF: [ ] perf
387387
string

0 commit comments

Comments
 (0)