Cursor

Struct Cursor 

Source
pub struct Cursor<'a, W: Widget + ?Sized = Buffer, S = ()> { /* private fields */ }
Expand description

A selection that can edit Text, but can’t alter selections

This struct will be used only inside functions passed to the edit_* family of methods from the Handle.

To make edits, you can use three different functions. You can, those being replace, insert, and append. replace will completely replace the Selection’s selection. insert will place text behind the caret, and append will place it after the caret.

You can also move the Selection’s selection in many different ways, which are described below, in the impl section for this struct.

let sel: String = handle.edit_main(&mut pa, |mut c| {
    c.set_anchor();
    c.set_caret_on_end();
    c.replace("my replacement");
    c.append(" and my edit");

    c.swap_ends();
    c.insert("This is ");
    c.swap_ends();

    c.move_hor(" and my edit".chars().count() as i32);
    c.set_anchor();
    c.move_hor(-("This is my replacement and my edit".chars().count() as i32));
    c.selection().into_iter().collect()
});

assert_eq!(&sel, "This is my replacement and my edit");

Implementations§

Source§

impl<'a, W: Widget + ?Sized, S> Cursor<'a, W, S>

Source

pub fn replace(&mut self, edit: impl ToString)

Replaces the entire selection with new text

If there is a selection, then it is treated as inclusive, therefore, a selection where caret == anchor will remove the character where the caret is. If there is no selection, then this has the same effect as insert. If you wish to append to the caret instead, see append.

After replacing the sele tion, if the caret is behind the anchor (or in the same spot), it will be placed on the start of the selection, while the anchor will be placed on the new end. If it is ahead, it will be placed ahead.

Source

pub fn insert(&mut self, edit: impl ToString)

Inserts new text directly behind the caret

If the anchor is ahead of the caret, it will move forwards by the number of chars in the new text.

If you wish to replace the selected text, see replace, if you want to append after the caret instead, see append

Source

pub fn append(&mut self, edit: impl ToString)

Appends new text directly after the caret

If the anchor is ahead of the caret, it will move forwards by the number of chars in the new text.

If you wish to replace the selected text, see replace, if you want to insert before the caret instead, see insert

Source

pub fn move_hor(&mut self, count: i32) -> i32

Moves the selection horizontally. May cause vertical movement

Returns the distance moved in chars.

Source

pub fn move_ver(&mut self, count: i32) -> i32

Moves the selection vertically. May cause horizontal movement

Returns the distance moved in lines.

Source

pub fn move_ver_wrapped(&mut self, count: i32)

Moves the selection vertically a number of wrapped lines. May cause horizontal movement

Returns the distance moved in wrapped lines.

Source

pub fn move_to(&mut self, point_or_points: impl CaretOrRange)

Moves the selection to a Point or a range of Points

If you give it just a Point, it will move the caret, without affecting the anchor. If you give it a range of Points, the anchor will be placed at the start, while the caret will be placed at the end of said range. You can flip those positions with a function like swap_ends.

If a Point is not valid, it will be corrected and clamped to the lenght of the Text.

Source

pub fn move_to_start(&mut self)

Moves the selection to Point::default, i.c., the start of the Text

Source

pub fn move_to_coords(&mut self, line: usize, col: usize)

Moves the selection to a line and a column

  • If the coords isn’t valid, it will move to the “maximum” position allowed.
Source

pub fn move_to_col(&mut self, col: usize)

Moves to a column on the current line

Source

pub fn unset_anchor(&mut self) -> Option<Point>

Returns and takes the anchor of the Selection.

Source

pub fn set_anchor(&mut self)

Sets the anchor to the current caret

Source

pub fn set_anchor_if_needed(&mut self) -> bool

Sets the anchor if it was not already set

Returns true if the anchor was set by this command.

Source

pub fn swap_ends(&mut self)

Swaps the position of the caret and anchor

Source

pub fn set_caret_on_start(&mut self) -> bool

