[tui] Add function for refreshing editor contents.

It's still temporary, but at least it isn't done ad-hoc.
This commit is contained in:
Shaun Reed 2026-01-19 18:01:35 -05:00
parent e65eb20048
commit bccc5a35e2
2 changed files with 32 additions and 14 deletions

View File

@ -8,6 +8,7 @@ use ratatui::layout::{Constraint, Direction, Layout, Rect};
use ratatui::prelude::{Color, Style, Widget};
use ratatui::widgets::{Block, Borders, Padding, Paragraph, Tabs, Wrap};
use ratatui::{DefaultTerminal, symbols};
use std::path::PathBuf;
use std::time::Duration;
pub struct App<'a> {
@ -16,7 +17,7 @@ pub struct App<'a> {
}
impl<'a> App<'a> {
pub(crate) fn new(root_path: std::path::PathBuf) -> Self {
pub(crate) fn new(root_path: PathBuf) -> Self {
let mut app = Self {
explorer: Explorer::new(&root_path),
editor: Editor::new(),
@ -90,6 +91,21 @@ impl<'a> App<'a> {
.wrap(Wrap { trim: false })
.render(area, buf);
}
/// Refresh the contents of the editor to match the selected TreeItem in the file Explorer.
/// If the selected item is not a file, this does nothing.
fn refresh_editor_contents(&mut self) {
if let Some(current_file_path) = self.editor.file_path.clone() {
if let Some(selected_path_string) = self.explorer.selected() {
let selected_pathbuf = PathBuf::from(selected_path_string);
if std::path::absolute(&selected_pathbuf).unwrap().is_file()
&& selected_pathbuf != current_file_path
{
self.editor.set_contents(&selected_pathbuf.into()).ok();
}
}
}
}
}
// TODO: Separate complex components into their own widgets.
@ -129,16 +145,7 @@ impl<'a> Widget for &mut App<'a> {
self.explorer.render(horizontal[0], buf);
self.draw_tabs(editor_layout[0], buf);
if let Some(editor) = self.editor.file_path.clone() {
let editor_abs = std::path::absolute(editor).unwrap();
if let Some(selected) = self.explorer.selected() {
let selected_abs = std::path::absolute(selected).unwrap();
if selected_abs.is_file() && selected_abs != editor_abs {
self.editor.set_contents(&selected_abs).ok();
}
}
}
self.refresh_editor_contents();
self.editor.render(editor_layout[1], buf);
}
}

View File

@ -9,6 +9,7 @@ use ratatui::crossterm::event::{Event, KeyCode, KeyEvent, KeyModifiers};
use ratatui::layout::{Alignment, Rect};
use ratatui::prelude::{Color, Style};
use ratatui::widgets::{Block, Borders, Padding, Widget};
use syntect::parsing::SyntaxSet;
// TODO: Consider using editor-command https://docs.rs/editor-command/latest/editor_command/
// TODO: Title should be detected programming language name
@ -52,20 +53,30 @@ impl Editor {
impl Widget for &mut Editor {
fn render(self, area: Rect, buf: &mut Buffer) {
// TODO: Use current file extension for syntax highlighting here.
let lang = self
.file_path
.as_ref()
.and_then(|p| p.extension())
.map(|e| e.to_str().unwrap_or("md"))
.unwrap_or("md");
let lang_name = SyntaxSet::load_defaults_nonewlines()
.find_syntax_by_extension(lang)
.map(|s| s.name.to_string())
.unwrap_or_else(|| "Unknown".to_string());
EditorView::new(&mut self.state)
.wrap(true)
.theme(
EditorTheme::default().block(
Block::default()
.title("Rust")
.title(lang_name.to_owned())
.title_style(Style::default().fg(Color::Yellow))
.title_alignment(Alignment::Right)
.borders(Borders::ALL)
.padding(Padding::new(0, 0, 0, 1)),
),
)
.syntax_highlighter(SyntaxHighlighter::new("dracula", "rs").ok())
.syntax_highlighter(SyntaxHighlighter::new("dracula", lang).ok())
.tab_width(2)
.line_numbers(LineNumbers::Absolute)
.render(area, buf);