mirror of
https://github.com/roc-lang/roc.git
synced 2024-11-10 10:02:38 +03:00
Merge pull request #2547 from rtfeldman/simplify-editor
simplify editor
This commit is contained in:
commit
8ec7b26a1c
@ -154,12 +154,18 @@ 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 {
|
||||
|
@ -15,6 +15,24 @@ 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),
|
||||
|
@ -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),
|
||||
}
|
||||
|
||||
|
@ -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) => {
|
||||
|
@ -27,7 +27,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
|
||||
);
|
||||
}
|
||||
|
@ -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..];
|
||||
|
@ -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,18 @@ 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,
|
||||
)
|
||||
}
|
||||
|
@ -468,3 +468,34 @@ 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);
|
||||
}
|
||||
}
|
||||
|
@ -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, see issue #2548
|
||||
pub fn update_key(
|
||||
&mut self,
|
||||
old_ident_name: &str,
|
||||
|
@ -43,7 +43,7 @@ From roc to render:
|
||||
- `ed_model` also contains an `EdModule`, which holds the parsed abstract syntax tree (AST).
|
||||
- In the `init_model` function:
|
||||
+ The AST is converted into a tree of `MarkupNode`. The different types of `MarkupNode` are similar to the elements/nodes in HTML. A line of roc code is represented as a nested `MarkupNode` containing mostly text `MarkupNode`s. The line `foo = "bar"` is represented as
|
||||
three text `MarkupNode` representing `foo`, ` = ` and `bar`. Multiple lines of roc code are represented as nested `MarkupNode` that contain other nested `MarkupNode`.
|
||||
three text `MarkupNode`; representing `foo`, ` = ` and `bar`. Multiple lines of roc code are represented as nested `MarkupNode` that contain other nested `MarkupNode`.
|
||||
+ `CodeLines` holds a `Vec` of `String`, each line of code is a `String`. When saving the file, the content of `CodeLines` is written to disk.
|
||||
+ `GridNodeMap` maps every position of a char of roc code to a `MarkNodeId`, for easy interaction with the caret.
|
||||
- Back in `editor/src/editor/main.rs` we convert the `EdModel` to `RenderedWgpu` by calling `model_to_wgpu`.
|
||||
|
@ -1,10 +1,7 @@
|
||||
use crate::ui::text::lines::Lines;
|
||||
use crate::ui::text::selection::Selection;
|
||||
use crate::ui::text::text_pos::TextPos;
|
||||
use crate::ui::ui_error::{LineInsertionFailed, OutOfBounds, UIResult};
|
||||
use crate::ui::ui_error::UIResult;
|
||||
use crate::ui::util::slice_get;
|
||||
use crate::ui::util::slice_get_mut;
|
||||
use std::cmp::Ordering;
|
||||
use std::fmt;
|
||||
|
||||
#[derive(Debug, Default)]
|
||||
@ -14,134 +11,11 @@ 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()?;
|
||||
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(),
|
||||
}
|
||||
|
||||
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 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
|
||||
|
@ -1,6 +1,4 @@
|
||||
use roc_ast::lang::core::ast::ASTNodeId;
|
||||
use roc_ast::lang::core::def::def2::Def2;
|
||||
use roc_code_markup::markup::common_nodes::new_blank_mn_w_nls;
|
||||
|
||||
use crate::editor::ed_error::EdResult;
|
||||
use crate::editor::mvc::app_update::InputOutcome;
|
||||
@ -30,24 +28,12 @@ pub fn break_line(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
|
||||
&& ed_model.code_lines.line_len(new_blank_line_nr).unwrap() == 0)
|
||||
{
|
||||
// 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,
|
||||
)?;
|
||||
EdModel::insert_empty_line(caret_line_nr + 1, &mut ed_model.grid_node_map)?;
|
||||
EdModel::insert_empty_line(caret_line_nr + 2, &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,
|
||||
)?;
|
||||
EdModel::insert_empty_line(caret_line_nr + 3, &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)?;
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -57,39 +43,25 @@ pub fn break_line(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
|
||||
Ok(InputOutcome::Accepted)
|
||||
}
|
||||
|
||||
pub fn insert_new_blank(
|
||||
ed_model: &mut EdModel,
|
||||
caret_pos: &TextPos,
|
||||
insert_on_line_nr: usize,
|
||||
) -> EdResult<()> {
|
||||
pub fn insert_new_blank(ed_model: &mut EdModel, 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)?;
|
||||
let insertion_index = index_of(def_mark_node_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_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],
|
||||
)?;
|
||||
.insert_def_at_index(new_line_blank_id, insertion_index);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
@ -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;
|
||||
@ -74,7 +75,8 @@ pub fn init_model<'a>(
|
||||
)?)
|
||||
}?;
|
||||
|
||||
let mut code_lines = CodeLines::default();
|
||||
let 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 +90,6 @@ pub fn init_model<'a>(
|
||||
&mut col_nr,
|
||||
*mark_node_id,
|
||||
&mut grid_node_map,
|
||||
&mut code_lines,
|
||||
&mark_node_pool,
|
||||
)?
|
||||
}
|
||||
|
@ -49,6 +49,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 +188,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 +217,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 +230,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 +242,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 +257,6 @@ impl<'a> EdModel<'a> {
|
||||
col_nr,
|
||||
child_id,
|
||||
grid_node_map,
|
||||
code_lines,
|
||||
mark_node_pool,
|
||||
)?;
|
||||
}
|
||||
@ -278,20 +269,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 +295,29 @@ 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)?;
|
||||
pub fn insert_empty_line(line_nr: usize, grid_node_map: &mut GridNodeMap) -> UIResult<()> {
|
||||
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();
|
||||
pub fn push_empty_line(grid_node_map: &mut GridNodeMap) {
|
||||
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.
|
||||
@ -347,9 +326,7 @@ impl<'a> EdModel<'a> {
|
||||
line_nr: usize,
|
||||
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)
|
||||
self.grid_node_map.del_range_at_line(line_nr, col_range)
|
||||
}
|
||||
|
||||
pub fn del_blank_expr_node(&mut self, txt_pos: TextPos) -> UIResult<()> {
|
||||
@ -602,7 +579,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 +600,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 +653,41 @@ 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> {
|
||||
@ -1080,6 +1090,7 @@ pub fn handle_new_char_expr(
|
||||
let (new_child_index, new_ast_child_index) = ed_model.get_curr_child_indices()?;
|
||||
// insert a Blank first, this results in cleaner code
|
||||
add_blank_child(new_child_index, new_ast_child_index, ed_model)?;
|
||||
ed_model.post_process_ast_update()?;
|
||||
handle_new_char(received_char, ed_model)?
|
||||
} else {
|
||||
InputOutcome::Ignored
|
||||
@ -1162,6 +1173,7 @@ pub fn handle_new_char_diff_mark_nodes_prev_is_expr(
|
||||
let new_ast_child_index = 0;
|
||||
// insert a Blank first, this results in cleaner code
|
||||
add_blank_child(new_child_index, new_ast_child_index, ed_model)?;
|
||||
ed_model.post_process_ast_update()?;
|
||||
handle_new_char(received_char, ed_model)?
|
||||
} else {
|
||||
InputOutcome::Ignored
|
||||
@ -1182,6 +1194,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 +1251,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 +1275,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;
|
||||
}
|
||||
|
||||
@ -1684,92 +1700,32 @@ pub mod test_ed_update {
|
||||
fn test_record() -> Result<(), String> {
|
||||
assert_insert_in_def_nls(ovec!["{ ┃ }"], '{')?;
|
||||
assert_insert_nls(ovec!["val = { ┃ }"], ovec!["val = { a┃ }"], 'a')?;
|
||||
assert_insert_nls(
|
||||
ovec!["val = { a┃ }"],
|
||||
ovec!["val = { ab┃: RunTimeError }"],
|
||||
'b',
|
||||
)?; // TODO: remove RunTimeError, see issue #1649
|
||||
assert_insert_nls(
|
||||
ovec!["val = { a┃ }"],
|
||||
ovec!["val = { a1┃: RunTimeError }"],
|
||||
'1',
|
||||
)?;
|
||||
assert_insert_nls(
|
||||
ovec!["val = { a1┃ }"],
|
||||
ovec!["val = { a1z┃: RunTimeError }"],
|
||||
'z',
|
||||
)?;
|
||||
assert_insert_nls(
|
||||
ovec!["val = { a1┃ }"],
|
||||
ovec!["val = { a15┃: RunTimeError }"],
|
||||
'5',
|
||||
)?;
|
||||
assert_insert_nls(
|
||||
ovec!["val = { ab┃ }"],
|
||||
ovec!["val = { abc┃: RunTimeError }"],
|
||||
'c',
|
||||
)?;
|
||||
assert_insert_nls(
|
||||
ovec!["val = { ┃abc }"],
|
||||
ovec!["val = { z┃abc: RunTimeError }"],
|
||||
'z',
|
||||
)?;
|
||||
assert_insert_nls(
|
||||
ovec!["val = { a┃b }"],
|
||||
ovec!["val = { az┃b: RunTimeError }"],
|
||||
'z',
|
||||
)?;
|
||||
assert_insert_nls(
|
||||
ovec!["val = { a┃b }"],
|
||||
ovec!["val = { a9┃b: RunTimeError }"],
|
||||
'9',
|
||||
)?;
|
||||
assert_insert_nls(ovec!["val = { a┃ }"], ovec!["val = { ab┃ }"], 'b')?;
|
||||
assert_insert_nls(ovec!["val = { a┃ }"], ovec!["val = { a1┃ }"], '1')?;
|
||||
assert_insert_nls(ovec!["val = { a1┃ }"], ovec!["val = { a1z┃ }"], 'z')?;
|
||||
assert_insert_nls(ovec!["val = { a1┃ }"], ovec!["val = { a15┃ }"], '5')?;
|
||||
assert_insert_nls(ovec!["val = { ab┃ }"], ovec!["val = { abc┃ }"], 'c')?;
|
||||
assert_insert_nls(ovec!["val = { ┃abc }"], ovec!["val = { z┃abc }"], 'z')?;
|
||||
assert_insert_nls(ovec!["val = { a┃b }"], ovec!["val = { az┃b }"], 'z')?;
|
||||
assert_insert_nls(ovec!["val = { a┃b }"], ovec!["val = { a9┃b }"], '9')?;
|
||||
|
||||
assert_insert_nls(
|
||||
ovec!["val = { a┃ }"],
|
||||
ovec!["val = { a┃: RunTimeError }"],
|
||||
':',
|
||||
)?;
|
||||
assert_insert_nls(
|
||||
ovec!["val = { abc┃ }"],
|
||||
ovec!["val = { abc┃: RunTimeError }"],
|
||||
':',
|
||||
)?;
|
||||
assert_insert_nls(
|
||||
ovec!["val = { aBc┃ }"],
|
||||
ovec!["val = { aBc┃: RunTimeError }"],
|
||||
':',
|
||||
)?;
|
||||
assert_insert_nls(ovec!["val = { a┃ }"], ovec!["val = { a: ┃ }"], ':')?;
|
||||
assert_insert_nls(ovec!["val = { abc┃ }"], ovec!["val = { abc: ┃ }"], ':')?;
|
||||
assert_insert_nls(ovec!["val = { aBc┃ }"], ovec!["val = { aBc: ┃ }"], ':')?;
|
||||
|
||||
assert_insert_seq_nls(
|
||||
ovec!["val = { a┃ }"],
|
||||
ovec!["val = { a┃: RunTimeError }"],
|
||||
":\"",
|
||||
)?;
|
||||
assert_insert_seq_nls(ovec!["val = { a┃ }"], 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 }"],
|
||||
":0",
|
||||
)?;
|
||||
assert_insert_seq_nls(ovec!["val = { a┃ }"], ovec!["val = { a: 0┃ }"], ":0")?;
|
||||
assert_insert_seq_nls(ovec!["val = { abc┃ }"], ovec!["val = { abc: 9┃ }"], ":9")?;
|
||||
assert_insert_seq_nls(ovec!["val = { a┃ }"], ovec!["val = { a: 1000┃ }"], ":1000")?;
|
||||
assert_insert_seq_nls(
|
||||
ovec!["val = { abc┃ }"],
|
||||
ovec!["val = { abc9┃: RunTimeError }"],
|
||||
":9",
|
||||
)?;
|
||||
assert_insert_seq_nls(
|
||||
ovec!["val = { a┃ }"],
|
||||
ovec!["val = { a1000┃: RunTimeError }"],
|
||||
":1000",
|
||||
)?;
|
||||
assert_insert_seq_nls(
|
||||
ovec!["val = { abc┃ }"],
|
||||
ovec!["val = { abc98761┃: RunTimeError }"],
|
||||
ovec!["val = { abc: 98761┃ }"],
|
||||
":98761",
|
||||
)?;
|
||||
|
||||
@ -1919,19 +1875,11 @@ pub mod test_ed_update {
|
||||
|
||||
#[test]
|
||||
fn test_nested_record() -> Result<(), String> {
|
||||
assert_insert_seq_nls(
|
||||
ovec!["val = { a┃ }"],
|
||||
ovec!["val = { a┃: RunTimeError }"],
|
||||
":{",
|
||||
)?;
|
||||
assert_insert_seq_nls(
|
||||
ovec!["val = { abc┃ }"],
|
||||
ovec!["val = { abc┃: RunTimeError }"],
|
||||
":{",
|
||||
)?;
|
||||
assert_insert_seq_nls(ovec!["val = { a┃ }"], ovec!["val = { a: { ┃ } }"], ":{")?;
|
||||
assert_insert_seq_nls(ovec!["val = { abc┃ }"], ovec!["val = { abc: { ┃ } }"], ":{")?;
|
||||
assert_insert_seq_nls(
|
||||
ovec!["val = { camelCase┃ }"],
|
||||
ovec!["val = { camelCase┃: RunTimeError }"],
|
||||
ovec!["val = { camelCase: { ┃ } }"],
|
||||
":{",
|
||||
)?;
|
||||
|
||||
@ -1953,49 +1901,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 +1960,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 +1987,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 +2024,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 +2047,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 +2063,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)?;
|
||||
@ -2198,44 +2168,23 @@ pub mod test_ed_update {
|
||||
assert_insert_seq_ignore_nls(ovec!["val = ┃{ a: { } }"], IGNORE_NO_LTR)?;
|
||||
assert_insert_seq_ignore_nls(ovec!["val = { ┃a: { } }"], "1")?;
|
||||
|
||||
assert_insert_seq_ignore_nls(
|
||||
ovec!["val = { camelCaseB1: { z15a:┃ RunTimeError } }"],
|
||||
IGNORE_NO_LTR,
|
||||
assert_insert_seq_ignore_nls(ovec!["val = { camelCaseB1: {┃ z15a } }"], IGNORE_NO_LTR)?;
|
||||
assert_insert_seq_ignore_nls(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_ignore_nls(
|
||||
ovec!["val = { camelCaseB1: {┃ z15a: RunTimeError } }"],
|
||||
IGNORE_NO_LTR,
|
||||
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: 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: 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 } }"], IGNORE_NO_LTR)?;
|
||||
assert_insert_seq_ignore_nls(ovec!["val = {┃ camelCaseB1: { z15a } }"], IGNORE_NO_LTR)?;
|
||||
assert_insert_seq_ignore_nls(ovec!["val = ┃{ camelCaseB1: { z15a } }"], IGNORE_NO_LTR)?;
|
||||
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 +2325,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 +2556,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 see issue #2548
|
||||
//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")?;
|
||||
|
@ -2,10 +2,7 @@ use roc_ast::lang::core::expr::expr2::Expr2::SmallInt;
|
||||
use roc_ast::lang::core::expr::expr2::IntStyle;
|
||||
use roc_ast::lang::core::expr::expr2::IntVal;
|
||||
use roc_ast::mem_pool::pool_str::PoolStr;
|
||||
use roc_code_markup::markup::attribute::Attributes;
|
||||
use roc_code_markup::markup::nodes::MarkupNode;
|
||||
use roc_code_markup::slow_pool::MarkNodeId;
|
||||
use roc_code_markup::syntax_highlight::HighlightStyle;
|
||||
|
||||
use crate::editor::ed_error::EdResult;
|
||||
use crate::editor::ed_error::StringParseError;
|
||||
@ -18,15 +15,14 @@ use crate::ui::text::lines::SelectableLines;
|
||||
// digit_char should be verified to be a digit before calling this function
|
||||
pub fn start_new_int(ed_model: &mut EdModel, digit_char: &char) -> EdResult<InputOutcome> {
|
||||
let NodeContext {
|
||||
old_caret_pos,
|
||||
curr_mark_node_id,
|
||||
old_caret_pos: _,
|
||||
curr_mark_node_id: _,
|
||||
curr_mark_node,
|
||||
parent_id_opt,
|
||||
parent_id_opt: _,
|
||||
ast_node_id,
|
||||
} = get_node_context(ed_model)?;
|
||||
|
||||
let is_blank_node = curr_mark_node.is_blank();
|
||||
let curr_mark_node_nls = curr_mark_node.get_newlines_at_end();
|
||||
|
||||
let int_var = ed_model.module.env.var_store.fresh();
|
||||
|
||||
@ -45,36 +41,10 @@ pub fn start_new_int(ed_model: &mut EdModel, digit_char: &char) -> EdResult<Inpu
|
||||
.pool
|
||||
.set(ast_node_id.to_expr_id()?, expr2_node);
|
||||
|
||||
let int_node = MarkupNode::Text {
|
||||
content: digit_string,
|
||||
ast_node_id,
|
||||
syn_high_style: HighlightStyle::Number,
|
||||
attributes: Attributes::default(),
|
||||
parent_id_opt,
|
||||
newlines_at_end: curr_mark_node_nls,
|
||||
};
|
||||
|
||||
if is_blank_node {
|
||||
ed_model
|
||||
.mark_node_pool
|
||||
.replace_node(curr_mark_node_id, int_node);
|
||||
|
||||
// remove data corresponding to Blank node
|
||||
ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?;
|
||||
|
||||
let char_len = 1;
|
||||
ed_model.simple_move_carets_right(char_len);
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
EdModel::insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
&digit_char.to_string(),
|
||||
curr_mark_node_id,
|
||||
&mut ed_model.grid_node_map,
|
||||
&mut ed_model.code_lines,
|
||||
)?;
|
||||
|
||||
Ok(InputOutcome::Accepted)
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
@ -109,16 +79,6 @@ pub fn update_int(
|
||||
|
||||
let content_str = int_mark_node.get_content();
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
EdModel::insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
&ch.to_string(),
|
||||
int_mark_node_id,
|
||||
&mut ed_model.grid_node_map,
|
||||
&mut ed_model.code_lines,
|
||||
)?;
|
||||
|
||||
// update ast
|
||||
let new_pool_str = PoolStr::new(&content_str, ed_model.module.env.pool);
|
||||
let int_ast_node = ed_model
|
||||
|
@ -1,12 +1,6 @@
|
||||
use roc_ast::lang::core::ast::ASTNodeId;
|
||||
use roc_ast::lang::core::expr::expr2::Expr2;
|
||||
use roc_ast::lang::core::pattern::Pattern2;
|
||||
use roc_ast::lang::core::val_def::ValueDef;
|
||||
use roc_code_markup::markup::attribute::Attributes;
|
||||
use roc_code_markup::markup::common_nodes::new_blank_mn_w_nls;
|
||||
use roc_code_markup::markup::common_nodes::new_equals_mn;
|
||||
use roc_code_markup::markup::nodes::MarkupNode;
|
||||
use roc_code_markup::syntax_highlight::HighlightStyle;
|
||||
use roc_module::symbol::Symbol;
|
||||
|
||||
use crate::editor::ed_error::EdResult;
|
||||
@ -17,26 +11,21 @@ use crate::editor::mvc::ed_update::NodeContext;
|
||||
|
||||
pub fn start_new_let_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<InputOutcome> {
|
||||
let NodeContext {
|
||||
old_caret_pos,
|
||||
curr_mark_node_id,
|
||||
old_caret_pos: _,
|
||||
curr_mark_node_id: _,
|
||||
curr_mark_node,
|
||||
parent_id_opt,
|
||||
parent_id_opt: _,
|
||||
ast_node_id,
|
||||
} = get_node_context(ed_model)?;
|
||||
|
||||
let is_blank_node = curr_mark_node.is_blank();
|
||||
let curr_mark_node_nls = curr_mark_node.get_newlines_at_end();
|
||||
|
||||
let val_name_string = new_char.to_string();
|
||||
// safe unwrap because our ArrString has a 30B capacity
|
||||
let val_expr2_node = Expr2::Blank;
|
||||
let val_expr_id = ed_model.module.env.pool.add(val_expr2_node);
|
||||
|
||||
let ident_id = ed_model
|
||||
.module
|
||||
.env
|
||||
.ident_ids
|
||||
.add(val_name_string.clone().into());
|
||||
let ident_id = ed_model.module.env.ident_ids.add(val_name_string.into());
|
||||
let var_symbol = Symbol::new(ed_model.module.env.home, ident_id);
|
||||
let body = Expr2::Var(var_symbol);
|
||||
let body_id = ed_model.module.env.pool.add(body);
|
||||
@ -63,50 +52,10 @@ pub fn start_new_let_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<
|
||||
.pool
|
||||
.set(ast_node_id.to_expr_id()?, expr2_node);
|
||||
|
||||
let val_name_mark_node = MarkupNode::Text {
|
||||
content: val_name_string,
|
||||
ast_node_id,
|
||||
syn_high_style: HighlightStyle::Value,
|
||||
attributes: Attributes::default(),
|
||||
parent_id_opt: Some(curr_mark_node_id),
|
||||
newlines_at_end: curr_mark_node_nls,
|
||||
};
|
||||
|
||||
let val_name_mn_id = ed_model.add_mark_node(val_name_mark_node);
|
||||
|
||||
let equals_mn_id = ed_model.add_mark_node(new_equals_mn(ast_node_id, Some(curr_mark_node_id)));
|
||||
|
||||
let body_mn_id = ed_model.add_mark_node(new_blank_mn_w_nls(
|
||||
ASTNodeId::AExprId(val_expr_id),
|
||||
Some(curr_mark_node_id),
|
||||
1,
|
||||
));
|
||||
|
||||
let val_mark_node = MarkupNode::Nested {
|
||||
ast_node_id,
|
||||
children_ids: vec![val_name_mn_id, equals_mn_id, body_mn_id],
|
||||
parent_id_opt,
|
||||
newlines_at_end: 1,
|
||||
};
|
||||
|
||||
if is_blank_node {
|
||||
ed_model
|
||||
.mark_node_pool
|
||||
.replace_node(curr_mark_node_id, val_mark_node);
|
||||
|
||||
// remove data corresponding to Blank node
|
||||
ed_model.del_blank_expr_node(old_caret_pos)?;
|
||||
|
||||
let char_len = 1;
|
||||
ed_model.simple_move_carets_right(char_len);
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_all_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
&[val_name_mn_id, equals_mn_id, body_mn_id],
|
||||
)?;
|
||||
|
||||
Ok(InputOutcome::Accepted)
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
|
@ -1,10 +1,7 @@
|
||||
use roc_ast::lang::core::ast::{ast_node_to_string, ASTNodeId};
|
||||
use roc_ast::lang::core::ast::ast_node_to_string;
|
||||
use roc_ast::lang::core::expr::expr2::{Expr2, ExprId};
|
||||
use roc_ast::mem_pool::pool_vec::PoolVec;
|
||||
use roc_code_markup::markup::common_nodes::{
|
||||
new_blank_mn, new_comma_mn, new_left_square_mn, new_right_square_mn,
|
||||
};
|
||||
use roc_code_markup::markup::nodes::{self, MarkupNode};
|
||||
use roc_code_markup::markup::nodes::{self};
|
||||
use roc_code_markup::slow_pool::MarkNodeId;
|
||||
|
||||
use crate::editor::ed_error::EdResult;
|
||||
@ -13,19 +10,17 @@ use crate::editor::mvc::app_update::InputOutcome;
|
||||
use crate::editor::mvc::ed_model::EdModel;
|
||||
use crate::editor::mvc::ed_update::get_node_context;
|
||||
use crate::editor::mvc::ed_update::NodeContext;
|
||||
use crate::ui::text::text_pos::TextPos;
|
||||
|
||||
pub fn start_new_list(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
|
||||
let NodeContext {
|
||||
old_caret_pos,
|
||||
curr_mark_node_id,
|
||||
old_caret_pos: _,
|
||||
curr_mark_node_id: _,
|
||||
curr_mark_node,
|
||||
parent_id_opt,
|
||||
parent_id_opt: _,
|
||||
ast_node_id,
|
||||
} = get_node_context(ed_model)?;
|
||||
|
||||
let is_blank_node = curr_mark_node.is_blank();
|
||||
let curr_mark_node_nls = curr_mark_node.get_newlines_at_end();
|
||||
|
||||
let expr2_node = Expr2::List {
|
||||
elem_var: ed_model.module.env.var_store.fresh(),
|
||||
@ -38,51 +33,9 @@ pub fn start_new_list(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
|
||||
.pool
|
||||
.set(ast_node_id.to_expr_id()?, expr2_node);
|
||||
|
||||
let left_bracket_node_id = ed_model.add_mark_node(new_left_square_mn(
|
||||
ast_node_id.to_expr_id()?,
|
||||
Some(curr_mark_node_id),
|
||||
));
|
||||
|
||||
let right_bracket_node_id = ed_model.add_mark_node(new_right_square_mn(
|
||||
ast_node_id.to_expr_id()?,
|
||||
Some(curr_mark_node_id),
|
||||
));
|
||||
|
||||
let nested_node = MarkupNode::Nested {
|
||||
ast_node_id,
|
||||
children_ids: vec![left_bracket_node_id, right_bracket_node_id],
|
||||
parent_id_opt,
|
||||
newlines_at_end: curr_mark_node_nls,
|
||||
};
|
||||
|
||||
if is_blank_node {
|
||||
ed_model
|
||||
.mark_node_pool
|
||||
.replace_node(curr_mark_node_id, nested_node);
|
||||
|
||||
ed_model.del_blank_expr_node(old_caret_pos)?;
|
||||
|
||||
ed_model.simple_move_carets_right(nodes::LEFT_SQUARE_BR.len());
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
EdModel::insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
nodes::LEFT_SQUARE_BR,
|
||||
left_bracket_node_id,
|
||||
&mut ed_model.grid_node_map,
|
||||
&mut ed_model.code_lines,
|
||||
)?;
|
||||
|
||||
EdModel::insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column + nodes::LEFT_SQUARE_BR.len(),
|
||||
nodes::RIGHT_SQUARE_BR,
|
||||
right_bracket_node_id,
|
||||
&mut ed_model.grid_node_map,
|
||||
&mut ed_model.code_lines,
|
||||
)?;
|
||||
|
||||
Ok(InputOutcome::Accepted)
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
@ -96,7 +49,7 @@ pub fn add_blank_child(
|
||||
ed_model: &mut EdModel,
|
||||
) -> EdResult<InputOutcome> {
|
||||
let NodeContext {
|
||||
old_caret_pos,
|
||||
old_caret_pos: _,
|
||||
curr_mark_node_id,
|
||||
curr_mark_node: _,
|
||||
parent_id_opt,
|
||||
@ -133,7 +86,7 @@ pub fn add_blank_child(
|
||||
.fail()
|
||||
};
|
||||
|
||||
let (blank_elt_id, list_ast_node_id, parent_id) = trip_result?;
|
||||
let (blank_elt_id, list_ast_node_id, _parent_id) = trip_result?;
|
||||
|
||||
let list_ast_node = ed_model.module.env.pool.get(list_ast_node_id);
|
||||
|
||||
@ -164,75 +117,9 @@ pub fn add_blank_child(
|
||||
.fail(),
|
||||
}?;
|
||||
|
||||
let new_mark_children = update_mark_children(
|
||||
new_child_index,
|
||||
blank_elt_id,
|
||||
list_ast_node_id,
|
||||
old_caret_pos,
|
||||
parent_id_opt,
|
||||
ed_model,
|
||||
)?;
|
||||
|
||||
let parent = ed_model.mark_node_pool.get_mut(parent_id);
|
||||
|
||||
for (indx, child) in new_mark_children.iter().enumerate() {
|
||||
parent.add_child_at_index(new_child_index + indx, *child)?;
|
||||
if new_child_index > 1 {
|
||||
ed_model.simple_move_carets_right(nodes::COMMA.len());
|
||||
}
|
||||
|
||||
Ok(InputOutcome::Accepted)
|
||||
}
|
||||
|
||||
// add a Blank child to the Nested mark node and update the caret
|
||||
pub fn update_mark_children(
|
||||
new_child_index: usize,
|
||||
blank_elt_id: ExprId,
|
||||
list_ast_node_id: ExprId,
|
||||
old_caret_pos: TextPos,
|
||||
parent_id_opt: Option<MarkNodeId>,
|
||||
ed_model: &mut EdModel,
|
||||
) -> EdResult<Vec<MarkNodeId>> {
|
||||
let blank_mark_node_id = ed_model.add_mark_node(new_blank_mn(
|
||||
ASTNodeId::AExprId(blank_elt_id),
|
||||
parent_id_opt,
|
||||
));
|
||||
|
||||
let mut children: Vec<MarkNodeId> = vec![];
|
||||
|
||||
if new_child_index > 1 {
|
||||
let comma_mark_node_id =
|
||||
ed_model.add_mark_node(new_comma_mn(list_ast_node_id, parent_id_opt));
|
||||
|
||||
ed_model.simple_move_carets_right(nodes::COMMA.len());
|
||||
|
||||
EdModel::insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
nodes::COMMA,
|
||||
comma_mark_node_id,
|
||||
&mut ed_model.grid_node_map,
|
||||
&mut ed_model.code_lines,
|
||||
)?;
|
||||
|
||||
children.push(comma_mark_node_id);
|
||||
}
|
||||
|
||||
children.push(blank_mark_node_id);
|
||||
|
||||
let comma_shift = if new_child_index == 1 {
|
||||
0
|
||||
} else {
|
||||
nodes::COMMA.len()
|
||||
};
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
EdModel::insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column + comma_shift,
|
||||
nodes::BLANK_PLACEHOLDER,
|
||||
blank_mark_node_id,
|
||||
&mut ed_model.grid_node_map,
|
||||
&mut ed_model.code_lines,
|
||||
)?;
|
||||
|
||||
Ok(children)
|
||||
}
|
||||
|
@ -15,7 +15,6 @@ pub fn update_invalid_lookup(
|
||||
ed_model: &mut EdModel,
|
||||
) -> EdResult<InputOutcome> {
|
||||
if input_str.chars().all(|ch| ch.is_ascii_alphanumeric()) {
|
||||
let old_caret_pos = ed_model.get_caret();
|
||||
let mut new_lookup_str = String::new();
|
||||
|
||||
new_lookup_str.push_str(old_pool_str.as_str(ed_model.module.env.pool));
|
||||
@ -35,24 +34,9 @@ pub fn update_invalid_lookup(
|
||||
.pool
|
||||
.set(expr_id, Expr2::InvalidLookup(new_pool_str));
|
||||
|
||||
// update MarkupNode
|
||||
let curr_mark_node_mut = ed_model.mark_node_pool.get_mut(curr_mark_node_id);
|
||||
let content_str_mut = curr_mark_node_mut.get_content_mut()?;
|
||||
content_str_mut.insert_str(caret_offset, input_str);
|
||||
|
||||
// update caret
|
||||
ed_model.simple_move_carets_right(input_str.len());
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
EdModel::insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
input_str,
|
||||
curr_mark_node_id,
|
||||
&mut ed_model.grid_node_map,
|
||||
&mut ed_model.code_lines,
|
||||
)?;
|
||||
|
||||
Ok(InputOutcome::Accepted)
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
|
@ -14,65 +14,32 @@ use roc_ast::lang::core::expr::record_field::RecordField;
|
||||
use roc_ast::mem_pool::pool_str::PoolStr;
|
||||
use roc_ast::mem_pool::pool_vec::PoolVec;
|
||||
use roc_code_markup::markup::attribute::Attributes;
|
||||
use roc_code_markup::markup::common_nodes::new_blank_mn;
|
||||
use roc_code_markup::markup::common_nodes::new_left_accolade_mn;
|
||||
use roc_code_markup::markup::common_nodes::new_right_accolade_mn;
|
||||
use roc_code_markup::markup::nodes;
|
||||
use roc_code_markup::markup::nodes::MarkupNode;
|
||||
use roc_code_markup::markup::nodes::COLON;
|
||||
use roc_code_markup::slow_pool::MarkNodeId;
|
||||
use roc_code_markup::syntax_highlight::HighlightStyle;
|
||||
use snafu::OptionExt;
|
||||
|
||||
pub fn start_new_record(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
|
||||
let NodeContext {
|
||||
old_caret_pos,
|
||||
curr_mark_node_id,
|
||||
old_caret_pos: _,
|
||||
curr_mark_node_id: _,
|
||||
curr_mark_node,
|
||||
parent_id_opt,
|
||||
parent_id_opt: _,
|
||||
ast_node_id,
|
||||
} = get_node_context(ed_model)?;
|
||||
|
||||
let is_blank_node = curr_mark_node.is_blank();
|
||||
let curr_mark_node_nls = curr_mark_node.get_newlines_at_end();
|
||||
|
||||
let ast_pool = &mut ed_model.module.env.pool;
|
||||
let expr2_node = Expr2::EmptyRecord;
|
||||
|
||||
ast_pool.set(ast_node_id.to_expr_id()?, expr2_node);
|
||||
|
||||
let left_bracket_node_id = ed_model.add_mark_node(new_left_accolade_mn(
|
||||
ast_node_id.to_expr_id()?,
|
||||
Some(curr_mark_node_id),
|
||||
));
|
||||
|
||||
let right_bracket_node_id = ed_model.add_mark_node(new_right_accolade_mn(
|
||||
ast_node_id.to_expr_id()?,
|
||||
Some(curr_mark_node_id),
|
||||
));
|
||||
|
||||
let nested_node = MarkupNode::Nested {
|
||||
ast_node_id,
|
||||
children_ids: vec![left_bracket_node_id, right_bracket_node_id],
|
||||
parent_id_opt,
|
||||
newlines_at_end: curr_mark_node_nls,
|
||||
};
|
||||
|
||||
if is_blank_node {
|
||||
ed_model
|
||||
.mark_node_pool
|
||||
.replace_node(curr_mark_node_id, nested_node);
|
||||
|
||||
ed_model.del_blank_expr_node(old_caret_pos)?;
|
||||
|
||||
ed_model.simple_move_carets_right(nodes::LEFT_ACCOLADE.len());
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_all_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
&[left_bracket_node_id, right_bracket_node_id],
|
||||
)?;
|
||||
|
||||
Ok(InputOutcome::Accepted)
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
@ -156,7 +123,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)
|
||||
@ -174,129 +140,74 @@ pub fn update_record_colon(
|
||||
) -> EdResult<InputOutcome> {
|
||||
let NodeContext {
|
||||
old_caret_pos,
|
||||
curr_mark_node_id,
|
||||
curr_mark_node,
|
||||
parent_id_opt,
|
||||
curr_mark_node_id: _,
|
||||
curr_mark_node: _,
|
||||
parent_id_opt: _,
|
||||
ast_node_id,
|
||||
} = get_node_context(ed_model)?;
|
||||
if let Some(parent_id) = parent_id_opt {
|
||||
let curr_ast_node = ed_model.module.env.pool.get(ast_node_id.to_expr_id()?);
|
||||
let curr_ast_node = ed_model.module.env.pool.get(ast_node_id.to_expr_id()?);
|
||||
|
||||
let prev_mark_node_id_opt = ed_model.get_prev_mark_node_id()?;
|
||||
if let Some(prev_mark_node_id) = prev_mark_node_id_opt {
|
||||
let prev_mark_node = ed_model.mark_node_pool.get(prev_mark_node_id);
|
||||
let prev_mark_node_id_opt = ed_model.get_prev_mark_node_id()?;
|
||||
if let Some(prev_mark_node_id) = prev_mark_node_id_opt {
|
||||
let prev_mark_node = ed_model.mark_node_pool.get(prev_mark_node_id);
|
||||
|
||||
match prev_mark_node.get_ast_node_id() {
|
||||
ASTNodeId::ADefId(_) => Ok(InputOutcome::Ignored),
|
||||
ASTNodeId::AExprId(prev_expr_id) => {
|
||||
let prev_expr = ed_model.module.env.pool.get(prev_expr_id);
|
||||
match prev_mark_node.get_ast_node_id() {
|
||||
ASTNodeId::ADefId(_) => Ok(InputOutcome::Ignored),
|
||||
ASTNodeId::AExprId(prev_expr_id) => {
|
||||
let prev_expr = ed_model.module.env.pool.get(prev_expr_id);
|
||||
|
||||
// current and prev node should always point to record when in valid position to add ':'
|
||||
if matches!(prev_expr, Expr2::Record { .. })
|
||||
&& matches!(curr_ast_node, Expr2::Record { .. })
|
||||
{
|
||||
let sibling_ids = curr_mark_node.get_sibling_ids(&ed_model.mark_node_pool);
|
||||
// current and prev node should always point to record when in valid position to add ':'
|
||||
if matches!(prev_expr, Expr2::Record { .. })
|
||||
&& matches!(curr_ast_node, Expr2::Record { .. })
|
||||
{
|
||||
let ast_node_ref = ed_model.module.env.pool.get(record_ast_node_id);
|
||||
|
||||
let new_child_index = index_of(curr_mark_node_id, &sibling_ids)?;
|
||||
match ast_node_ref {
|
||||
Expr2::Record {
|
||||
record_var: _,
|
||||
fields,
|
||||
} => {
|
||||
if ed_model.node_exists_at_caret() {
|
||||
let next_mark_node_id =
|
||||
ed_model.grid_node_map.get_id_at_row_col(old_caret_pos)?;
|
||||
let next_mark_node = ed_model.mark_node_pool.get(next_mark_node_id);
|
||||
if next_mark_node.get_content() == nodes::RIGHT_ACCOLADE {
|
||||
// update AST node
|
||||
let new_field_val = Expr2::Blank;
|
||||
let new_field_val_id =
|
||||
ed_model.module.env.pool.add(new_field_val);
|
||||
|
||||
let ast_node_ref = ed_model.module.env.pool.get(record_ast_node_id);
|
||||
let first_field_mut = fields
|
||||
.iter_mut(ed_model.module.env.pool)
|
||||
.next()
|
||||
.with_context(|| RecordWithoutFields {})?;
|
||||
|
||||
match ast_node_ref {
|
||||
Expr2::Record {
|
||||
record_var: _,
|
||||
fields,
|
||||
} => {
|
||||
if ed_model.node_exists_at_caret() {
|
||||
let next_mark_node_id =
|
||||
ed_model.grid_node_map.get_id_at_row_col(old_caret_pos)?;
|
||||
let next_mark_node =
|
||||
ed_model.mark_node_pool.get(next_mark_node_id);
|
||||
if next_mark_node.get_content() == nodes::RIGHT_ACCOLADE {
|
||||
// update AST node
|
||||
let new_field_val = Expr2::Blank;
|
||||
let new_field_val_id =
|
||||
ed_model.module.env.pool.add(new_field_val);
|
||||
*first_field_mut = RecordField::LabeledValue(
|
||||
*first_field_mut.get_record_field_pool_str(),
|
||||
*first_field_mut.get_record_field_var(),
|
||||
new_field_val_id,
|
||||
);
|
||||
|
||||
let first_field_mut = fields
|
||||
.iter_mut(ed_model.module.env.pool)
|
||||
.next()
|
||||
.with_context(|| RecordWithoutFields {})?;
|
||||
// update caret
|
||||
ed_model.simple_move_carets_right(COLON.len());
|
||||
|
||||
*first_field_mut = RecordField::LabeledValue(
|
||||
*first_field_mut.get_record_field_pool_str(),
|
||||
*first_field_mut.get_record_field_var(),
|
||||
new_field_val_id,
|
||||
);
|
||||
|
||||
// update Markup
|
||||
let record_colon = nodes::COLON;
|
||||
|
||||
let record_colon_node = MarkupNode::Text {
|
||||
content: record_colon.to_owned(),
|
||||
ast_node_id: ASTNodeId::AExprId(record_ast_node_id),
|
||||
syn_high_style: HighlightStyle::Operator,
|
||||
attributes: Attributes::default(),
|
||||
parent_id_opt: Some(parent_id),
|
||||
newlines_at_end: 0,
|
||||
};
|
||||
|
||||
let record_colon_node_id =
|
||||
ed_model.add_mark_node(record_colon_node);
|
||||
ed_model
|
||||
.mark_node_pool
|
||||
.get_mut(parent_id)
|
||||
.add_child_at_index(
|
||||
new_child_index,
|
||||
record_colon_node_id,
|
||||
)?;
|
||||
|
||||
let record_blank_node_id =
|
||||
ed_model.add_mark_node(new_blank_mn(
|
||||
ASTNodeId::AExprId(new_field_val_id),
|
||||
Some(parent_id),
|
||||
));
|
||||
|
||||
ed_model
|
||||
.mark_node_pool
|
||||
.get_mut(parent_id)
|
||||
.add_child_at_index(
|
||||
new_child_index + 1,
|
||||
record_blank_node_id,
|
||||
)?;
|
||||
|
||||
// update caret
|
||||
ed_model.simple_move_carets_right(record_colon.len());
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_all_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
&[record_colon_node_id, record_blank_node_id],
|
||||
)?;
|
||||
|
||||
Ok(InputOutcome::Accepted)
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
}
|
||||
Ok(InputOutcome::Accepted)
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
}
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
}
|
||||
_ => Ok(InputOutcome::Ignored),
|
||||
}
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
_ => Ok(InputOutcome::Ignored),
|
||||
}
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
}
|
||||
}
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
}
|
||||
} else {
|
||||
MissingParent {
|
||||
node_id: curr_mark_node_id,
|
||||
}
|
||||
.fail()
|
||||
Ok(InputOutcome::Ignored)
|
||||
}
|
||||
}
|
||||
|
||||
@ -329,16 +240,6 @@ pub fn update_record_field(
|
||||
// update caret
|
||||
ed_model.simple_move_carets_right(new_input.len());
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
EdModel::insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
new_input,
|
||||
curr_mark_node_id,
|
||||
&mut ed_model.grid_node_map,
|
||||
&mut ed_model.code_lines,
|
||||
)?;
|
||||
|
||||
// update AST Node
|
||||
let first_field = record_fields
|
||||
.iter(ed_model.module.env.pool)
|
||||
|
@ -2,10 +2,6 @@ use roc_ast::lang::core::expr::expr2::ArrString;
|
||||
use roc_ast::lang::core::expr::expr2::Expr2;
|
||||
use roc_ast::lang::core::str::update_str_expr;
|
||||
use roc_ast::mem_pool::pool_str::PoolStr;
|
||||
use roc_code_markup::markup::attribute::Attributes;
|
||||
use roc_code_markup::markup::nodes;
|
||||
use roc_code_markup::markup::nodes::MarkupNode;
|
||||
use roc_code_markup::syntax_highlight::HighlightStyle;
|
||||
|
||||
use crate::editor::ed_error::EdResult;
|
||||
use crate::editor::mvc::app_update::InputOutcome;
|
||||
@ -21,21 +17,19 @@ pub fn update_small_string(
|
||||
let NodeContext {
|
||||
old_caret_pos,
|
||||
curr_mark_node_id,
|
||||
curr_mark_node: _,
|
||||
curr_mark_node,
|
||||
parent_id_opt: _,
|
||||
ast_node_id,
|
||||
} = get_node_context(ed_model)?;
|
||||
|
||||
let new_input = &new_char.to_string();
|
||||
|
||||
// update markup
|
||||
let curr_mark_node_mut = ed_model.mark_node_pool.get_mut(curr_mark_node_id);
|
||||
let content_str_mut = curr_mark_node_mut.get_content_mut()?;
|
||||
let content_str = curr_mark_node.get_content();
|
||||
let node_caret_offset = ed_model
|
||||
.grid_node_map
|
||||
.get_offset_to_node_id(old_caret_pos, curr_mark_node_id)?;
|
||||
|
||||
if node_caret_offset != 0 && node_caret_offset < content_str_mut.len() {
|
||||
if node_caret_offset != 0 && node_caret_offset < content_str.len() {
|
||||
if old_array_str.len() < old_array_str.capacity() {
|
||||
if let Expr2::SmallStr(ref mut mut_array_str) =
|
||||
ed_model.module.env.pool.get_mut(ast_node_id.to_expr_id()?)
|
||||
@ -58,18 +52,6 @@ pub fn update_small_string(
|
||||
.set(ast_node_id.to_expr_id()?, new_ast_node);
|
||||
}
|
||||
|
||||
content_str_mut.insert_str(node_caret_offset, new_input);
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
EdModel::insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
new_input,
|
||||
curr_mark_node_id,
|
||||
&mut ed_model.grid_node_map,
|
||||
&mut ed_model.code_lines,
|
||||
)?;
|
||||
|
||||
// update caret
|
||||
ed_model.simple_move_carets_right(new_input.len());
|
||||
|
||||
@ -83,31 +65,17 @@ pub fn update_string(new_char: char, ed_model: &mut EdModel) -> EdResult<InputOu
|
||||
let NodeContext {
|
||||
old_caret_pos,
|
||||
curr_mark_node_id,
|
||||
curr_mark_node: _,
|
||||
curr_mark_node,
|
||||
parent_id_opt: _,
|
||||
ast_node_id,
|
||||
} = get_node_context(ed_model)?;
|
||||
|
||||
// update markup
|
||||
let curr_mark_node_mut = ed_model.mark_node_pool.get_mut(curr_mark_node_id);
|
||||
let content_str_mut = curr_mark_node_mut.get_content_mut()?;
|
||||
let content_str = curr_mark_node.get_content();
|
||||
let node_caret_offset = ed_model
|
||||
.grid_node_map
|
||||
.get_offset_to_node_id(old_caret_pos, curr_mark_node_id)?;
|
||||
|
||||
if node_caret_offset != 0 && node_caret_offset < content_str_mut.len() {
|
||||
content_str_mut.insert(node_caret_offset, new_char);
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
EdModel::insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
&new_char.to_string(),
|
||||
curr_mark_node_id,
|
||||
&mut ed_model.grid_node_map,
|
||||
&mut ed_model.code_lines,
|
||||
)?;
|
||||
|
||||
if node_caret_offset != 0 && node_caret_offset < content_str.len() {
|
||||
// update ast
|
||||
update_str_expr(
|
||||
ast_node_id.to_expr_id()?,
|
||||
@ -127,16 +95,15 @@ pub fn update_string(new_char: char, ed_model: &mut EdModel) -> EdResult<InputOu
|
||||
|
||||
pub fn start_new_string(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
|
||||
let NodeContext {
|
||||
old_caret_pos,
|
||||
curr_mark_node_id,
|
||||
old_caret_pos: _,
|
||||
curr_mark_node_id: _,
|
||||
curr_mark_node,
|
||||
parent_id_opt,
|
||||
parent_id_opt: _,
|
||||
ast_node_id,
|
||||
} = get_node_context(ed_model)?;
|
||||
|
||||
if curr_mark_node.is_blank() {
|
||||
let new_expr2_node = Expr2::SmallStr(arrayvec::ArrayString::new());
|
||||
let curr_mark_node_nls = curr_mark_node.get_newlines_at_end();
|
||||
|
||||
ed_model
|
||||
.module
|
||||
@ -144,32 +111,6 @@ pub fn start_new_string(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
|
||||
.pool
|
||||
.set(ast_node_id.to_expr_id()?, new_expr2_node);
|
||||
|
||||
let new_string_node = MarkupNode::Text {
|
||||
content: nodes::STRING_QUOTES.to_owned(),
|
||||
ast_node_id,
|
||||
syn_high_style: HighlightStyle::String,
|
||||
attributes: Attributes::default(),
|
||||
parent_id_opt,
|
||||
newlines_at_end: curr_mark_node_nls,
|
||||
};
|
||||
|
||||
ed_model
|
||||
.mark_node_pool
|
||||
.replace_node(curr_mark_node_id, new_string_node);
|
||||
|
||||
// remove data corresponding to Blank node
|
||||
ed_model.del_blank_expr_node(old_caret_pos)?;
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
EdModel::insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
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);
|
||||
|
||||
Ok(InputOutcome::Accepted)
|
||||
|
@ -1,10 +1,5 @@
|
||||
use roc_ast::lang::core::{ast::ASTNodeId, def::def2::Def2, expr::expr2::Expr2};
|
||||
use roc_code_markup::{
|
||||
markup::{
|
||||
common_nodes::new_blank_mn_w_nls, nodes::set_parent_for_all, top_level_def::tld_mark_node,
|
||||
},
|
||||
slow_pool::MarkNodeId,
|
||||
};
|
||||
use roc_ast::lang::core::{def::def2::Def2, expr::expr2::Expr2};
|
||||
use roc_code_markup::slow_pool::MarkNodeId;
|
||||
|
||||
use crate::{
|
||||
editor::ed_error::{EdResult, FailedToUpdateIdentIdName, KeyNotFound},
|
||||
@ -20,19 +15,17 @@ use super::{
|
||||
// Top Level Defined Value. example: `main = "Hello, World!"`
|
||||
pub fn start_new_tld_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<InputOutcome> {
|
||||
let NodeContext {
|
||||
old_caret_pos,
|
||||
curr_mark_node_id,
|
||||
old_caret_pos: _,
|
||||
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 +50,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 +61,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 +75,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)
|
||||
|
Loading…
Reference in New Issue
Block a user