pub struct BufferUpdated(/* private fields */);Expand description
Hookable: Triggers when a Buffer updates.
This is triggered after a batch of writing calls to the Buffer,
once per frame. This can happen after typing a key, calling a
command, triggering hooks, or any other action with access to a
Pass, which could be used to write to the Buffer.
Think of this is as a “last pass” on the Buffer, right before
printing, where it can be adjusted given the modifications to it,
like Changes and such.
As an example, here’s a hook that will highlight every non ascii character:
use duat::{
prelude::*,
text::{Strs, Tags},
};
static TRACKER: BufferTracker = BufferTracker::new();
fn setup() {
let tagger = Tagger::new();
let tag = form::id_of!("non_ascii_char").to_tag(50);
let hl_non_ascii = move |tags: &mut Tags, strs: &Strs, range: Range<Point>| {
for (b, char) in strs[range.clone()].char_indices() {
let b = b + range.start.byte();
if !char.is_ascii() {
tags.insert(tagger, b..b + char.len_utf8(), tag);
}
}
};
hook::add::<BufferOpened>(move |pa, handle| {
TRACKER.register_buffer(handle.write(pa));
let mut parts = handle.text_parts(pa);
let range = Point::default()..parts.strs.end_point();
hl_non_ascii(&mut parts.tags, parts.strs, range);
});
hook::add::<BufferUpdated>(move |pa, handle| {
let mut parts = TRACKER.parts(handle.write(pa)).unwrap();
for change in parts.changes {
parts.tags.remove(tagger, change.added_range());
hl_non_ascii(&mut parts.tags, parts.strs, change.added_range())
}
});
}The BufferTracker will keep track of each registered
Buffer, telling you about every new Change that took place
since the last call to BufferTracker::parts. The
BufferTracker::parts function works much like Text::parts,
by separating the Strs, Tags and Selections, letting
you modify the tags, without permitting further edits to the
Text.
This is a nice way to automatically keep track of the changes, and it will work even if the function isn’t called frequently.