pub struct TextArea {
pub keep_selection_after_mouseup: bool,
pub selection_style: Style,
pub show_scrollbar: bool,
pub scrollbar_track_style: Style,
pub scrollbar_thumb_style: Style,
pub scrollbar_padding: u16,
/* private fields */
}Fields§
§keep_selection_after_mouseup: boolWhether to keep the selection visible after mouse-up.
When false, selection clears immediately on mouse-up (fully transient).
selection_style: StyleStyle applied to selected text. Defaults to a tokyonight-inspired
blue background (rgb(49, 62, 115)) with an explicit light foreground
(rgb(192, 202, 245)) so the selection is legible regardless of the
host terminal’s colour scheme.
Override to match your own theme, e.g.:
textarea.selection_style = Style::default().bg(Color::Rgb(60, 60, 60));show_scrollbar: boolWhether to show a scrollbar on the right edge when content overflows.
When enabled, the rightmost column is reserved for the scrollbar track
and the text area wraps at width - 1. Defaults to true.
scrollbar_track_style: StyleStyle for the scrollbar track (empty space). Defaults to a dark tokyonight-inspired background. Override to match your theme’s background when embedding the textarea in a non-default-bg context.
scrollbar_thumb_style: StyleStyle for the scrollbar thumb (draggable indicator). Defaults to a slightly lighter tokyonight shade. Override to match your theme.
scrollbar_padding: u16Padding (in columns) between the text content and the scrollbar track.
Only applies when the scrollbar is visible. Defaults to 0.
Implementations§
Source§impl TextArea
impl TextArea
pub fn new() -> Self
Sourcepub fn tab_width(&self) -> u8
pub fn tab_width(&self) -> u8
Columns per tab for display width and tab→space expansion (0 = passthrough).
Sourcepub fn set_tab_width(&mut self, tab_width: u8)
pub fn set_tab_width(&mut self, tab_width: u8)
Set columns per tab. Also controls expansion on insert/set_text/replace_range.
Sourcepub fn expand_tabs<'a>(&self, text: &'a str) -> Cow<'a, str>
pub fn expand_tabs<'a>(&self, text: &'a str) -> Cow<'a, str>
Expand \t to tab_width spaces (scrollback-compatible fixed width).
tab_width == 0 or no tabs → borrowed input.
Public because it is the exact transform every insert path applies
(see insert_str /
insert_element), letting hosts canonicalize
external text before comparing it against buffer content.
pub fn set_text(&mut self, text: &str)
pub fn text(&self) -> &str
pub fn insert_str(&mut self, text: &str)
pub fn insert_str_at(&mut self, pos: usize, text: &str)
pub fn replace_range(&mut self, range: Range<usize>, text: &str)
pub fn cursor(&self) -> usize
pub fn set_cursor(&mut self, pos: usize)
Sourcepub fn set_scroll_override(&mut self, scroll: Option<u16>)
pub fn set_scroll_override(&mut self, scroll: Option<u16>)
Override the scroll position, bypassing cursor-follow logic.
When set to Some(offset), effective_scroll will use this offset
instead of ensuring the cursor is visible. Useful for forcing a
specific viewport (e.g., scroll-to-top when the textarea is collapsed
and unfocused). Set to None to restore normal cursor-following.
Note: unlike the internal scroll_override set by mousewheel events, this is NOT cleared by cursor movement — it persists until explicitly cleared by the caller.
Sourcepub fn scroll_override(&self) -> Option<u16>
pub fn scroll_override(&self) -> Option<u16>
Current scroll override value (if any).
pub fn desired_height(&self, width: u16) -> u16
pub fn cursor_pos(&self, area: Rect) -> Option<(u16, u16)>
Sourcepub fn cursor_pos_with_state(
&self,
area: Rect,
state: TextAreaState,
) -> Option<(u16, u16)>
pub fn cursor_pos_with_state( &self, area: Rect, state: TextAreaState, ) -> Option<(u16, u16)>
Compute the on-screen cursor position taking scrolling into account.
Returns None if the cursor is not visible in the current viewport
(e.g. the user scrolled the viewport away from the cursor via mousewheel).
Unlike Self::screen_position_of, this applies a wrap-boundary adjustment:
when the cursor sits at the exact wrap boundary (col == content width),
it is shown at the start of the next visual line instead of on the
invisible right border.
Sourcepub fn screen_position_of(
&self,
pos: usize,
area: Rect,
state: TextAreaState,
) -> Option<(u16, u16)>
pub fn screen_position_of( &self, pos: usize, area: Rect, state: TextAreaState, ) -> Option<(u16, u16)>
Compute the on-screen position of an arbitrary buffer byte offset.
Returns None if the position is outside the visible viewport.
Does not apply cursor-specific wrap-boundary adjustments — see
Self::cursor_pos_with_state for cursor positioning.
Sourcepub fn screen_spans_of_range(
&self,
range: Range<usize>,
area: Rect,
state: TextAreaState,
) -> Vec<Rect>
pub fn screen_spans_of_range( &self, range: Range<usize>, area: Rect, state: TextAreaState, ) -> Vec<Rect>
Compute the on-screen cells covered by a buffer byte range.
A soft-wrapped range can cross visual rows, so unlike
Self::screen_position_of this returns one height-1 Rect per visual
row the range intersects, top to bottom, clamped to the content
region (text_width columns — excludes any scrollbar column). Rows
scrolled outside the viewport are skipped, so a partially visible
range yields only its visible rows. Bytes belonging to no row (a
\n, or whitespace dropped at a wrap boundary) are not covered;
trailing spaces kept on a row are. Ranges that are empty, extend
past the text, or have non-char-boundary endpoints yield no spans.
Sourcepub fn buffer_pos_at_screen(
&self,
col: u16,
row: u16,
area: Rect,
state: TextAreaState,
) -> Option<usize>
pub fn buffer_pos_at_screen( &self, col: u16, row: u16, area: Rect, state: TextAreaState, ) -> Option<usize>
Map screen coordinates (col, row) to a buffer byte position.
Returns None if (col, row) is outside the textarea area.
Edge cases:
- Click past end of a wrapped line → snaps to line end.
- Click below all text → snaps to
text.len(). - Click on an element → snaps to nearest element boundary (start or end).
Sourcepub fn element_at_screen(
&self,
col: u16,
row: u16,
area: Rect,
state: TextAreaState,
) -> Option<&TextElement>
pub fn element_at_screen( &self, col: u16, row: u16, area: Rect, state: TextAreaState, ) -> Option<&TextElement>
Return the element at screen coordinates, if any.
Uses buffer_pos_at_screen to find the buffer position, then checks
whether that position falls inside an element.
Sourcepub fn selection_range(&self) -> Option<Range<usize>>
pub fn selection_range(&self) -> Option<Range<usize>>
Normalized selection range, expanded to element boundaries.
Returns None if no selection is active or anchor == head (empty).
Sourcepub fn selected_text(&self) -> Option<String>
pub fn selected_text(&self) -> Option<String>
Text within the current selection (buffer text, not display text).
Sourcepub fn clear_selection(&mut self)
pub fn clear_selection(&mut self)
Clear the selection without affecting the clipboard.
Sourcepub fn delete_selection(&mut self) -> bool
pub fn delete_selection(&mut self) -> bool
Delete the selected range (if any). Returns true if text was deleted.
This is a single undo step. After deletion, the cursor is placed at the start of the deleted range and the selection is cleared.
Sourcepub fn set_selection(&mut self, anchor: usize, head: usize)
pub fn set_selection(&mut self, anchor: usize, head: usize)
Set the selection programmatically.
Sourcepub fn take_clipboard(&mut self) -> Option<String>
pub fn take_clipboard(&mut self) -> Option<String>
Take the clipboard contents (returns None if empty).
This is the primary way for the host app to retrieve text that was selected by mouse drag / double-click / triple-click.
Sourcepub fn clipboard(&self) -> Option<&str>
pub fn clipboard(&self) -> Option<&str>
Peek at the current clipboard content without consuming it.
Sourcepub fn set_clipboard_provider(
&mut self,
provider: Box<dyn ClipboardProvider + Send>,
)
pub fn set_clipboard_provider( &mut self, provider: Box<dyn ClipboardProvider + Send>, )
Replace the clipboard provider. The default is InternalClipboard
(in-memory only). Pass an arboard-backed implementation to sync
copy/cut/paste with the system clipboard.
Sourcepub fn poll_element_event(&mut self) -> Option<TextElementEvent>
pub fn poll_element_event(&mut self) -> Option<TextElementEvent>
Take the pending TextElementEvent, if any.
Call this after handle_mouse to check whether
an element was clicked or hover-entered/left.
Sourcepub fn poll_timeout_ms(&self) -> Option<u64>
pub fn poll_timeout_ms(&self) -> Option<u64>
Recommended poll timeout for the host event loop.
When the textarea has pending timer-driven work (e.g. continuous
drag-scrolling while the mouse is held outside the area), this
returns Some(ms). The host should use this as the
event::poll timeout. When the poll times out without an event,
call tick.
Returns None when no timer work is pending — the host can use
its own default timeout.
Sourcepub fn tick(&mut self, area: Rect, state: TextAreaState) -> MouseAction
pub fn tick(&mut self, area: Rect, state: TextAreaState) -> MouseAction
Advance timer-driven work (called by the host when poll times
out). Returns a MouseAction describing what changed (typically
SelectionUpdated for drag-scroll, or Nothing).
Sourcepub fn handle_mouse(
&mut self,
event: MouseEvent,
area: Rect,
state: TextAreaState,
) -> MouseAction
pub fn handle_mouse( &mut self, event: MouseEvent, area: Rect, state: TextAreaState, ) -> MouseAction
Process a crossterm MouseEvent and return what happened.
The host app is expected to call this from its event loop for
every Event::Mouse(mouse) and pass the textarea’s render area
plus the current TextAreaState (for scroll info).
pub fn is_empty(&self) -> bool
pub fn input(&mut self, event: KeyEvent)
Sourcepub fn clear_history(&mut self)
pub fn clear_history(&mut self)
Clear the undo/redo history, leaving the current text and cursor untouched.
Use this when a buffer is reset to represent a new logical
context — e.g. a shared input widget that is reused for a
different target — so that a later undo can’t resurrect text
that belonged to the previous context. set_text deliberately
records a checkpoint (so an accidental replace is undoable), so
callers that want a hard reset must follow it with this.
Sourcepub fn undo(&mut self) -> bool
pub fn undo(&mut self) -> bool
Undo the last mutation. Returns true if there was something to undo.
Sourcepub fn redo(&mut self) -> bool
pub fn redo(&mut self) -> bool
Redo the last undone mutation. Returns true if there was something to redo.
pub fn can_undo(&self) -> bool
pub fn can_redo(&self) -> bool
Sourcepub fn begin_undo_group(&mut self)
pub fn begin_undo_group(&mut self)
Begin an undo group. All mutations between begin_undo_group() and
end_undo_group() are collapsed into a single undo step.
Groups can be nested: only the outermost end_undo_group() pushes
the checkpoint. Inner begin/end pairs are reference-counted.
Use cases:
- Autocomplete:
replace_range_with_element+insert_str(" ")= 1 undo step - Line-select: enter → N live-updates → confirm = 1 undo step
Sourcepub fn end_undo_group(&mut self)
pub fn end_undo_group(&mut self)
End an undo group. If this closes the outermost group and the state actually changed, a single undo entry is pushed.
Sourcepub fn cancel_undo_group(&mut self)
pub fn cancel_undo_group(&mut self)
Cancel an undo group. Restores the textarea to the state it was in
when begin_undo_group() was called — no undo entry is created.
Use case: line-select cancel → revert all live-updates, leave no trace.
pub fn delete_backward(&mut self, n: usize)
pub fn delete_forward(&mut self, n: usize)
pub fn delete_backward_word(&mut self)
Sourcepub fn delete_backward_unix_word(&mut self)
pub fn delete_backward_unix_word(&mut self)
readline unix-word-rubout (whitespace-delimited), vs
Self::delete_backward_word’s punctuation-chunked M-DEL semantics.
Sourcepub fn delete_forward_word(&mut self)
pub fn delete_forward_word(&mut self)
Delete text to the right of the cursor using readline-style word semantics.
Deletes from the current cursor position through the end of the next word as determined
by end_of_next_word(). Any delimiters between the cursor and that word
(whitespace, punctuation, newlines) are included in the deletion.
pub fn kill_to_end_of_line(&mut self)
pub fn kill_to_beginning_of_line(&mut self)
Sourcepub fn kill_current_line(&mut self)
pub fn kill_current_line(&mut self)
Kill the entire current line (BOL to EOL), regardless of cursor position. If the line is already empty, consumes the preceding newline to join lines.
pub fn yank(&mut self)
Sourcepub fn move_cursor_left(&mut self)
pub fn move_cursor_left(&mut self)
Move the cursor left by a single grapheme cluster.
Sourcepub fn move_cursor_right(&mut self)
pub fn move_cursor_right(&mut self)
Move the cursor right by a single grapheme cluster.
pub fn move_cursor_up(&mut self)
pub fn move_cursor_down(&mut self)
Sourcepub fn move_cursor_to_beginning_of_line(&mut self, move_up_at_bol: bool)
pub fn move_cursor_to_beginning_of_line(&mut self, move_up_at_bol: bool)
Home / Super+Left when move_up_at_bol is false (visual row if wrapped);
Ctrl+A when true (logical line; already-at-BOL chains to previous line).
Sourcepub fn move_cursor_to_end_of_line(&mut self, move_down_at_eol: bool)
pub fn move_cursor_to_end_of_line(&mut self, move_down_at_eol: bool)
End / Super+Right when move_down_at_eol is false (visual row if wrapped);
Ctrl+E when true (logical line; already-at-EOL chains to next line).
Sourcepub fn insert_element(
&mut self,
text: &str,
kind: ElementKind,
display: Option<Line<'static>>,
) -> ElementId
pub fn insert_element( &mut self, text: &str, kind: ElementKind, display: Option<Line<'static>>, ) -> ElementId
Insert an atomic text element at the current cursor position.
The text is inserted into the buffer and registered as an element.
The kind tag is opaque to the textarea (host-defined).
The display optionally overrides how the element is rendered.
Returns the assigned ElementId so the host can store associated metadata.
Sourcepub fn replace_range_with_element(
&mut self,
range: Range<usize>,
text: &str,
kind: ElementKind,
display: Option<Line<'static>>,
) -> ElementId
pub fn replace_range_with_element( &mut self, range: Range<usize>, text: &str, kind: ElementKind, display: Option<Line<'static>>, ) -> ElementId
Replace a range of buffer text with an atomic element.
This is the “confirm autocomplete” operation: the trigger text (e.g. @foo)
is deleted and replaced with element text (e.g. @src/foo.rs) in a single
atomic operation. The cursor is placed at the end of the new element.
Returns the assigned ElementId.
Sourcepub fn element_at_cursor(&self) -> Option<&TextElement>
pub fn element_at_cursor(&self) -> Option<&TextElement>
Returns the element at the current cursor position, if any.
If the cursor is at an element’s start boundary, that element is returned. If the cursor is strictly inside an element (shouldn’t happen in normal operation), the containing element is returned.
Sourcepub fn element_text(&self, id: ElementId) -> Option<&str>
pub fn element_text(&self, id: ElementId) -> Option<&str>
Returns the underlying buffer text for the element with the given id.
Sourcepub fn set_element_display(
&mut self,
id: ElementId,
display: Option<Line<'static>>,
)
pub fn set_element_display( &mut self, id: ElementId, display: Option<Line<'static>>, )
Update the display for an existing element. Invalidates the wrap cache.
Sourcepub fn elements(&self) -> &[TextElement]
pub fn elements(&self) -> &[TextElement]
Returns a slice of all elements, sorted by buffer position.
Sourcepub fn restore_elements(
&mut self,
elems: impl IntoIterator<Item = (Range<usize>, ElementKind, Option<Line<'static>>)>,
)
pub fn restore_elements( &mut self, elems: impl IntoIterator<Item = (Range<usize>, ElementKind, Option<Line<'static>>)>, )
Re-register elements after a Self::set_text call that placed their
buffer text back verbatim. Each (range, kind, display) tuple
describes one element whose text already occupies range in the
buffer. No text is inserted — this only recreates the element
metadata so the textarea renders chips instead of raw text.
Sourcepub fn inline_element(&mut self, id: ElementId) -> bool
pub fn inline_element(&mut self, id: ElementId) -> bool
Inline an element: remove it from the element list so its buffer text becomes plain editable characters. The text content is unchanged.
The cursor is placed at the end of the inlined region. This operation is a single undoable step.
Returns true if the element was found and inlined, false otherwise.
Sourcepub fn word_at_cursor(&self) -> Option<(Range<usize>, &str)>
pub fn word_at_cursor(&self) -> Option<(Range<usize>, &str)>
Get the contiguous non-whitespace “word” that the cursor is inside or at the start of.
Returns (byte_range, text) where byte_range is the range in the buffer.
Returns None if the cursor is on whitespace or the buffer is empty.
This is useful for trigger-character detection (e.g. finding @foo under the cursor
for autocomplete). The host can then check text.starts_with('@') etc.
Sourcepub fn beginning_of_previous_word(&self) -> usize
pub fn beginning_of_previous_word(&self) -> usize
Move to the beginning of the previous navigable chunk.
Word characters are alphanumeric plus _. Punctuation runs (such as
-) are their own chunk, so moving left across aa-bb stops at the
right side of -, then the left side of -, then the start of aa.
Whitespace is skipped over. Elements remain atomic units.
Sourcepub fn beginning_of_previous_unix_word(&self) -> usize
pub fn beginning_of_previous_unix_word(&self) -> usize
Start of the previous whitespace-delimited WORD; elements count as non-whitespace.
Sourcepub fn end_of_next_word(&self) -> usize
pub fn end_of_next_word(&self) -> usize
Move to the end of the next navigable chunk.
Word characters are alphanumeric plus _. Punctuation runs (such as
-) are their own chunk, so moving right across aa-bb stops at the
left side of -, then the right side of -, then the end of bb.
Whitespace is skipped over. Elements remain atomic units.
Trait Implementations§
Auto Trait Implementations§
impl !Freeze for TextArea
impl !RefUnwindSafe for TextArea
impl !Sync for TextArea
impl !UnwindSafe for TextArea
impl Send for TextArea
impl Unpin for TextArea
impl UnsafeUnpin for TextArea
Blanket Implementations§
Source§impl<T> BorrowMut<T> for Twhere
T: ?Sized,
impl<T> BorrowMut<T> for Twhere
T: ?Sized,
Source§fn borrow_mut(&mut self) -> &mut T
fn borrow_mut(&mut self) -> &mut T
Source§impl<T> IntoEither for T
impl<T> IntoEither for T
Source§fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
fn into_either(self, into_left: bool) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left is true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read moreSource§fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
fn into_either_with<F>(self, into_left: F) -> Either<Self, Self> ⓘ
self into a Left variant of Either<Self, Self>
if into_left(&self) returns true.
Converts self into a Right variant of Either<Self, Self>
otherwise. Read more