diff options
Diffstat (limited to 'rprt-engine/src/selection_functions/function_end.rs')
| -rw-r--r-- | rprt-engine/src/selection_functions/function_end.rs | 204 |
1 files changed, 156 insertions, 48 deletions
diff --git a/rprt-engine/src/selection_functions/function_end.rs b/rprt-engine/src/selection_functions/function_end.rs index 75b4c96..ad161d2 100644 --- a/rprt-engine/src/selection_functions/function_end.rs +++ b/rprt-engine/src/selection_functions/function_end.rs @@ -1,57 +1,142 @@ use crate::{ - dispatch_selection_function, - selection::Selection, - selection_function, - selection_functions::types::{SFArguments, SFError, SFResult, get_buffer}, + buffer::BufferID, + expression::SearchModifier, + selection::{Interval, Selection}, + selection_functions::types::{ + SelectionFunction, SelectionFunctionError, UnparameterisedSelectionFunction, get_buffer, + }, state::EditorState, }; -selection_function! { - name: end, - param_type: (), - niladic: |(_, es): ((), &EditorState)| { +pub struct End; + +impl UnparameterisedSelectionFunction for End { + const NAME: &'static str = "end"; + + fn niladic(&self, es: &EditorState) -> Result<Selection, SelectionFunctionError> { let buf = get_buffer(es, es.current_buffer_id)?; Ok(Selection::Scalar { buffer_id: es.current_buffer_id, pos: buf.max_pos(), }) - }, - monadic_rank0: |_, buffer_id, pos | Ok(Selection::Scalar { buffer_id, pos }), - monadic_rank1: |_, buffer_id, int | Ok(Selection::Scalar { buffer_id, pos: int.end }) + } + + fn monadic_rank0( + &self, + _es: &EditorState, + buffer_id: BufferID, + pos: usize, + ) -> Result<Selection, SelectionFunctionError> { + Ok(Selection::Scalar { buffer_id, pos }) + } + + fn monadic_rank1( + &self, + _es: &EditorState, + buffer_id: BufferID, + interval: &Interval, + ) -> Result<Selection, SelectionFunctionError> { + Ok(Selection::Scalar { + buffer_id, + pos: interval.end, + }) + } } -selection_function! { - name: reverse_end, - param_type: (), - niladic: |(_, es): ((), &EditorState)| { +pub struct ReverseEnd; + +impl UnparameterisedSelectionFunction for ReverseEnd { + const NAME: &'static str = "reverse_end"; + + fn niladic(&self, es: &EditorState) -> Result<Selection, SelectionFunctionError> { Ok(Selection::Scalar { buffer_id: es.current_buffer_id, pos: 0, }) - }, - monadic_rank0: |_, buffer_id, pos | Ok(Selection::Scalar { buffer_id, pos }), - monadic_rank1: |_, buffer_id, int | Ok(Selection::Scalar { buffer_id, pos: int.start }) + } + + fn monadic_rank0( + &self, + _es: &EditorState, + buffer_id: BufferID, + pos: usize, + ) -> Result<Selection, SelectionFunctionError> { + Ok(Selection::Scalar { buffer_id, pos }) + } + + fn monadic_rank1( + &self, + _es: &EditorState, + buffer_id: BufferID, + interval: &Interval, + ) -> Result<Selection, SelectionFunctionError> { + Ok(Selection::Scalar { + buffer_id, + pos: interval.start, + }) + } } -selection_function! { - name: sequential_end, - param_type: (), - niladic: |_| Err(SFError::NoNiladicForm(";$").into()), - monadic_rank0: |_, buffer_id, pos| Ok(Selection::Scalar { buffer_id, pos }), - monadic_rank1: |(_, es), buffer_id, _| { +pub struct SequentialEnd; + +impl UnparameterisedSelectionFunction for SequentialEnd { + const NAME: &'static str = "sequential_end"; + + fn niladic(&self, _es: &EditorState) -> Result<Selection, SelectionFunctionError> { + Err(SelectionFunctionError::NoNiladicForm(";$")) + } + + fn monadic_rank0( + &self, + es: &EditorState, + buffer_id: BufferID, + _pos: usize, + ) -> Result<Selection, SelectionFunctionError> { + let buf = get_buffer(es, buffer_id)?; + Ok(Selection::Scalar { + buffer_id, + pos: buf.max_pos(), + }) + } + + fn monadic_rank1( + &self, + es: &EditorState, + buffer_id: BufferID, + _interval: &Interval, + ) -> Result<Selection, SelectionFunctionError> { let buf = get_buffer(es, buffer_id)?; - Ok(Selection::Scalar { buffer_id, pos: buf.max_pos() }) + Ok(Selection::Scalar { + buffer_id, + pos: buf.max_pos(), + }) } } -selection_function! { - name: sequential_reverse_end, - param_type: (), - niladic: |_| Err(SFError::NoNiladicForm(";'$").into()), - monadic_rank0: |_, buffer_id, pos| { +pub struct SequentialReverseEnd; + +impl UnparameterisedSelectionFunction for SequentialReverseEnd { + const NAME: &'static str = "sequential_reverse_end"; + + fn niladic(&self, _es: &EditorState) -> Result<Selection, SelectionFunctionError> { + Err(SelectionFunctionError::NoNiladicForm(";'$")) + } + + fn monadic_rank0( + &self, + _es: &EditorState, + buffer_id: BufferID, + pos: usize, + ) -> Result<Selection, SelectionFunctionError> { Ok(Selection::Scalar { buffer_id, pos }) - }, - monadic_rank1: |_, buffer_id, interval| { + } + + fn monadic_rank1( + &self, + _es: &EditorState, + buffer_id: BufferID, + interval: &Interval, + ) -> Result<Selection, SelectionFunctionError> { Ok(Selection::Scalar { buffer_id, pos: interval.end, @@ -59,14 +144,30 @@ selection_function! { } } -selection_function! { - name: reverse_sequential_end, - param_type: (), - niladic: |_| Err(SFError::NoNiladicForm("';$").into()), - monadic_rank0: |_, buffer_id, pos| { +pub struct ReverseSequentialEnd; + +impl UnparameterisedSelectionFunction for ReverseSequentialEnd { + const NAME: &'static str = "reverse_sequential_end"; + + fn niladic(&self, _es: &EditorState) -> Result<Selection, SelectionFunctionError> { + Err(SelectionFunctionError::NoNiladicForm("';$")) + } + + fn monadic_rank0( + &self, + _es: &EditorState, + buffer_id: BufferID, + pos: usize, + ) -> Result<Selection, SelectionFunctionError> { Ok(Selection::Scalar { buffer_id, pos }) - }, - monadic_rank1: |_, buffer_id, interval| { + } + + fn monadic_rank1( + &self, + _es: &EditorState, + buffer_id: BufferID, + interval: &Interval, + ) -> Result<Selection, SelectionFunctionError> { Ok(Selection::Scalar { buffer_id, pos: interval.end, @@ -74,12 +175,19 @@ selection_function! { } } -dispatch_selection_function!( - name: selection_function_end, - param_type: (), - base: end, - sequential: sequential_end, - reverse: reverse_end, - sequential_reverse: sequential_reverse_end, - reverse_sequential: reverse_sequential_end, -); +/// Dispatch on the search modifier and apply the matching end-family +/// function to the supplied selections. +pub fn selection_function_end( + es: &EditorState, + left: Option<&Selection>, + right: Option<&Selection>, + search_mod: Option<SearchModifier>, +) -> Result<Selection, SelectionFunctionError> { + match search_mod { + None => End.apply(&(), es, left, right), + Some(SearchModifier::Sequential) => SequentialEnd.apply(&(), es, left, right), + Some(SearchModifier::Reverse) => ReverseEnd.apply(&(), es, left, right), + Some(SearchModifier::SequentialReverse) => SequentialReverseEnd.apply(&(), es, left, right), + Some(SearchModifier::ReverseSequential) => ReverseSequentialEnd.apply(&(), es, left, right), + } +} |
