fmt, cleanup, improved comments

This commit is contained in:
Anton-4 2021-04-17 12:46:51 +02:00
parent 97c67de37b
commit 8f6afab13e
7 changed files with 167 additions and 133 deletions

View File

@ -55,7 +55,7 @@ impl CodeLines {
line_ref.drain(selection.start_pos.column..selection.end_pos.column);
} else {
// TODO
// TODO support multiline selections
}
Ok(())

View File

@ -1,4 +1,5 @@
use crate::editor::slow_pool::MarkNodeId;
use crate::ui::ui_error::UIResult;
use colored::*;
use snafu::{Backtrace, ErrorCompat, NoneError, ResultExt, Snafu};
@ -72,7 +73,7 @@ pub enum EdError {
},
#[snafu(display(
"MissingSelection: ed_model.selected_expr2_id was some but ed_model.caret_w_sel_vec did not contain any Some(Selection)."
"MissingSelection: ed_model.selected_expr2_id was Some(NodeId<Expr2>) but ed_model.caret_w_sel_vec did not contain any Some(Selection)."
))]
MissingSelection { backtrace: Backtrace },
@ -209,3 +210,10 @@ impl From<UIError> for EdError {
dummy_res.context(UIErrorBacktrace { msg }).unwrap_err()
}
}
pub fn from_ui_res<T>(ui_res: UIResult<T>) -> EdResult<T> {
match ui_res {
Ok(t) => Ok(t),
Err(ui_err) => Err(EdError::from(ui_err)),
}
}

View File

