mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-11 05:34:11 +03:00
fmt, cleanup, improved comments
This commit is contained in:
parent
97c67de37b
commit
8f6afab13e
@ -55,7 +55,7 @@ impl CodeLines {
|
||||
|
||||
line_ref.drain(selection.start_pos.column..selection.end_pos.column);
|
||||
} else {
|
||||
// TODO
|
||||
// TODO support multiline selections
|
||||
}
|
||||
|
||||
Ok(())
|
||||
|
@ -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)),
|
||||
}
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -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)?;
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
}
|
||||
|
@ -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],
|
||||
|
Loading…
Reference in New Issue
Block a user