Sets the caret of the Selection on the start of the selection

Returns true if a swap occurred

Source

pub fn set_caret_on_end(&mut self) -> bool

Sets the caret of the Selection on the end of the selection

Returns true if a swap occurred

Source

pub fn reset(&mut self)

Resets the Selection to how it was before being modified

Source

pub fn copy(&mut self) -> Cursor<'_, W, S>

Copies the current Selection in place

This will leave an additional Selection with the current selection. Do note that normal intersection rules apply, so if at the end of the movement, this selection intersects with any other, they will be merged into one.

When this Cursor is dropped, like with normal Cursors, its Selection will be added to the Selections, unless you destroy it.

Source

pub fn destroy(self)

Destroys the current Selection

Will not destroy it if it is the last Selection left

If this was the main selection, the main selection will now be the selection immediately behind it.

Source

pub fn set_desired_vcol(&mut self, x: usize)

Sets the “desired visual column”

The desired visual column determines at what point in a line the caret will be placed when moving up and down through lines of varying lengths.

Will also set the “desired wrapped visual column”, which is the same thing but used when moving vertically in a wrapped fashion.

Source

pub fn chars_fwd(&self) -> impl Iterator<Item = (Point, char)> + '_

Iterates over the chars

This iteration will begin on the caret. It will also include the Point of each char

Source

pub fn chars_rev(&self) -> impl Iterator<Item = (Point, char)>

Iterates over the chars, in reverse

This iteration will begin on the caret. It will also include the Point of each char

Source

pub fn matches<R: RegexPattern>(&self, pat: R) -> bool

Wether the current selection matches a regex pattern

Source

pub fn search_fwd<R: RegexPattern>( &self, pat: R, ) -> impl Iterator<Item = R::Match> + '_

Searches the Text for a regex

The search will begin on the caret and returns the Range<usize> for the match, where the bounding usizes represents a byte index, and can be directly used in, for example, Cursor::move_to.

fn search_nth(pa: &mut Pass, handle: &Handle, n: usize, pat: &str) {
    handle.edit_all(pa, |mut c| {
        let mut nth = c.search_fwd(pat).nth(n);
        if let Some(range) = nth {
            c.move_to(range);
        }
    })
}
§Panics

If the regex is not valid, this method will panic.

Source

pub fn search_fwd_until<R: RegexPattern>( &self, pat: R, until: impl TextIndex, ) -> impl Iterator<Item = R::Match> + '_

Searches the Text for a regex, with an upper limit

The search will begin on the caret and returns the Range<usize> for the match, where the bounding usizes represents a byte index, and can be directly used in, for example, Cursor::move_to.

fn find_within(pa: &mut Pass, handle: &Handle, pat: &str) {
    handle.edit_all(pa, |mut c| {
        c.set_caret_on_start();
        let mut range = c.search_fwd_until(pat, c.range().end).next();
        if let Some(range) = range {
            c.move_to(range);
        }
    })
}
§Panics

If the regex is not valid, this method will panic.

Source

pub fn search_fwd_excl<R: RegexPattern>( &self, pat: R, ) -> impl Iterator<Item = R::Match> + '_

Searches the Text for a regex, skipping the caret’s character

The search will begin one character afer the caret and returns the Range<usize> for the match, where the bounding usizes represents a byte index, and can be directly used in, for example, Cursor::move_to.

fn next_paren_match(pa: &mut Pass, handle: &Handle) {
    handle.edit_all(pa, |mut c| {
        let mut start_count = 0;
        let mut start_bound = None;
        let end_bound = c.search_fwd_excl([r"\(", r"\)"]).find(|(id, range)| {
            start_count += ((*id == 0) as u32).saturating_sub((*id == 1) as u32);
            start_bound = (*id == 0 && start_count == 0).then_some(range.clone());
            start_count == 0 && *id == 1
        });

        if let (Some(start), Some((_, end))) = (start_bound, end_bound) {
            c.move_to(start.start..end.end);
        }
    })
}
§Panics

