mirror of
https://github.com/roc-lang/roc.git
synced 2024-09-21 07:49:17 +03:00
newline bug fixes, restructuring
This commit is contained in:
parent
f5b30b71da
commit
91490044f6
@ -1,8 +1,8 @@
|
||||
use crate::ui::text::lines::Lines;
|
||||
use crate::ui::text::selection::Selection;
|
||||
use crate::ui::text::text_pos::TextPos;
|
||||
use crate::ui::ui_error::{OutOfBounds, UIResult};
|
||||
use crate::ui::util::slice_get;
|
||||
use crate::ui::ui_error::{OutOfBounds, UIResult, LineInsertionFailed};
|
||||
use crate::ui::util::{slice_get};
|
||||
use crate::ui::util::slice_get_mut;
|
||||
use bumpalo::collections::String as BumpString;
|
||||
use bumpalo::Bump;
|
||||
@ -15,21 +15,6 @@ pub struct CodeLines {
|
||||
}
|
||||
|
||||
impl CodeLines {
|
||||
pub fn from_str(code_str: &str) -> CodeLines {
|
||||
let mut lines: Vec<String> = code_str
|
||||
.split_inclusive('\n')
|
||||
.map(|s| s.to_owned())
|
||||
.collect();
|
||||
|
||||
if code_str.ends_with('\n') {
|
||||
lines.push(String::new());
|
||||
}
|
||||
|
||||
CodeLines {
|
||||
lines,
|
||||
nr_of_chars: code_str.len(),
|
||||
}
|
||||
}
|
||||
|
||||
pub fn insert_between_line(
|
||||
&mut self,
|
||||
@ -37,9 +22,25 @@ impl CodeLines {
|
||||
index: usize,
|
||||
new_str: &str,
|
||||
) -> UIResult<()> {
|
||||
let line_ref = slice_get_mut(line_nr, &mut self.lines)?;
|
||||
let nr_of_lines = self.lines.len();
|
||||
|
||||
line_ref.insert_str(index, new_str);
|
||||
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();
|
||||
|
||||
@ -61,6 +62,10 @@ impl CodeLines {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn push_empty_line(&mut self) -> UIResult<()> {
|
||||
self.insert_empty_line(self.lines.len())
|
||||
}
|
||||
|
||||
pub fn del_at_line(&mut self, line_nr: usize, index: usize) -> UIResult<()> {
|
||||
let line_ref = slice_get_mut(line_nr, &mut self.lines)?;
|
||||
|
||||
@ -71,6 +76,14 @@ impl CodeLines {
|
||||
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)?;
|
||||
@ -85,11 +98,11 @@ impl CodeLines {
|
||||
|
||||
// last column of last line
|
||||
pub fn end_txt_pos(&self) -> TextPos {
|
||||
let last_line = self.nr_of_lines() - 1;
|
||||
|
||||
let last_line_nr = self.nr_of_lines() - 1;
|
||||
|
||||
TextPos {
|
||||
line: last_line,
|
||||
column: self.line_len(last_line).unwrap(), // safe because we just calculated last_line
|
||||
line: last_line_nr,
|
||||
column: self.line_len(last_line_nr).unwrap(), // safe because we just calculated last_line
|
||||
}
|
||||
}
|
||||
|
||||
@ -100,6 +113,15 @@ impl CodeLines {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for CodeLines {
|
||||
fn default() -> Self {
|
||||
CodeLines {
|
||||
lines: Vec::new(),
|
||||
nr_of_chars: 0,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl Lines for CodeLines {
|
||||
fn get_line(&self, line_nr: usize) -> UIResult<&str> {
|
||||
let line_string = slice_get(line_nr, &self.lines)?;
|
||||
|
@ -9,7 +9,7 @@ use crate::editor::util::index_of;
|
||||
use crate::lang::parse::ASTNodeId;
|
||||
use crate::ui::text::selection::Selection;
|
||||
use crate::ui::text::text_pos::TextPos;
|
||||
use crate::ui::ui_error::{OutOfBounds, UIResult};
|
||||
use crate::ui::ui_error::{OutOfBounds, UIResult, LineInsertionFailed};
|
||||
use crate::ui::util::{slice_get, slice_get_mut};
|
||||
use snafu::OptionExt;
|
||||
use std::fmt;
|
||||
@ -22,20 +22,6 @@ pub struct GridNodeMap {
|
||||
}
|
||||
|
||||
impl GridNodeMap {
|
||||
pub fn new() -> GridNodeMap {
|
||||
GridNodeMap {
|
||||
lines: vec![vec![]],
|
||||
}
|
||||
}
|
||||
|
||||
pub fn add_to_line(&mut self, line_nr: usize, len: usize, node_id: MarkNodeId) -> UIResult<()> {
|
||||
let line_ref = slice_get_mut(line_nr, &mut self.lines)?;
|
||||
let mut new_cols_vec: Vec<MarkNodeId> = std::iter::repeat(node_id).take(len).collect();
|
||||
|
||||
line_ref.append(&mut new_cols_vec);
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn insert_between_line(
|
||||
&mut self,
|
||||
@ -44,10 +30,26 @@ impl GridNodeMap {
|
||||
len: usize,
|
||||
node_id: MarkNodeId,
|
||||
) -> UIResult<()> {
|
||||
let line_ref = slice_get_mut(line_nr, &mut self.lines)?;
|
||||
let new_cols_vec: Vec<MarkNodeId> = std::iter::repeat(node_id).take(len).collect();
|
||||
let nr_of_lines = self.lines.len();
|
||||
|
||||
line_ref.splice(index..index, new_cols_vec);
|
||||
if line_nr < nr_of_lines {
|
||||
let line_ref = slice_get_mut(line_nr, &mut self.lines)?;
|
||||
let new_cols_vec: Vec<MarkNodeId> = std::iter::repeat(node_id).take(len).collect();
|
||||
|
||||
line_ref.splice(index..index, new_cols_vec);
|
||||
} else if line_nr >= nr_of_lines {
|
||||
|
||||
for _ in 0..((line_nr - nr_of_lines) + 1) {
|
||||
self.push_empty_line()?;
|
||||
}
|
||||
|
||||
self.insert_between_line(line_nr, index, len, node_id)?;
|
||||
} else {
|
||||
LineInsertionFailed {
|
||||
line_nr,
|
||||
nr_of_lines,
|
||||
}.fail()?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
@ -67,10 +69,22 @@ impl GridNodeMap {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn del_at_line(&mut self, line_nr: usize, index: usize) -> UIResult<()> {
|
||||
pub fn push_empty_line(&mut self) -> UIResult<()> {
|
||||
self.insert_empty_line(self.lines.len())
|
||||
}
|
||||
|
||||
pub fn del_at_line(&mut self, line_nr: usize, column: usize) -> UIResult<()> {
|
||||
let line_ref = slice_get_mut(line_nr, &mut self.lines)?;
|
||||
|
||||
line_ref.remove(index);
|
||||
line_ref.remove(column);
|
||||
|
||||
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(())
|
||||
}
|
||||
@ -360,6 +374,14 @@ impl GridNodeMap {
|
||||
}
|
||||
}
|
||||
|
||||
impl Default for GridNodeMap {
|
||||
fn default() -> Self {
|
||||
GridNodeMap {
|
||||
lines: vec![Vec::new()],
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl fmt::Display for GridNodeMap {
|
||||
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
|
||||
for row in &self.lines {
|
||||
|
@ -175,6 +175,17 @@ impl MarkupNode {
|
||||
}
|
||||
}
|
||||
|
||||
// gets content and adds newline from newline_at_end
|
||||
pub fn get_full_content(&self) -> String {
|
||||
let mut full_content = self.get_content();
|
||||
|
||||
if self.has_newline_at_end() {
|
||||
full_content.push('\n')
|
||||
}
|
||||
|
||||
full_content
|
||||
}
|
||||
|
||||
pub fn get_content_mut(&mut self) -> EdResult<&mut String> {
|
||||
match self {
|
||||
MarkupNode::Nested { .. } => ExpectedTextNode {
|
||||
|
@ -70,8 +70,15 @@ pub fn init_model<'a>(
|
||||
)
|
||||
}?;
|
||||
|
||||
let code_lines = EdModel::build_code_lines_from_markup(&markup_ids, &mark_node_pool)?;
|
||||
let grid_node_map = EdModel::build_node_map_from_markup(&markup_ids, &mark_node_pool)?;
|
||||
let mut code_lines = CodeLines::default();
|
||||
let mut grid_node_map = GridNodeMap::default();
|
||||
|
||||
let mut line_nr = 0;
|
||||
let mut col_nr = 0;
|
||||
|
||||
for mark_node_id in &markup_ids {
|
||||
EdModel::insert_mark_node_between_line(&mut line_nr, &mut col_nr, *mark_node_id, &mut grid_node_map, &mut code_lines, &mark_node_pool)?
|
||||
}
|
||||
|
||||
let caret = match caret_pos {
|
||||
CaretPos::Start => CaretWSelect::default(),
|
||||
|
@ -6,7 +6,7 @@ use crate::editor::ed_error::EdResult;
|
||||
use crate::editor::ed_error::MissingSelection;
|
||||
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::common_nodes::new_blank_mn_w_nl;
|
||||
use crate::editor::markup::nodes;
|
||||
use crate::editor::markup::nodes::MarkupNode;
|
||||
use crate::editor::markup::nodes::EQUALS;
|
||||
@ -132,70 +132,10 @@ impl<'a> EdModel<'a> {
|
||||
}
|
||||
}
|
||||
|
||||
pub fn build_node_map_from_markup(
|
||||
markup_ids: &[MarkNodeId],
|
||||
mark_node_pool: &SlowPool,
|
||||
) -> EdResult<GridNodeMap> {
|
||||
let mut grid_node_map = GridNodeMap::new();
|
||||
let mut line_ctr = 0;
|
||||
|
||||
for mark_id in markup_ids.iter() {
|
||||
EdModel::build_grid_node_map(
|
||||
*mark_id,
|
||||
&mut grid_node_map,
|
||||
&mut line_ctr,
|
||||
mark_node_pool,
|
||||
)?;
|
||||
}
|
||||
|
||||
Ok(grid_node_map)
|
||||
}
|
||||
|
||||
pub fn add_mark_node(&mut self, node: MarkupNode) -> MarkNodeId {
|
||||
self.mark_node_pool.add(node)
|
||||
}
|
||||
|
||||
fn build_grid_node_map(
|
||||
node_id: MarkNodeId,
|
||||
grid_node_map: &mut GridNodeMap,
|
||||
line_ctr: &mut usize,
|
||||
mark_node_pool: &SlowPool,
|
||||
) -> EdResult<()> {
|
||||
let node = mark_node_pool.get(node_id);
|
||||
|
||||
if node.is_nested() {
|
||||
for child_id in node.get_children_ids() {
|
||||
EdModel::build_grid_node_map(child_id, grid_node_map, line_ctr, mark_node_pool)?;
|
||||
}
|
||||
} else {
|
||||
let node_content_str = node.get_content();
|
||||
|
||||
grid_node_map.add_to_line(*line_ctr, node_content_str.len(), node_id)?;
|
||||
}
|
||||
|
||||
if node.has_newline_at_end() {
|
||||
*line_ctr += 1;
|
||||
grid_node_map.lines.push(vec![]);
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn build_code_lines_from_markup(
|
||||
markup_node_ids: &[MarkNodeId],
|
||||
mark_node_pool: &SlowPool,
|
||||
) -> EdResult<CodeLines> {
|
||||
let mut all_code_string = String::new();
|
||||
|
||||
for mark_node_id in markup_node_ids.iter() {
|
||||
EdModel::build_markup_string(*mark_node_id, &mut all_code_string, mark_node_pool)?;
|
||||
}
|
||||
|
||||
let code_lines = CodeLines::from_str(&all_code_string);
|
||||
|
||||
Ok(code_lines)
|
||||
}
|
||||
|
||||
fn build_markup_string(
|
||||
node_id: MarkNodeId,
|
||||
all_code_string: &mut String,
|
||||
@ -222,39 +162,118 @@ impl<'a> EdModel<'a> {
|
||||
|
||||
// updates grid_node_map and code_lines but nothing else.
|
||||
pub fn insert_between_line(
|
||||
&mut self,
|
||||
line_nr: usize,
|
||||
index: usize,
|
||||
new_str: &str,
|
||||
node_id: MarkNodeId,
|
||||
grid_node_map: &mut GridNodeMap,
|
||||
code_lines: &mut CodeLines,
|
||||
) -> UIResult<()> {
|
||||
self.grid_node_map
|
||||
grid_node_map
|
||||
.insert_between_line(line_nr, index, new_str.len(), node_id)?;
|
||||
self.code_lines.insert_between_line(line_nr, index, new_str)
|
||||
code_lines
|
||||
.insert_between_line(line_nr, index, new_str)
|
||||
}
|
||||
|
||||
pub fn insert_all_between_line(
|
||||
&mut self,
|
||||
line_nr: usize,
|
||||
index: usize,
|
||||
node_ids: &[MarkNodeId],
|
||||
leaf_node_ids: &[MarkNodeId],
|
||||
) -> UIResult<()> {
|
||||
let mut col_nr = index;
|
||||
let mut curr_line_nr = line_nr;
|
||||
|
||||
for &node_id in node_ids {
|
||||
let node_content_str = self.mark_node_pool.get(node_id).get_content();
|
||||
for &node_id in leaf_node_ids {
|
||||
let mark_node = self.mark_node_pool.get(node_id);
|
||||
let node_content_str = mark_node.get_full_content();
|
||||
|
||||
self.grid_node_map.insert_between_line(
|
||||
line_nr,
|
||||
col_nr,
|
||||
node_content_str.len(),
|
||||
node_id,
|
||||
if node_content_str.contains('\n') {
|
||||
//insert seperate lines separately
|
||||
let split_lines = node_content_str.split_inclusive('\n');
|
||||
|
||||
for line in split_lines {
|
||||
|
||||
self.grid_node_map.insert_between_line(
|
||||
curr_line_nr,
|
||||
col_nr,
|
||||
line.len(),
|
||||
node_id,
|
||||
)?;
|
||||
|
||||
self.code_lines
|
||||
.insert_between_line(curr_line_nr, col_nr, line)?;
|
||||
|
||||
curr_line_nr += 1;
|
||||
col_nr = 0;
|
||||
}
|
||||
} else {
|
||||
self.grid_node_map.insert_between_line(
|
||||
line_nr,
|
||||
col_nr,
|
||||
node_content_str.len(),
|
||||
node_id,
|
||||
)?;
|
||||
|
||||
self.code_lines
|
||||
.insert_between_line(line_nr, col_nr, &node_content_str)?;
|
||||
|
||||
col_nr += node_content_str.len();
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn insert_mark_node_between_line(
|
||||
line_nr: &mut usize,
|
||||
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);
|
||||
let node_has_newline = mark_node.has_newline_at_end();
|
||||
|
||||
if mark_node.is_nested() {
|
||||
|
||||
let children_ids = mark_node.get_children_ids();
|
||||
|
||||
for child_id in children_ids {
|
||||
EdModel::insert_mark_node_between_line(
|
||||
line_nr,
|
||||
col_nr,
|
||||
child_id,
|
||||
grid_node_map,
|
||||
code_lines,
|
||||
mark_node_pool,
|
||||
)?;
|
||||
}
|
||||
|
||||
if node_has_newline {
|
||||
*line_nr += 1;
|
||||
*col_nr = 0;
|
||||
}
|
||||
} else {
|
||||
let node_content = mark_node.get_content();
|
||||
|
||||
EdModel::insert_between_line(
|
||||
*line_nr,
|
||||
*col_nr,
|
||||
&node_content,
|
||||
mark_node_id,
|
||||
grid_node_map,
|
||||
code_lines,
|
||||
)?;
|
||||
|
||||
self.code_lines
|
||||
.insert_between_line(line_nr, col_nr, &node_content_str)?;
|
||||
|
||||
col_nr += node_content_str.len();
|
||||
if node_has_newline {
|
||||
*line_nr += 1;
|
||||
*col_nr = 0;
|
||||
} else {
|
||||
*col_nr += node_content.len();
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
Ok(())
|
||||
@ -271,6 +290,24 @@ impl<'a> EdModel<'a> {
|
||||
self.code_lines.del_at_line(line_nr, index)
|
||||
}
|
||||
|
||||
// updates grid_node_map and code_lines but nothing else.
|
||||
pub fn del_range_at_line(&mut self, 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)
|
||||
}
|
||||
|
||||
pub fn del_blank_node(&mut self, txt_pos: TextPos, with_newline: bool) -> UIResult<()> {
|
||||
|
||||
let line_nr = txt_pos.line;
|
||||
let column = txt_pos.column;
|
||||
|
||||
if with_newline {
|
||||
self.del_range_at_line(line_nr, column..column + 2) // 1 for newline + 1 because range excludes end
|
||||
} else {
|
||||
self.del_at_line(line_nr, column)
|
||||
}
|
||||
}
|
||||
|
||||
pub fn set_selected_expr(
|
||||
&mut self,
|
||||
expr_start_pos: TextPos,
|
||||
@ -494,11 +531,13 @@ impl<'a> EdModel<'a> {
|
||||
if let Some(expr_mark_node_id) = expr_mark_node_id_opt {
|
||||
let caret_pos = self.get_caret();
|
||||
|
||||
self.insert_between_line(
|
||||
EdModel::insert_between_line(
|
||||
caret_pos.line,
|
||||
caret_pos.column,
|
||||
nodes::BLANK_PLACEHOLDER,
|
||||
expr_mark_node_id,
|
||||
&mut self.grid_node_map,
|
||||
&mut self.code_lines,
|
||||
)?;
|
||||
}
|
||||
|
||||
@ -1061,7 +1100,7 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
|
||||
ed_model.module.ast.def_ids.insert(prev_def_mn_id_indx, new_line_blank_id);
|
||||
|
||||
let blank_mn_id = ed_model
|
||||
.add_mark_node(new_blank_mn(ASTNodeId::ADefId(new_line_blank_id), None));
|
||||
.add_mark_node(new_blank_mn_w_nl(ASTNodeId::ADefId(new_line_blank_id), None));
|
||||
|
||||
ed_model.markup_ids.insert(prev_def_mn_id_indx + 1,blank_mn_id); // + 1 because first markup node is header
|
||||
|
||||
@ -1109,7 +1148,7 @@ pub fn handle_new_char(received_char: &char, ed_model: &mut EdModel) -> EdResult
|
||||
ed_model.module.ast.def_ids.insert(prev_def_mn_id_indx, new_blank_id);
|
||||
|
||||
let blank_mn_id = ed_model
|
||||
.add_mark_node(new_blank_mn(ASTNodeId::ADefId(new_blank_id), None));
|
||||
.add_mark_node(new_blank_mn_w_nl(ASTNodeId::ADefId(new_blank_id), None));
|
||||
|
||||
ed_model.markup_ids.insert(prev_def_mn_id_indx + 1,blank_mn_id); // + 1 because first mark_node is header
|
||||
|
||||
|
@ -65,11 +65,13 @@ pub fn start_new_int(ed_model: &mut EdModel, digit_char: &char) -> EdResult<Inpu
|
||||
ed_model.simple_move_carets_right(char_len);
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_between_line(
|
||||
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)
|
||||
@ -107,11 +109,13 @@ pub fn update_int(
|
||||
let content_str = int_mark_node.get_content();
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_between_line(
|
||||
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
|
||||
|
@ -93,7 +93,7 @@ pub fn start_new_let_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<
|
||||
.replace_node(curr_mark_node_id, val_mark_node);
|
||||
|
||||
// remove data corresponding to Blank node
|
||||
ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?;
|
||||
ed_model.del_blank_node(old_caret_pos, curr_mark_node_has_nl)?;
|
||||
|
||||
let char_len = 1;
|
||||
ed_model.simple_move_carets_right(char_len);
|
||||
|
@ -57,28 +57,32 @@ pub fn start_new_list(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
|
||||
};
|
||||
|
||||
if is_blank_node {
|
||||
|
||||
ed_model
|
||||
.mark_node_pool
|
||||
.replace_node(curr_mark_node_id, nested_node);
|
||||
|
||||
// remove data corresponding to Blank node
|
||||
ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?;
|
||||
ed_model.del_blank_node(old_caret_pos, curr_mark_node_has_nl)?;
|
||||
|
||||
ed_model.simple_move_carets_right(nodes::LEFT_SQUARE_BR.len());
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_between_line(
|
||||
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,
|
||||
)?;
|
||||
|
||||
ed_model.insert_between_line(
|
||||
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)
|
||||
@ -202,11 +206,13 @@ pub fn update_mark_children(
|
||||
|
||||
ed_model.simple_move_carets_right(nodes::COMMA.len());
|
||||
|
||||
ed_model.insert_between_line(
|
||||
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);
|
||||
@ -221,11 +227,13 @@ pub fn update_mark_children(
|
||||
};
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_between_line(
|
||||
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)
|
||||
|
@ -43,11 +43,13 @@ pub fn update_invalid_lookup(
|
||||
ed_model.simple_move_carets_right(input_str.len());
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_between_line(
|
||||
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)
|
||||
|
@ -59,8 +59,7 @@ pub fn start_new_record(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
|
||||
.mark_node_pool
|
||||
.replace_node(curr_mark_node_id, nested_node);
|
||||
|
||||
// remove data corresponding to Blank node
|
||||
ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?;
|
||||
ed_model.del_blank_node(old_caret_pos, curr_mark_node_has_nl)?;
|
||||
|
||||
ed_model.simple_move_carets_right(nodes::LEFT_ACCOLADE.len());
|
||||
|
||||
@ -148,11 +147,13 @@ pub fn update_empty_record(
|
||||
ed_model.simple_move_carets_right(1);
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_between_line(
|
||||
EdModel::insert_between_line(
|
||||
old_caret_pos.line,
|
||||
old_caret_pos.column,
|
||||
new_input,
|
||||
record_field_node_id,
|
||||
&mut ed_model.grid_node_map,
|
||||
&mut ed_model.code_lines,
|
||||
)?;
|
||||
|
||||
Ok(InputOutcome::Accepted)
|
||||
@ -326,11 +327,13 @@ pub fn update_record_field(
|
||||
ed_model.simple_move_carets_right(new_input.len());
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_between_line(
|
||||
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
|
||||
|
@ -62,11 +62,13 @@ pub fn update_small_string(
|
||||
content_str_mut.insert_str(node_caret_offset, new_input);
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_between_line(
|
||||
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
|
||||
@ -98,11 +100,13 @@ pub fn update_string(new_char: char, ed_model: &mut EdModel) -> EdResult<InputOu
|
||||
content_str_mut.insert(node_caret_offset, new_char);
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_between_line(
|
||||
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,
|
||||
)?;
|
||||
|
||||
// update ast
|
||||
@ -155,14 +159,16 @@ pub fn start_new_string(ed_model: &mut EdModel) -> EdResult<InputOutcome> {
|
||||
.replace_node(curr_mark_node_id, new_string_node);
|
||||
|
||||
// remove data corresponding to Blank node
|
||||
ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?;
|
||||
ed_model.del_blank_node(old_caret_pos, curr_mark_node_has_nl)?;
|
||||
|
||||
// update GridNodeMap and CodeLines
|
||||
ed_model.insert_between_line(
|
||||
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);
|
||||
|
@ -40,9 +40,6 @@ pub fn tld_mark_node<'a>(
|
||||
|
||||
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],
|
||||
@ -57,11 +54,13 @@ pub fn start_new_tld_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<
|
||||
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 curr_mark_node_has_nl = curr_mark_node.has_newline_at_end();
|
||||
|
||||
let val_expr_node = Expr2::Blank;
|
||||
let val_expr_id = ed_model.module.env.pool.add(val_expr_node);
|
||||
|
||||
@ -124,18 +123,21 @@ pub fn start_new_tld_value(ed_model: &mut EdModel, new_char: &char) -> EdResult<
|
||||
set_parent_for_all(curr_mark_node_id, &mut ed_model.mark_node_pool);
|
||||
|
||||
// remove data corresponding to old Blank node
|
||||
ed_model.del_at_line(old_caret_pos.line, old_caret_pos.column)?;
|
||||
ed_model.del_blank_node(old_caret_pos, curr_mark_node_has_nl)?;
|
||||
|
||||
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(),
|
||||
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)
|
||||
@ -177,11 +179,13 @@ pub fn update_tld_val_name(
|
||||
}
|
||||
|
||||
|
||||
ed_model.insert_between_line(
|
||||
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);
|
||||
|
@ -94,6 +94,7 @@ fn markup_to_wgpu_helper<'a>(
|
||||
txt_row_col: &mut (usize, usize),
|
||||
mark_node_pool: &'a SlowPool,
|
||||
) -> EdResult<()> {
|
||||
|
||||
match markup_node {
|
||||
MarkupNode::Nested {
|
||||
ast_node_id: _,
|
||||
@ -130,11 +131,7 @@ fn markup_to_wgpu_helper<'a>(
|
||||
} => {
|
||||
let highlight_color = map_get(&code_style.ed_theme.syntax_high_map, syn_high_style)?;
|
||||
|
||||
let mut full_content = content.to_owned();
|
||||
|
||||
if *newline_at_end {
|
||||
full_content.push('\n');
|
||||
}
|
||||
let full_content = markup_node.get_full_content();
|
||||
|
||||
let glyph_text = glyph_brush::OwnedText::new(full_content)
|
||||
.with_color(colors::to_slice(*highlight_color))
|
||||
@ -156,7 +153,10 @@ fn markup_to_wgpu_helper<'a>(
|
||||
parent_id_opt: _,
|
||||
newline_at_end,
|
||||
} => {
|
||||
let glyph_text = glyph_brush::OwnedText::new(BLANK_PLACEHOLDER)
|
||||
|
||||
let full_content = markup_node.get_full_content();
|
||||
|
||||
let glyph_text = glyph_brush::OwnedText::new(full_content)
|
||||
.with_color(colors::to_slice(colors::WHITE))
|
||||
.with_scale(code_style.font_size);
|
||||
|
||||
|
@ -185,7 +185,7 @@ pub fn move_caret_right<T: Lines>(
|
||||
let is_last_line = lines.is_last_line(old_line_nr);
|
||||
|
||||
if !is_last_line {
|
||||
if old_col_nr + 1 > curr_line_len - 1 {
|
||||
if old_col_nr + 2 > curr_line_len {
|
||||
(old_line_nr + 1, 0)
|
||||
} else {
|
||||
(old_line_nr, old_col_nr + 1)
|
||||
@ -260,10 +260,18 @@ pub fn move_caret_up<T: Lines>(
|
||||
} else if old_line_nr == 0 {
|
||||
(old_line_nr, 0)
|
||||
} else {
|
||||
|
||||
let prev_line_len = lines.line_len(old_line_nr - 1)?;
|
||||
|
||||
if prev_line_len <= old_col_nr {
|
||||
(old_line_nr - 1, prev_line_len - 1)
|
||||
let new_column =
|
||||
if prev_line_len > 0 {
|
||||
prev_line_len - 1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
(old_line_nr - 1, new_column)
|
||||
} else {
|
||||
(old_line_nr - 1, old_col_nr)
|
||||
}
|
||||
@ -331,7 +339,14 @@ pub fn move_caret_down<T: Lines>(
|
||||
|
||||
if next_line_len <= old_col_nr {
|
||||
if !is_last_line {
|
||||
(old_line_nr + 1, next_line_len - 1)
|
||||
let new_column =
|
||||
if next_line_len > 0 {
|
||||
next_line_len - 1
|
||||
} else {
|
||||
0
|
||||
};
|
||||
|
||||
(old_line_nr + 1, new_column)
|
||||
} else {
|
||||
(old_line_nr + 1, next_line_len)
|
||||
}
|
||||
|
@ -8,6 +8,12 @@ use snafu::{Backtrace, Snafu};
|
||||
#[derive(Debug, Snafu)]
|
||||
#[snafu(visibility(pub))]
|
||||
pub enum UIError {
|
||||
#[snafu(display("LineInsertionFailed: line_nr ({}) needs to be <= nr_of_lines ({}).", line_nr, nr_of_lines))]
|
||||
LineInsertionFailed {
|
||||
line_nr: usize,
|
||||
nr_of_lines: usize,
|
||||
backtrace: Backtrace,
|
||||
},
|
||||
#[snafu(display(
|
||||
"OutOfBounds: index {} was out of bounds for {} with length {}.",
|
||||
index,
|
||||
|
Loading…
Reference in New Issue
Block a user