simplification, stricter adherence to projectional editing approach

This commit is contained in:
Anton-4 2022-02-21 14:47:57 +01:00
parent 5374f6d6b8
commit 48d5775f62
No known key found for this signature in database
GPG Key ID: C954D6E0F9C0ABFD
19 changed files with 274 additions and 364 deletions

View File

@ -154,12 +154,22 @@ fn canonicalize_field<'a>(
let (loc_can_expr, output) =
expr_to_expr2(env, scope, &loc_expr.value, loc_expr.region);
Ok(CanonicalField::LabelAndValue {
label: label.value,
value_expr: loc_can_expr,
value_output: output,
var: field_var,
})
match loc_can_expr {
Expr2::RuntimeError() => {
Ok(CanonicalField::InvalidLabelOnly {
label: label.value,
var: field_var,
})
}
_ => {
Ok(CanonicalField::LabelAndValue {
label: label.value,
value_expr: loc_can_expr,
value_output: output,
var: field_var,
})
}
}
}
OptionalValue(label, _, loc_expr) => Err(CanonicalizeFieldProblem::InvalidOptionalValue {

View File

@ -15,6 +15,26 @@ pub struct AST {
pub def_ids: Vec<DefId>,
}
impl AST {
pub fn insert_def_at_index(&mut self, new_def_id: DefId, index: usize) {
self.def_ids.insert(index, new_def_id);
}
// TODO print in tree shape, similar to linux tree command
pub fn ast_to_string(&self, pool: &Pool) -> String {
let mut full_ast_string = String::new();
for def_id in self.def_ids.iter() {
full_ast_string.push_str(&def2_to_string(*def_id, pool));
full_ast_string.push_str("\n\n");
}
full_ast_string
}
}
#[derive(Debug, PartialEq, Copy, Clone)]
pub enum ASTNodeId {
ADefId(DefId),

View File

@ -148,6 +148,9 @@ fn expr2_to_string_helper(
&Expr2::Var { .. } => {
out_string.push_str(&format!("{:?}", expr2,));
}
Expr2::RuntimeError { .. } => {
out_string.push_str("RuntimeError\n");
}
other => todo!("Implement for {:?}", other),
}

View File

@ -50,6 +50,7 @@ pub fn expr_to_expr2<'a>(
region: Region,
) -> (Expr2, self::Output) {
use roc_parse::ast::Expr::*;
//dbg!("{:?}", parse_expr);
match parse_expr {
Float(string) => {

View File

@ -28,7 +28,7 @@ pub fn load_module(src_file: &Path) -> LoadedModule {
Ok(x) => x,
Err(roc_load::file::LoadingProblem::FormattedReport(report)) => {
panic!(
"Failed to load module from src_file {:?}. Report: {:?}",
"Failed to load module from src_file {:?}. Report: {}",
src_file, report
);
}

View File

@ -25,7 +25,7 @@ pub fn parse_from_string<'a>(
) -> ASTResult<AST> {
let blank_line_indx = code_str
.find("\n\n")
.expect("I was expecting a double newline to split header and rest of code.");
.expect("I was expecting two newline chars to split header and rest of code.");
let header_str = &code_str[0..blank_line_indx];
let tail_str = &code_str[blank_line_indx..];

View File

@ -64,13 +64,12 @@ pub fn expr2_to_markup<'a>(
Expr2::Str(text) => {
let content = format!("\"{}\"", text.as_str(env.pool));
new_markup_node(
with_indent(indent_level, &content),
ast_node_id,
HighlightStyle::String,
mark_node_pool,
indent_level,
)
string_mark_node(&content, indent_level, ast_node_id, mark_node_pool)
}
Expr2::SmallStr(array_str) => {
let content = format!("\"{}\"", array_str.as_str());
string_mark_node(&content, indent_level, ast_node_id, mark_node_pool)
}
Expr2::GlobalTag { name, .. } => new_markup_node(
with_indent(indent_level, &get_string(env, name)),
@ -387,3 +386,13 @@ fn with_indent(indent_level: usize, some_str: &str) -> String {
full_string
}
fn string_mark_node(content: &str, indent_level: usize, ast_node_id: ASTNodeId, mark_node_pool: &mut SlowPool) -> MarkNodeId {
new_markup_node(
with_indent(indent_level, &content),
ast_node_id,
HighlightStyle::String,
mark_node_pool,
indent_level,
)
}

View File

@ -468,3 +468,33 @@ pub fn join_mark_nodes_commas(
mark_nodes.into_iter().interleave(join_nodes).collect()
}
pub fn mark_nodes_to_string(
markup_node_ids: &[MarkNodeId],
mark_node_pool: &SlowPool,
) -> String {
let mut all_code_string = String::new();
for mark_node_id in markup_node_ids.iter() {
node_to_string_w_children(*mark_node_id, &mut all_code_string, mark_node_pool)
}
all_code_string
}
pub fn node_to_string_w_children(node_id: MarkNodeId, str_buffer: &mut String, mark_node_pool: &SlowPool) {
let node = mark_node_pool.get(node_id);
if node.is_nested() {
for child_id in node.get_children_ids() {
node_to_string_w_children(child_id, str_buffer, mark_node_pool);
}
for _ in 0..node.get_newlines_at_end() {
str_buffer.push('\n')
}
} else {
let node_content_str = node.get_full_content();
str_buffer.push_str(&node_content_str);
}
}

View File

@ -580,6 +580,7 @@ impl IdentIds {
}
// necessary when the name of a value is changed in the editor
// TODO fix when same ident_name is present multiple times
pub fn update_key(
&mut self,
old_ident_name: &str,

View File

@ -14,136 +14,16 @@ pub struct CodeLines {
}
impl CodeLines {
pub fn insert_between_line(
&mut self,
line_nr: usize,
index: usize,
new_str: &str,
) -> UIResult<()> {
let nr_of_lines = self.lines.len();
if line_nr < nr_of_lines {
let line_ref = slice_get_mut(line_nr, &mut self.lines)?;
line_ref.insert_str(index, new_str);
} else if line_nr >= self.lines.len() {
for _ in 0..((line_nr - nr_of_lines) + 1) {
self.push_empty_line();
}
self.insert_between_line(line_nr, index, new_str)?;
} else {
LineInsertionFailed {
line_nr,
nr_of_lines,
}
.fail()?;
}
self.nr_of_chars += new_str.len();
Ok(())
}
pub fn insert_empty_line(&mut self, line_nr: usize) -> UIResult<()> {
if line_nr <= self.lines.len() {
self.lines.insert(line_nr, String::new());
Ok(())
} else {
OutOfBounds {
index: line_nr,
collection_name: "code_lines.lines".to_owned(),
len: self.lines.len(),
}
.fail()
pub fn from_str(code_str: &str) -> CodeLines {
CodeLines {
lines: code_str
.split('\n')
.map(|s| s.to_owned())
.collect(),
nr_of_chars: code_str.len(),
}
}
pub fn push_empty_line(&mut self) {
self.lines.push(String::new())
}
pub fn break_line(&mut self, line_nr: usize, col_nr: usize) -> UIResult<()> {
// clippy prefers this over if-else
match line_nr.cmp(&self.lines.len()) {
Ordering::Less => {
self.insert_empty_line(line_nr + 1)?;
let line_ref = self.lines.get_mut(line_nr).unwrap(); // safe because we checked line_nr
if col_nr < line_ref.len() {
let next_line_str: String = line_ref.drain(col_nr..).collect();
let next_line_ref = self.lines.get_mut(line_nr + 1).unwrap(); // safe because we just added the line
*next_line_ref = next_line_str;
}
Ok(())
}
Ordering::Equal => self.insert_empty_line(line_nr + 1),
Ordering::Greater => OutOfBounds {
index: line_nr,
collection_name: "code_lines.lines".to_owned(),
len: self.lines.len(),
}
.fail(),
}
}
pub fn clear_line(&mut self, line_nr: usize) -> UIResult<()> {
let line_ref = slice_get_mut(line_nr, &mut self.lines)?;
*line_ref = String::new();
Ok(())
}
pub fn del_line(&mut self, line_nr: usize) -> UIResult<()> {
let line_len = self.line_len(line_nr)?;
self.lines.remove(line_nr);
self.nr_of_chars -= line_len;
Ok(())
}
pub fn del_at_line(&mut self, line_nr: usize, index: usize) -> UIResult<()> {
let line_ref = slice_get_mut(line_nr, &mut self.lines)?;
line_ref.remove(index);
self.nr_of_chars -= 1;
Ok(())
}
pub fn del_range_at_line(
&mut self,
line_nr: usize,
col_range: std::ops::Range<usize>,
) -> UIResult<()> {
let line_ref = slice_get_mut(line_nr, &mut self.lines)?;
line_ref.drain(col_range);
Ok(())
}
pub fn del_selection(&mut self, selection: Selection) -> UIResult<()> {
if selection.is_on_same_line() {
let line_ref = slice_get_mut(selection.start_pos.line, &mut self.lines)?;
line_ref.drain(selection.start_pos.column..selection.end_pos.column);
} else {
// TODO support multiline selections
}
Ok(())
}
// last column of last line
pub fn end_txt_pos(&self) -> TextPos {
let last_line_nr = self.nr_of_lines() - 1;

View File

@ -32,22 +32,19 @@ pub fn break_line(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
// two blank lines between top level definitions
EdModel::insert_empty_line(
caret_line_nr + 1,
&mut ed_model.code_lines,
&mut ed_model.grid_node_map,
)?;
EdModel::insert_empty_line(
caret_line_nr + 2,
&mut ed_model.code_lines,
&mut ed_model.grid_node_map,
)?;
// third "empty" line will be filled by the blank
EdModel::insert_empty_line(
caret_line_nr + 3,
&mut ed_model.code_lines,
&mut ed_model.grid_node_map,
)?;
insert_new_blank(ed_model, caret_pos, caret_pos.line + 3)?;
insert_new_blank(ed_model, caret_pos.line + 3)?;
}
}
}
@ -59,37 +56,22 @@ pub fn break_line(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
pub fn insert_new_blank(
ed_model: &mut EdModel,
caret_pos: &TextPos,
insert_on_line_nr: usize,
) -> EdResult<()> {
println!("{}", ed_model.module.ast.ast_to_string(ed_model.module.env.pool));
// find position of the previous ASTNode to figure out where to add this new Blank ASTNode
let def_mark_node_id = ed_model.grid_node_map.get_def_mark_node_id_before_line(
insert_on_line_nr,
&ed_model.mark_node_pool,
)?;
let new_line_blank = Def2::Blank;
let new_line_blank_id = ed_model.module.env.pool.add(new_line_blank);
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 insertion_index = index_of(def_mark_node_id, &ed_model.markup_ids)?;
ed_model.module.ast.insert_def_at_index(new_line_blank_id, insertion_index);
let blank_mn_id = ed_model.add_mark_node(new_blank_mn_w_nls(
ASTNodeId::ADefId(new_line_blank_id),
None,
2,
));
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(
insert_on_line_nr, // one blank line between top level definitions
0,
&[blank_mn_id],
)?;
Ok(())
}

View File

@ -16,6 +16,7 @@ use roc_ast::lang::env::Env;
use roc_ast::mem_pool::pool_str::PoolStr;
use roc_ast::parse::parse_ast;
use roc_code_markup::markup::convert::from_ast::ast_to_mark_nodes;
use roc_code_markup::markup::nodes;
use roc_code_markup::slow_pool::{MarkNodeId, SlowPool};
use roc_load::file::LoadedModule;
use roc_module::symbol::Interns;
@ -63,6 +64,7 @@ pub fn init_model<'a>(
let mut mark_node_pool = SlowPool::default();
// TODO replace this with post_process_ast_update
let markup_ids = if code_str.is_empty() {
EmptyCodeString {}.fail()
} else {
@ -74,7 +76,10 @@ pub fn init_model<'a>(
)?)
}?;
let mut code_lines = CodeLines::default();
let mut code_lines = CodeLines::from_str(
&nodes::mark_nodes_to_string(&markup_ids, &mark_node_pool)
);
let mut grid_node_map = GridNodeMap::default();
let mut line_nr = 0;
@ -88,7 +93,6 @@ pub fn init_model<'a>(
&mut col_nr,
*mark_node_id,
&mut grid_node_map,
&mut code_lines,
&mark_node_pool,
)?
}

View File

@ -36,6 +36,7 @@ use crate::ui::util::path_to_string;
use crate::ui::util::write_to_file;
use crate::window::keyboard_input::Modifiers;
use bumpalo::Bump;
use roc_ast::ast_error::ASTResult;
use roc_ast::constrain::constrain_expr;
use roc_ast::constrain::Constraint;
use roc_ast::lang::core::ast::ASTNodeId;
@ -49,6 +50,7 @@ use roc_ast::mem_pool::pool_str::PoolStr;
use roc_ast::solve_type;
use roc_can::expected::Expected;
use roc_code_markup::markup::attribute::Attributes;
use roc_code_markup::markup::convert::from_ast::ast_to_mark_nodes;
use roc_code_markup::markup::nodes;
use roc_code_markup::markup::nodes::MarkupNode;
use roc_code_markup::markup::nodes::EQUALS;
@ -187,10 +189,8 @@ impl<'a> EdModel<'a> {
new_str: &str,
node_id: MarkNodeId,
grid_node_map: &mut GridNodeMap,
code_lines: &mut CodeLines,
) -> UIResult<()> {
grid_node_map.insert_between_line(line_nr, index, new_str.len(), node_id)?;
code_lines.insert_between_line(line_nr, index, new_str)
grid_node_map.insert_between_line(line_nr, index, new_str.len(), node_id)
}
pub fn insert_all_between_line(
@ -218,9 +218,6 @@ impl<'a> EdModel<'a> {
node_id,
)?;
self.code_lines
.insert_between_line(curr_line_nr, col_nr, line)?;
curr_line_nr += 1;
col_nr = 0;
}
@ -234,9 +231,6 @@ impl<'a> EdModel<'a> {
node_id,
)?;
self.code_lines
.insert_between_line(line_nr, col_nr, &node_content)?;
col_nr += node_content.len();
}
}
@ -249,7 +243,6 @@ impl<'a> EdModel<'a> {
col_nr: &mut usize,
mark_node_id: MarkNodeId,
grid_node_map: &mut GridNodeMap,
code_lines: &mut CodeLines,
mark_node_pool: &SlowPool,
) -> UIResult<()> {
let mark_node = mark_node_pool.get(mark_node_id);
@ -265,7 +258,6 @@ impl<'a> EdModel<'a> {
col_nr,
child_id,
grid_node_map,
code_lines,
mark_node_pool,
)?;
}
@ -278,20 +270,19 @@ impl<'a> EdModel<'a> {
&node_content,
mark_node_id,
grid_node_map,
code_lines,
)?;
*col_nr += node_content.len();
}
if node_newlines > 0 {
EdModel::break_line(*line_nr, *col_nr, code_lines, grid_node_map)?;
EdModel::break_line(*line_nr, *col_nr, grid_node_map)?;
*line_nr += 1;
*col_nr = 0;
for _ in 1..node_newlines {
EdModel::insert_empty_line(*line_nr, code_lines, grid_node_map)?;
EdModel::insert_empty_line(*line_nr, grid_node_map)?;
*line_nr += 1;
*col_nr = 0;
@ -305,40 +296,32 @@ impl<'a> EdModel<'a> {
pub fn break_line(
line_nr: usize,
col_nr: usize,
code_lines: &mut CodeLines,
grid_node_map: &mut GridNodeMap,
) -> UIResult<()> {
code_lines.break_line(line_nr, col_nr)?;
grid_node_map.break_line(line_nr, col_nr)
}
pub fn insert_empty_line(
line_nr: usize,
code_lines: &mut CodeLines,
grid_node_map: &mut GridNodeMap,
) -> UIResult<()> {
code_lines.insert_empty_line(line_nr)?;
grid_node_map.insert_empty_line(line_nr)
}
pub fn push_empty_line(code_lines: &mut CodeLines, grid_node_map: &mut GridNodeMap) {
code_lines.push_empty_line();
grid_node_map.push_empty_line();
}
pub fn clear_line(&mut self, line_nr: usize) -> UIResult<()> {
self.grid_node_map.clear_line(line_nr)?;
self.code_lines.clear_line(line_nr)
self.grid_node_map.clear_line(line_nr)
}
pub fn del_line(&mut self, line_nr: usize) -> UIResult<()> {
self.grid_node_map.del_line(line_nr);
self.code_lines.del_line(line_nr)
pub fn del_line(&mut self, line_nr: usize) {
self.grid_node_map.del_line(line_nr)
}
pub fn del_at_line(&mut self, line_nr: usize, index: usize) -> UIResult<()> {
self.grid_node_map.del_at_line(line_nr, index)?;
self.code_lines.del_at_line(line_nr, index)
self.grid_node_map.del_at_line(line_nr, index)
}
// updates grid_node_map and code_lines but nothing else.
@ -348,8 +331,7 @@ impl<'a> EdModel<'a> {
col_range: std::ops::Range<usize>,
) -> UIResult<()> {
self.grid_node_map
.del_range_at_line(line_nr, col_range.clone())?;
self.code_lines.del_range_at_line(line_nr, col_range)
.del_range_at_line(line_nr, col_range.clone())
}
pub fn del_blank_expr_node(&mut self, txt_pos: TextPos) -> UIResult<()> {
@ -602,7 +584,6 @@ impl<'a> EdModel<'a> {
let active_selection = self.get_selection().context(MissingSelection {})?;
self.code_lines.del_selection(active_selection)?;
self.grid_node_map.del_selection(active_selection)?;
match sel_block.ast_node_id {
@ -624,7 +605,6 @@ impl<'a> EdModel<'a> {
nodes::BLANK_PLACEHOLDER,
expr_mark_node_id,
&mut self.grid_node_map,
&mut self.code_lines,
)?;
self.set_sel_none();
@ -678,6 +658,40 @@ impl<'a> EdModel<'a> {
Ok(())
}
/// update MarkupNode's, grid_node_map, code_lines after the AST has been updated
fn post_process_ast_update(&mut self) -> EdResult<()> {
//dbg!("{}",self.module.ast.ast_to_string(self.module.env.pool));
self.markup_ids = ast_to_mark_nodes(
&mut self.module.env,
&self.module.ast,
&mut self.mark_node_pool,
&self.loaded_module.interns,
)?;
self.code_lines = CodeLines::from_str(
&nodes::mark_nodes_to_string(&self.markup_ids, &self.mark_node_pool)
);
self.grid_node_map = GridNodeMap::default();
let mut line_nr = 0;
let mut col_nr = 0;
for mark_node_id in &self.markup_ids {
// for debugging:
//println!("{}", tree_as_string(*mark_node_id, &mark_node_pool));
EdModel::insert_mark_node_between_line(
&mut line_nr,
&mut col_nr,
*mark_node_id,
&mut self.grid_node_map,
&self.mark_node_pool,
)?
}
Ok(())
}
}
impl<'a> SelectableLines for EdModel<'a> {
@ -1182,6 +1196,8 @@ pub fn handle_new_char_diff_mark_nodes_prev_is_expr(
// updates the ed_model based on the char the user just typed if the result would be syntactically correct.
pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult<InputOutcome> {
//dbg!("{}", ed_model.module.ast.ast_to_string(ed_model.module.env.pool));
let input_outcome = match received_char {
'\u{e000}'..='\u{f8ff}' // http://www.unicode.org/faq/private_use.html
| '\u{f0000}'..='\u{ffffd}' // ^
@ -1237,7 +1253,8 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
for caret_pos in ed_model.get_carets() {
if caret_pos.line > 0 {
insert_new_blank(ed_model, &caret_pos, caret_pos.line)?;
insert_new_blank(ed_model, caret_pos.line)?;
ed_model.post_process_ast_update()?;
}
}
handle_new_char(received_char, ed_model)?
@ -1260,6 +1277,7 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
};
if let InputOutcome::Accepted = input_outcome {
ed_model.post_process_ast_update()?;
ed_model.dirty = true;
}
@ -1686,90 +1704,90 @@ pub mod test_ed_update {
assert_insert_nls(ovec!["val = { ┃ }"], ovec!["val = { a┃ }"], 'a')?;
assert_insert_nls(
ovec!["val = { a┃ }"],
ovec!["val = { ab┃: RunTimeError }"],
ovec!["val = { ab┃ }"],
'b',
)?; // TODO: remove RunTimeError, see issue #1649
)?;
assert_insert_nls(
ovec!["val = { a┃ }"],
ovec!["val = { a1┃: RunTimeError }"],
ovec!["val = { a1┃ }"],
'1',
)?;
assert_insert_nls(
ovec!["val = { a1┃ }"],
ovec!["val = { a1z┃: RunTimeError }"],
ovec!["val = { a1z┃ }"],
'z',
)?;
assert_insert_nls(
ovec!["val = { a1┃ }"],
ovec!["val = { a15┃: RunTimeError }"],
ovec!["val = { a15┃ }"],
'5',
)?;
assert_insert_nls(
ovec!["val = { ab┃ }"],
ovec!["val = { abc┃: RunTimeError }"],
ovec!["val = { abc┃ }"],
'c',
)?;
assert_insert_nls(
ovec!["val = { ┃abc }"],
ovec!["val = { z┃abc: RunTimeError }"],
ovec!["val = { z┃abc }"],
'z',
)?;
assert_insert_nls(
ovec!["val = { a┃b }"],
ovec!["val = { az┃b: RunTimeError }"],
ovec!["val = { az┃b }"],
'z',
)?;
assert_insert_nls(
ovec!["val = { a┃b }"],
ovec!["val = { a9┃b: RunTimeError }"],
ovec!["val = { a9┃b }"],
'9',
)?;
assert_insert_nls(
ovec!["val = { a┃ }"],
ovec!["val = { a┃: RunTimeError }"],
ovec!["val = { a: ┃ }"],
':',
)?;
assert_insert_nls(
ovec!["val = { abc┃ }"],
ovec!["val = { abc┃: RunTimeError }"],
ovec!["val = { abc: ┃ }"],
':',
)?;
assert_insert_nls(
ovec!["val = { aBc┃ }"],
ovec!["val = { aBc┃: RunTimeError }"],
ovec!["val = { aBc: ┃ }"],
':',
)?;
assert_insert_seq_nls(
ovec!["val = { a┃ }"],
ovec!["val = { a┃: RunTimeError }"],
ovec!["val = { a: \"\" }"],
":\"",
)?;
assert_insert_seq_nls(
ovec!["val = { abc┃ }"],
ovec!["val = { abc┃: RunTimeError }"],
ovec!["val = { abc: \"\" }"],
":\"",
)?;
assert_insert_seq_nls(
ovec!["val = { a┃ }"],
ovec!["val = { a0┃: RunTimeError }"],
ovec!["val = { a: 0┃ }"],
":0",
)?;
assert_insert_seq_nls(
ovec!["val = { abc┃ }"],
ovec!["val = { abc9┃: RunTimeError }"],
ovec!["val = { abc: 9┃ }"],
":9",
)?;
assert_insert_seq_nls(
ovec!["val = { a┃ }"],
ovec!["val = { a1000┃: RunTimeError }"],
ovec!["val = { a: 1000┃ }"],
":1000",
)?;
assert_insert_seq_nls(
ovec!["val = { abc┃ }"],
ovec!["val = { abc98761┃: RunTimeError }"],
ovec!["val = { abc: 98761┃ }"],
":98761",
)?;
@ -1921,17 +1939,17 @@ pub mod test_ed_update {
fn test_nested_record() -> Result<(), String> {
assert_insert_seq_nls(
ovec!["val = { a┃ }"],
ovec!["val = { a┃: RunTimeError }"],
ovec!["val = { a: { ┃ } }"],
":{",
)?;
assert_insert_seq_nls(
ovec!["val = { abc┃ }"],
ovec!["val = { abc┃: RunTimeError }"],
ovec!["val = { abc: { ┃ } }"],
":{",
)?;
assert_insert_seq_nls(
ovec!["val = { camelCase┃ }"],
ovec!["val = { camelCase┃: RunTimeError }"],
ovec!["val = { camelCase: { ┃ } }"],
":{",
)?;
@ -1953,49 +1971,49 @@ pub mod test_ed_update {
assert_insert_seq_nls(
ovec!["val = { a: { zulu┃ } }"],
ovec!["val = { a: { zulu┃: RunTimeError } }"],
ovec!["val = { a: { zulu: ┃ } }"],
":",
)?;
assert_insert_seq_nls(
ovec!["val = { abc: { camelCase┃ } }"],
ovec!["val = { abc: { camelCase┃: RunTimeError } }"],
ovec!["val = { abc: { camelCase: ┃ } }"],
":",
)?;
assert_insert_seq_nls(
ovec!["val = { camelCase: { z┃ } }"],
ovec!["val = { camelCase: { z┃: RunTimeError } }"],
ovec!["val = { camelCase: { z: ┃ } }"],
":",
)?;
assert_insert_seq_nls(
ovec!["val = { a┃: { zulu } }"],
ovec!["val = { a0┃: { zulu: RunTimeError } }"],
ovec!["val = { a0┃: { zulu } }"],
"0",
)?;
assert_insert_seq_nls(
ovec!["val = { ab┃c: { camelCase } }"],
ovec!["val = { abz┃c: { camelCase: RunTimeError } }"],
ovec!["val = { abz┃c: { camelCase } }"],
"z",
)?;
assert_insert_seq_nls(
ovec!["val = { ┃camelCase: { z } }"],
ovec!["val = { x┃camelCase: { z: RunTimeError } }"],
ovec!["val = { x┃camelCase: { z } }"],
"x",
)?;
assert_insert_seq_nls(
ovec!["val = { a: { zulu┃ } }"],
ovec!["val = { a: { zulu┃: RunTimeError } }"],
ovec!["val = { a: { zulu: \"\" } }"],
":\"",
)?;
assert_insert_seq_nls(
ovec!["val = { abc: { camelCase┃ } }"],
ovec!["val = { abc: { camelCase┃: RunTimeError } }"],
ovec!["val = { abc: { camelCase: \"\" } }"],
":\"",
)?;
assert_insert_seq_nls(
ovec!["val = { camelCase: { z┃ } }"],
ovec!["val = { camelCase: { z┃: RunTimeError } }"],
ovec!["val = { camelCase: { z: \"\" } }"],
":\"",
)?;
@ -2012,17 +2030,17 @@ pub mod test_ed_update {
assert_insert_seq_nls(
ovec!["val = { a: { zulu┃ } }"],
ovec!["val = { a: { zulu1┃: RunTimeError } }"],
ovec!["val = { a: { zulu: 1┃ } }"],
":1",
)?;
assert_insert_seq_nls(
ovec!["val = { abc: { camelCase┃ } }"],
ovec!["val = { abc: { camelCase0┃: RunTimeError } }"],
ovec!["val = { abc: { camelCase: 0┃ } }"],
":0",
)?;
assert_insert_seq_nls(
ovec!["val = { camelCase: { z┃ } }"],
ovec!["val = { camelCase: { z45┃: RunTimeError } }"],
ovec!["val = { camelCase: { z: 45┃ } }"],
":45",
)?;
@ -2039,17 +2057,17 @@ pub mod test_ed_update {
assert_insert_seq_nls(
ovec!["val = { a: { zulu┃ } }"],
ovec!["val = { a: { zulu┃: RunTimeError } }"],
ovec!["val = { a: { zulu: { ┃ } } }"],
":{",
)?;
assert_insert_seq_nls(
ovec!["val = { abc: { camelCase┃ } }"],
ovec!["val = { abc: { camelCase┃: RunTimeError } }"],
ovec!["val = { abc: { camelCase: { ┃ } } }"],
":{",
)?;
assert_insert_seq_nls(
ovec!["val = { camelCase: { z┃ } }"],
ovec!["val = { camelCase: { z┃: RunTimeError } }"],
ovec!["val = { camelCase: { z: { ┃ } } }"],
":{",
)?;
@ -2076,17 +2094,17 @@ pub mod test_ed_update {
assert_insert_seq_nls(
ovec!["val = { a┃: { bcD: { eFgHij: { k15 } } } }"],
ovec!["val = { a4┃: { bcD: { eFgHij: { k15: RunTimeError } } } }"],
ovec!["val = { a4┃: { bcD: { eFgHij: { k15 } } } }"],
"4",
)?;
assert_insert_seq_nls(
ovec!["val = { ┃a: { bcD: { eFgHij: { k15 } } } }"],
ovec!["val = { y┃a: { bcD: { eFgHij: { k15: RunTimeError } } } }"],
ovec!["val = { y┃a: { bcD: { eFgHij: { k15 } } } }"],
"y",
)?;
assert_insert_seq_nls(
ovec!["val = { a: { bcD: { eF┃gHij: { k15 } } } }"],
ovec!["val = { a: { bcD: { eFxyz┃gHij: { k15: RunTimeError } } } }"],
ovec!["val = { a: { bcD: { eFxyz┃gHij: { k15 } } } }"],
"xyz",
)?;
@ -2099,6 +2117,14 @@ pub mod test_ed_update {
Ok(())
}
fn concat_strings(str_a: &str, str_b: &str) -> String {
let mut string_a = str_a.to_owned();
string_a.push_str(str_b);
string_a
}
#[test]
fn test_ignore_record() -> Result<(), String> {
assert_insert_seq_ignore_nls(ovec!["val = ┃{ }"], IGNORE_CHARS)?;
@ -2107,23 +2133,37 @@ pub mod test_ed_update {
assert_insert_seq_ignore_nls(ovec!["val = { ┃}"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = { ┃ }"], IGNORE_NO_LTR)?;
assert_insert_seq_ignore_nls(ovec!["val = { ┃a: RunTimeError }"], IGNORE_NO_LTR)?;
assert_insert_seq_ignore_nls(ovec!["val = { ┃abc: RunTimeError }"], IGNORE_NO_LTR)?;
assert_insert_seq_ignore_nls(ovec!["val = { ┃a }"], IGNORE_NO_LTR)?;
assert_insert_seq_ignore_nls(ovec!["val = { ┃abc }"], IGNORE_NO_LTR)?;
assert_insert_seq_ignore_nls(ovec!["val = ┃{ a: RunTimeError }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = { a: ┃RunTimeError }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = {┃ a: RunTimeError }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = { a:┃ RunTimeError }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = ┃{ a }"], IGNORE_CHARS)?;
assert_insert_seq_nls(
ovec!["val = { a┃ }"],
ovec!["val = { a:┃ }"],
&concat_strings(":🡰", IGNORE_CHARS),
)?;
assert_insert_seq_nls(
ovec!["val = { a┃ }"],
ovec!["val = { a: ┃ }"],
&concat_strings(":🡲", IGNORE_CHARS),
)?;
assert_insert_seq_ignore_nls(ovec!["val = {┃ a }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = ┃{ a15: RunTimeError }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = { a15: ┃RunTimeError }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = {┃ a15: RunTimeError }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = { a15:┃ RunTimeError }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = ┃{ a15 }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = {┃ a15 }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = ┃{ camelCase: RunTimeError }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = { camelCase: ┃RunTimeError }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = {┃ camelCase: RunTimeError }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = { camelCase:┃ RunTimeError }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = ┃{ camelCase }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = {┃ camelCase }"], IGNORE_CHARS)?;
assert_insert_seq_nls(
ovec!["val = { camelCase┃ }"],
ovec!["val = { camelCase:┃ }"],
&concat_strings(":🡰", IGNORE_CHARS),
)?;
assert_insert_seq_nls(
ovec!["val = { camelCase┃ }"],
ovec!["val = { camelCase: ┃ }"],
&concat_strings(":🡲", IGNORE_CHARS),
)?;
assert_insert_seq_ignore_nls(ovec!["val = ┃{ a: \"\" }"], IGNORE_CHARS)?;
assert_insert_seq_ignore_nls(ovec!["val = {┃ a: \"\" }"], IGNORE_CHARS)?;
@ -2199,43 +2239,37 @@ pub mod test_ed_update {
assert_insert_seq_ignore_nls(ovec!["val = { ┃a: { } }"], "1")?;
assert_insert_seq_ignore_nls(
ovec!["val = { camelCaseB1: { z15a:┃ RunTimeError } }"],
ovec!["val = { camelCaseB1: { z15a } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { camelCaseB1: {┃ z15a: RunTimeError } }"],
ovec!["val = { camelCaseB1: ┃{ z15a } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_nls(
ovec!["val = { camelCaseB1: { z15a┃ } }"],
ovec!["val = { camelCaseB1: { z15a:┃ } }"],
&concat_strings(":🡰", IGNORE_CHARS),
)?;
assert_insert_seq_nls(
ovec!["val = { camelCaseB1: { z15a┃ } }"],
ovec!["val = { camelCaseB1: { z15a: ┃ } }"],
&concat_strings(":🡲", IGNORE_CHARS),
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { camelCaseB1:┃ { z15a } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { camelCaseB1: ┃{ z15a: RunTimeError } }"],
ovec!["val = { camelCaseB1: { z15a } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { camelCaseB1: { z15a: ┃RunTimeError } }"],
ovec!["val = { camelCaseB1: { z15a } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { camelCaseB1: { z15a: R┃unTimeError } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { camelCaseB1: { z15a: Ru┃nTimeError } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { camelCaseB1:┃ { z15a: RunTimeError } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = {┃ camelCaseB1: { z15a: RunTimeError } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = ┃{ camelCaseB1: { z15a: RunTimeError } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(ovec!["val = { ┃camelCaseB1: { z15a: RunTimeError } }"], "1")?;
assert_insert_seq_ignore_nls(ovec!["val = { camelCaseB1: { ┃z15a: RunTimeError } }"], "1")?;
assert_insert_seq_ignore_nls(ovec!["val = { ┃camelCaseB1: { z15a } }"], "1")?;
assert_insert_seq_ignore_nls(ovec!["val = { camelCaseB1: { ┃z15a } }"], "1")?;
assert_insert_seq_ignore_nls(
ovec!["val = { camelCaseB1: { z15a: \"\"┃ } }"],
@ -2376,39 +2410,27 @@ pub mod test_ed_update {
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { g: { oi: { ng: { d: { e: { e: { p: { camelCase:┃ RunTimeError } } } } } } } }"],
ovec!["val = { g: { oi: { ng: { d: { e: { e: { p: { camelCase } } } } } } } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { g: { oi: { ng: { d: { e: { e: { p: { camelCase: R┃unTimeError } } } } } } } }"],
ovec!["val = { g: { oi: { ng: { d: { e: { e: { p: { camelCase } } } } } } } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { g: { oi: { ng: { d: { e: { e: { p: { camelCase: RunTimeError } } } } } } } }"],
ovec!["val = { g: { oi: { ng: { d: { e: { e: { p: { camelCase } } } } } } } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { g: { oi: { ng: { d: { e: { e: { p: { camelCase: RunTimeEr┃ror } } } } } } } }"],
ovec!["val = { g: { oi: { ng: { d: { e: { e: { p: { camelCase } } } } } } } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { g: { oi: { ng: { d: { e: { e: { p: { camelCase: RunTimeError } } } } } } } }"],
ovec!["val = { g: { oi: { ng: { d: { e: { e: { p: { camelCase } } } } } } } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { g: { oi: { ng: { d: { e: { e:┃ { p: { camelCase: RunTimeError } } } } } } } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = {┃ g: { oi: { ng: { d: { e: { e: { p: { camelCase: RunTimeError } } } } } } } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = ┃{ g: { oi: { ng: { d: { e: { e: { p: { camelCase: RunTimeError } } } } } } } }"],
IGNORE_NO_LTR,
)?;
assert_insert_seq_ignore_nls(
ovec!["val = { ┃g: { oi: { ng: { d: { e: { e: { p: { camelCase: RunTimeError } } } } } } } }"],
ovec!["val = { ┃g: { oi: { ng: { d: { e: { e: { p: { camelCase } } } } } } } }"],
"2",
)?;
Ok(())
@ -2619,7 +2641,8 @@ pub mod test_ed_update {
assert_insert_nls(ovec![""], ovec!["z┃ = "], 'z')?;
assert_insert_seq_nls(ovec![""], ovec!["ab┃ = "], "ab")?;
assert_insert_seq_nls(ovec![""], ovec!["mainVal┃ = "], "mainVal")?;
// TODO make issue for this, see update_key function
//assert_insert_seq_nls(ovec!["┃"], ovec!["mainVal┃ = "], "mainVal")?;
assert_insert_seq_nls(ovec![""], ovec!["camelCase123┃ = "], "camelCase123")?;
assert_insert_seq_nls(ovec![""], ovec!["c137┃ = "], "c137")?;
assert_insert_seq_nls(ovec![""], ovec!["c137Bb┃ = "], "c137Bb")?;

View File

@ -72,7 +72,6 @@ pub fn start_new_int(ed_model: &mut EdModel, digit_char: &char) -> EdResult<Inpu
&digit_char.to_string(),
curr_mark_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
Ok(InputOutcome::Accepted)
@ -116,7 +115,6 @@ pub fn update_int(
&ch.to_string(),
int_mark_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
// update ast

View File

@ -71,7 +71,6 @@ pub fn start_new_list(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
nodes::LEFT_SQUARE_BR,
left_bracket_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
EdModel::insert_between_line(
@ -80,7 +79,6 @@ pub fn start_new_list(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
nodes::RIGHT_SQUARE_BR,
right_bracket_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
Ok(InputOutcome::Accepted)
@ -210,7 +208,6 @@ pub fn update_mark_children(
nodes::COMMA,
comma_mark_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
children.push(comma_mark_node_id);
@ -231,7 +228,6 @@ pub fn update_mark_children(
nodes::BLANK_PLACEHOLDER,
blank_mark_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
Ok(children)

View File

@ -50,7 +50,6 @@ pub fn update_invalid_lookup(
input_str,
curr_mark_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
Ok(InputOutcome::Accepted)

View File

@ -156,7 +156,6 @@ pub fn update_empty_record(
new_input,
record_field_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
Ok(InputOutcome::Accepted)
@ -336,7 +335,6 @@ pub fn update_record_field(
new_input,
curr_mark_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
// update AST Node

View File

@ -67,7 +67,6 @@ pub fn update_small_string(
new_input,
curr_mark_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
// update caret
@ -105,7 +104,6 @@ pub fn update_string(new_char: char, ed_model: &mut EdModel) -> EdResult<InputOu
&new_char.to_string(),
curr_mark_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
// update ast
@ -167,7 +165,6 @@ pub fn start_new_string(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
nodes::STRING_QUOTES,
curr_mark_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
ed_model.simple_move_carets_right(1);

View File

@ -21,18 +21,16 @@ use super::{
pub fn start_new_tld_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<InputOutcome> {
let NodeContext {
old_caret_pos,
curr_mark_node_id,
curr_mark_node_id: _,
curr_mark_node: _,
parent_id_opt: _,
ast_node_id,
} = get_node_context(ed_model)?;
// create new blank >> m = Blank
let val_expr_node = Expr2::Blank;
let val_expr_id = ed_model.module.env.pool.add(val_expr_node);
let val_expr_mn = new_blank_mn_w_nls(ASTNodeId::AExprId(val_expr_id), None, 0);
let val_expr_mn_id = ed_model.mark_node_pool.add(val_expr_mn);
let val_name_string = new_char.to_string();
let ident_id = ed_model
@ -57,14 +55,6 @@ pub fn start_new_tld_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<
.fail()?
}
let tld_mark_node = tld_mark_node(
ident_id,
val_expr_mn_id,
ast_node_id,
&mut ed_model.mark_node_pool,
&ed_model.module.env,
)?;
let new_ast_node = Def2::ValueDef {
identifier_id: ident_id,
expr_id: val_expr_id,
@ -76,31 +66,9 @@ pub fn start_new_tld_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<
.pool
.set(ast_node_id.to_def_id()?, new_ast_node);
ed_model
.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_line(old_caret_pos.line + 1)?;
ed_model.del_line(old_caret_pos.line)?;
let char_len = 1;
ed_model.simple_move_carets_right(char_len);
let mut curr_line = old_caret_pos.line;
let mut curr_column = old_caret_pos.column;
EdModel::insert_mark_node_between_line(
&mut curr_line,
&mut curr_column,
curr_mark_node_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
&ed_model.mark_node_pool,
)?;
Ok(InputOutcome::Accepted)
}
@ -112,37 +80,28 @@ pub fn update_tld_val_name(
) -> EdResult<InputOutcome> {
if new_char.is_ascii_alphanumeric() {
// update markup
let val_name_mn_mut = ed_model.mark_node_pool.get_mut(val_name_mn_id);
let content_str_mut = val_name_mn_mut.get_content_mut()?;
let val_name_mn = ed_model.mark_node_pool.get(val_name_mn_id);
let mut val_name_str = val_name_mn.get_content();
let old_val_name = content_str_mut.clone();
let old_val_name = val_name_str.clone();
let node_caret_offset = ed_model
.grid_node_map
.get_offset_to_node_id(old_caret_pos, val_name_mn_id)?;
if node_caret_offset <= content_str_mut.len() {
content_str_mut.insert(node_caret_offset, *new_char);
if node_caret_offset <= val_name_str.len() {
val_name_str.insert(node_caret_offset, *new_char);
let update_val_name_res = ed_model
.module
.env
.ident_ids
.update_key(&old_val_name, content_str_mut);
.update_key(&old_val_name, &val_name_str);
if let Err(err_str) = update_val_name_res {
FailedToUpdateIdentIdName { err_str }.fail()?;
}
EdModel::insert_between_line(
old_caret_pos.line,
old_caret_pos.column,
&new_char.to_string(),
val_name_mn_id,
&mut ed_model.grid_node_map,
&mut ed_model.code_lines,
)?;
ed_model.simple_move_caret_right(old_caret_pos, 1);
Ok(InputOutcome::Accepted)