pub struct EditorSession {
pub buffer: TextBuffer,
pub edit: TextEditState,
pub config: EditorConfig,
pub click_state: EditorClickState,
}Expand description
Mutable editor session state: text buffer plus edit, viewport, and click state.
§Examples
use ailloli_ui_editor::{EditorSession, EditorWrapMode};
use ailloli_ui_text::TextBuffer;
let session = EditorSession::new(TextBuffer::from_string("hello"));
assert_eq!(session.buffer.as_str(), "hello");
assert_eq!(session.config.wrap_mode, EditorWrapMode::SoftWrap);
assert_eq!(session.edit.caret_byte, 0);Fields§
§buffer: TextBufferEditable rope-backed UTF-8 buffer.
edit: TextEditStateCaret, selection, IME, scroll, drag, and undo/redo state.
config: EditorConfigCurrent style and wrapping policy.
click_state: EditorClickStateMulti-click recognition history.
Implementations§
Source§impl EditorSession
Applies input and configuration transitions to an editor session.
impl EditorSession
Applies input and configuration transitions to an editor session.
Sourcepub fn new(buffer: TextBuffer) -> Self
pub fn new(buffer: TextBuffer) -> Self
Creates a session with default configuration and empty edit/click state.
§Examples
use ailloli_ui_editor::EditorSession;
use ailloli_ui_text::TextBuffer;
let session = EditorSession::new(TextBuffer::from_string("abc"));
assert_eq!(session.edit.caret_byte, 0);
assert_eq!(session.buffer.as_str(), "abc");Sourcepub fn with_config(buffer: TextBuffer, config: EditorConfig) -> Self
pub fn with_config(buffer: TextBuffer, config: EditorConfig) -> Self
Creates a session with an explicit configuration.
Edit and click state still start empty; configuration is stored verbatim.
§Examples
use ailloli_ui_editor::{EditorConfig, EditorSession, EditorWrapMode};
use ailloli_ui_text::TextBuffer;
let config = EditorConfig { wrap_mode: EditorWrapMode::NoWrap, ..EditorConfig::default() };
let session = EditorSession::with_config(TextBuffer::new(), config);
assert_eq!(session.config.wrap_mode, EditorWrapMode::NoWrap);Sourcepub fn set_config(&mut self, config: EditorConfig) -> bool
pub fn set_config(&mut self, config: EditorConfig) -> bool
Replaces configuration when different.
Returns false for exact equality. Switching to soft wrap also forces
horizontal scroll to zero; switching to no-wrap preserves it. An equal
soft-wrap configuration does not repair a manually nonzero scroll value.
§Examples
use ailloli_ui_editor::{EditorConfig, EditorSession, EditorWrapMode};
use ailloli_ui_text::TextBuffer;
let mut session = EditorSession::new(TextBuffer::new());
session.edit.scroll_x = 20.0;
let nowrap = EditorConfig { wrap_mode: EditorWrapMode::NoWrap, ..EditorConfig::default() };
assert!(session.set_config(nowrap));
assert_eq!(session.edit.scroll_x, 20.0);
assert!(session.set_config(EditorConfig::default()));
assert_eq!(session.edit.scroll_x, 0.0);Sourcepub fn replace_buffer_if_changed(&mut self, buffer: TextBuffer) -> bool
pub fn replace_buffer_if_changed(&mut self, buffer: TextBuffer) -> bool
Replaces the buffer only when its text differs.
Equal text returns false and retains the existing buffer, even if the
supplied buffer has different internal revisions. A replacement clamps
generic edit state to valid UTF-8 bounds.
§Examples
use ailloli_ui_editor::EditorSession;
use ailloli_ui_text::TextBuffer;
let mut session = EditorSession::new(TextBuffer::from_string("long"));
session.edit.caret_byte = 4;
assert!(session.replace_buffer_if_changed(TextBuffer::from_string("x")));
assert_eq!(session.edit.caret_byte, 1);
assert!(!session.replace_buffer_if_changed(TextBuffer::from_string("x")));Sourcepub fn apply_edit_action(
&mut self,
action: TextEditAction,
) -> EditorInputOutcome
pub fn apply_edit_action( &mut self, action: TextEditAction, ) -> EditorInputOutcome
Applies one text-edit action and returns its neutral side effects.
Buffer mutation, undo/redo, selection, IME, and clipboard semantics are
inherited from [TextEditState::apply].
§Examples
use ailloli_ui_editor::EditorSession;
use ailloli_ui_text::{TextBuffer, TextEditAction};
let mut session = EditorSession::new(TextBuffer::new());
let outcome = session.apply_edit_action(TextEditAction::InsertText { text: "hi".into() });
assert!(outcome.text_changed);
assert_eq!(session.buffer.as_str(), "hi");Sourcepub fn scroll_by(&mut self, delta: Offset, metrics: ScrollMetrics) -> bool
pub fn scroll_by(&mut self, delta: Offset, metrics: ScrollMetrics) -> bool
Applies a logical-pixel scroll delta and clamps it to content metrics.
Soft wrap disables horizontal movement. Returns whether either stored offset changed; non-finite values are normalized by scroll primitives.
§Examples
use ailloli_ui_core::{Offset, ScrollMetrics, Size};
use ailloli_ui_editor::EditorSession;
use ailloli_ui_text::TextBuffer;
let mut session = EditorSession::new(TextBuffer::new());
let metrics = ScrollMetrics::new(Size::new(100.0, 50.0), Size::new(100.0, 200.0));
assert!(session.scroll_by(Offset::new(20.0, 30.0), metrics));
assert_eq!((session.edit.scroll_x, session.edit.scroll_y), (0.0, 30.0));Sourcepub fn begin_pointer_selection(&mut self, byte: usize, extend: bool) -> bool
pub fn begin_pointer_selection(&mut self, byte: usize, extend: bool) -> bool
Starts pointer selection and moves or extends the caret.
drag_anchor stores the supplied byte verbatim, while the caret setter
clamps backward to a valid UTF-8 boundary. Returns whether caret,
selection, or desired horizontal position changed; setting only a new
drag anchor can therefore return false.
§Examples
use ailloli_ui_editor::EditorSession;
use ailloli_ui_text::TextBuffer;
let mut session = EditorSession::new(TextBuffer::from_string("abc"));
session.begin_pointer_selection(2, false);
assert_eq!(session.edit.drag_anchor, Some(2));
assert_eq!(session.edit.caret_byte, 2);Sourcepub fn update_pointer_selection(&mut self, anchor: usize, byte: usize)
pub fn update_pointer_selection(&mut self, anchor: usize, byte: usize)
Updates a drag selection from supplied byte offsets.
Both offsets are stored verbatim in [TextSelection]. The separate
edit.caret_byte is numerically clamped to buffer length but not repaired
to a UTF-8 boundary. Hit-test callers must therefore provide valid,
in-range boundaries. This method reports no change flag and does not
modify drag_anchor or desired_x.
§Examples
use ailloli_ui_editor::EditorSession;
use ailloli_ui_text::TextBuffer;
let mut session = EditorSession::new(TextBuffer::from_string("abc"));
session.update_pointer_selection(1, 99);
assert_eq!(session.edit.selection.unwrap().normalized(), (1, 99));
assert_eq!(session.edit.caret_byte, 3);Sourcepub fn end_pointer_selection(&mut self) -> bool
pub fn end_pointer_selection(&mut self) -> bool
Ends an active pointer drag.
Returns true only when a drag anchor was present. Selection and caret
remain unchanged.
§Examples
use ailloli_ui_editor::EditorSession;
use ailloli_ui_text::TextBuffer;
let mut session = EditorSession::new(TextBuffer::from_string("abc"));
session.begin_pointer_selection(1, false);
assert!(session.end_pointer_selection());
assert!(!session.end_pointer_selection());Sourcepub fn register_pointer_click(
&mut self,
now: Instant,
pos: Point,
byte: usize,
zone: EditorClickZone,
) -> u8
pub fn register_pointer_click( &mut self, now: Instant, pos: Point, byte: usize, zone: EditorClickZone, ) -> u8
Registers a click using a process-local monotonic Instant.
Returns a count in 1..=3. A sequence continues only within 500 ms and
four logical pixels at the identical byte and zone. Legacy and explicit
event timestamps never mix into one sequence.
§Examples
use std::time::Instant;
use ailloli_ui_core::Point;
use ailloli_ui_editor::{EditorClickZone, EditorSession};
use ailloli_ui_text::TextBuffer;
let mut session = EditorSession::new(TextBuffer::new());
let now = Instant::now();
assert_eq!(session.register_pointer_click(now, Point::new(0.0, 0.0), 0, EditorClickZone::Text), 1);
assert_eq!(session.register_pointer_click(now, Point::new(4.0, 0.0), 0, EditorClickZone::Text), 2);Sourcepub fn register_pointer_click_at(
&mut self,
timestamp: Duration,
pos: Point,
byte: usize,
zone: EditorClickZone,
) -> u8
pub fn register_pointer_click_at( &mut self, timestamp: Duration, pos: Point, byte: usize, zone: EditorClickZone, ) -> u8
Registers a click using a provider-neutral monotonic event timestamp.
This is the deterministic counterpart to Self::register_pointer_click
for hosts that attach an explicit timestamp to each input event. Backward
timestamps reset the sequence. Counts saturate at three.
§Examples
use std::time::Duration;
use ailloli_ui_core::Point;
use ailloli_ui_editor::{EditorClickZone, EditorSession};
use ailloli_ui_text::TextBuffer;
let mut session = EditorSession::new(TextBuffer::new());
for expected in [1, 2, 3, 3] {
let count = session.register_pointer_click_at(Duration::from_millis(expected as u64), Point::new(0.0, 0.0), 0, EditorClickZone::Text);
assert_eq!(count, expected.min(3));
}Sourcepub fn select_word_at_byte(
&mut self,
byte: usize,
syntax_tokens: Option<&[SyntaxToken]>,
language: EditorLanguage,
) -> bool
pub fn select_word_at_byte( &mut self, byte: usize, syntax_tokens: Option<&[SyntaxToken]>, language: EditorLanguage, ) -> bool
Selects a syntax token or lexical word around a byte offset.
If no selectable unit exists, this instead moves the caret and clears selection. Otherwise selection is ordered start-to-end and the caret is placed at its end. Returns whether editor state changed.
§Examples
use ailloli_ui_editor::{EditorLanguage, EditorSession};
use ailloli_ui_text::TextBuffer;
let mut session = EditorSession::new(TextBuffer::from_string("hello world"));
assert!(session.select_word_at_byte(7, None, EditorLanguage::PlainText));
assert_eq!(session.edit.selection.unwrap().normalized(), (6, 11));Sourcepub fn select_line_at_byte(&mut self, byte: usize) -> bool
pub fn select_line_at_byte(&mut self, byte: usize) -> bool
Selects the logical line containing a byte, excluding its newline.
The byte is clamped to a UTF-8 boundary by the line selector. The caret moves to the range end and drag/desired-x state is cleared. Returns whether those stored values changed.
§Examples
use ailloli_ui_editor::EditorSession;
use ailloli_ui_text::TextBuffer;
let mut session = EditorSession::new(TextBuffer::from_string("one\ntwo"));
assert!(session.select_line_at_byte(5));
assert_eq!(session.edit.selection.unwrap().normalized(), (4, 7));Trait Implementations§
Source§impl Clone for EditorSession
impl Clone for EditorSession
Source§fn clone(&self) -> EditorSession
fn clone(&self) -> EditorSession
1.0.0 · Source§fn clone_from(&mut self, source: &Self)
fn clone_from(&mut self, source: &Self)
source. Read more