pub struct Handle<W: Widget + ?Sized = Buffer> { /* 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:
- A
&mut Pass, which will give you access to all of duat’s shared state; - The key that was sent, may be a mapped key.
- The
Handlefor aMode::Widget.
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
impl Handle
Sourcepub fn save(&self, pa: &mut Pass) -> Result<bool, Text>
pub fn save(&self, pa: &mut Pass) -> Result<bool, Text>
Writes the buffer to the current PathBuf, if one was set.
Sourcepub fn save_to(&self, pa: &mut Pass, path: impl AsRef<Path>) -> Result<bool>
pub fn save_to(&self, pa: &mut Pass, path: impl AsRef<Path>) -> Result<bool>
Writes the buffer to the given Path.
Sourcepub fn printed_line_numbers(&self, pa: &Pass) -> Vec<PrintedLine>
pub fn printed_line_numbers(&self, pa: &Pass) -> Vec<PrintedLine>
Returns the list of printed line numbers.
These are returned as a usize, showing the index of the line
in the buffer, and a bool, which is true when the line is
wrapped.
If you want the actual content of these lines (as Strss),
check out Handle::printed_lines. If you want the content
of only the visible portion of these lines, check out
Handle::visible_lines.
Sourcepub fn full_printed_range(&self, pa: &Pass) -> Range<Point>
pub fn full_printed_range(&self, pa: &Pass) -> Range<Point>
The printed Range<Point>, from the top of the screen to
the bottom.
Do note that this includes all concealed lines and parts that
are out of screen. If you want only to include partially
visible lines, while excluding fully hidden ones, check out
Handle::printed_lines. If you want to exclude every
concealed or out of screen section, check out
Handle::visible_lines.
Sourcepub fn printed_lines<'b>(&'b self, pa: &'b Pass) -> Vec<&'b Strs>
pub fn printed_lines<'b>(&'b self, pa: &'b Pass) -> Vec<&'b Strs>
Returns the list of printed lines.
These are returned as Strs, which are duat’s equivalent of
str for the Text struct.
Note that this function returns all portions of printed lines, not just those that are visible. This means that it will also include partially concealed lines and parts of the line that are out of screen.
If you want a list of only the visible sections, check out
Handle::visible_lines.
If you want a Range<Point> of the printed section of the
Text (including concealed lines), check out
Handle::full_printed_range.
If you just want the line numbers of the printed lines, check
out Handle::printed_line_numbers.
Sourcepub fn printed_line_ranges(&self, pa: &Pass) -> Vec<Range<usize>>
pub fn printed_line_ranges(&self, pa: &Pass) -> Vec<Range<usize>>
A list of Range<usize>s for the byte ranges of each
printed line.
This is just a shorthand for calling Handle::printed_lines
and mapping each one via Strs::byte_range.
Sourcepub fn visible_lines<'b>(&'b self, _: &'b Pass) -> Vec<&'b Strs>
pub fn visible_lines<'b>(&'b self, _: &'b Pass) -> Vec<&'b Strs>
Only the visible parts of printed lines.
This is just like Handle::printed_lines, but excludes
every section that was concealed or is not visible on
screen.
Source§impl<W: Widget + ?Sized> Handle<W>
impl<W: Widget + ?Sized> Handle<W>
Sourcepub fn read<'a>(&'a self, pa: &'a Pass) -> &'a W
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.
Sourcepub fn read_as<'a, W2: Widget>(&'a self, pa: &'a Pass) -> Option<&'a W2>
pub fn read_as<'a, W2: Widget>(&'a self, pa: &'a Pass) -> Option<&'a W2>
Tries to read as a concrete Widget implementor.
Sourcepub fn declare_as_read(&self)
pub fn declare_as_read(&self)
Sourcepub fn write<'a>(&'a self, pa: &'a mut Pass) -> &'a mut W
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.
Sourcepub fn write_with_area<'p>(
&'p self,
pa: &'p mut Pass,
) -> (&'p mut W, &'p mut Area)
pub fn write_with_area<'p>( &'p self, pa: &'p mut Pass, ) -> (&'p mut W, &'p 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.
Sourcepub fn write_then<'p, Tup: WriteableTuple<'p, impl Any>>(
&'p self,
pa: &'p mut Pass,
tup_fn: impl FnOnce(&'p W) -> Tup,
) -> (&'p mut W, Tup::Return)
pub fn write_then<'p, Tup: WriteableTuple<'p, impl Any>>( &'p self, pa: &'p mut Pass, tup_fn: impl FnOnce(&'p W) -> Tup, ) -> (&'p mut W, Tup::Return)
The same as RwData::write_then.
This lets you write to a Widget and other RwData-like
structs within said Widget at the same time.
Sourcepub fn declare_written(&self)
pub fn declare_written(&self)
Sourcepub fn try_downcast<W2: Widget>(&self) -> Option<Handle<W2>>
pub fn try_downcast<W2: Widget>(&self) -> Option<Handle<W2>>
Tries to downcast from dyn Widget to a concrete Widget.
Sourcepub fn text_parts<'p>(&'p self, pa: &'p mut Pass) -> TextParts<'p>
pub fn text_parts<'p>(&'p self, pa: &'p mut Pass) -> TextParts<'p>
Sourcepub fn selections<'p>(&'p self, pa: &'p Pass) -> &'p Selections
pub fn selections<'p>(&'p self, pa: &'p Pass) -> &'p Selections
A shared reference to the Selections of the Widget’s
Text.
This is the same as calling handle.read(pa).selections().
Sourcepub fn selections_mut<'p>(&'p self, pa: &'p mut Pass) -> &'p mut Selections
pub fn selections_mut<'p>(&'p self, pa: &'p mut Pass) -> &'p mut Selections
A mutable reference to the Selections of the Widget’s
Text.
This is the same as calling
handle.write(pa).selections_mut().
Sourcepub fn edit_nth<Ret>(
&self,
pa: &mut Pass,
n: usize,
edit: impl FnOnce(Cursor<'_, W>) -> Ret,
) -> Ret
pub fn edit_nth<Ret>( &self, pa: &mut Pass, n: usize, edit: impl FnOnce(Cursor<'_, W>) -> 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 all Selections, see edit_all.
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.
Sourcepub fn edit_main<Ret>(
&self,
pa: &mut Pass,
edit: impl FnOnce(Cursor<'_, W>) -> Ret,
) -> Ret
pub fn edit_main<Ret>( &self, pa: &mut Pass, edit: impl FnOnce(Cursor<'_, W>) -> 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_all.
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.
Sourcepub fn edit_last<Ret>(
&self,
pa: &mut Pass,
edit: impl FnOnce(Cursor<'_, W>) -> Ret,
) -> Ret
pub fn edit_last<Ret>( &self, pa: &mut Pass, edit: impl FnOnce(Cursor<'_, W>) -> 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 all
Selections, see edit_all.
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.
Sourcepub fn edit_all(&self, pa: &mut Pass, edit: impl FnMut(Cursor<'_, W>))
pub fn edit_all(&self, pa: &mut Pass, edit: impl FnMut(Cursor<'_, W>))
A shortcut for iterating over all selections.
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.
Sourcepub fn scroll_ver(&self, pa: &mut Pass, dist: i32)
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.
Sourcepub fn scroll_to_points(&self, pa: &mut Pass, points: TwoPoints)
pub fn scroll_to_points(&self, pa: &mut Pass, points: TwoPoints)
Sourcepub fn start_points(&self, pa: &Pass) -> TwoPoints
pub fn start_points(&self, pa: &Pass) -> TwoPoints
The start points that should be printed.
Sourcepub fn end_points(&self, pa: &Pass) -> TwoPoints
pub fn end_points(&self, pa: &Pass) -> TwoPoints
The end points that should be printed.
Sourcepub fn mask(&self) -> &Arc<Mutex<&'static str>>
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. To see more about how masks work, see
form::enable_mask.
Sourcepub fn set_mask(&self, mask: &'static str) -> &'static str
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. To see more about how masks work, see
form::enable_mask.
Sourcepub fn has_changed(&self, pa: &Pass) -> bool
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.
Sourcepub fn ptr_eq<T: ?Sized>(&self, other: &RwData<T>) -> bool
pub fn ptr_eq<T: ?Sized>(&self, other: &RwData<T>) -> bool
Wether the RwData within and another point to the same
value.
Sourcepub fn request_update(&self)
pub fn request_update(&self)
Request that this Handle be updated.
You can use this to request updates from other threads.
Sourcepub fn master(&self) -> Result<&Handle<dyn Widget>, Text>
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.
Sourcepub fn buffer(&self) -> Result<Handle, Text>
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.
Sourcepub fn push_inner_widget<PW: Widget>(
&self,
pa: &mut Pass,
widget: PW,
specs: PushSpecs,
) -> Handle<PW>
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.
Sourcepub fn push_outer_widget<PW: Widget>(
&self,
pa: &mut Pass,
widget: PW,
specs: PushSpecs,
) -> Handle<PW>
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.
Sourcepub fn spawn_widget<SW: Widget>(
&self,
pa: &mut Pass,
widget: SW,
specs: DynSpawnSpecs,
) -> Option<Handle<SW>>
pub fn spawn_widget<SW: Widget>( &self, pa: &mut Pass, widget: SW, specs: DynSpawnSpecs, ) -> Option<Handle<SW>>
Spawns a floating Widget.