If the regex is not valid, this method will panic.

Source

pub fn search_fwd_excl_until<R: RegexPattern>( &self, pat: R, until: impl TextIndex, ) -> impl Iterator<Item = R::Match> + '_

Searches the Text for a regex, with an upper limit and skipping the caret’s character

The search will begin one character afer the caret and returns the Range<usize> for the match, where the bounding usizes represents a byte index, and can be directly used in, for example, Cursor::move_to.

#[derive(Clone, Copy)]
enum Action {
    Move,
    Select,
    Delete,
    Change,
}

fn f_key_from_vim(pa: &mut Pass, handle: &Handle, char: char, n: usize, action: Action) {
    handle.edit_all(pa, |mut c| {
        let line_end = c.search_fwd('\n').next().unwrap();
        let mut nth = c.search_fwd_excl_until(char, line_end.start).nth(n);

        match (nth, action) {
            (Some(range), Action::Move) => {
                c.unset_anchor();
                c.move_to(range.start);
            }
            (Some(range), Action::Select) => {
                c.set_anchor_if_needed();
                c.move_to(range.start);
            }
            (Some(range), Action::Delete | Action::Change) => {
                c.set_anchor_if_needed();
                c.move_to(range.start);
                c.replace("");
            }
            _ => {}
        }
    });

    if let Action::Change = action {
        mode::set(Insert);
    }
}
§Panics

If the regex is not valid, this method will panic.

Source

pub fn search_rev<R: RegexPattern>( &self, pat: R, ) -> impl Iterator<Item = R::Match> + '_

Searches the Text for a regex, in reverse

The search will begin on the caret and returns the Range<usize> for the match, where the bounding usizes represents a byte index, and can be directly used in, for example, Cursor::move_to.

fn remove_prefix(pa: &mut Pass, handle: &Handle) {
    let prefix_pat = format!(r"{}*\z", handle.opts(pa).word_chars_regex());
    handle.edit_all(pa, |mut c| {
        let prefix_range = c.search_rev(&prefix_pat).next();
        if let Some(range) = prefix_range {
            c.move_to(range);
            c.replace("");
        }
    })
}
§Panics

If the regex is not valid, this method will panic.

Source

pub fn search_rev_until<R: RegexPattern>( &self, pat: R, until: impl TextIndex, ) -> impl Iterator<Item = R::Match> + '_

Searches the Text for a regex, in reverse, until a given point

The search will begin on the caret and returns the Range<usize> for the match, where the bounding usizes represents a byte index, and can be directly used in, for example, Cursor::move_to.

fn search_before_but_after_prev(pa: &mut Pass, handle: &Handle, pat: &str) {
    let mut last_end = 0;
    handle.edit_all(pa, |mut c| {
        let mut nth = c.search_rev_until(pat, last_end).next();
        if let Some(range) = nth {
            c.move_to(range)
        }
        last_end = c.range().end.byte();
    })
}
§Panics

If the regex is not valid, this method will panic.

Source

pub fn search_rev_incl<R: RegexPattern>( &self, pat: R, ) -> impl Iterator<Item = R::Match> + '_

Searches the Text for a regex, in reverse, including the caret’s character

The search will begin on the character right after the caret and returns the Range<usize> for the match, where the bounding usizes represents a byte index, and can be directly used in, for example, Cursor::move_to.

fn last_word_in_selection(pa: &mut Pass, handle: &Handle) {
    let word_pat = format!(r"{}+", handle.opts(pa).word_chars_regex());
    handle.edit_all(pa, |mut c| {
        c.set_caret_on_end();
        let mut nth = c.search_rev_incl(&word_pat).next();
        if let Some(range) = nth {
            c.move_to(range)
        } else {
            c.reset()
        }
    })
}
§Panics

If the regex is not valid, this method will panic.

Source

