mirror of
https://github.com/roc-lang/roc.git
synced 2025-09-29 14:54:47 +00:00
updating TLD value name works!
This commit is contained in:
parent
6c889b35b9
commit
3c858cff96
10 changed files with 280 additions and 25 deletions
|
@ -81,8 +81,6 @@ impl Symbol {
|
|||
)
|
||||
});
|
||||
|
||||
dbg!(ident_ids);
|
||||
|
||||
ident_ids
|
||||
.get_name(self.ident_id())
|
||||
.unwrap_or_else(|| {
|
||||
|
@ -576,7 +574,7 @@ impl IdentIds {
|
|||
if let Some(vec_elt) = by_id.get_mut(key_index) {
|
||||
*vec_elt = new_ident_name.into();
|
||||
} else {
|
||||
// we get the index from by_id so unless there is a bug in the rust std lib, this is unreachable
|
||||
// we get the index from by_id
|
||||
unreachable!()
|
||||
}
|
||||
|
||||
|
@ -592,7 +590,7 @@ impl IdentIds {
|
|||
}
|
||||
}
|
||||
None => {
|
||||
Err("Tried to update key in IdentIds but I could not find the key.".to_string())
|
||||
Err(format!("Tried to update key in IdentIds ({:?}) but I could not find the key ({}).", self.by_ident, old_ident_name))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -13,6 +13,15 @@ use snafu::{Backtrace, ErrorCompat, NoneError, ResultExt, Snafu};
|
|||
#[snafu(visibility(pub))]
|
||||
pub enum EdError {
|
||||
|
||||
#[snafu(display(
|
||||
"ASTNodeIdWithoutDefId: The expr_id_opt in ASTNode({:?}) was `None` but I was expexting `Some(DefId)` .",
|
||||
ast_node_id
|
||||
))]
|
||||
ASTNodeIdWithoutDefId {
|
||||
ast_node_id: ASTNodeId,
|
||||
backtrace: Backtrace,
|
||||
},
|
||||
|
||||
#[snafu(display(
|
||||
"ASTNodeIdWithoutExprId: The expr_id_opt in ASTNode({:?}) was `None` but I was expexting `Some(ExprId)` .",
|
||||
ast_node_id
|
||||
|
|
|
@ -148,8 +148,8 @@ impl GridNodeMap {
|
|||
}
|
||||
}
|
||||
|
||||
// returns start and end pos of Expr2, relevant AST node and MarkNodeId of the corresponding MarkupNode
|
||||
pub fn get_expr_start_end_pos(
|
||||
// returns start and end pos of Expr2/Def2, relevant AST node and MarkNodeId of the corresponding MarkupNode
|
||||
pub fn get_block_start_end_pos(
|
||||
&self,
|
||||
caret_pos: TextPos,
|
||||
ed_model: &EdModel,
|
||||
|
|
|
@ -3,6 +3,7 @@ use crate::editor::ed_error::EdResult;
|
|||
use crate::editor::ed_error::ExpectedTextNode;
|
||||
use crate::editor::ed_error::{NestedNodeMissingChild, NestedNodeRequired};
|
||||
use crate::editor::markup::common_nodes::new_blank_mn;
|
||||
use crate::editor::markup::common_nodes::new_blank_mn_w_nl;
|
||||
use crate::editor::markup::common_nodes::new_colon_mn;
|
||||
use crate::editor::markup::common_nodes::new_comma_mn;
|
||||
use crate::editor::markup::common_nodes::new_equals_mn;
|
||||
|
@ -19,7 +20,7 @@ use crate::lang::ast::DefId;
|
|||
use crate::lang::ast::ExprId;
|
||||
use crate::lang::ast::RecordField;
|
||||
use crate::lang::ast::ValueDef;
|
||||
use crate::lang::ast::expr2_to_string;
|
||||
use crate::editor::mvc::tld_value_update::tld_mark_node;
|
||||
use crate::lang::parse::ASTNodeId;
|
||||
use crate::lang::parse::{AppHeader, AST};
|
||||
use crate::lang::pattern::get_identifier_string;
|
||||
|
@ -284,7 +285,39 @@ pub fn def2_to_markup<'a, 'b>(
|
|||
mark_node_pool: &mut SlowPool,
|
||||
interns: &Interns,
|
||||
) -> EdResult<MarkNodeId> {
|
||||
unimplemented!();
|
||||
|
||||
let ast_node_id = ASTNodeId::ADefId(def2_node_id);
|
||||
|
||||
let mark_node_id = match def2 {
|
||||
Def2::ValueDef { identifier_id, expr_id } => {
|
||||
|
||||
let expr_mn_id = expr2_to_markup(
|
||||
arena,
|
||||
env,
|
||||
env.pool.get(*expr_id),
|
||||
*expr_id,
|
||||
mark_node_pool,
|
||||
interns,
|
||||
)?;
|
||||
|
||||
let expr_mn = mark_node_pool.get_mut(expr_mn_id);
|
||||
expr_mn.add_newline_at_end();
|
||||
|
||||
|
||||
let tld_mn = tld_mark_node(*identifier_id, expr_mn_id, ast_node_id, mark_node_pool, env, interns)?;
|
||||
|
||||
mark_node_pool.add(
|
||||
tld_mn
|
||||
)
|
||||
},
|
||||
Def2::Blank => {
|
||||
mark_node_pool.add(
|
||||
new_blank_mn_w_nl(ast_node_id, None)
|
||||
)
|
||||
},
|
||||
};
|
||||
|
||||
Ok(mark_node_id)
|
||||
}
|
||||
|
||||
// make Markup Nodes: generate String representation, assign Highlighting Style
|
||||
|
@ -296,7 +329,6 @@ pub fn expr2_to_markup<'a, 'b>(
|
|||
mark_node_pool: &mut SlowPool,
|
||||
interns: &Interns,
|
||||
) -> EdResult<MarkNodeId> {
|
||||
dbg!(expr2_to_string(expr2_node_id, env.pool));
|
||||
|
||||
let ast_node_id = ASTNodeId::AExprId(expr2_node_id);
|
||||
|
||||
|
@ -442,17 +474,14 @@ pub fn expr2_to_markup<'a, 'b>(
|
|||
Expr2::Blank => mark_node_pool.add(new_blank_mn(ast_node_id, None)),
|
||||
Expr2::LetValue {
|
||||
def_id,
|
||||
body_id,
|
||||
body_var,
|
||||
body_id:_,
|
||||
body_var:_,
|
||||
} => {
|
||||
/*dbg!(expr2);
|
||||
dbg!(env.pool.get(*body_id));
|
||||
dbg!(env.pool.get(*def_id));
|
||||
dbg!(body_var);*/
|
||||
|
||||
let pattern_id = env.pool.get(*def_id).get_pattern_id();
|
||||
|
||||
let pattern2 = env.pool.get(pattern_id);
|
||||
dbg!(pattern2);
|
||||
|
||||
let val_name = get_identifier_string(pattern2, interns)?;
|
||||
|
||||
let val_name_mn = MarkupNode::Text {
|
||||
|
|
|
@ -8,6 +8,7 @@ use crate::editor::grid_node_map::GridNodeMap;
|
|||
use crate::editor::markup::attribute::Attributes;
|
||||
use crate::editor::markup::common_nodes::new_blank_mn;
|
||||
use crate::editor::markup::nodes;
|
||||
use crate::editor::markup::nodes::EQUALS;
|
||||
use crate::editor::markup::nodes::MarkupNode;
|
||||
use crate::editor::mvc::app_update::InputOutcome;
|
||||
use crate::editor::mvc::ed_model::EdModel;
|
||||
|
@ -26,6 +27,7 @@ use crate::editor::mvc::string_update::update_string;
|
|||
use crate::editor::slow_pool::MarkNodeId;
|
||||
use crate::editor::slow_pool::SlowPool;
|
||||
use crate::editor::syntax_highlight::HighlightStyle;
|
||||
use crate::editor::mvc::tld_value_update::{start_new_tld_value, update_tld_val_name};
|
||||
use crate::lang::ast::Def2;
|
||||
use crate::lang::ast::{Expr2, ExprId};
|
||||
use crate::lang::constrain::constrain_expr;
|
||||
|
@ -85,6 +87,18 @@ impl<'a> EdModel<'a> {
|
|||
}
|
||||
}
|
||||
|
||||
// disregards EdModel.code_lines because the caller knows the resulting caret position will be valid.
|
||||
// allows us to prevent multiple updates to EdModel.code_lines
|
||||
// TODO error if no match was found for old_caret_pos
|
||||
pub fn simple_move_caret_right(&mut self, old_caret_pos: TextPos, repeat: usize) {
|
||||
for caret_tup in self.caret_w_select_vec.iter_mut() {
|
||||
if caret_tup.0.caret_pos == old_caret_pos {
|
||||
caret_tup.0.caret_pos.column += 1;
|
||||
caret_tup.1 = None;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// disregards EdModel.code_lines because the caller knows the resulting caret position will be valid.
|
||||
// allows us to prevent multiple updates to EdModel.code_lines
|
||||
pub fn simple_move_carets_left(&mut self, repeat: usize) {
|
||||
|
@ -106,6 +120,7 @@ impl<'a> EdModel<'a> {
|
|||
|
||||
// disregards EdModel.code_lines because the caller knows the resulting caret position will be valid.
|
||||
// allows us to prevent multiple updates to EdModel.code_lines
|
||||
// TODO error if no match was found for old_caret_pos
|
||||
pub fn simple_move_caret_down(&mut self, old_caret_pos: TextPos, repeat: usize) {
|
||||
for caret_tup in self.caret_w_select_vec.iter_mut() {
|
||||
if caret_tup.0.caret_pos == old_caret_pos {
|
||||
|
@ -311,7 +326,7 @@ impl<'a> EdModel<'a> {
|
|||
if self.grid_node_map.node_exists_at_pos(caret_pos) {
|
||||
let (expr_start_pos, expr_end_pos, ast_node_id, mark_node_id) = self
|
||||
.grid_node_map
|
||||
.get_expr_start_end_pos(self.get_caret(), self)?;
|
||||
.get_block_start_end_pos(self.get_caret(), self)?;
|
||||
|
||||
self.set_selected_expr(expr_start_pos, expr_end_pos, ast_node_id, mark_node_id)?;
|
||||
} else if self
|
||||
|
@ -320,7 +335,7 @@ impl<'a> EdModel<'a> {
|
|||
{
|
||||
let (expr_start_pos, expr_end_pos, ast_node_id, mark_node_id) = self
|
||||
.grid_node_map
|
||||
.get_expr_start_end_pos(self.get_caret().decrement_col(), self)?;
|
||||
.get_block_start_end_pos(self.get_caret().decrement_col(), self)?;
|
||||
|
||||
self.set_selected_expr(expr_start_pos, expr_end_pos, ast_node_id, mark_node_id)?;
|
||||
}
|
||||
|
@ -686,10 +701,37 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
|
|||
let ast_node_id = curr_mark_node.get_ast_node_id();
|
||||
|
||||
match ast_node_id {
|
||||
ASTNodeId::ADefId(_) => {
|
||||
//let def_ref = ed_model.module.env.pool.get(def_id);
|
||||
ASTNodeId::ADefId(def_id) => {
|
||||
let def_ref = ed_model.module.env.pool.get(def_id);
|
||||
|
||||
unimplemented!("TODO")
|
||||
match def_ref {
|
||||
Def2::Blank {..} => {
|
||||
match ch {
|
||||
'a'..='z' => {
|
||||
start_new_tld_value(ed_model, ch)?
|
||||
},
|
||||
_ => InputOutcome::Ignored
|
||||
}
|
||||
}
|
||||
Def2::ValueDef { .. } => {
|
||||
let val_name_mn_id = if curr_mark_node.get_content() == EQUALS {
|
||||
if let Some(prev_mark_node_id) = prev_mark_node_id_opt {
|
||||
prev_mark_node_id
|
||||
} else {
|
||||
unreachable!()
|
||||
}
|
||||
} else {
|
||||
curr_mark_node_id
|
||||
};
|
||||
|
||||
update_tld_val_name(
|
||||
val_name_mn_id,
|
||||
ed_model.get_caret(), // TODO update for multiple carets
|
||||
ed_model,
|
||||
ch
|
||||
)?
|
||||
},
|
||||
}
|
||||
},
|
||||
ASTNodeId::AExprId(expr_id) => {
|
||||
let expr_ref = ed_model.module.env.pool.get(expr_id);
|
||||
|
|
|
@ -128,7 +128,7 @@ pub fn update_let_value(
|
|||
.grid_node_map
|
||||
.get_offset_to_node_id(old_caret_pos, val_name_mn_id)?;
|
||||
|
||||
if node_caret_offset != 0 && node_caret_offset <= content_str_mut.len() {
|
||||
if node_caret_offset <= content_str_mut.len() {
|
||||
content_str_mut.insert(node_caret_offset, *new_char);
|
||||
|
||||
// update ast
|
||||
|
|
|
@ -5,6 +5,7 @@ pub mod ed_update;
|
|||
pub mod ed_view;
|
||||
mod int_update;
|
||||
mod let_update;
|
||||
pub mod tld_value_update;
|
||||
mod list_update;
|
||||
mod lookup_update;
|
||||
mod record_update;
|
||||
|
|
165
editor/src/editor/mvc/tld_value_update.rs
Normal file
165
editor/src/editor/mvc/tld_value_update.rs
Normal file
|
@ -0,0 +1,165 @@
|
|||
use roc_module::symbol::{Interns, Symbol};
|
||||
|
||||
use crate::{editor::{ed_error::{EdResult, KeyNotFound}, markup::{attribute::Attributes, common_nodes::{new_blank_mn_w_nl, new_equals_mn}, nodes::MarkupNode}, slow_pool::{MarkNodeId, SlowPool}, syntax_highlight::HighlightStyle}, lang::{ast::{Def2, Expr2}, expr::Env, parse::ASTNodeId, pattern::{Pattern2, get_identifier_string}, pool::NodeId}, ui::text::text_pos::TextPos};
|
||||
|
||||
use super::{app_update::InputOutcome, ed_model::EdModel, ed_update::{NodeContext, get_node_context}};
|
||||
|
||||
|
||||
|
||||
// Top Level Defined Value. example: `main = "Hello, World!"`
|
||||
|
||||
pub fn tld_mark_node<'a>(
|
||||
identifier_id: NodeId<Pattern2>,
|
||||
expr_mark_node_id: MarkNodeId,
|
||||
ast_node_id: ASTNodeId,
|
||||
mark_node_pool: &mut SlowPool,
|
||||
env: &Env<'a>,
|
||||
interns: &Interns,
|
||||
) -> EdResult<MarkupNode> {
|
||||
let pattern2 = env.pool.get(identifier_id);
|
||||
let val_name = get_identifier_string(pattern2, interns)?;
|
||||
|
||||
let val_name_mn = MarkupNode::Text {
|
||||
content: val_name,
|
||||
ast_node_id,
|
||||
syn_high_style: HighlightStyle::Variable,
|
||||
attributes: Attributes::new(),
|
||||
parent_id_opt: None,
|
||||
newline_at_end: false,
|
||||
};
|
||||
|
||||
let val_name_mn_id = mark_node_pool.add(val_name_mn);
|
||||
|
||||
let equals_mn_id = mark_node_pool.add(new_equals_mn(ast_node_id, None));
|
||||
|
||||
let expr_mn = mark_node_pool.get_mut(expr_mark_node_id);
|
||||
expr_mn.add_newline_at_end();
|
||||
|
||||
let full_let_node = MarkupNode::Nested {
|
||||
ast_node_id,
|
||||
children_ids: vec![val_name_mn_id, equals_mn_id, expr_mark_node_id],
|
||||
parent_id_opt: None,
|
||||
newline_at_end: true,
|
||||
};
|
||||
|
||||
Ok(
|
||||
full_let_node
|
||||
)
|
||||
}
|
||||
|
||||
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:_,
|
||||
parent_id_opt:_,
|
||||
ast_node_id,
|
||||
} = get_node_context(ed_model)?;
|
||||
|
||||
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_nl(ASTNodeId::AExprId(val_expr_id), None);
|
||||
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
|
||||
.module
|
||||
.env
|
||||
.ident_ids
|
||||
.add(val_name_string.clone().into());
|
||||
|
||||
let module_ident_ids_opt = ed_model.loaded_module.interns.all_ident_ids.get_mut(&ed_model.module.env.home);
|
||||
|
||||
if let Some(module_ident_ids_ref) = module_ident_ids_opt {
|
||||
// this might create different IdentId for interns and env.ident_ids which may be a problem
|
||||
module_ident_ids_ref.add(val_name_string.clone().into());
|
||||
} else {
|
||||
KeyNotFound {
|
||||
key_str: format!("{:?}", ed_model.module.env.home)
|
||||
}.fail()?
|
||||
}
|
||||
|
||||
let val_symbol = Symbol::new(ed_model.module.env.home, ident_id);
|
||||
|
||||
let patt2 = Pattern2::Identifier(val_symbol);
|
||||
let patt2_id = ed_model.module.env.pool.add(patt2);
|
||||
|
||||
let tld_mark_node = tld_mark_node(
|
||||
patt2_id,
|
||||
val_expr_mn_id,
|
||||
ast_node_id,
|
||||
&mut ed_model.mark_node_pool,
|
||||
&ed_model.module.env,
|
||||
&ed_model.loaded_module.interns
|
||||
)?;
|
||||
|
||||
let new_ast_node =
|
||||
Def2::ValueDef {
|
||||
identifier_id: patt2_id,
|
||||
expr_id: val_expr_id,
|
||||
};
|
||||
|
||||
ed_model.module.env.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);
|
||||
|
||||
// remove data corresponding to old 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);
|
||||
|
||||
ed_model.insert_all_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
&ed_model.mark_node_pool.get(curr_mark_node_id).get_children_ids(),
|
||||
)?;
|
||||
|
||||
Ok(InputOutcome::Accepted)
|
||||
}
|
||||
|
||||
pub fn update_tld_val_name(val_name_mn_id: MarkNodeId, old_caret_pos: TextPos, ed_model: &mut EdModel, new_char: &char) -> 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 old_val_name = content_str_mut.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);
|
||||
|
||||
// TODO no unwrap
|
||||
ed_model
|
||||
.module
|
||||
.env
|
||||
.ident_ids
|
||||
.update_key(&old_val_name, content_str_mut)
|
||||
.unwrap();
|
||||
|
||||
ed_model.insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
&new_char.to_string(),
|
||||
val_name_mn_id,
|
||||
)?;
|
||||
|
||||
ed_model.simple_move_caret_right(old_caret_pos, 1);
|
||||
|
||||
Ok(InputOutcome::Accepted)
|
||||
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
}
|
||||
} else {
|
||||
Ok(InputOutcome::Ignored)
|
||||
}
|
||||
}
|
|
@ -1017,14 +1017,12 @@ pub fn to_def2_from_def<'a>(
|
|||
Body(&loc_pattern, &loc_expr) => {
|
||||
// TODO loc_pattern use identifier
|
||||
let expr2 = loc_expr_to_expr2(arena, loc_expr, env, scope, region).0;
|
||||
dbg!(&expr2);
|
||||
let expr_id = env.pool.add(expr2);
|
||||
dbg!(expr_id);
|
||||
|
||||
use roc_parse::ast::Pattern::*;
|
||||
|
||||
match loc_pattern.value {
|
||||
Identifier(str_ref) => {
|
||||
Identifier(_) => {
|
||||
let (_, pattern2) = to_pattern2(
|
||||
env,
|
||||
scope,
|
||||
|
|
|
@ -32,6 +32,19 @@ impl ASTNodeId {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn to_def_id(&self) -> EdResult<DefId>{
|
||||
match self {
|
||||
ASTNodeId::ADefId(def_id) => {
|
||||
Ok(*def_id)
|
||||
},
|
||||
_ => {
|
||||
ASTNodeIdWithoutExprId {
|
||||
ast_node_id: *self
|
||||
}.fail()?
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#[derive(Debug)]
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue