Struct Handle

Source
pub struct Handle<W: Widget<U>, U: Ui, 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_core::prelude::*;
/// A very basic example Mode.
#[derive(Clone)]
struct PlacesCharactersAndMoves;

impl<U: Ui> Mode<U> for PlacesCharactersAndMoves {
    type Widget = File<U>;

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

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

use duat_core::prelude::*;
#[derive(Clone)]
struct PlacesCharactersAndMoves;
impl<U: Ui> Mode<U> for PlacesCharactersAndMoves {
    type Widget = File<U>;

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

(You can use the key! macro in order to match KeyEvents).

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<U: Ui> Mode<U> for PlacesCharactersAndMoves {
    /* ... */
    fn send_key(&mut self, pa: &mut Pass, key: KeyEvent, handle: Handle<Self::Widget, U>) {
        match key {
            key!(KeyCode::Char(c)) => {
                handle.edit_all(pa, |mut e| {
                    e.insert('c');
                    e.move_hor(1);
                });
            },
            key!(KeyCode::Right, KeyMod::SHIFT) => {
                handle.edit_all(pa, |mut e| {
                    if e.anchor().is_none() {
                        e.set_anchor();
                    }
                    e.move_hor(1);
                });
            }
            key!(KeyCode::Right) => {
                handle.edit_all(pa, |mut e| {
                    e.unset_anchor();
                    e.move_hor(1);
                });
            }
            _ => todo!("Predictable remaining implementations")
        }
    }

Implementations§

Source§

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

Source

pub fn read<Ret>( &self, pa: &Pass<'_>, f: impl FnOnce(&W, &U::Area) -> Ret, ) -> Ret

Reads from the Widget and the Area using 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.

§Panics

Panics if there is a mutable borrow of this struct somewhere, which could happen if you use RwData::write_unsafe or RwData::write_unsafe_as from some other place

Source

pub fn write<Ret>( &self, pa: &mut Pass<'_>, f: impl FnOnce(&mut W, &U::Area) -> Ret, ) -> Ret

Writes to the Widget and Area within using 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.

§Panics

Panics if there is any type of borrow of this struct somewhere, which could happen if you use RwData::read_unsafe or RwData::write_unsafe, for example.

Source

pub fn edit_nth<Ret>( &self, pa: &mut Pass<'_>, n: usize, edit: impl FnOnce(Cursor<'_, W, U::Area, 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, U::Area, 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, U::Area, 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, U::Area, 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, U::Area, 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 read_text<Ret>( &self, pa: &Pass<'_>, read: impl FnOnce(&Text) -> Ret, ) -> Ret

Reads the Text of the Widget

Source

pub fn write_text<Ret>( &self, pa: &mut Pass<'_>, write: impl FnOnce(&mut Text) -> Ret, ) -> Ret

Writes to the Text of the Widget

Source

pub fn read_selections<Ret>( &self, pa: &Pass<'_>, read: impl FnOnce(&Selections) -> Ret, ) -> Ret

Reads the Selections of the Widget

Source

pub fn write_selections<Ret>( &self, pa: &mut Pass<'_>, write: impl FnOnce(&mut Selections) -> Ret, ) -> Ret

Writes to the Selections of the Widget

Source

pub fn clone_text(&self, pa: &Pass<'_>) -> Text

Clones the Text within

Source

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

Replaces the Text within with a Default version

Source

pub fn replace_text(&self, pa: &mut Pass<'_>, text: impl Into<Text>) -> Text

Replaces the Text of the Widget, returning the previous value

Source

pub fn undo(&self, pa: &mut Pass<'_>)

Undoes the last moment in the history, if there is one

Source

pub fn redo(&self, pa: &mut Pass<'_>)

Redoes the last moment in the history, if there is one

Source

pub fn new_moment(&self, pa: &mut Pass<'_>)

Finishes the current moment and adds a new one to the history

Source

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

This Handle’s Widget

Source

pub fn area(&self) -> &U::Area

This Handle’s U::Area

Source

pub fn mask(&self) -> &Rc<Cell<&'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) -> 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 cfg(&self, pa: &Pass<'_>) -> PrintCfg

The Widget’s PrintCfg

Source§

impl<U: Ui> Handle<File<U>, U>

Source

pub fn attach_searcher( &self, searcher: Searcher, ) -> Handle<File<U>, U, 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-utils. 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-utils crate, as well as the duat-kak crate, which has some more advanced usage.

Trait Implementations§

Source§

impl<W: Widget<U>, U: Ui, S: Clone> Clone for Handle<W, U, S>

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: Debug + Widget<U>, U: Debug + Ui, S: Debug> Debug for Handle<W, U, S>
where U::Area: Debug,

Source§

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

Formats the value using the given formatter. Read more

Auto Trait Implementations§

§

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

§

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

§

impl<W, U, S = ()> !Send for Handle<W, U, S>

§

impl<W, U, S = ()> !Sync for Handle<W, U, S>

§

impl<W, U, S> Unpin for Handle<W, U, S>
where <U as Ui>::Area: Unpin, S: Unpin,

§

impl<W, U, S = ()> !UnwindSafe for Handle<W, U, 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> 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.