Merge pull request #874 from rtfeldman/selection_tests

Text selection test DSL, many tests
This commit is contained in:
Richard Feldman 2021-01-06 22:10:14 -05:00 committed by GitHub
commit 93297c0051
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
9 changed files with 2151 additions and 34 deletions

2
Cargo.lock generated
View file

@ -2672,6 +2672,8 @@ dependencies = [
"log", "log",
"maplit", "maplit",
"page_size", "page_size",
"pest",
"pest_derive",
"pretty_assertions", "pretty_assertions",
"quickcheck", "quickcheck",
"quickcheck_macros", "quickcheck_macros",

View file

@ -66,6 +66,8 @@ cgmath = "0.17.0"
itertools = "0.9.0" itertools = "0.9.0"
snafu = { version = "0.6", features = ["backtraces"] } snafu = { version = "0.6", features = ["backtraces"] }
colored = "2" colored = "2"
pest = "2.1"
pest_derive = "2.1"
[dependencies.bytemuck] [dependencies.bytemuck]

View file

@ -55,8 +55,8 @@ These are potentially inspirational resources for the editor's design.
### Productivity features ### Productivity features
* When refactoring; * When refactoring;
- cutting and pasting code to a new file should automatically add imports to the new file and delete them from the old file. - Cutting and pasting code to a new file should automatically add imports to the new file and delete them from the old file.
- When renaming a function for example, references in comments should be brought to the user's attention. - Ability to link e.g. variable name in comments to actual variable name. Comment is automatically updated when variable name is changed.
* Automatically create all "arms" when pattern matching after entering `when var is` based on the type. * Automatically create all "arms" when pattern matching after entering `when var is` based on the type.
- All `when ... is` should be updated if the type is changed, e.g. adding Indigo to the Color type should add an arm everywhere where `when color is` is used. - All `when ... is` should be updated if the type is changed, e.g. adding Indigo to the Color type should add an arm everywhere where `when color is` is used.

View file

@ -8,6 +8,11 @@
// See this link to learn wgpu: https://sotrh.github.io/learn-wgpu/ // See this link to learn wgpu: https://sotrh.github.io/learn-wgpu/
extern crate pest;
#[cfg(test)]
#[macro_use]
extern crate pest_derive;
use crate::error::print_err; use crate::error::print_err;
use crate::graphics::lowlevel::buffer::create_rect_buffers; use crate::graphics::lowlevel::buffer::create_rect_buffers;
use crate::graphics::lowlevel::ortho::{init_ortho, update_ortho_buffer, OrthoResources}; use crate::graphics::lowlevel::ortho::{init_ortho, update_ortho_buffer, OrthoResources};

File diff suppressed because it is too large Load diff

View file

@ -15,7 +15,6 @@ pub fn init_model() -> Model {
} }
} }
//Is model.rs the right place for these structs?
#[derive(Debug, Copy, Clone)] #[derive(Debug, Copy, Clone)]
pub struct Position { pub struct Position {
pub line: usize, pub line: usize,

View file

@ -11,7 +11,12 @@ pub fn move_caret_left(
let old_line_nr = old_caret_pos.line; let old_line_nr = old_caret_pos.line;
let old_col_nr = old_caret_pos.column; let old_col_nr = old_caret_pos.column;
let (line_nr, col_nr) = if old_col_nr == 0 { let (line_nr, col_nr) = if old_selection_opt.is_some() && !shift_pressed {
match old_selection_opt {
Some(old_selection) => (old_selection.start_pos.line, old_selection.start_pos.column),
None => unreachable!(),
}
} else if old_col_nr == 0 {
if old_line_nr == 0 { if old_line_nr == 0 {
(0, 0) (0, 0)
} else if let Some(curr_line) = lines.get(old_line_nr - 1) { } else if let Some(curr_line) = lines.get(old_line_nr - 1) {
@ -30,6 +35,16 @@ pub fn move_caret_left(
let new_selection_opt = if shift_pressed { let new_selection_opt = if shift_pressed {
if let Some(old_selection) = old_selection_opt { if let Some(old_selection) = old_selection_opt {
if old_caret_pos >= old_selection.end_pos {
if new_caret_pos == old_selection.start_pos {
None
} else {
Some(RawSelection {
start_pos: old_selection.start_pos,
end_pos: new_caret_pos,
})
}
} else {
Some(RawSelection { Some(RawSelection {
start_pos: Position { start_pos: Position {
line: line_nr, line: line_nr,
@ -37,6 +52,7 @@ pub fn move_caret_left(
}, },
end_pos: old_selection.end_pos, end_pos: old_selection.end_pos,
}) })
}
} else if !(old_line_nr == line_nr && old_col_nr == col_nr) { } else if !(old_line_nr == line_nr && old_col_nr == col_nr) {
Some(RawSelection { Some(RawSelection {
start_pos: Position { start_pos: Position {
@ -67,7 +83,12 @@ pub fn move_caret_right(
let old_line_nr = old_caret_pos.line; let old_line_nr = old_caret_pos.line;
let old_col_nr = old_caret_pos.column; let old_col_nr = old_caret_pos.column;
let (line_nr, col_nr) = if let Some(curr_line) = lines.get(old_line_nr) { let (line_nr, col_nr) = if old_selection_opt.is_some() && !shift_pressed {
match old_selection_opt {
Some(old_selection) => (old_selection.end_pos.line, old_selection.end_pos.column),
None => unreachable!(),
}
} else if let Some(curr_line) = lines.get(old_line_nr) {
if let Some(last_char) = curr_line.chars().last() { if let Some(last_char) = curr_line.chars().last() {
if is_newline(&last_char) { if is_newline(&last_char) {
if old_col_nr + 1 > curr_line.len() - 1 { if old_col_nr + 1 > curr_line.len() - 1 {
@ -94,6 +115,16 @@ pub fn move_caret_right(
let new_selection_opt = if shift_pressed { let new_selection_opt = if shift_pressed {
if let Some(old_selection) = old_selection_opt { if let Some(old_selection) = old_selection_opt {
if old_caret_pos <= old_selection.start_pos {
if new_caret_pos == old_selection.end_pos {
None
} else {
Some(RawSelection {
start_pos: new_caret_pos,
end_pos: old_selection.end_pos,
})
}
} else {
Some(RawSelection { Some(RawSelection {
start_pos: old_selection.start_pos, start_pos: old_selection.start_pos,
end_pos: Position { end_pos: Position {
@ -101,6 +132,7 @@ pub fn move_caret_right(
column: col_nr, column: col_nr,
}, },
}) })
}
} else if !(old_line_nr == line_nr && old_col_nr == col_nr) { } else if !(old_line_nr == line_nr && old_col_nr == col_nr) {
Some(RawSelection { Some(RawSelection {
start_pos: Position { start_pos: Position {
@ -131,10 +163,15 @@ pub fn move_caret_up(
let old_line_nr = old_caret_pos.line; let old_line_nr = old_caret_pos.line;
let old_col_nr = old_caret_pos.column; let old_col_nr = old_caret_pos.column;
let (line_nr, col_nr) = if old_line_nr == 0 { let (line_nr, col_nr) = if old_selection_opt.is_some() && !shift_pressed {
(old_line_nr, old_col_nr) match old_selection_opt {
Some(old_selection) => (old_selection.start_pos.line, old_selection.start_pos.column),
None => unreachable!(),
}
} else if old_line_nr == 0 {
(old_line_nr, 0)
} else if let Some(prev_line) = lines.get(old_line_nr - 1) { } else if let Some(prev_line) = lines.get(old_line_nr - 1) {
if prev_line.len() < old_col_nr { if prev_line.len() <= old_col_nr {
(old_line_nr - 1, prev_line.len() - 1) (old_line_nr - 1, prev_line.len() - 1)
} else { } else {
(old_line_nr - 1, old_col_nr) (old_line_nr - 1, old_col_nr)
@ -150,10 +187,21 @@ pub fn move_caret_up(
let new_selection_opt = if shift_pressed { let new_selection_opt = if shift_pressed {
if let Some(old_selection) = old_selection_opt { if let Some(old_selection) = old_selection_opt {
if old_selection.end_pos <= old_caret_pos {
if new_caret_pos == old_selection.start_pos {
None
} else {
Some(RawSelection {
start_pos: min(old_selection.start_pos, new_caret_pos),
end_pos: max(old_selection.start_pos, new_caret_pos),
})
}
} else {
Some(RawSelection { Some(RawSelection {
start_pos: new_caret_pos, start_pos: new_caret_pos,
end_pos: old_selection.end_pos, end_pos: old_selection.end_pos,
}) })
}
} else if !(old_line_nr == line_nr && old_col_nr == col_nr) { } else if !(old_line_nr == line_nr && old_col_nr == col_nr) {
Some(RawSelection { Some(RawSelection {
start_pos: min(old_caret_pos, new_caret_pos), start_pos: min(old_caret_pos, new_caret_pos),
@ -178,10 +226,19 @@ pub fn move_caret_down(
let old_line_nr = old_caret_pos.line; let old_line_nr = old_caret_pos.line;
let old_col_nr = old_caret_pos.column; let old_col_nr = old_caret_pos.column;
let (line_nr, col_nr) = if old_line_nr + 1 >= lines.len() { let (line_nr, col_nr) = if old_selection_opt.is_some() && !shift_pressed {
(old_line_nr, old_col_nr) match old_selection_opt {
Some(old_selection) => (old_selection.end_pos.line, old_selection.end_pos.column),
None => unreachable!(),
}
} else if old_line_nr + 1 >= lines.len() {
if let Some(curr_line) = lines.get(old_line_nr) {
(old_line_nr, curr_line.len())
} else {
unreachable!()
}
} else if let Some(next_line) = lines.get(old_line_nr + 1) { } else if let Some(next_line) = lines.get(old_line_nr + 1) {
if next_line.len() < old_col_nr { if next_line.len() <= old_col_nr {
if let Some(last_char) = next_line.chars().last() { if let Some(last_char) = next_line.chars().last() {
if is_newline(&last_char) { if is_newline(&last_char) {
(old_line_nr + 1, next_line.len() - 1) (old_line_nr + 1, next_line.len() - 1)
@ -205,10 +262,21 @@ pub fn move_caret_down(
let new_selection_opt = if shift_pressed { let new_selection_opt = if shift_pressed {
if let Some(old_selection) = old_selection_opt { if let Some(old_selection) = old_selection_opt {
if old_caret_pos <= old_selection.start_pos {
if new_caret_pos == old_selection.end_pos {
None
} else {
Some(RawSelection {
start_pos: min(old_selection.end_pos, new_caret_pos),
end_pos: max(old_selection.end_pos, new_caret_pos),
})
}
} else {
Some(RawSelection { Some(RawSelection {
start_pos: old_selection.start_pos, start_pos: old_selection.start_pos,
end_pos: new_caret_pos, end_pos: new_caret_pos,
}) })
}
} else if !(old_line_nr == line_nr && old_col_nr == col_nr) { } else if !(old_line_nr == line_nr && old_col_nr == col_nr) {
Some(RawSelection { Some(RawSelection {
start_pos: min(old_caret_pos, new_caret_pos), start_pos: min(old_caret_pos, new_caret_pos),

View file

@ -1,5 +1,5 @@
pub fn is_newline(char_ref: &char) -> bool { pub fn is_newline(char_ref: &char) -> bool {
let newline_codes = vec!['\u{d}']; let newline_codes = vec!['\u{d}', '\n'];
newline_codes.contains(char_ref) newline_codes.contains(char_ref)
} }

View file

@ -0,0 +1,11 @@
text = { (ASCII_ALPHANUMERIC | " " | "\t" | "\n")* }
caret = {"|"}
optSelStart = { "["{0,1} }
optSelEnd = { "]"{0,1} }
optCaret = { caret{0,1} }
linesWithSelect = { SOI ~ text ~ optCaret ~ text ~ optSelStart ~ text ~ optCaret ~ text ~ optCaret ~ text ~ optSelEnd ~ text ~ optCaret ~ text ~ EOI}