@ -1,7 +1,7 @@
use crate::editor::ed_error::NestedNodeWithoutChildren;
use crate::editor::mvc::ed_model::EdModel;
use crate::editor::ed_error::EdResult;
use crate::editor::ed_error::NestedNodeWithoutChildren;
use crate::editor::ed_error::NodeIdNotInGridNodeMap;
use crate::editor::mvc::ed_model::EdModel;
use crate::editor::slow_pool::MarkNodeId;
use crate::editor::util::first_last_index_of;
use crate::editor::util::index_of;
@ -11,8 +11,8 @@ use crate::ui::text::selection::Selection;
use crate::ui::text::text_pos::TextPos;
use crate::ui::ui_error::UIResult;
use crate::ui::util::{slice_get, slice_get_mut};
use std::fmt;
use snafu::OptionExt;
use std::fmt;
#[derive(Debug)]
pub struct GridNodeMap {
@ -146,77 +146,94 @@ impl GridNodeMap {
let (start_pos, end_pos) = self.get_nested_start_end_pos(*node_id, ed_model)?;
Ok((start_pos, end_pos, node.get_ast_node_id()))
} else {
} else {
let (first_node_index, last_node_index) = first_last_index_of(*node_id, line)?;
let curr_node_id = slice_get(first_node_index, line)?;
let curr_ast_node_id = ed_model.markup_node_pool.get(*curr_node_id).get_ast_node_id();
let curr_node_id = slice_get(first_node_index, line)?;
let curr_ast_node_id = ed_model
.markup_node_pool
.get(*curr_node_id)
.get_ast_node_id();
let mut expr_start_index = first_node_index;
let mut expr_end_index = last_node_index;
let mut expr_start_index = first_node_index;
let mut expr_end_index = last_node_index;
// we may encounter ast id's of children of the current node
let mut pos_extra_subtract = 0;
// we may encounter ast id's of children of the current node
let mut pos_extra_subtract = 0;
for i in (0..first_node_index).rev() {
let prev_pos_node_id = slice_get(i, line)?;
let prev_ast_node_id = ed_model.markup_node_pool.get(*prev_pos_node_id).get_ast_node_id();
for i in (0..first_node_index).rev() {
let prev_pos_node_id = slice_get(i, line)?;
let prev_ast_node_id = ed_model
.markup_node_pool
.get(*prev_pos_node_id)
.get_ast_node_id();
if prev_ast_node_id == curr_ast_node_id {
if pos_extra_subtract > 0 {
expr_start_index -= pos_extra_subtract + 1;
pos_extra_subtract = 0;
if prev_ast_node_id == curr_ast_node_id {
if pos_extra_subtract > 0 {
expr_start_index -= pos_extra_subtract + 1;
pos_extra_subtract = 0;
} else {
expr_start_index -= 1;
}
} else {
expr_start_index -= 1;
pos_extra_subtract += 1;
}
} else {
pos_extra_subtract += 1;
}
}
// we may encounter ast id's of children of the current node
let mut pos_extra_add = 0;
// we may encounter ast id's of children of the current node
let mut pos_extra_add = 0;
for i in last_node_index..line.len() {
let next_pos_node_id = slice_get(i, line)?;
let next_ast_node_id = ed_model.markup_node_pool.get(*next_pos_node_id).get_ast_node_id();
for i in last_node_index..line.len() {
let next_pos_node_id = slice_get(i, line)?;
let next_ast_node_id = ed_model
.markup_node_pool
.get(*next_pos_node_id)
.get_ast_node_id();
if next_ast_node_id == curr_ast_node_id {
if pos_extra_add > 0 {
expr_end_index += pos_extra_add + 1;
pos_extra_add = 0;
if next_ast_node_id == curr_ast_node_id {
if pos_extra_add > 0 {
expr_end_index += pos_extra_add + 1;
pos_extra_add = 0;
} else {
expr_end_index += 1;
}
} else {
expr_end_index += 1;
pos_extra_add += 1;
}
} else {
pos_extra_add += 1;
}
}
Ok((
TextPos {
line: caret_pos.line,
column: expr_start_index,
},
TextPos {
line: caret_pos.line,
column: expr_end_index,
},
curr_ast_node_id,
))
Ok((
TextPos {
line: caret_pos.line,
column: expr_start_index,
},
TextPos {
line: caret_pos.line,
column: expr_end_index,
},
curr_ast_node_id,
))
}
}
pub fn get_nested_start_end_pos(&self, nested_node_id: MarkNodeId, ed_model: &EdModel) -> EdResult<(TextPos, TextPos)> {
pub fn get_nested_start_end_pos(
&self,
nested_node_id: MarkNodeId,
ed_model: &EdModel,
) -> EdResult<(TextPos, TextPos)> {
let parent_mark_node = ed_model.markup_node_pool.get(nested_node_id);
let all_child_ids = parent_mark_node.get_children_ids();
let first_child_id = all_child_ids
.first()
.with_context(|| NestedNodeWithoutChildren { node_id: nested_node_id })?;
.with_context(|| NestedNodeWithoutChildren {
node_id: nested_node_id,
})?;
let last_child_id = all_child_ids
.last()
.with_context(|| NestedNodeWithoutChildren { node_id: nested_node_id })?;
.with_context(|| NestedNodeWithoutChildren {
node_id: nested_node_id,
})?;
let expr_start_pos = ed_model
.grid_node_map

View File

@ -59,6 +59,7 @@ impl MarkupNode {
}
}
// finds the the id of the MarkupNode whose deletion would result in the deletion of all MarkupNodes corresponding to a specific ast node
pub fn get_expr2_level_node(
&self,
curr_mark_node_id: MarkNodeId,

View File

@ -1,7 +1,6 @@
use super::app_model::AppModel;
use super::ed_update;
use crate::editor::ed_error::EdResult;
use crate::ui::text::lines::SelectableLines;
use crate::window::keyboard_input::from_winit;
use winit::event::{ModifiersState, VirtualKeyCode};
@ -44,7 +43,7 @@ pub fn pass_keydown_to_focused(
if let Some(ref mut ed_model) = app_model.ed_model_opt {
if ed_model.has_focus {
ed_model.handle_key_down(&modifiers, virtual_keycode)?;
ed_model.ed_handle_key_down(&modifiers, virtual_keycode)?;
}
}

View File

@ -1,4 +1,5 @@
use crate::editor::code_lines::CodeLines;
use crate::editor::ed_error::from_ui_res;
use crate::editor::ed_error::print_ui_err;
use crate::editor::ed_error::EdResult;
use crate::editor::ed_error::MissingSelection;
@ -143,7 +144,9 @@ impl<'a> EdModel<'a> {
self.code_lines.del_at_line(line_nr, index)
}
// select all MarkupNodes that refer to specific ast node and it's children.
pub fn select_expr(&mut self) -> EdResult<()> {
// include parent in selection if an `Expr2` was already selected
if let Some(sel_expr2_id) = self.selected_expr2_id {
let curr_mark_node_id = self.get_curr_mark_node_id()?;
let curr_mark_node = self.markup_node_pool.get(curr_mark_node_id);
@ -159,7 +162,9 @@ impl<'a> EdModel<'a> {
let parent_mark_node = self.markup_node_pool.get(parent_id);
let ast_node_id = parent_mark_node.get_ast_node_id();
let (expr_start_pos, expr_end_pos) = self.grid_node_map.get_nested_start_end_pos(parent_id, self)?;
let (expr_start_pos, expr_end_pos) = self
.grid_node_map
.get_nested_start_end_pos(parent_id, self)?;
self.set_raw_sel(RawSelection {
start_pos: expr_start_pos,
@ -172,6 +177,7 @@ impl<'a> EdModel<'a> {
self.dirty = true;
}
} else {
// select `Expr2` in which caret is currently positioned
let caret_pos = self.get_caret();
if self.grid_node_map.node_exists_at_pos(caret_pos) {
let (expr_start_pos, expr_end_pos, ast_node_id) = self
@ -191,6 +197,84 @@ impl<'a> EdModel<'a> {
Ok(())
}
pub fn ed_handle_key_down(
&mut self,
modifiers: &Modifiers,
virtual_keycode: VirtualKeyCode,
) -> EdResult<()> {
match virtual_keycode {
Left => from_ui_res(self.move_caret_left(modifiers)),
Up => {
if modifiers.ctrl && modifiers.shift {
self.select_expr()
} else {
from_ui_res(self.move_caret_up(modifiers))
}
}
Right => from_ui_res(self.move_caret_right(modifiers)),
Down => from_ui_res(self.move_caret_down(modifiers)),
A => {
if modifiers.ctrl {
from_ui_res(self.select_all())
} else {
Ok(())
}
}
Home => from_ui_res(self.move_caret_home(modifiers)),
End => from_ui_res(self.move_caret_end(modifiers)),
F11 => {
self.show_debug_view = !self.show_debug_view;
self.dirty = true;
Ok(())
}
_ => Ok(()),
}
}
fn replace_slected_expr_with_blank(&mut self) -> EdResult<()> {
if let Some(sel_expr2_id) = self.selected_expr2_id {
let curr_mark_node_id = self.get_curr_mark_node_id()?;
let curr_mark_node = self.markup_node_pool.get(curr_mark_node_id);
let expr2_level_mark_node_id = curr_mark_node.get_expr2_level_node(
curr_mark_node_id,
sel_expr2_id,
self.module.env.pool,
)?;
let expr2_level_mark_node = self.markup_node_pool.get(expr2_level_mark_node_id);
let blank_replacement = MarkupNode::Blank {
ast_node_id: sel_expr2_id,
attributes: Attributes::new(),
syn_high_style: HighlightStyle::Blank,
parent_id_opt: expr2_level_mark_node.get_parent_id_opt(),
};
self.markup_node_pool
.replace_node(expr2_level_mark_node_id, blank_replacement);
let active_selection = self.get_selection().context(MissingSelection {})?;
self.code_lines.del_selection(active_selection)?;
self.grid_node_map.del_selection(active_selection)?;
let caret_pos = self.get_caret();
self.insert_between_line(
caret_pos.line,
caret_pos.column,
nodes::BLANK_PLACEHOLDER,
expr2_level_mark_node_id,
)?;
self.module.env.pool.set(sel_expr2_id, Expr2::Blank)
}
self.set_sel_none();
Ok(())
}
}
impl<'a> SelectableLines for EdModel<'a> {
@ -320,39 +404,10 @@ impl<'a> SelectableLines for EdModel<'a> {
fn handle_key_down(
&mut self,
modifiers: &Modifiers,
virtual_keycode: VirtualKeyCode,
_modifiers: &Modifiers,
_virtual_keycode: VirtualKeyCode,
) -> UIResult<()> {
match virtual_keycode {
Left => self.move_caret_left(modifiers),
Up => {
if modifiers.ctrl && modifiers.shift {
// TODO remove unwrap
self.select_expr().unwrap();
Ok(())
} else {
self.move_caret_up(modifiers)
}
}
Right => self.move_caret_right(modifiers),
Down => self.move_caret_down(modifiers),
A => {
if modifiers.ctrl {
self.select_all()
} else {
Ok(())
}
}
Home => self.move_caret_home(modifiers),
End => self.move_caret_end(modifiers),
F11 => {
self.show_debug_view = !self.show_debug_view;
self.dirty = true;
Ok(())
}
_ => Ok(()),
}
unreachable!("Use EdModel::ed_handle_key_down instead.")
}
}
@ -383,8 +438,6 @@ pub fn get_node_context<'a>(ed_model: &'a EdModel) -> EdResult<NodeContext<'a>>
}
pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult<InputOutcome> {
// TODO nested records
let input_outcome = match received_char {
'\u{1}' // Ctrl + A
| '\u{3}' // Ctrl + C
@ -401,52 +454,7 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
// On Linux, '\u{8}' is backspace,
// on macOS '\u{7f}'.
if let Some(sel_expr2_id) = ed_model.selected_expr2_id {
let curr_mark_node_id = ed_model.get_curr_mark_node_id()?;
let curr_mark_node = ed_model.markup_node_pool.get(curr_mark_node_id);
let expr2_level_mark_node_id =
curr_mark_node.get_expr2_level_node(
curr_mark_node_id,
sel_expr2_id,
ed_model.module.env.pool,
)?;
let expr2_level_mark_node = ed_model.markup_node_pool.get(expr2_level_mark_node_id);
let blank_replacement = MarkupNode::Blank {
ast_node_id: sel_expr2_id,
attributes: Attributes::new(),
syn_high_style: HighlightStyle::Blank,
parent_id_opt: expr2_level_mark_node.get_parent_id_opt(),
};
ed_model.markup_node_pool.replace_node(
expr2_level_mark_node_id,
blank_replacement
);
let active_selection = ed_model.get_selection().context(
MissingSelection{}
)?;
ed_model.code_lines.del_selection(active_selection)?;
ed_model.grid_node_map.del_selection(active_selection)?;
let caret_pos = ed_model.get_caret();
ed_model.insert_between_line(
caret_pos.line,
caret_pos.column,
nodes::BLANK_PLACEHOLDER,
expr2_level_mark_node_id,
)?;
ed_model.module.env.pool.set(
sel_expr2_id,
Expr2::Blank,
)
}
ed_model.set_sel_none();
ed_model.replace_slected_expr_with_blank()?;
InputOutcome::Accepted
}

View File

@ -32,6 +32,7 @@ pub fn index_of<T: ::std::fmt::Debug + std::cmp::Eq>(elt: T, slice: &[T]) -> EdR
Ok(index)
}
// returns the index of the first occurence of element and index of the last occurence
pub fn first_last_index_of<T: ::std::fmt::Debug + std::cmp::Eq>(
elt: T,
slice: &[T],