Text Editor in Rust egui — Open, Save & File Dialogs | Learn egui Ep32
Video: Text Editor in Rust egui — Open, Save & File Dialogs | Learn egui Ep32 by Taught by Celeste AI - AI Coding Coach
Watch full page →Text Editor in Rust egui — Open, Save & File Dialogs
This example demonstrates how to build a simple text editor in Rust using the egui GUI framework and the rfd crate for native file dialogs. It covers opening and saving files with filters, displaying a multiline text area with a monospace font, and managing the current file state with Option and PathBuf.
Code
use eframe::{egui, epi};
use egui::{TextEdit, TopBottomPanel, Layout, ScrollArea, TextStyle};
use rfd::FileDialog;
use std::fs;
use std::path::PathBuf;
struct TextEditorApp {
text: String,
current_file: Option<PathBuf>,
}
impl Default for TextEditorApp {
fn default() -> Self {
Self {
text: String::new(),
current_file: None,
}
}
}
impl epi::App for TextEditorApp {
fn name(&self) -> &str {
"egui Text Editor"
}
fn update(&mut self, ctx: &egui::Context, _frame: &epi::Frame) {
// Top toolbar panel with buttons
TopBottomPanel::top("toolbar").show(ctx, |ui| {
ui.horizontal(|ui| {
if ui.button("New").clicked() {
self.text.clear();
self.current_file = None;
}
if ui.button("Open").clicked() {
if let Some(path) = FileDialog::new()
.add_filter("Text", &["txt", "rs", "md", "toml"])
.pick_file()
{
if let Ok(contents) = fs::read_to_string(&path) {
self.text = contents;
self.current_file = Some(path);
}
}
}
if ui.button("Save").clicked() {
if let Some(path) = &self.current_file {
let _ = fs::write(path, &self.text);
} else {
// Delegate to Save As if no file selected
if let Some(path) = FileDialog::new()
.add_filter("Text", &["txt", "rs", "md", "toml"])
.save_file()
{
let _ = fs::write(&path, &self.text);
self.current_file = Some(path);
}
}
}
if ui.button("Save As").clicked() {
if let Some(path) = FileDialog::new()
.add_filter("Text", &["txt", "rs", "md", "toml"])
.save_file()
{
let _ = fs::write(&path, &self.text);
self.current_file = Some(path);
}
}
});
});
// Central scrollable multiline text editor
egui::CentralPanel::default().show(ctx, |ui| {
ScrollArea::vertical().show(ui, |ui| {
ui.add(
TextEdit::multiline(&mut self.text)
.font(TextStyle::Monospace) // Use monospace font
.desired_rows(20)
.lock_focus(true)
);
});
});
// Bottom status bar with character count aligned right
TopBottomPanel::bottom("status_bar").show(ctx, |ui| {
ui.with_layout(Layout::right_to_left(), |ui| {
ui.label(format!("{} chars", self.text.chars().count()));
});
});
}
}
fn main() {
let app = TextEditorApp::default();
let native_options = eframe::NativeOptions::default();
eframe::run_native(Box::new(app), native_options);
}
Key Points
- The rfd crate provides native file dialogs with FileDialog::new(), supporting filters and open/save modes.
- Use std::fs::read_to_string and fs::write for reading and writing file contents as Strings.
- Track the currently opened file with Option<PathBuf> to manage save behavior.
- egui's TextEdit::multiline with monospace font creates a comfortable text editing area.
- TopBottomPanel and Layout::right_to_left enable toolbar and status bar with aligned controls and info.