Handle

Struct Handle 

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

A handle to a Widget in Duat

The Handle lets you do all sorts of edits on a Widget. You can, for example, make use of the Selections in its Text in order to edit the Text in a very declarative way.

One of the places where this is commonly done is within Modes, where you get access to the Handle of the currently active Widget. Below is a very straightforward Mode:

use duat::prelude::*;

/// A very basic example Mode.
#[derive(Clone)]
struct PlacesCharactersAndMoves;

impl Mode for PlacesCharactersAndMoves {
    type Widget = Buffer;

    // ..
    fn send_key(&mut self, _: &mut Pass, _: KeyEvent, _: Handle) {
        todo!();
    }
}

In order to modify the widget, you must implement the Mode::send_key method. In it, you receive the following:

use duat::prelude::*;

#[derive(Clone)]
struct PlacesCharactersAndMoves;
impl Mode for PlacesCharactersAndMoves {
    type Widget = Buffer;

    fn send_key(&mut self, pa: &mut Pass, key_event: KeyEvent, handle: Handle) {
        match key_event {
            // actions based on the key pressed
            event!(KeyCode::Char(char)) => {
                // Do something when the character 'c' is typed.
            }
            _ => todo!("The remaining keys"),
        }
    }
}

Note the event! macro. It (alongside alt!, ctrl! and shift!) can be used to easily create KeyEvents for matching purposes. They are very useful for succinctly describing an exact match in just a short pattern:

use KeyCode::*;
use duat::prelude::*;

let key_event = KeyEvent::from(Char('a'));
match key_event {
    event!('a' | 'b') => { /* .. */ }
    shift!(Right | Left) => { /* .. */ }
    ctrl!(alt!('d')) => { /* .. */ }
    _ => { /* .. */ }
}

With the Handle, you can modify Text in a simplified way. This is done by two actions, editing and moving. You can only do one of these on any number of selections at the same time.

impl Mode for PlacesCharactersAndMoves {
    type Widget = Buffer;