pub fn search_rev_incl_until<R: RegexPattern>( &self, pat: R, until: impl TextIndex, ) -> impl Iterator<Item = R::Match> + '_

Searches the Text for a regex, in reverse, including the caret’s character, until a given point

The search will begin on the character right after the caret and returns the Range<usize> for the match, where the bounding usizes represents a byte index, and can be directly used in, for example, Cursor::move_to.

fn last_word_limited_to_selection(pa: &mut Pass, handle: &Handle) {
    let word_pat = format!(r"{}+", handle.opts(pa).word_chars_regex());
    handle.edit_all(pa, |mut c| {
        c.set_caret_on_end();
        let start = c.range().start;
        let mut nth = c.search_rev_incl_until(&word_pat, start).next();
        if let Some(range) = nth {
            c.move_to(range)
        } else {
            c.reset()
        }
    })
}
§Panics

If the regex is not valid, this method will panic.

Source

pub fn char(&self) -> char

Returns the char in the caret

Source

pub fn char_at(&self, i: impl TextIndex) -> Option<char>

Returns the char at a given Point

Source

pub fn selection(&self) -> Strs<'_>

Returns the Selection’s selection

The reason why this return value is IntoIter<&str, 2> is because the Text utilizes an underlying GapBuffer to store the characters. This means that the text is always separated into two distinct chunks.

If this Selection’s selection happens to be entirely within one of these chunks, the other &str will just be empty.

Source

pub fn strs(&self, range: impl TextRange) -> Option<Strs<'_>>

Returns the Strs for the given TextRange

Source

pub fn len(&self) -> Point

Returns the length of the Text, in Point

Source

pub fn last_point(&self) -> Point

Returns the position of the last char if there is one

Source

pub fn lines(&self) -> Lines<'_>

An Iterator over the lines the Cursor’s range

Source

pub fn lines_on(&self, range: impl TextRange) -> Lines<'_>

An Iterator over the lines in a given range

Source

pub fn indent(&self) -> usize

Gets the current level of indentation

Source

pub fn indent_on(&self, p: Point) -> usize

Gets the indentation level on the given Point

Source

pub fn caret(&self) -> Point

Returns the caret

Source

pub fn anchor(&self) -> Option<Point>

Returns the anchor

Source

pub fn range(&self) -> Range<Point>

The Point range of the Selection

This is an inclusive range (not Rust’s RangeInclusive however), this means that, even if there is no anchor, the lenght of this range will always be at least 1.

If you want an exclusive range, see Cursor::range_excl

Source

pub fn range_excl(&self) -> Range<Point>

An exclusive Point range of the Selection

If you wish for an inclusive range, whose length is always greater than or equal to 1, see RangeInclusive.

Source

pub fn v_caret(&self) -> VPoint

The VPoint range of the Selection

Use only if you need the things that the VPoint provides, in order to preven extraneous calculations

Source

pub fn v_anchor(&self) -> Option<VPoint>

The VPoint of the anchor, if it exists

Use only if you need the things that the VPoint provides, in order to preven extraneous calculations

Source

pub fn anchor_is_start(&self) -> bool

Returns true if the anchor exists before the caret

Source

pub fn is_main(&self) -> bool

Whether or not this is the main Selection

Source

pub fn text(&self) -> &Text

The Text of the Widget

Source

pub fn opts(&self) -> PrintOpts

The PrintOpts in use

Source§

impl<S> Cursor<'_, Buffer, S>

Source

pub fn read_parser<Rd: Parser, Ret>( &self, read: impl FnOnce(&Rd) -> Ret, ) -> Option<Ret>

Reads the Bytes and a Parser

Source§

impl<W: Widget + ?Sized> Cursor<'_, W, Searcher>

Incremental search functions, only available on IncSearchers

Source

pub fn search_inc_fwd( &mut self, end: Option<Point>, ) -> impl Iterator<Item = Range<usize>> + '_

Search incrementally from an IncSearch request

