Skip to main content

TextArea

Struct TextArea 

Source
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: bool

Whether to keep the selection visible after mouse-up. When false, selection clears immediately on mouse-up (fully transient).

§selection_style: Style

Style 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: bool

Whether 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: Style

Style 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: Style

Style for the scrollbar thumb (draggable indicator). Defaults to a slightly lighter tokyonight shade. Override to match your theme.

§scrollbar_padding: u16

Padding (in columns) between the text content and the scrollbar track. Only applies when the scrollbar is visible. Defaults to 0.

Implementations§

Source§

impl TextArea

Source

pub fn new() -> Self

Source

pub fn tab_width(&self) -> u8

Columns per tab for display width and tab→space expansion (0 = passthrough).

Source

pub fn set_tab_width(&mut self, tab_width: u8)

Set columns per tab. Also controls expansion on insert/set_text/replace_range.

Source

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.

Source

pub fn set_text(&mut self, text: &str)

Source

pub fn text(&self) -> &str

Source

pub fn insert_str(&mut self, text: &str)

Source

pub fn insert_str_at(&mut self, pos: usize, text: &str)

Source

pub fn replace_range(&mut self, range: Range<usize>, text: &str)

Source

pub fn cursor(&self) -> usize

Source

pub fn set_cursor(&mut self, pos: usize)

Source

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.

Source

pub fn scroll_override(&self) -> Option<u16>

Current scroll override value (if any).

Source

pub fn desired_height(&self, width: u16) -> u16

Source

pub fn cursor_pos(&self, area: Rect) -> Option<(u16, u16)>

Source

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.

Source

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.

Source

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.

Source

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).
Source

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.

Source

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).

Source

pub fn selected_text(&self) -> Option<String>

Text within the current selection (buffer text, not display text).

Source

pub fn clear_selection(&mut self)

Clear the selection without affecting the clipboard.

Source

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.

Source

pub fn set_selection(&mut self, anchor: usize, head: usize)

Set the selection programmatically.

Source

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.

Source

pub fn clipboard(&self) -> Option<&str>

Peek at the current clipboard content without consuming it.

Source

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.

Source

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.

Source

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.

Source

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).

Source

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).

Source

pub fn is_empty(&self) -> bool

Source

pub fn input(&mut self, event: KeyEvent)

Source

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.

Source

pub fn undo(&mut self) -> bool

Undo the last mutation. Returns true if there was something to undo.

Source

pub fn redo(&mut self) -> bool

Redo the last undone mutation. Returns true if there was something to redo.

Source

pub fn can_undo(&self) -> bool

Source

pub fn can_redo(&self) -> bool

Source

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
Source

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.

Source

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.

Source

pub fn delete_backward(&mut self, n: usize)

Source

pub fn delete_forward(&mut self, n: usize)

Source

pub fn delete_backward_word(&mut self)

Source

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.

Source

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.

Source

pub fn kill_to_end_of_line(&mut self)

Source

pub fn kill_to_beginning_of_line(&mut self)

Source

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.

Source

pub fn yank(&mut self)

Source

pub fn move_cursor_left(&mut self)

Move the cursor left by a single grapheme cluster.

Source

pub fn move_cursor_right(&mut self)

Move the cursor right by a single grapheme cluster.

Source

pub fn move_cursor_up(&mut self)

Source

pub fn move_cursor_down(&mut self)

Source

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).

Source

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).

Source

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.

Source

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.

Source

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.

Source

pub fn element_text(&self, id: ElementId) -> Option<&str>

Returns the underlying buffer text for the element with the given id.

Source

pub fn set_element_display( &mut self, id: ElementId, display: Option<Line<'static>>, )

Update the display for an existing element. Invalidates the wrap cache.

Source

pub fn elements(&self) -> &[TextElement]

Returns a slice of all elements, sorted by buffer position.

Source

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.

Source

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.

Source

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.

Source

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.

Source

pub fn beginning_of_previous_unix_word(&self) -> usize

Start of the previous whitespace-delimited WORD; elements count as non-whitespace.

Source

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§

Source§

impl Debug for TextArea

Source§

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

Formats the value using the given formatter. Read more
Source§

impl StatefulWidgetRef for &TextArea

Source§

type State = TextAreaState

State associated with the stateful widget. Read more
Source§

fn render_ref(&self, area: Rect, buf: &mut Buffer, state: &mut Self::State)

Draws the current state of the widget in the given buffer. That is the only method required to implement a custom stateful widget.
Source§

impl WidgetRef for &TextArea

Source§

fn render_ref(&self, area: Rect, buf: &mut Buffer)

Draws the current state of the widget in the given buffer. That is the only method required to implement a custom widget.

Auto Trait Implementations§

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> 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> IntoEither for T

Source§

fn into_either(self, into_left: bool) -> Either<Self, Self>

Converts 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 more
Source§

fn into_either_with<F>(self, into_left: F) -> Either<Self, Self>
where F: FnOnce(&Self) -> bool,

Converts 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
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.