progress adding new tld at correct position in mark_node_ids

This commit is contained in:
Anton-4 2021-09-03 20:12:49 +02:00
parent 864e76be10
commit f5b30b71da
5 changed files with 94 additions and 36 deletions

View File

@ -67,6 +67,12 @@ pub enum EdError {
))]
EmptyCodeString { backtrace: Backtrace },
#[snafu(display(
"FailedToUpdateIdentIdName: {}",
err_str
))]
FailedToUpdateIdentIdName { err_str: String, backtrace: Backtrace },
#[snafu(display("GetContentOnNestedNode: tried to get string content from Nested MarkupNode. Can only get content from Text or Blank nodes."))]
GetContentOnNestedNode { backtrace: Backtrace },
@ -123,6 +129,12 @@ pub enum EdError {
backtrace: Backtrace,
},
#[snafu(display("NoDefMarkNodeBeforeLineNr: I could not find a MarkupNode whose root parent points to a DefId located before the given line number: {}.", line_nr))]
NoDefMarkNodeBeforeLineNr {
line_nr: usize,
backtrace: Backtrace,
},
#[snafu(display("NodeWithoutAttributes: expected to have a node with attributes. This is a Nested MarkupNode, only Text and Blank nodes have attributes."))]
NodeWithoutAttributes { backtrace: Backtrace },

View File

@ -1,6 +1,6 @@
use crate::editor::ed_error::EdResult;
use crate::editor::ed_error::NestedNodeWithoutChildren;
use crate::editor::ed_error::NodeIdNotInGridNodeMap;
use crate::editor::ed_error::{NodeIdNotInGridNodeMap, NoDefMarkNodeBeforeLineNr};
use crate::editor::mvc::ed_model::EdModel;
use crate::editor::slow_pool::MarkNodeId;
use crate::editor::slow_pool::SlowPool;
@ -14,6 +14,8 @@ use crate::ui::util::{slice_get, slice_get_mut};
use snafu::OptionExt;
use std::fmt;
use super::markup::nodes::get_root_mark_node_id;
#[derive(Debug)]
pub struct GridNodeMap {
pub lines: Vec<Vec<MarkNodeId>>,
@ -79,16 +81,13 @@ impl GridNodeMap {
line_ref.drain(selection.start_pos.column..selection.end_pos.column);
} else {
// TODO support multiline
unimplemented!("TODO support deleting multiline selection")
}
Ok(())
}
/*pub fn new_line(&mut self) {
self.lines.push(vec![])
}*/
pub fn get_id_at_row_col(&self, caret_pos: TextPos) -> UIResult<MarkNodeId> {
let line = slice_get(caret_pos.line, &self.lines)?;
let node_id = slice_get(caret_pos.column, line)?;
@ -327,6 +326,38 @@ impl GridNodeMap {
Ok(last_child_id)
}
// get id of root mark_node whose ast_node_id points to a DefId
pub fn get_def_mark_node_id_before_line(
&self,
line_nr: usize,
mark_node_pool: &SlowPool,
) -> EdResult<MarkNodeId> {
for curr_line_nr in (0..line_nr).rev() {
let first_col_pos =
TextPos {
line: curr_line_nr,
column: 0
};
if self.node_exists_at_pos(first_col_pos) {
let mark_node_id = self.get_id_at_row_col(first_col_pos)?;
let root_mark_node_id = get_root_mark_node_id(mark_node_id, mark_node_pool);
let ast_node_id = mark_node_pool.get(root_mark_node_id).get_ast_node_id();
match ast_node_id {
ASTNodeId::ADefId(_) => return Ok(root_mark_node_id),
_ => (),
}
}
}
NoDefMarkNodeBeforeLineNr {
line_nr
}.fail()
}
}
impl fmt::Display for GridNodeMap {

View File

@ -829,3 +829,20 @@ fn tree_as_string_helper(
tree_as_string_helper(child, level + 1, tree_string, mark_node_pool);
}
}
// return to the the root parent_id of the current node
pub fn get_root_mark_node_id(
mark_node_id: MarkNodeId,
mark_node_pool: &SlowPool,
) -> MarkNodeId {
let mut curr_mark_node_id = mark_node_id;
let mut curr_parent_id_opt = mark_node_pool.get(curr_mark_node_id).get_parent_id_opt();
while let Some(curr_parent_id) = curr_parent_id_opt {
curr_mark_node_id = curr_parent_id;
curr_parent_id_opt = mark_node_pool.get(curr_mark_node_id).get_parent_id_opt();
}
curr_mark_node_id
}

View File

