use crate::{ buffer::BufferID, expression::SearchModifier, selection::{Interval, Selection}, selection_functions::types::{ SelectionFunction, SelectionFunctionError, UnparameterisedSelectionFunction, get_buffer, }, state::EditorState, }; pub struct End; impl UnparameterisedSelectionFunction for End { const NAME: &'static str = "end"; fn niladic(&self, es: &EditorState) -> Result { let buf = get_buffer(es, es.current_buffer_id)?; Ok(Selection::Scalar { buffer_id: es.current_buffer_id, pos: buf.max_pos(), }) } fn monadic_rank0( &self, _es: &EditorState, buffer_id: BufferID, pos: usize, ) -> Result { Ok(Selection::Scalar { buffer_id, pos }) } fn monadic_rank1( &self, _es: &EditorState, buffer_id: BufferID, interval: &Interval, ) -> Result { Ok(Selection::Scalar { buffer_id, pos: interval.end, }) } } pub struct ReverseEnd; impl UnparameterisedSelectionFunction for ReverseEnd { const NAME: &'static str = "reverse_end"; fn niladic(&self, es: &EditorState) -> Result { Ok(Selection::Scalar { buffer_id: es.current_buffer_id, pos: 0, }) } fn monadic_rank0( &self, _es: &EditorState, buffer_id: BufferID, pos: usize, ) -> Result { Ok(Selection::Scalar { buffer_id, pos }) } fn monadic_rank1( &self, _es: &EditorState, buffer_id: BufferID, interval: &Interval, ) -> Result { Ok(Selection::Scalar { buffer_id, pos: interval.start, }) } } pub struct SequentialEnd; impl UnparameterisedSelectionFunction for SequentialEnd { const NAME: &'static str = "sequential_end"; fn niladic(&self, _es: &EditorState) -> Result { Err(SelectionFunctionError::NoNiladicForm(";$")) } fn monadic_rank0( &self, es: &EditorState, buffer_id: BufferID, _pos: usize, ) -> Result { 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 { let buf = get_buffer(es, buffer_id)?; Ok(Selection::Scalar { buffer_id, pos: buf.max_pos(), }) } } pub struct SequentialReverseEnd; impl UnparameterisedSelectionFunction for SequentialReverseEnd { const NAME: &'static str = "sequential_reverse_end"; fn niladic(&self, _es: &EditorState) -> Result { Err(SelectionFunctionError::NoNiladicForm(";'$")) } fn monadic_rank0( &self, _es: &EditorState, buffer_id: BufferID, pos: usize, ) -> Result { Ok(Selection::Scalar { buffer_id, pos }) } fn monadic_rank1( &self, _es: &EditorState, buffer_id: BufferID, interval: &Interval, ) -> Result { Ok(Selection::Scalar { buffer_id, pos: interval.end, }) } } pub struct ReverseSequentialEnd; impl UnparameterisedSelectionFunction for ReverseSequentialEnd { const NAME: &'static str = "reverse_sequential_end"; fn niladic(&self, _es: &EditorState) -> Result { Err(SelectionFunctionError::NoNiladicForm("';$")) } fn monadic_rank0( &self, _es: &EditorState, buffer_id: BufferID, pos: usize, ) -> Result { Ok(Selection::Scalar { buffer_id, pos }) } fn monadic_rank1( &self, _es: &EditorState, buffer_id: BufferID, interval: &Interval, ) -> Result { Ok(Selection::Scalar { buffer_id, pos: interval.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, ) -> Result { 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), } }