pub struct MarkdownWidget<'a> {
pub inner_area: Option<Rect>,
/* private fields */
}markdown-preview only.Expand description
A scrollable, interactive markdown widget.
This widget renders markdown content with:
- Scroll support (keyboard and mouse)
- Click-to-highlight line selection
- Clickable headings to collapse/expand sections
- Clickable frontmatter to collapse/expand
- Expandable content blocks (“Show more”/“Show less”)
- Text selection and copy support (drag to select)
- Double-click detection
- Statusline showing mode and scroll position
The widget handles ALL event processing internally and returns MarkdownEvent
variants so the parent application can react appropriately.
§Mouse Capture Requirement
For click events to work (line highlighting, TOC navigation, text selection), you must enable mouse capture in your terminal setup:
use crossterm::{
event::{EnableMouseCapture, DisableMouseCapture},
execute,
terminal::{EnterAlternateScreen, LeaveAlternateScreen},
};
// On startup:
execute!(stdout, EnterAlternateScreen, EnableMouseCapture)?;
// On cleanup:
execute!(stdout, LeaveAlternateScreen, DisableMouseCapture)?;Without EnableMouseCapture, scroll wheel events may still work (terminal-dependent),
but click events will not be received by the application.
Fields§
§inner_area: Option<Rect>Inner area calculated during render (for mouse event handling).
Implementations§
Source§impl<'a> MarkdownWidget<'a>
Construct MarkdownWidget from a unified MarkdownState.
impl<'a> MarkdownWidget<'a>
Construct MarkdownWidget from a unified MarkdownState.
Sourcepub fn from_state(state: &'a MarkdownState) -> MarkdownWidget<'a>
pub fn from_state(state: &'a MarkdownState) -> MarkdownWidget<'a>
Create a new MarkdownWidget from a unified MarkdownState.
This constructor clones the state into the widget, allowing the widget to own its state internally without holding references to the original state.
§Arguments
content- The markdown content to renderstate- The unified markdown state containing all component states
§Returns
A new MarkdownWidget instance that owns its state.
§Example
use ratatui_toolkit::markdown_widget::state::MarkdownState;
use ratatui_toolkit::MarkdownWidget;
let mut state = MarkdownState::default();
state.source.set_content("# Hello World");
let widget = MarkdownWidget::from_state(&state);Source§impl<'a> MarkdownWidget<'a>
Constructor for has_pane option.
impl<'a> MarkdownWidget<'a>
Constructor for has_pane option.
Sourcepub fn with_has_pane(self, has_pane: bool) -> MarkdownWidget<'a>
pub fn with_has_pane(self, has_pane: bool) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Constructor for MarkdownWidget.
impl<'a> MarkdownWidget<'a>
Constructor for MarkdownWidget.
Sourcepub fn new(
content: String,
scroll: ScrollState,
source: SourceState,
cache: CacheState,
display: DisplaySettings,
collapse: CollapseState,
expandable: ExpandableState,
git_stats_state: GitStatsState,
vim: VimState,
selection: SelectionState,
double_click: DoubleClickState,
) -> MarkdownWidget<'a>
pub fn new( content: String, scroll: ScrollState, source: SourceState, cache: CacheState, display: DisplaySettings, collapse: CollapseState, expandable: ExpandableState, git_stats_state: GitStatsState, vim: VimState, selection: SelectionState, double_click: DoubleClickState, ) -> MarkdownWidget<'a>
Create a new MarkdownWidget with the given content and state managers.
This constructor takes owned state values, allowing the widget to own its state internally.
§Arguments
content- The markdown content to renderscroll- Scroll state (position, viewport, current line)source- Content source statecache- Render cache statedisplay- Display settings (line numbers, themes)collapse- Section collapse stateexpandable- Expandable content stategit_stats_state- Git stats statevim- Vim keybinding stateselection- Selection state for text selection/copydouble_click- Double-click state for detection
§Returns
A new MarkdownWidget instance.
Source§impl<'a> MarkdownWidget<'a>
Constructor for pane configuration.
impl<'a> MarkdownWidget<'a>
Constructor for pane configuration.
Sourcepub fn with_pane(self, pane: Pane<'a>) -> MarkdownWidget<'a>
pub fn with_pane(self, pane: Pane<'a>) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Constructor for pane color.
impl<'a> MarkdownWidget<'a>
Constructor for pane color.
Sourcepub fn with_pane_color(self, color: impl Into<Color>) -> MarkdownWidget<'a>
pub fn with_pane_color(self, color: impl Into<Color>) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Constructor for pane title.
impl<'a> MarkdownWidget<'a>
Constructor for pane title.
Sourcepub fn with_pane_title(self, title: impl Into<String>) -> MarkdownWidget<'a>
pub fn with_pane_title(self, title: impl Into<String>) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Set the custom scrollbar configuration.
impl<'a> MarkdownWidget<'a>
Set the custom scrollbar configuration.
Sourcepub fn scrollbar_config(self, config: ScrollbarConfig) -> MarkdownWidget<'a>
pub fn scrollbar_config(self, config: ScrollbarConfig) -> MarkdownWidget<'a>
Set the custom scrollbar configuration.
§Arguments
config- The scrollbar configuration to use
§Returns
Self for method chaining.
§Example
use ratatui::style::{Color, Style};
use ratatui_toolkit::markdown_widget::extensions::scrollbar::ScrollbarConfig;
let config = ScrollbarConfig {
thumb_style: Style::default().fg(Color::Cyan),
..Default::default()
};
let widget = MarkdownWidget::from_state(&content, &mut state)
.show_custom_scrollbar(true)
.scrollbar_config(config);Source§impl<'a> MarkdownWidget<'a>
Set whether selection mode is active.
impl<'a> MarkdownWidget<'a>
Set whether selection mode is active.
Sourcepub fn selection_active(self, active: bool) -> MarkdownWidget<'a>
pub fn selection_active(self, active: bool) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Enable or disable the scrollbar.
impl<'a> MarkdownWidget<'a>
Enable or disable the scrollbar.
Sourcepub fn show_scrollbar(self, show: bool) -> MarkdownWidget<'a>
pub fn show_scrollbar(self, show: bool) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Enable or disable the statusline.
impl<'a> MarkdownWidget<'a>
Enable or disable the statusline.
Sourcepub fn show_statusline(self, show: bool) -> MarkdownWidget<'a>
pub fn show_statusline(self, show: bool) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Enable or disable the TOC (Table of Contents).
impl<'a> MarkdownWidget<'a>
Enable or disable the TOC (Table of Contents).
Sourcepub fn show_toc(self, show: bool) -> MarkdownWidget<'a>
pub fn show_toc(self, show: bool) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Set the TOC configuration.
impl<'a> MarkdownWidget<'a>
Set the TOC configuration.
Sourcepub fn toc_config(self, config: TocConfig) -> MarkdownWidget<'a>
pub fn toc_config(self, config: TocConfig) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Set the TOC hovered state.
impl<'a> MarkdownWidget<'a>
Set the TOC hovered state.
Sourcepub fn toc_hovered(self, hovered: bool) -> MarkdownWidget<'a>
pub fn toc_hovered(self, hovered: bool) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Set the hovered TOC entry index.
impl<'a> MarkdownWidget<'a>
Set the hovered TOC entry index.
Sourcepub fn toc_hovered_entry(self, index: Option<usize>) -> MarkdownWidget<'a>
pub fn toc_hovered_entry(self, index: Option<usize>) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Set the TOC scroll offset.
impl<'a> MarkdownWidget<'a>
Set the TOC scroll offset.
Sourcepub fn toc_scroll_offset(self, offset: usize) -> MarkdownWidget<'a>
pub fn toc_scroll_offset(self, offset: usize) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Theme application constructor for MarkdownWidget.
impl<'a> MarkdownWidget<'a>
Theme application constructor for MarkdownWidget.
Sourcepub fn with_theme(self, theme: &AppTheme) -> MarkdownWidget<'a>
pub fn with_theme(self, theme: &AppTheme) -> MarkdownWidget<'a>
Applies an application theme to the widget.
When a theme is applied, the widget will use theme colors for:
- Statusline (mode colors, background, text)
- TOC (text, active, hover, background, border colors)
- Selection highlighting
If no theme is set, the widget falls back to default hardcoded colors.
§Arguments
theme- The application theme to use for styling
§Returns
Self for method chaining.
§Example
use ratatui_toolkit::{MarkdownWidget, theme::AppTheme};
let theme = AppTheme::default();
// let widget = MarkdownWidget::new(content, scroll, selection, double_click)
// .with_theme(&theme);Source§impl<'a> MarkdownWidget<'a>
TOC state constructor for MarkdownWidget.
impl<'a> MarkdownWidget<'a>
TOC state constructor for MarkdownWidget.
Sourcepub fn with_toc_state(self, toc_state: TocState) -> MarkdownWidget<'a>
pub fn with_toc_state(self, toc_state: TocState) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
impl<'a> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Calculate the TOC area.
impl<'a> MarkdownWidget<'a>
Calculate the TOC area.
Sourcepub fn calculate_toc_area(&self, total_area: Rect) -> Option<Rect>
pub fn calculate_toc_area(&self, total_area: Rect) -> Option<Rect>
Calculate the TOC area based on current widget configuration.
Uses dynamic dimensions based on content:
- Expanded mode: width fits all headers, height fits all entries
- Compact mode: fixed width, height based on entry count and line spacing
§Arguments
total_area- The total area available for the widget
§Returns
Some(Rect) with the TOC area if TOC is enabled, None otherwise.
Source§impl MarkdownWidget<'_>
impl MarkdownWidget<'_>
Sourcepub fn handle_key(&mut self, key: KeyEvent) -> MarkdownEvent
pub fn handle_key(&mut self, key: KeyEvent) -> MarkdownEvent
Sourcepub fn handle_mouse(&mut self, event: MouseEvent, area: Rect) -> MarkdownEvent
pub fn handle_mouse(&mut self, event: MouseEvent, area: Rect) -> MarkdownEvent
Handle a mouse event for all interactions.
This is a convenience method that delegates to the internal handler. The widget manages all state internally.
§Arguments
event- The mouse event to handlearea- The area the widget occupies (for bounds checking)
§Returns
A MarkdownEvent indicating what action was taken.
Sourcepub fn update_git_stats(&mut self)
pub fn update_git_stats(&mut self)
Update git stats for the current content.
This method loads git stats for the file if the source is a file path.
Source§impl<'a> MarkdownWidget<'a>
Git stats setter for MarkdownWidget.
impl<'a> MarkdownWidget<'a>
Git stats setter for MarkdownWidget.
Sourcepub fn git_stats(self, stats: GitStats) -> MarkdownWidget<'a>
pub fn git_stats(self, stats: GitStats) -> MarkdownWidget<'a>
Sourcepub fn maybe_git_stats(self, stats: Option<GitStats>) -> MarkdownWidget<'a>
pub fn maybe_git_stats(self, stats: Option<GitStats>) -> MarkdownWidget<'a>
Sourcepub fn git_stats_tuple(
self,
additions: usize,
modified: usize,
deletions: usize,
) -> MarkdownWidget<'a>
pub fn git_stats_tuple( self, additions: usize, modified: usize, deletions: usize, ) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Handle keyboard events for the markdown widget.
impl<'a> MarkdownWidget<'a>
Handle keyboard events for the markdown widget.
Sourcepub fn handle_key_event(&mut self, key: KeyEvent) -> MarkdownEvent
pub fn handle_key_event(&mut self, key: KeyEvent) -> MarkdownEvent
Handle a keyboard event for navigation and actions.
This method handles:
j/Down: Move focused line down (scrolls when near edge)k/Up: Move focused line up (scrolls when near edge)PageDown: Scroll down by viewport heightPageUp: Scroll up by viewport heightHome/gg: Go to topEnd/G: Go to bottom/: Enter filter modeEsc: Exit selection mode or filter modey: Copy selection to clipboard (when selection active)Ctrl+Shift+C: Copy selection to clipboard
Returns a MarkdownEvent indicating what action was taken.
Source§impl<'a> MarkdownWidget<'a>
impl<'a> MarkdownWidget<'a>
Sourcepub fn get_line_info_at_position(
&self,
y: usize,
width: usize,
) -> Option<(usize, String, String)>
pub fn get_line_info_at_position( &self, y: usize, width: usize, ) -> Option<(usize, String, String)>
Get line information at a given screen position.
Returns (line_number, line_kind, content) if found.
Sourcepub fn set_rendered_lines(&mut self, lines: Vec<Line<'static>>)
pub fn set_rendered_lines(&mut self, lines: Vec<Line<'static>>)
Set the rendered lines for selection text extraction.
Call this after rendering to update the cached lines.
Sourcepub fn is_selection_active(&self) -> bool
pub fn is_selection_active(&self) -> bool
Check if selection mode is active.
Sourcepub fn selection(&self) -> &SelectionState
pub fn selection(&self) -> &SelectionState
Get the current selection state (for rendering).
Source§impl<'a> MarkdownWidget<'a>
Handle TOC click events for scroll-to-heading navigation.
impl<'a> MarkdownWidget<'a>
Handle TOC click events for scroll-to-heading navigation.
Sourcepub fn handle_toc_click(&mut self, event: &MouseEvent, area: Rect) -> bool
pub fn handle_toc_click(&mut self, event: &MouseEvent, area: Rect) -> bool
Handle a click on the TOC to scroll to the selected heading.
§Arguments
event- The mouse eventarea- The total widget area
§Returns
true if the click was handled (was on a TOC entry), false otherwise.
§Example
// In your event loop:
if let Event::Mouse(mouse_event) = event {
if matches!(mouse_event.kind, MouseEventKind::Down(MouseButton::Left)) {
if widget.handle_toc_click(&mouse_event, area) {
// Click was handled - you may want to redraw
}
}
}Sourcepub fn handle_toc_click_in_area(
&mut self,
event: &MouseEvent,
toc_area: Rect,
) -> bool
pub fn handle_toc_click_in_area( &mut self, event: &MouseEvent, toc_area: Rect, ) -> bool
Source§impl<'a> MarkdownWidget<'a>
Handle TOC hover events for interactive expansion and entry highlight.
impl<'a> MarkdownWidget<'a>
Handle TOC hover events for interactive expansion and entry highlight.
Sourcepub fn handle_toc_hover(&mut self, event: &MouseEvent, area: Rect) -> bool
pub fn handle_toc_hover(&mut self, event: &MouseEvent, area: Rect) -> bool
Handle mouse move events to detect TOC hover.
Call this method with MouseEventKind::Moved events to track
whether the mouse is hovering over the TOC area and which entry
is being hovered.
§Arguments
event- The mouse event (should be a Moved event)area- The total widget area
§Returns
true if the hover state changed (entered/exited hover or hovered entry changed),
false otherwise.
§Example
// In your event loop:
if let Event::Mouse(mouse_event) = event {
if matches!(mouse_event.kind, MouseEventKind::Moved) {
if widget.handle_toc_hover(&mouse_event, area) {
// Hover state changed - you may want to redraw
}
}
}Sourcepub fn is_toc_hovered(&self) -> bool
pub fn is_toc_hovered(&self) -> bool
Check if the TOC is currently being hovered.
§Returns
true if the mouse is over the TOC, false otherwise.
Sourcepub fn get_toc_hovered_entry(&self) -> Option<usize>
pub fn get_toc_hovered_entry(&self) -> Option<usize>
Get the currently hovered TOC entry index.
§Returns
The index of the hovered entry, or None if no entry is hovered.
Sourcepub fn set_toc_hovered(&mut self, hovered: bool)
pub fn set_toc_hovered(&mut self, hovered: bool)
Set the TOC hover state directly.
Useful for manually controlling hover state in tests or special scenarios.
§Arguments
hovered- Whether the TOC should be considered hovered.
Sourcepub fn get_toc_scroll_offset(&self) -> usize
pub fn get_toc_scroll_offset(&self) -> usize
Sourcepub fn set_toc_scroll_offset(&mut self, offset: usize)
pub fn set_toc_scroll_offset(&mut self, offset: usize)
Sourcepub fn update_toc_hovered_entry(&mut self, x: u16, y: u16, toc_area: Rect)
pub fn update_toc_hovered_entry(&mut self, x: u16, y: u16, toc_area: Rect)
Update the hovered entry based on current mouse position and scroll offset.
Call this after scrolling the TOC to recalculate which entry is under the cursor.
§Arguments
x- Mouse X coordinatey- Mouse Y coordinatetoc_area- The TOC area rect
Source§impl<'a> MarkdownWidget<'a>
Set resizing state method for MarkdownWidget.
impl<'a> MarkdownWidget<'a>
Set resizing state method for MarkdownWidget.
Sourcepub fn is_resizing(self, resizing: bool) -> MarkdownWidget<'a>
pub fn is_resizing(self, resizing: bool) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
Methods for retrieving the last double-click info and copied text.
impl<'a> MarkdownWidget<'a>
Methods for retrieving the last double-click info and copied text.
Sourcepub fn take_last_double_click(&mut self) -> Option<(usize, String, String)>
pub fn take_last_double_click(&mut self) -> Option<(usize, String, String)>
Get the last double-click info and clear it.
Call this after processing events to check if a double-click occurred.
§Returns
Some((line_number, line_kind, content)) if a double-click occurred, None otherwise.
Sourcepub fn take_last_copied(&mut self) -> Option<String>
pub fn take_last_copied(&mut self) -> Option<String>
Get the last copied text and clear it.
Call this after processing events to check if text was copied to clipboard. Use this to show a toast notification when text is copied.
§Returns
Some(text) if text was copied, None otherwise.
Source§impl<'a> MarkdownWidget<'a>
Set mode method for MarkdownWidget.
impl<'a> MarkdownWidget<'a>
Set mode method for MarkdownWidget.
Sourcepub fn mode(self, mode: MarkdownWidgetMode) -> MarkdownWidget<'a>
pub fn mode(self, mode: MarkdownWidgetMode) -> MarkdownWidget<'a>
Source§impl<'a> MarkdownWidget<'a>
impl<'a> MarkdownWidget<'a>
pub fn rendered_lines(&self) -> &Vec<Line<'static>>
Source§impl<'a> MarkdownWidget<'a>
impl<'a> MarkdownWidget<'a>
Sourcepub fn get_state_sync(&mut self) -> WidgetStateSync
pub fn get_state_sync(&mut self) -> WidgetStateSync
Get the state that needs to be synced back to MarkdownState.
This method captures the TOC and selection state from the widget so it can be synced back after the widget is dropped.
§Returns
A WidgetStateSync struct containing the state values to sync.
§Example
let sync_state = {
let mut widget = MarkdownWidget::from_state(&content, &mut state).show_toc(true);
widget.handle_toc_hover(&mouse, render_area);
widget.handle_toc_click(&mouse, render_area);
widget.handle_mouse_event(&mouse, render_area);
widget.get_state_sync()
};
sync_state.apply_to(&mut state);Sourcepub fn sync_state_back(self, state: &mut MarkdownState)
pub fn sync_state_back(self, state: &mut MarkdownState)
Sync widget state back to MarkdownState by consuming self.
This method consumes the widget and syncs TOC and selection state back to the MarkdownState, ensuring state persistence between frames.
Call this after handling mouse events to preserve hover and selection state.
§Arguments
state- The MarkdownState to sync state back to
§Example
let mut widget = MarkdownWidget::from_state(&content, &mut state).show_toc(true);
widget.handle_toc_hover(&mouse, render_area);
widget.handle_toc_click(&mouse, render_area);
widget.handle_mouse_event(&mouse, render_area);
widget.sync_state_back(&mut state);Trait Implementations§
Source§impl<'a> Widget for &mut MarkdownWidget<'a>
impl<'a> Widget for &mut MarkdownWidget<'a>
Auto Trait Implementations§
impl<'a> Freeze for MarkdownWidget<'a>
impl<'a> RefUnwindSafe for MarkdownWidget<'a>
impl<'a> Send for MarkdownWidget<'a>
impl<'a> !Sync for MarkdownWidget<'a>
impl<'a> Unpin for MarkdownWidget<'a>
impl<'a> UnsafeUnpin for MarkdownWidget<'a>
impl<'a> UnwindSafe for MarkdownWidget<'a>
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> Instrument for T
impl<T> Instrument for T
Source§fn instrument(self, span: Span) -> Instrumented<Self>
fn instrument(self, span: Span) -> Instrumented<Self>
Source§fn in_current_span(self) -> Instrumented<Self>
fn in_current_span(self) -> Instrumented<Self>
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