aboutsummaryrefslogtreecommitdiff
path: root/rprt-engine/src
diff options
context:
space:
mode:
Diffstat (limited to 'rprt-engine/src')
-rw-r--r--rprt-engine/src/lib.rs4
-rw-r--r--rprt-engine/src/selection_function.rs242
-rw-r--r--rprt-engine/src/selection_functions/function_character.rs38
-rw-r--r--rprt-engine/src/selection_functions/function_empty.rs10
-rw-r--r--rprt-engine/src/selection_functions/function_end.rs37
-rw-r--r--rprt-engine/src/selection_functions/mod.rs5
-rw-r--r--rprt-engine/src/selection_functions/result_transformation.rs77
-rw-r--r--rprt-engine/src/selection_functions/types.rs78
8 files changed, 246 insertions, 245 deletions
diff --git a/rprt-engine/src/lib.rs b/rprt-engine/src/lib.rs
index 3eda2e4..8886578 100644
--- a/rprt-engine/src/lib.rs
+++ b/rprt-engine/src/lib.rs
@@ -1,10 +1,8 @@
-// RPRT Engine - Core text editing functionality
-
pub mod buffer;
pub mod expression;
pub mod monad;
pub mod parser;
pub mod selection;
-pub mod selection_function;
+pub mod selection_functions;
pub mod state;
pub mod token;
diff --git a/rprt-engine/src/selection_function.rs b/rprt-engine/src/selection_function.rs
deleted file mode 100644
index 95281ad..0000000
--- a/rprt-engine/src/selection_function.rs
+++ /dev/null
@@ -1,242 +0,0 @@
-use crate::buffer::BufferID;
-use crate::selection::{Interval, Selection, VectoriseError};
-use crate::state::EditorState;
-use thiserror::Error;
-
-#[derive(Error, Debug)]
-pub enum SFError {
- #[error("Could not find buffer {0}")]
- BufferNotFound(BufferID),
- #[error("Function {0} has no dyadic form")]
- NoDyadicForm(&'static str),
-}
-
-pub enum SFArguments<'a> {
- Niladic {
- es: &'a EditorState,
- },
- Monadic {
- es: &'a EditorState,
- left: Selection,
- },
- Dyadic {
- es: &'a EditorState,
- left: Selection,
- right: Selection,
- },
-}
-
-type SFResult = Result<Selection, VectoriseError<SFError>>;
-
-fn rust_has_an_annoying_issue(r: Result<Selection, SFError>) -> SFResult {
- r.map_err(Into::into)
-}
-
-macro_rules! selection_function {
- (
- name: $name:ident,
- niladic: $niladic_body:expr,
- monadic_rank0: $monadic_rank0_body:expr,
- monadic_rank1: $monadic_rank1_body:expr
- ) => {
- pub fn $name(arg: SFArguments) -> SFResult {
- match arg {
- SFArguments::Niladic { es } => rust_has_an_annoying_issue({ $niladic_body(es) }),
- SFArguments::Monadic { es, left } => {
- left.vectorise(es, $monadic_rank0_body, $monadic_rank1_body)
- }
- SFArguments::Dyadic { .. } => Err(SFError::NoDyadicForm(stringify!($name)).into()),
- }
- }
- };
-}
-
-macro_rules! selection_function_param {
- (
- name: $name:ident,
- param_type: $P:ty,
- niladic: $niladic_body:expr,
- monadic_rank0: $monadic_rank0_body:expr,
- monadic_rank1: $monadic_rank1_body:expr
- ) => {
- pub fn $name(param: $P, arg: SFArguments) -> SFResult {
- match arg {
- SFArguments::Niladic { es } => {
- rust_has_an_annoying_issue({ $niladic_body((param, es)) })
- }
- SFArguments::Monadic { es, left } => {
- left.vectorise(&(param, es), $monadic_rank0_body, $monadic_rank1_body)
- }
- SFArguments::Dyadic { .. } => Err(SFError::NoDyadicForm(stringify!($name)).into()),
- }
- }
- };
-}
-
-// ----------------------------------------------------------------
-pub fn complement_transform(es: &EditorState, result: Selection, _: &SFArguments) -> SFResult {
- fn complement_rank0(
- es: &EditorState,
- buffer_id: BufferID,
- pos: usize,
- ) -> Result<Selection, SFError> {
- if let Some(buf) = es.get_buffer(buffer_id) {
- let mut ranges = Vec::new();
- if pos > 0 {
- ranges.push(Interval::new(0, pos));
- }
- let max_pos = buf.max_pos();
- if pos + 1 < max_pos {
- ranges.push(Interval::new(pos + 1, max_pos));
- }
- Ok(Selection::Ranges { buffer_id, ranges })
- } else {
- Err(SFError::BufferNotFound(buffer_id))
- }
- }
-
- fn complement_rank1(
- es: &EditorState,
- buffer_id: BufferID,
- interval: &Interval,
- ) -> Result<Selection, SFError> {
- if let Some(buf) = es.get_buffer(buffer_id) {
- let max_pos = buf.max_pos();
- if interval.start == 0 && interval.end >= max_pos {
- return Ok(Selection::empty());
- }
-
- let mut ranges = Vec::new();
- if interval.start == 0 {
- if interval.end < max_pos {
- ranges.push(Interval::new(interval.end, max_pos));
- }
- } else if interval.end == max_pos {
- ranges.push(Interval::new(0, interval.start));
- } else {
- ranges.push(Interval::new(0, interval.start));
- ranges.push(Interval::new(interval.end, max_pos));
- }
- Ok(Selection::Ranges { buffer_id, ranges })
- } else {
- Err(SFError::BufferNotFound(buffer_id))
- }
- }
-
- result.vectorise(es, complement_rank0, complement_rank1)
-}
-
-pub fn conditional_transform(
- _: &EditorState,
- mut result: Selection,
- arg: &SFArguments,
-) -> SFResult {
- if !result.is_empty() {
- Ok(match arg {
- // TODO: think about this niladic case?
- SFArguments::Niladic { .. } => Selection::empty(),
- SFArguments::Monadic { es: _, left } => left.clone(),
- SFArguments::Dyadic {
- es: _,
- left,
- right: _,
- } => left.clone(),
- })
- } else {
- Ok(result)
- }
-}
-
-// ----------------------------------------------------------------
-
-pub fn empty_sequential(_: SFArguments) -> SFResult {
- Ok(Selection::empty())
-}
-
-pub fn empy_structural(_: SFArguments) -> SFResult {
- Ok(Selection::empty())
-}
-
-selection_function! {
- name: end_sequential,
- niladic: |es: &EditorState| {
- es.current_buffer().map(|buf| Selection::Position {
- buffer_id: es.current_buffer_id,
- pos: buf.max_pos()
- }).ok_or(SFError::BufferNotFound(es.current_buffer_id))
- },
- monadic_rank0: |_, buffer_id, pos| {
- Ok(Selection::Position { buffer_id, pos })
- },
- monadic_rank1: |_, buffer_id, interval| {
- Ok(Selection::Position {
- buffer_id,
- pos: interval.end,
- })
- }
-}
-
-selection_function! {
- name: end_structural,
- niladic: |es: &EditorState| {
- if let Some(buf) = es.current_buffer() {
- Ok(Selection::Position {
- buffer_id: es.current_buffer_id,
- pos: buf.max_pos(),
- })
- } else {
- Err(SFError::BufferNotFound(es.current_buffer_id).into())
- }
- },
- monadic_rank0: |_, buffer_id, pos | Ok(Selection::Position { buffer_id, pos }),
- monadic_rank1: |_, buffer_id, int | Ok(Selection::Position {
- buffer_id,
- pos: int.end,
- })
-}
-
-selection_function_param! {
- name: character_structural,
- param_type: usize,
- niladic: |(param, es): (usize, &EditorState)| {
- if let Some(buf) = es.current_buffer() {
- Ok(Selection::Position {
- buffer_id: es.current_buffer_id,
- pos: usize::min(param, buf.max_pos()),
- })
- } else {
- Err(SFError::BufferNotFound(es.current_buffer_id).into())
- }
- },
- monadic_rank0: |_, buffer_id, pos| Ok(Selection::Position {buffer_id, pos}),
- monadic_rank1: |(param, _), buffer_id, int| Ok(Selection::Position {buffer_id, pos: usize::min(int.end, *param)})
-}
-
-selection_function_param! {
- name: character_sequential,
- param_type: usize,
- niladic: |(param, es): (usize, &EditorState)| {
- if let Some(buf) = es.current_buffer() {
- Ok(Selection::Position {
- buffer_id: es.current_buffer_id,
- pos: usize::min(param, buf.max_pos()),
- })
- } else {
- Err(SFError::BufferNotFound(es.current_buffer_id).into())
- }
- },
- monadic_rank0: |(param, es), buffer_id, pos| {
- if let Some(buf) = es.get_buffer(buffer_id) {
- Ok(Selection::Position {buffer_id, pos: usize::min(pos+*param, buf.max_pos())})
- } else {
- Err(SFError::BufferNotFound(buffer_id).into())
- }
- },
- monadic_rank1: |(param, es), buffer_id, int| {
- if let Some(buf) = es.get_buffer(buffer_id) {
- Ok(Selection::Position {buffer_id, pos: usize::min(int.end+*param, buf.max_pos())})
- } else {
- Err(SFError::BufferNotFound(buffer_id).into())
- }
- }
-}
diff --git a/rprt-engine/src/selection_functions/function_character.rs b/rprt-engine/src/selection_functions/function_character.rs
new file mode 100644
index 0000000..3d9695f
--- /dev/null
+++ b/rprt-engine/src/selection_functions/function_character.rs
@@ -0,0 +1,38 @@
+use crate::selection::Selection;
+use crate::selection_function_param;
+use crate::selection_functions::types::{get_buffer, SFArguments, SFError, SFResult};
+use crate::state::EditorState;
+
+selection_function_param! {
+ name: character_structural,
+ param_type: usize,
+ niladic: |(param, es): (usize, &EditorState)| {
+ let buf = get_buffer(es, es.current_buffer_id)?;
+ Ok(Selection::Position {
+ buffer_id: es.current_buffer_id,
+ pos: usize::min(param, buf.max_pos())
+
+ }) },
+ monadic_rank0: |_, buffer_id, pos| Ok(Selection::Position {buffer_id, pos}),
+ monadic_rank1: |(param, _), buffer_id, int| Ok(Selection::Position {buffer_id, pos: usize::min(int.end, *param)})
+}
+
+selection_function_param! {
+ name: character_sequential,
+ param_type: usize,
+ niladic: |(param, es): (usize, &EditorState)| {
+ let buf = get_buffer(es, es.current_buffer_id)?;
+ Ok(Selection::Position {
+ buffer_id: es.current_buffer_id,
+ pos: usize::min(param, buf.max_pos()),
+ })
+ },
+ monadic_rank0: |(param, es), buffer_id, pos| {
+ let buf = get_buffer(es, buffer_id)?;
+ Ok(Selection::Position {buffer_id, pos: usize::min(pos+*param, buf.max_pos())})
+ },
+ monadic_rank1: |(param, es), buffer_id, int| {
+ let buf = get_buffer(es, buffer_id)?;
+ Ok(Selection::Position {buffer_id, pos: usize::min(int.end+*param, buf.max_pos())})
+ }
+}
diff --git a/rprt-engine/src/selection_functions/function_empty.rs b/rprt-engine/src/selection_functions/function_empty.rs
new file mode 100644
index 0000000..8290de3
--- /dev/null
+++ b/rprt-engine/src/selection_functions/function_empty.rs
@@ -0,0 +1,10 @@
+use crate::selection::Selection;
+use crate::selection_functions::types::{SFArguments, SFResult};
+
+pub fn empty_sequential(_: SFArguments) -> SFResult {
+ Ok(Selection::empty())
+}
+
+pub fn empy_structural(_: SFArguments) -> SFResult {
+ Ok(Selection::empty())
+}
diff --git a/rprt-engine/src/selection_functions/function_end.rs b/rprt-engine/src/selection_functions/function_end.rs
new file mode 100644
index 0000000..47cff79
--- /dev/null
+++ b/rprt-engine/src/selection_functions/function_end.rs
@@ -0,0 +1,37 @@
+use crate::selection::Selection;
+use crate::selection_function;
+use crate::selection_functions::types::{get_buffer, SFArguments, SFError, SFResult};
+use crate::state::EditorState;
+
+selection_function! {
+ name: end_sequential,
+ niladic: |es: &EditorState| {
+ let buf = get_buffer(es, es.current_buffer_id)?;
+ Ok(Selection::Position {
+ buffer_id: es.current_buffer_id,
+ pos: buf.max_pos()
+ })
+ },
+ monadic_rank0: |_, buffer_id, pos| {
+ Ok(Selection::Position { buffer_id, pos })
+ },
+ monadic_rank1: |_, buffer_id, interval| {
+ Ok(Selection::Position {
+ buffer_id,
+ pos: interval.end,
+ })
+ }
+}
+
+selection_function! {
+ name: end_structural,
+ niladic: |es: &EditorState| {
+ let buf = get_buffer(es, es.current_buffer_id)?;
+ Ok(Selection::Position {
+ buffer_id: es.current_buffer_id,
+ pos: buf.max_pos(),
+ })
+ },
+ monadic_rank0: |_, buffer_id, pos | Ok(Selection::Position { buffer_id, pos }),
+ monadic_rank1: |_, buffer_id, int | Ok(Selection::Position { buffer_id, pos: int.end })
+}
diff --git a/rprt-engine/src/selection_functions/mod.rs b/rprt-engine/src/selection_functions/mod.rs
new file mode 100644
index 0000000..3f64be4
--- /dev/null
+++ b/rprt-engine/src/selection_functions/mod.rs
@@ -0,0 +1,5 @@
+pub mod function_character;
+pub mod function_empty;
+pub mod function_end;
+pub mod result_transformation;
+pub mod types;
diff --git a/rprt-engine/src/selection_functions/result_transformation.rs b/rprt-engine/src/selection_functions/result_transformation.rs
new file mode 100644
index 0000000..89a071a
--- /dev/null
+++ b/rprt-engine/src/selection_functions/result_transformation.rs
@@ -0,0 +1,77 @@
+use crate::buffer::BufferID;
+use crate::selection::{Interval, Selection};
+use crate::selection_functions::types::{SFArguments, SFError, SFResult};
+use crate::state::EditorState;
+
+pub fn complement_transform(es: &EditorState, result: Selection, _: &SFArguments) -> SFResult {
+ fn complement_rank0(
+ es: &EditorState,
+ buffer_id: BufferID,
+ pos: usize,
+ ) -> Result<Selection, SFError> {
+ if let Some(buf) = es.get_buffer(buffer_id) {
+ let mut ranges = Vec::new();
+ if pos > 0 {
+ ranges.push(Interval::new(0, pos));
+ }
+ let max_pos = buf.max_pos();
+ if pos + 1 < max_pos {
+ ranges.push(Interval::new(pos + 1, max_pos));
+ }
+ Ok(Selection::Ranges { buffer_id, ranges })
+ } else {
+ Err(SFError::BufferNotFound(buffer_id))
+ }
+ }
+
+ fn complement_rank1(
+ es: &EditorState,
+ buffer_id: BufferID,
+ interval: &Interval,
+ ) -> Result<Selection, SFError> {
+ if let Some(buf) = es.get_buffer(buffer_id) {
+ let max_pos = buf.max_pos();
+ if interval.start == 0 && interval.end >= max_pos {
+ return Ok(Selection::empty());
+ }
+
+ let mut ranges = Vec::new();
+ if interval.start == 0 {
+ if interval.end < max_pos {
+ ranges.push(Interval::new(interval.end, max_pos));
+ }
+ } else if interval.end == max_pos {
+ ranges.push(Interval::new(0, interval.start));
+ } else {
+ ranges.push(Interval::new(0, interval.start));
+ ranges.push(Interval::new(interval.end, max_pos));
+ }
+ Ok(Selection::Ranges { buffer_id, ranges })
+ } else {
+ Err(SFError::BufferNotFound(buffer_id))
+ }
+ }
+
+ result.vectorise(es, complement_rank0, complement_rank1)
+}
+
+pub fn conditional_transform(
+ _: &EditorState,
+ mut result: Selection,
+ arg: &SFArguments,
+) -> SFResult {
+ if !result.is_empty() {
+ Ok(match arg {
+ // TODO: think about this niladic case?
+ SFArguments::Niladic { .. } => Selection::empty(),
+ SFArguments::Monadic { es: _, left } => left.clone(),
+ SFArguments::Dyadic {
+ es: _,
+ left,
+ right: _,
+ } => left.clone(),
+ })
+ } else {
+ Ok(result)
+ }
+}
diff --git a/rprt-engine/src/selection_functions/types.rs b/rprt-engine/src/selection_functions/types.rs
new file mode 100644
index 0000000..728d084
--- /dev/null
+++ b/rprt-engine/src/selection_functions/types.rs
@@ -0,0 +1,78 @@
+use crate::buffer::{Buffer, BufferID};
+use crate::selection::{Selection, VectoriseError};
+use crate::state::EditorState;
+use thiserror::Error;
+
+#[derive(Error, Debug)]
+pub enum SFError {
+ #[error("Could not find buffer {0}")]
+ BufferNotFound(BufferID),
+ #[error("Function {0} has no dyadic form")]
+ NoDyadicForm(&'static str),
+}
+
+pub enum SFArguments<'a> {
+ Niladic {
+ es: &'a EditorState,
+ },
+ Monadic {
+ es: &'a EditorState,
+ left: Selection,
+ },
+ Dyadic {
+ es: &'a EditorState,
+ left: Selection,
+ right: Selection,
+ },
+}
+
+pub type SFResult = Result<Selection, VectoriseError<SFError>>;
+
+#[macro_export]
+macro_rules! selection_function {
+ (
+ name: $name:ident,
+ niladic: $niladic_body:expr,
+ monadic_rank0: $monadic_rank0_body:expr,
+ monadic_rank1: $monadic_rank1_body:expr
+ ) => {
+ pub fn $name(arg: SFArguments) -> SFResult {
+ match arg {
+ SFArguments::Niladic { es } => $niladic_body(es),
+ SFArguments::Monadic { es, left } => {
+ left.vectorise(es, $monadic_rank0_body, $monadic_rank1_body)
+ }
+ SFArguments::Dyadic { .. } => Err(SFError::NoDyadicForm(stringify!($name)).into()),
+ }
+ }
+ };
+}
+
+#[macro_export]
+macro_rules! selection_function_param {
+ (
+ name: $name:ident,
+ param_type: $P:ty,
+ niladic: $niladic_body:expr,
+ monadic_rank0: $monadic_rank0_body:expr,
+ monadic_rank1: $monadic_rank1_body:expr
+ ) => {
+ pub fn $name(param: $P, arg: SFArguments) -> SFResult {
+ match arg {
+ SFArguments::Niladic { es } => $niladic_body((param, es)),
+ SFArguments::Monadic { es, left } => {
+ left.vectorise(&(param, es), $monadic_rank0_body, $monadic_rank1_body)
+ }
+ SFArguments::Dyadic { .. } => Err(SFError::NoDyadicForm(stringify!($name)).into()),
+ }
+ }
+ };
+}
+
+pub fn get_buffer(es: &EditorState, buffer_id: BufferID) -> Result<&Buffer, SFError> {
+ if let Some(buf) = es.get_buffer(buffer_id) {
+ Ok(buf)
+ } else {
+ Err(SFError::BufferNotFound(es.current_buffer_id))
+ }
+}