    // ..
    fn send_key(&mut self, pa: &mut Pass, key_event: KeyEvent, handle: Handle) {
        use KeyCode::*;
        match key_event {
            event!(Char(char)) => handle.edit_all(pa, |mut c| {
                c.insert('c');
                c.move_hor(1);
            }),
            shift!(Right) => handle.edit_all(pa, |mut c| {
                if c.anchor().is_none() {
                    c.set_anchor();
                }
                c.move_hor(1);
            }),
            event!(KeyCode::Right) => handle.edit_all(pa, |mut c| {
                c.unset_anchor();
                c.move_hor(1);
            }),
            _ => todo!("Predictable remaining implementations"),
        }
    }

Implementations§

Source§

impl Handle

Source

pub fn add_parser<P: Parser>( &self, pa: &mut Pass, f: impl FnOnce(BufferTracker) -> P, ) -> Result<(), Text>

Adds a Parser to react to Text Changes

Source§

impl<W: Widget + ?Sized, S> Handle<W, S>

Source

pub fn read<'a>(&'a self, pa: &'a Pass) -> &'a W

Reads from the Widget, making use of a Pass

The consistent use of a Pass for the purposes of reading/writing to the values of RwDatas ensures that no panic or invalid borrow happens at runtime, even while working with untrusted code. More importantly, Duat uses these guarantees in order to give the end user a ridiculous amount of freedom in where they can do things, whilst keeping Rust’s number one rule and ensuring thread safety, even with a relatively large amount of shareable state.

Source

pub fn read_as<'a, W2: Widget>(&'a self, pa: &'a Pass) -> Option<&'a W2>

Tries to read as a concrete Widget implementor

Source

pub fn declare_as_read(&self)

Declares the Widget within as read

Same as calling handle.widget().declare_as_read(). You should use this function if you want to signal to others that the widget was read, even if you don’t have access to a Pass.

Source

pub fn write<'a>(&'a self, pa: &'a mut Pass) -> &'a mut W

Writes to the Widget, making use of a Pass

The consistent use of a Pass for the purposes of reading/writing to the values of RwDatas ensures that no panic or invalid borrow happens at runtime, even while working with untrusted code. More importantly, Duat uses these guarantees in order to give the end user a ridiculous amount of freedom in where they can do things, whilst keeping Rust’s number one rule and ensuring thread safety, even with a relatively large amount of shareable state.

Source

pub fn write_with_area<'a>( &'a self, pa: &'a mut Pass, ) -> (&'a mut W, &'a mut Area)

Writes to the Widget and Area, making use of a Pass

The consistent use of a Pass for the purposes of reading/writing to the values of RwDatas ensures that no panic or invalid borrow happens at runtime, even while working with untrusted code. More importantly, Duat uses these guarantees in order to give the end user a ridiculous amount of freedom in where they can do things, whilst keeping Rust’s number one rule and ensuring thread safety, even with a relatively large amount of shareable state.

Source

pub fn declare_written(&self)

Declares the Widget within as written

Same as calling handle.widget().declare_written(). You should use this function if you want to signal to others that the widget was written to, even if you don’t have access to a Pass.

Source

pub fn try_downcast<W2: Widget>(&self) -> Option<Handle<W2>>

Tries to downcast from dyn Widget to a concrete Widget

Source

pub fn text<'a>(&'a self, pa: &'a Pass) -> &'a Text

A shared reference to the Text of the Widget

This is the same as calling handle.read(pa).text().

Source

pub fn text_mut<'a>(&'a self, pa: &'a mut Pass) -> &'a mut Text

A mutable reference to the Text of the Widget

This is the same as calling handle.write(pa).text_mut().

Source

pub fn text_parts<'a>(&'a self, pa: &'a mut Pass) -> TextParts<'a>

The TextParts of the Widget

You can use this in order to get a shared reference to the Bytes and Selections, while maintaining a mutable reference to the Tags of the Text, letting you place Tags while still reading other information from the Widget

This is the same as calling handle.text_mut().parts().

Source

pub fn selections<'a>(&'a self, pa: &'a Pass) -> &'a Selections

A shared reference to the Selections of the Widget’s Text

This is the same as calling handle.read(pa).selections().

Source

pub fn selections_mut<'a>(&'a self, pa: &'a mut Pass) -> &'a mut Selections

A mutable reference to the Selections of the Widget’s Text

This is the same as calling handle.write(pa).selections_mut().

Source

pub fn edit_nth<Ret>( &self, pa: &mut Pass, n: usize, edit: impl FnOnce(Cursor<'_, W, S>) -> Ret, ) -> Ret

Edits the nth Selection in the Text

Once dropped, the Selection in this Cursor will be added back to the list of Selections, unless it is destroyed

If you want to edit on the main selection, see edit_main, if you want to edit on many Selections, see edit_iter.

Just like all other edit methods, this one will populate the Selections, so if there are no Selections, it will create one at Point::default.

Source

pub fn edit_main<Ret>( &self, pa: &mut Pass, edit: impl FnOnce(Cursor<'_, W, S>) -> Ret, ) -> Ret

Edits the main Selection in the Text

Once dropped, the Selection in this Cursor will be added back to the list of Selections, unless it is destroyed

If you want to edit on the nth selection, see edit_nth, same for edit_last, if you want to edit on many Selections, see edit_iter.

Just like all other edit methods, this one will populate the Selections, so if there are no Selections, it will create one at Point::default.

Source

pub fn edit_last<Ret>( &self, pa: &mut Pass, edit: impl FnOnce(Cursor<'_, W, S>) -> Ret, ) -> Ret

Edits the last Selection in the Text

Once dropped, the Selection in this Cursor will be added back to the list of Selections, unless it is destroyed

If you want to edit on the nth selection, see edit_nth, same for edit_main, if you want to edit on many Selections, see edit_iter.

Just like all other edit methods, this one will populate the Selections, so if there are no Selections, it will create one at Point::default.

Source

pub fn edit_iter<Ret>( &self, pa: &mut Pass, edit: impl FnOnce(Cursors<'_, W, S>) -> Ret, ) -> Ret

A Lender over all Cursors of the Text

This lets you easily iterate over all Selections, without having to worry about insertion affecting the order at which they are edited (like what repeated calls to edit_nth would do)

Note however that you can’t use a Lender (also known as a lending iterator) in a for loop, but you should be able to just while let Some(e) = editors.next() {} or handle.edit_iter().for_each(|_| {}) instead.

Just like all other edit methods, this one will populate the Selections, so if there are no Selections, it will create one at Point::default.

Source

pub fn edit_all(&self, pa: &mut Pass, edit: impl FnMut(Cursor<'_, W, S>))

A shortcut for iterating over all selections

This is the equivalent of calling:

handle.edit_iter(pa, |iter| iter.for_each(|e| { /* .. */ }));

But it can’t return a value, and is meant to reduce the indentation that will inevitably come from using the equivalent long form call.

Source

pub fn scroll_ver(&self, pa: &mut Pass, dist: i32)

Scrolls the Text veritcally by an amount

If PrintOpts.allow_overscroll is set, then the Text will be allowed to scroll beyond the last line, up until reaching the scrolloff.y value.

Source

pub fn scroll_to_points(&self, pa: &mut Pass, points: TwoPoints)

Scrolls the Text to the visual line of a TwoPoints

If scroll_beyond is set, then the Text will be allowed to scroll beyond the last line, up until reaching the scrolloff.y value.

Source

pub fn start_points(&self, pa: &Pass) -> TwoPoints

The start points that should be printed

Source

pub fn end_points(&self, pa: &Pass) -> TwoPoints

The end points that should be printed

Source

pub fn widget(&self) -> &RwData<W>

This Handle’s Widget

Source

pub fn area(&self) -> &RwArea

This Handle’s RwArea

Source

pub fn mask(&self) -> &Arc<Mutex<&'static str>>

Gets this Handle’s mask

This mask is going to be used to map Forms to other Forms when printing via Widget::print. To see more about how masks work, see form::enable_mask.

Source

pub fn set_mask(&self, mask: &'static str) -> &'static str

Sets this Handle’s mask, returning the previous one

This mask is going to be used to map Forms to other Forms when printing via Widget::print. To see more about how masks work, see form::enable_mask.

Source

pub fn has_changed(&self, pa: &Pass) -> bool

Wether someone else called write or write_as since the last read or write

Do note that this DOES NOT mean that the value inside has actually been changed, it just means a mutable reference was acquired after the last call to has_changed.

Some types like Text, and traits like Widget offer needs_update methods, you should try to determine what parts to look for changes.

Generally though, you can use this method to gauge that.

Source

pub fn ptr_eq<T: ?Sized>(&self, other: &RwData<T>) -> bool

Wether the RwData within and another point to the same value

Source

pub fn opts(&self, pa: &Pass) -> PrintOpts

The Widget’s PrintOpts

Source

pub fn master(&self) -> Result<&Handle<dyn Widget>, Text>

Returns the Handle this one was pushed to, if it was pushed to another

Will return Some if this self was created by calling Handle::push_outer_widget, Handle::push_inner_widget, Handle::spawn_widget, or if the Widget was spawned on the master’s Text

Source

pub fn buffer(&self) -> Result<Handle, Text>

Returns the Handle<Buffer> this one was pushed to, if it was pushed to one

Will return Some if this self was created by calling Handle::push_outer_widget, Handle::push_inner_widget, Handle::spawn_widget, or if the Widget was spawned on the master’s Text

Reads related Widgets of type W2, as well as its Area

This can also be done by calling Handle::get_related, and Handle::read, but this function should generally be faster, since there is no cloning of Arcs going on.

Gets related Handles of type Widget

If you are doing this just to read the Widget and Area, consider using Handle::read_related.

Source

pub fn attach_searcher(&self, searcher: Searcher) -> Handle<W, Searcher>

Attaches a Searcher to this Handle, so you can do incremental search

An Handle with a Searcher not only has its usual editing capabilities, but is also able to act on requested regex searches, like those from IncSearch, in duat. This means that a user can type up a prompt to search for something, and the Handle can use the Searcher to interpret how that search will be utilized. Examples of this can be found in the duat crate, as well as the duat-kak crate, which has some more advanced usage.

Source

pub fn push_inner_widget<PW: Widget>( &self, pa: &mut Pass, widget: PW, specs: PushSpecs, ) -> Handle<PW>

Pushes a Widget around this one

This Widget will be placed internally, i.e., around the Area of self. This is in contrast to Handle::push_outer_widget, which will push around the “cluster master” of self.

A cluster master is the collection of every Widget that was pushed around a central one with PushSpecs::cluster set to true.

Both of these functions behave identically in the situation where no other Widgets were pushed around self.

However, if, for example, a Widget was previously pushed below self, when pushing to the left, the following would happen:

╭────────────────╮    ╭─────┬──────────╮
│                │    │     │          │
│      self      │    │ new │   self   │
│                │ -> │     │          │
├────────────────┤    ├─────┴──────────┤
│      old       │    │      old       │
╰────────────────╯    ╰────────────────╯

While in Handle::push_outer_widget, this happens instead:

╭────────────────╮    ╭─────┬──────────╮
│                │    │     │          │
│      self      │    │     │   self   │
│                │ -> │ new │          │
├────────────────┤    │     ├──────────┤
│      old       │    │     │   old    │
╰────────────────╯    ╰─────┴──────────╯

Note that new was pushed around other clustered widgets in the second case, not just around self.

Source

pub fn push_outer_widget<PW: Widget>( &self, pa: &mut Pass, widget: PW, specs: PushSpecs, ) -> Handle<PW>

Pushes a Widget around the “cluster master” of this one

A cluster master is the collection of every Widget that was pushed around a central one with PushSpecs::cluster set to true.

This Widget will be placed externally, i.e., around every other Widget that was pushed around self. This is in contrast to Handle::push_inner_widget, which will push only around self.

Both of these functions behave identically in the situation where no other Widgets were pushed around self.

However, if, for example, a Widget was previously pushed to the left of self, when pushing to the left again, the following would happen:

╭──────┬──────────╮    ╭─────┬─────┬──────╮
│      │          │    │     │     │      │
│      │          │    │     │     │      │
│  old │   self   │ -> │ new │ old │ self │
│      │          │    │     │     │      │
│      │          │    │     │     │      │
╰──────┴──────────╯    ╰─────┴─────┴──────╯

While in Handle::push_inner_widget, this happens instead:

╭──────┬──────────╮    ╭─────┬─────┬──────╮
│      │          │    │     │     │      │
│      │          │    │     │     │      │
│  old │   self   │ -> │ old │ new │ self │
│      │          │    │     │     │      │
│      │          │    │     │     │      │
╰──────┴──────────╯    ╰─────┴─────┴──────╯

Note that new was pushed around other clustered widgets in the first case, not just around self.

Source

pub fn spawn_widget<SW: Widget>( &self, pa: &mut Pass, widget: SW, specs: SpawnSpecs, ) -> Option<Handle<SW>>

Spawns a floating Widget

Source

pub fn close(&self, pa: &mut Pass) -> Result<(), Text>

Closes this Handle, removing the Widget from the Window

Source

pub fn is_closed(&self, pa: &Pass) -> bool

Wether this Handle was already closed

Source§

impl<W: Widget, S> Handle<W, S>

Source

pub fn to_dyn(&self) -> Handle<dyn Widget>

Transforms this Handle into a Handle<dyn Widget>

Trait Implementations§

Source§

impl<W: Widget + ?Sized> Clone for Handle<W>

Source§

fn clone(&self) -> Self

Returns a duplicate of the value. Read more
1.0.0 · Source§

fn clone_from(&mut self, source: &Self)

Performs copy-assignment from source. Read more
Source§

impl<W: Widget + ?Sized, S> Debug for Handle<W, S>

Source§

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

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

impl<W1: Widget, W2: Widget + ?Sized> PartialEq<Handle<W2>> for FocusedOn<W1>

Source§

fn eq(&self, other: &Handle<W2>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<W1: Widget, W2: Widget + ?Sized> PartialEq<Handle<W2>> for UnfocusedFrom<W1>

Source§

fn eq(&self, other: &Handle<W2>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<W1, W2, S1, S2> PartialEq<Handle<W2, S2>> for Handle<W1, S1>
where W1: Widget + ?Sized, W2: Widget + ?Sized,

Source§

fn eq(&self, other: &Handle<W2, S2>) -> bool

Tests for self and other values to be equal, and is used by ==.
1.0.0 · Source§

fn ne(&self, other: &Rhs) -> bool

Tests for !=. The default implementation is almost always sufficient, and should not be overridden without very good reason.
Source§

impl<W: Widget + ?Sized> PushTarget for Handle<W>

Source§

fn try_downcast<DW: Widget>(&self) -> Option<Handle<DW>>

Tries to downcast to a Handle of some W
Source§

fn push_inner<PW: Widget>( &self, pa: &mut Pass, widget: PW, specs: PushSpecs, ) -> Handle<PW>

Pushes a Widget around self Read more
Source§

fn push_outer<PW: Widget>( &self, pa: &mut Pass, widget: PW, specs: PushSpecs, ) -> Handle<PW>

Pushes a Widget around the “master region” of self Read more
Source§

impl<W: Widget + ?Sized, S> Send for Handle<W, S>

Source§

impl<W: Widget + ?Sized, S> Sync for Handle<W, S>

Auto Trait Implementations§

§

impl<W = Buffer, S = ()> !Freeze for Handle<W, S>

§

impl<W = Buffer, S = ()> !RefUnwindSafe for Handle<W, S>

§

impl<W, S> Unpin for Handle<W, S>
where S: Unpin, W: ?Sized,

§

impl<W = Buffer, S = ()> !UnwindSafe for Handle<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> CloneToUninit for T
where T: Clone,

Source§

unsafe fn clone_to_uninit(&self, dest: *mut u8)

🔬This is a nightly-only experimental API. (clone_to_uninit)
Performs copy-assignment from self to dest. 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> DowncastSync for T
where T: Any + Send + Sync,

Source§

fn into_any_arc(self: Arc<T>) -> Arc<dyn Any + Send + Sync>

Convert Arc<Trait> (where Trait: Downcast) to Arc<Any>. Arc<Any> can then be further downcast into Arc<ConcreteType> where ConcreteType implements Trait.
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> ToOwned for T
where T: Clone,

Source§

type Owned = T

The resulting type after obtaining ownership.
Source§

fn to_owned(&self) -> T

Creates owned data from borrowed data, usually by cloning. Read more
Source§

fn clone_into(&self, target: &mut T)

Uses borrowed data to replace owned data, usually by cloning. Read more
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.