EdTUI is a text editor widget for the Ratatui ecosystem.
It is designed to provide a user experience inspired by Vim. Edtui is developed to be used as an
editor in ratatui apps. It is not supposed to be a stand-alone code editor.
Create a new EditorState and render it using EditorView.
You can customize the theme, enable line wrapping, syntax highlight the text or set the tab
width:
use edtui::{EditorState, EditorTheme, EditorView};
use ratatui::widgets::Widget;
let mut state = EditorState::default();
EditorView::new(&mut state)
.theme(EditorTheme::default())
.wrap(true)
.syntax_highlighter(None)
.tab_width(2)
.render(area, buf);Handle events (Vim mode by default):
use edtui::EditorEventHandler;
let mut event_handler = EditorEventHandler::default();
event_handler.on_key_event(key_event, &mut state);Or use Emacs mode (modeless editing):
use edtui::{EditorState, EditorEventHandler, Lines};
let mut state = EditorState::new(Lines::from("Hello World"));
let mut event_handler = EditorEventHandler::emacs_mode();
event_handler.on_key_event(key_event, &mut state);Or customize keybindings:
let mut key_handler = KeyEventHandler::vim_mode();
key_handler.insert(
KeyEventRegister::n(vec![KeyInput::ctrl('x')]),
SwitchMode(EditorMode::Insert),
);
let event_handler = EditorEventHandler::new(key_handler);- Custom theming.
- Mouse events.
- Vim and Emacs keybindings.
- Copy paste using the systems clipboard.
- Line wrapping.
- Syntax highlighting.
- Line numbers (absolute and relative).
- System editor support (optional, via
system-editorfeature).
Customize the editor EditorTheme:
use edtui::{EditorTheme, EditorStatusLine};
use ratatui::style::{Style, Color};
use ratatui::widgets::Block;
let theme = EditorTheme::default()
.block(Block::default())
.base(Style::default().bg(Color::Black).fg(Color::White))
.cursor_style(Style::default().bg(Color::White).fg(Color::Black))
.selection_style(Style::default().bg(Color::Yellow).fg(Color::Black))
.hide_status_line(); // or use `.status_line(..)` for styling the status lineDisplay absolute or relative line numbers:
use edtui::{EditorView, EditorState, EditorTheme, LineNumbers};
use ratatui::style::{Style, Color};
EditorView::new(&mut EditorState::default())
.theme(EditorTheme::default().line_numbers_style(Style::default().fg(Color::DarkGray)))
.line_numbers(LineNumbers::Absolute) // or LineNumbers::Relative
.render(area, buf);For search boxes and single-line input fields, enable single-line mode to block newline insertion:
use edtui::{EditorState, EditorView};
let mut state = EditorState::default();
EditorView::new(&mut state)
.single_line(true)
.render(area, buf);When enabled, newline insertion is blocked and pasting text with newlines will replace them with spaces.
Edtui supports mouse input for moving the cursor and selecting text.
Mouse handling is enabled by default via a feature toggle.
Typically, mouse events are processed automatically when you call on_event:
let event_handler = EditorEventHandler::default();
event_handler.on_event(event, &mut state); // handles mouse events tooIf you want finer control you can handle mouse events explicitly using on_mouse_event:
event_handler.on_mouse_event(mouse_event, &mut state);Syntax highlighting was added in version 0.8.4.
Edtui offers a number of custom themes, see [SyntaxHighlighter::theme] for a complete list.
If you want to use a custom theme, see [SyntaxHighlighter::custom_theme]. Check syntect
for more details about themes and extensions.
use edtui::{EditorView, EditorState, SyntaxHighlighter};
let syntax_highlighter = SyntaxHighlighter::new("dracula", "rs");
EditorView::new(&mut EditorState::default())
.syntax_highlighter(Some(syntax_highlighter))
.render(area, buf);If you want to enable paste (via ctrl+y or cmd+y) you must explicitly enable it at the start of your app:
use ratatui::crossterm::event::EnableBracketedPaste;
let mut stdout = std::io::stdout();
ratatui::crossterm::xecute!(stdout, EnableBracketedPaste);and disable it during cleanup:
use ratatui::crossterm::event::DisableBracketedPaste;
ratatui::crossterm::execute!(std::io::stdout(), DisableBracketedPaste);See examples/app/term.rs for a an example.
With the system-editor feature enabled you can open the editor content in an external
text editor (e.g., nvim) using Ctrl+e in normal mode (or Alt+e in Emacs mode).
The system editor is decoupled from the event handler. After handling events, check
if a system editor request is pending and call open yourself:
use edtui::system_editor;
event_handler.on_event(event, &mut state);
if system_editor::is_pending(&state) {
system_editor::open(&mut state, &mut terminal)?;
// Re-enable mouse capture or other terminal modes if necessary
// crossterm::execute!(stdout(), EnableMouseCapture, EnableBracketedPaste)?;
}The editor used is determined by the VISUAL or EDITOR environment variables,
falling back to a platform-specific default if neither is set.
EdTUI offers Vim keybindings by default and Emacs keybindings as an alternative.
| Keybinding | Description |
|---|---|
i |
Enter Insert mode |
v |
Enter Visual mode |
h, j, k, l |
Navigate left, down, up, and right |
w |
Move forward to the start of a word |
e |
Move forward to the end of a word |
b |
Move backward to the start of a word |
ctrl+d |
Jump a half page down |
ctrl+u |
Jump a half page up |
PageDown |
Jump a full page down |
PageUp |
Jump a full page up |
x |
Delete the character under the cursor |
u, ctrl+r |
Undo/Redo last action |
Esc |
Escape Visual mode |
0 |
Move cursor to start of line |
_ |
Move cursor to first non-blank character |
$ |
Move cursor to end of line |
gg |
Move cursor to the first row |
G |
Move cursor to the last row |
% |
Move cursor to closing/opening bracket |
a |
Append after the cursor |
A |
Append at the end of the line |
o |
Add a new line below and enter Insert mode |
O |
Add a new line above and enter Insert mode |
J |
Join current line with the line below |
d |
Delete the selection (Visual mode) |
dd |
Delete the current line |
D |
Delete to the end of the line |
viw |
Select between word. |
ciw |
Change between word. |
vi + ", ', (, [ or { |
Select between delimiter ", ', (, [ or { |
ci + ", ', (, [ or { |
Change between delimiter ", ', (, [ or { |
u |
Undo the last change |
r |
Redo the last undone action |
y |
Copy the selected text in visual mode |
yy |
Copy the current line in normal mode |
p |
Paste the copied text |
Home |
Move cursor to start of line |
End |
Move cursor to end of line |
ctrl+e |
Open in system editor (requires system-editor feature) |
| Keybinding | Description |
|---|---|
Esc |
Return to Normal mode |
Backspace |
Delete the previous character |
Delete |
Delete the character after the cursor |
Enter |
Insert line break |
Arrows |
Navigation |
Home |
Move cursor to start of line |
End |
Move cursor to end of line |
Ctrl+Left |
Move backward to the start of a word |
Ctrl+Right |
Move forward to the start of a word |
PageDown |
Jump a full page down |
PageUp |
Jump a full page up |
ctrl+u |
Delete until first character |
Emacs Mode was added in version 0.10.1.
Note that Emacs Mode is less feature complete and less tested than vim mode.
| Keybinding | Description |
|---|---|
Ctrl+f |
Move forward |
Ctrl+b |
Move backward |
Ctrl+n |
Move to next line |
Ctrl+p |
Move to previous line |
Ctrl+a |
Move to start of line |
Ctrl+e |
Move to end of line |
Ctrl+v |
Half page down |
Alt+v |
Half page up |
PageDown |
Full page down |
PageUp |
Full page up |
Alt+f |
Forward word |
Alt+b |
Backward word |
Alt+< |
Beginning of buffer |
Alt+> |
End of buffer |
Ctrl+d |
Delete character forward |
Ctrl+h |
Delete character backward |
Alt+d |
Delete word forward |
Alt+Backspace |
Delete word backward |
Ctrl+k |
Delete to end of line |
Alt+u |
Delete to start of line |
Ctrl+o |
Open line (insert newline, stay) |
Ctrl+j |
Newline |
Ctrl+y |
Paste |
Ctrl+u |
Undo |
Ctrl+r |
Redo |
Ctrl+g |
Cancel search |
Enter |
Insert line break |
Backspace |
Delete previous character |
Arrows |
Navigation |
Home |
Move to start of line |
End |
Move to end of line |
Ctrl+Left |
Move backward to the start of a word |
Ctrl+Right |
Move forward to the start of a word |
Alt+e |
Open in system editor (requires system-editor feature) |
Ctrl+s |
Start search |
Ctrl+s |
Search mode: Go to next match |
Ctrl+r |
Search mode: Go to previous match |
Enter |
Search mode: Select current match |
- Support termwiz and termion
License: MIT