This will match the Regex pattern from the current position of the caret. if end is Some, the search will end at the requested Point.

Source

pub fn search_inc_rev( &mut self, start: Option<Point>, ) -> impl Iterator<Item = Range<usize>> + '_

Search incrementally from an IncSearch request in reverse

This will match the Regex pattern from the current position of the caret in reverse. if start is Some, the search will end at the requested Point.

Source

pub fn matches_inc(&mut self) -> bool

Whether the Selection’s selection matches the IncSearch request

Trait Implementations§

Source§

impl<'a, W: Widget + ?Sized, S> Debug for Cursor<'a, W, S>

Source§

fn fmt(&self, f: &mut Formatter<'_>) -> Result

Formats the value using the given formatter. Read more
Source§

impl<'a, W: Widget + ?Sized + 'a, S: 'a> Drop for Cursor<'a, W, S>

Source§

fn drop(&mut self)

Executes the destructor for this type. Read more

Auto Trait Implementations§

§

impl<'a, W = Buffer, S = ()> !Freeze for Cursor<'a, W, S>

§

impl<'a, W = Buffer, S = ()> !RefUnwindSafe for Cursor<'a, W, S>

§

impl<'a, W = Buffer, S = ()> !Send for Cursor<'a, W, S>

§

impl<'a, W = Buffer, S = ()> !Sync for Cursor<'a, W, S>

§

impl<'a, W, S> Unpin for Cursor<'a, W, S>
where W: ?Sized,

§

impl<'a, W = Buffer, S = ()> !UnwindSafe for Cursor<'a, W, S>

Blanket Implementations§

Source§

impl<T> Any for T
where T: 'static + ?Sized,

Source§

fn type_id(&self) -> TypeId

Gets the TypeId of self. Read more
Source§

impl<T> Borrow<T> for T
where T: ?Sized,

Source§

fn borrow(&self) -> &T

Immutably borrows from an owned value. Read more
Source§

impl<T> BorrowMut<T> for T
where T: ?Sized,

Source§

fn borrow_mut(&mut self) -> &mut T

Mutably borrows from an owned value. Read more
Source§

impl<T> Downcast for T
where T: Any,

Source§

fn into_any(self: Box<T>) -> Box<dyn Any>

Convert Box<dyn Trait> (where Trait: Downcast) to Box<dyn Any>. Box<dyn Any> can then be further downcast into Box<ConcreteType> where ConcreteType implements Trait.
Source§

fn into_any_rc(self: Rc<T>) -> Rc<dyn Any>

Convert Rc<Trait> (where Trait: Downcast) to Rc<Any>. Rc<Any> can then be further downcast into Rc<ConcreteType> where ConcreteType implements Trait.
Source§

fn as_any(&self) -> &(dyn Any + 'static)

Convert &Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &Any’s vtable from &Trait’s.
Source§

fn as_any_mut(&mut self) -> &mut (dyn Any + 'static)

Convert &mut Trait (where Trait: Downcast) to &Any. This is needed since Rust cannot generate &mut Any’s vtable from &mut Trait’s.
Source§

impl<T> From<T> for T

Source§

fn from(t: T) -> T

Returns the argument unchanged.

Source§

impl<T, U> Into<U> for T
where U: From<T>,

Source§

fn into(self) -> U

Calls U::from(self).

That is, this conversion is whatever the implementation of From<T> for U chooses to do.

Source§

impl<T, U> TryFrom<U> for T
where U: Into<T>,

Source§

type Error = Infallible

The type returned in the event of a conversion error.
Source§

fn try_from(value: U) -> Result<T, <T as TryFrom<U>>::Error>

Performs the conversion.
Source§

impl<T, U> TryInto<U> for T
where U: TryFrom<T>,

Source§

type Error = <U as TryFrom<T>>::Error

The type returned in the event of a conversion error.
Source§

fn try_into(self) -> Result<U, <U as TryFrom<T>>::Error>

Performs the conversion.