tlc: implement actual TUI event loops for tlcedit and tlcview
Both open_file() functions were stubs that opened the file but never launched the terminal interface. tlcedit/tlcview would silently exit without displaying anything. - editor::open_file(): create Tui, render editor, run key event loop, handle Save/Close/SaveThenClose/DiscardThenClose results - viewer::open_file(): create Tui, render viewer, run key event loop, exit when handle_key returns true
This commit is contained in:
@@ -1334,18 +1334,58 @@ impl Editor {
|
||||
/// Backwards-compat shim for the old `open_file` API. The new API
|
||||
/// is to construct an [`Editor`] directly via [`Editor::open`].
|
||||
pub fn open_file(file: &str, line: Option<u64>) -> anyhow::Result<()> {
|
||||
use crate::terminal::event::translate_key;
|
||||
use crate::terminal::color::DEFAULT_THEME;
|
||||
use termion::event::Event as TermEvent;
|
||||
use termion::input::TermReadEventsAndRaw;
|
||||
|
||||
let mut ed = Editor::open(file);
|
||||
if let Some(n) = line {
|
||||
// Move cursor to the start of line `n` (1-based).
|
||||
let target = n.saturating_sub(1) as usize;
|
||||
if target < ed.buffer.line_count() {
|
||||
let off = ed.buffer.line_offset(target);
|
||||
ed.cursor.set_position(off, &ed.buffer);
|
||||
}
|
||||
}
|
||||
// No TTY to render to here; just return Ok so callers that just
|
||||
// want to verify the path can do so.
|
||||
let _ = ed;
|
||||
|
||||
let mut tui = crate::terminal::Tui::new()?;
|
||||
let stdin = std::io::stdin();
|
||||
let mut events = stdin.lock().events_and_raw();
|
||||
|
||||
loop {
|
||||
let (w, h) = tui.size();
|
||||
if w >= 10 && h >= 5 {
|
||||
let area = ratatui::layout::Rect::new(0, 0, w, h);
|
||||
tui.draw(|frame| {
|
||||
ed.render(frame, area, &DEFAULT_THEME);
|
||||
})?;
|
||||
}
|
||||
|
||||
let (event, _) = match events.next() {
|
||||
Some(Ok(pair)) => pair,
|
||||
Some(Err(_)) => continue,
|
||||
None => break,
|
||||
};
|
||||
let tk = match event {
|
||||
TermEvent::Key(k) => k,
|
||||
_ => continue,
|
||||
};
|
||||
let key = translate_key(tk);
|
||||
|
||||
match ed.handle_key(key) {
|
||||
EditorResult::Running => {}
|
||||
EditorResult::Save => {
|
||||
let _ = ed.save();
|
||||
}
|
||||
EditorResult::Close => break,
|
||||
EditorResult::SaveThenClose => {
|
||||
let _ = ed.save();
|
||||
break;
|
||||
}
|
||||
EditorResult::DiscardThenClose => break,
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
@@ -438,8 +438,42 @@ impl Viewer {
|
||||
|
||||
/// Backwards-compat shim: `open_file` was the Phase 0 stub.
|
||||
pub fn open_file(file: &str) -> Result<()> {
|
||||
let mut _v = Viewer::open(file)?;
|
||||
// Phase 3.2 will implement the actual TUI render loop.
|
||||
use crate::terminal::event::translate_key;
|
||||
use crate::terminal::color::DEFAULT_THEME;
|
||||
use termion::event::Event as TermEvent;
|
||||
use termion::input::TermReadEventsAndRaw;
|
||||
|
||||
let mut v = Viewer::open(file)?;
|
||||
|
||||
let mut tui = crate::terminal::Tui::new()?;
|
||||
let stdin = std::io::stdin();
|
||||
let mut events = stdin.lock().events_and_raw();
|
||||
|
||||
loop {
|
||||
let (w, h) = tui.size();
|
||||
if w >= 10 && h >= 5 {
|
||||
let area = ratatui::layout::Rect::new(0, 0, w, h);
|
||||
tui.draw(|frame| {
|
||||
v.render(frame, area, &DEFAULT_THEME);
|
||||
})?;
|
||||
}
|
||||
|
||||
let (event, _) = match events.next() {
|
||||
Some(Ok(pair)) => pair,
|
||||
Some(Err(_)) => continue,
|
||||
None => break,
|
||||
};
|
||||
let tk = match event {
|
||||
TermEvent::Key(k) => k,
|
||||
_ => continue,
|
||||
};
|
||||
let key = translate_key(tk);
|
||||
|
||||
if v.handle_key(key) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user