@ -28,6 +28,7 @@ use crate::editor::mvc::tld_value_update::{start_new_tld_value, update_tld_val_n
use crate::editor::slow_pool::MarkNodeId;
use crate::editor::slow_pool::SlowPool;
use crate::editor::syntax_highlight::HighlightStyle;
use crate::editor::util::index_of;
use crate::lang::ast::Def2;
use crate::lang::ast::DefId;
use crate::lang::ast::{Expr2, ExprId};
@ -755,7 +756,7 @@ pub fn handle_new_char_expr(
start_new_list(ed_model)?
}
'\r' => {
// For convenience and consistency there is only one way to format Roc, you can't add extra blank lines.
println!("For convenience and consistency there is only one way to format Roc, you can't add extra blank lines.");
InputOutcome::Ignored
}
_ => InputOutcome::Ignored,
@ -1032,7 +1033,7 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
} else { //no MarkupNode at the current position
if *received_char == '\r' {
// TODO move to separate file
// TODO move to separate function
let carets = ed_model.get_carets();
for caret_pos in carets.iter() {
@ -1055,14 +1056,14 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
let new_line_blank = Def2::Blank;
let new_line_blank_id = ed_model.module.env.pool.add(new_line_blank);
// TODO this should insert at caret line_nr, not push at end
ed_model.module.ast.def_ids.push(new_line_blank_id);
let prev_def_mn_id = ed_model.grid_node_map.get_def_mark_node_id_before_line(caret_pos.line + 1, &ed_model.mark_node_pool)?;
let prev_def_mn_id_indx = index_of(prev_def_mn_id, &ed_model.markup_ids)?;
ed_model.module.ast.def_ids.insert(prev_def_mn_id_indx, new_line_blank_id);
let blank_mn_id = ed_model
.add_mark_node(new_blank_mn(ASTNodeId::ADefId(new_line_blank_id), None));
// TODO this should insert at caret line_nr, not push at end
ed_model.markup_ids.push(blank_mn_id);
ed_model.markup_ids.insert(prev_def_mn_id_indx + 1,blank_mn_id); // + 1 because first markup node is header
ed_model.insert_all_between_line(
caret_pos.line + 2, // one blank line between top level definitions
@ -1103,14 +1104,14 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
let new_blank = Def2::Blank;
let new_blank_id = ed_model.module.env.pool.add(new_blank);
// TODO this should insert at caret line_nr, not push at end
ed_model.module.ast.def_ids.push(new_blank_id);
let prev_def_mn_id = ed_model.grid_node_map.get_def_mark_node_id_before_line(caret_pos.line, &ed_model.mark_node_pool)?;
let prev_def_mn_id_indx = index_of(prev_def_mn_id, &ed_model.markup_ids)?;
ed_model.module.ast.def_ids.insert(prev_def_mn_id_indx, new_blank_id);
let blank_mn_id = ed_model
.add_mark_node(new_blank_mn(ASTNodeId::ADefId(new_blank_id), None));
// TODO this should insert at caret line_nr, not push at end
ed_model.markup_ids.push(blank_mn_id);
ed_model.markup_ids.insert(prev_def_mn_id_indx + 1,blank_mn_id); // + 1 because first mark_node is header
if ed_model.code_lines.line_is_only_newline(caret_pos.line - 1)? {
@ -1124,7 +1125,7 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
ed_model.simple_move_caret_down(caret_pos, 1);
ed_model.insert_all_between_line(
caret_pos.line + 1,
caret_pos.line,
0,
&[blank_mn_id],
)?;

View File

@ -1,25 +1,12 @@
use roc_module::symbol::{Interns, Symbol};
use crate::{
editor::{
ed_error::{EdResult, KeyNotFound},
markup::{
attribute::Attributes,
common_nodes::{new_blank_mn_w_nl, new_equals_mn},
nodes::MarkupNode,
},
slow_pool::{MarkNodeId, SlowPool},
syntax_highlight::HighlightStyle,
},
lang::{
use crate::{editor::{ed_error::{EdResult, KeyNotFound, FailedToUpdateIdentIdName}, markup::{attribute::Attributes, common_nodes::{new_blank_mn_w_nl, new_equals_mn}, nodes::{MarkupNode, set_parent_for_all}}, slow_pool::{MarkNodeId, SlowPool}, syntax_highlight::HighlightStyle}, lang::{
ast::{Def2, Expr2},
expr::Env,
parse::ASTNodeId,
pattern::{get_identifier_string, Pattern2},
pool::NodeId,
},
ui::text::text_pos::TextPos,
};
}, ui::text::text_pos::TextPos};
use super::{
app_update::InputOutcome,
@ -134,6 +121,8 @@ pub fn start_new_tld_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<
.mark_node_pool
.replace_node(curr_mark_node_id, tld_mark_node);
set_parent_for_all(curr_mark_node_id, &mut ed_model.mark_node_pool);
// remove data corresponding to old Blank node
ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?;
@ -172,13 +161,21 @@ pub fn update_tld_val_name(
if node_caret_offset <= content_str_mut.len() {
content_str_mut.insert(node_caret_offset, *new_char);
// TODO no unwrap
ed_model
let update_val_name_res = ed_model
.module
.env
.ident_ids
.update_key(&old_val_name, content_str_mut)
.unwrap();
.update_key(&old_val_name, content_str_mut);
match update_val_name_res {
Err(err_str) => {
FailedToUpdateIdentIdName {
err_str
}.fail()?;
}
_ => (),
}
ed_model.insert_between_line(
old_caret_pos.line,