From 4e4863e12229aab1e8be1c70720f4351f7713c01 Mon Sep 17 00:00:00 2001 From: vasilito Date: Sat, 20 Jun 2026 10:26:28 +0300 Subject: [PATCH] =?UTF-8?q?tlc:=20FM=E2=86=92editor/viewer=20handoff=20wit?= =?UTF-8?q?h=20line=20numbers?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit FindOutcome::View/Edit now carry Option line number from FindHit. FileManager gains open_editor_at_line() and open_viewer_at_line() that jump to the target line after opening. --- .../tlc/source/src/filemanager/dialog_ops.rs | 36 ++++++++++++++++--- .../tui/tlc/source/src/filemanager/find.rs | 12 +++---- 2 files changed, 38 insertions(+), 10 deletions(-) diff --git a/local/recipes/tui/tlc/source/src/filemanager/dialog_ops.rs b/local/recipes/tui/tlc/source/src/filemanager/dialog_ops.rs index d1faed9714..1d469c488e 100644 --- a/local/recipes/tui/tlc/source/src/filemanager/dialog_ops.rs +++ b/local/recipes/tui/tlc/source/src/filemanager/dialog_ops.rs @@ -9,6 +9,7 @@ //! themselves via a `confirmed`/`cancelled` flag. use anyhow::Result; +use std::path::Path; use crate::filemanager::{ config_dialog, edit_history, external_panelize, filtered_view, find, help, hotlist, @@ -257,6 +258,26 @@ impl FileManager { Ok(()) } + /// Open the F4 editor at a specific 1-based line number. + pub fn open_editor_at_line(&mut self, path: &Path, line: u32) { + let mut ed = crate::editor::Editor::open(path); + ed.goto_line(line); + self.editor = Some(ed); + self.status.set_message(format!("Editing {}:{}", path.display(), line)); + } + + /// Open the F3 viewer at a specific 1-based line number. + pub fn open_viewer_at_line(&mut self, path: &Path, line: u64) { + match crate::viewer::Viewer::open(path) { + Ok(mut v) => { + let _ = v.goto_line(line); + self.viewer = Some(v); + self.status.set_message(format!("Viewing {}:{}", path.display(), line)); + } + Err(e) => self.status.set_message(format!("view: {e}")), + } + } + /// Open the F3 viewer for the cursor entry. pub fn open_viewer_for_cursor(&mut self) -> Result<()> { let p = self.active_panel().cursor_path(); @@ -549,16 +570,23 @@ impl FileManager { FindOutcome::Open(path) => { self.open_file_via_path(&path); } - FindOutcome::View(path) => match crate::viewer::Viewer::open(&path) { - Ok(v) => { + FindOutcome::View(path, line) => match crate::viewer::Viewer::open(&path) { + Ok(mut v) => { + if let Some(ln) = line { + v.jump_to_line(ln); + } self.viewer = Some(v); self.status .set_message(format!("Viewing {}", path.display())); } Err(e) => self.status.set_message(format!("view: {e}")), }, - FindOutcome::Edit(path) => { - self.editor = Some(crate::editor::Editor::open(&path)); + FindOutcome::Edit(path, line) => { + let mut ed = crate::editor::Editor::open(&path); + if let Some(ln) = line { + ed.goto_line(ln as u32); + } + self.editor = Some(ed); self.status .set_message(format!("Editing {}", path.display())); } diff --git a/local/recipes/tui/tlc/source/src/filemanager/find.rs b/local/recipes/tui/tlc/source/src/filemanager/find.rs index f1d1e35f61..6445d79ddf 100644 --- a/local/recipes/tui/tlc/source/src/filemanager/find.rs +++ b/local/recipes/tui/tlc/source/src/filemanager/find.rs @@ -93,9 +93,9 @@ pub enum FindOutcome { /// directory in the active panel. Open(PathBuf), /// User pressed F3 on a hit — open the file in the viewer. - View(PathBuf), + View(PathBuf, Option), /// User pressed F4 on a hit — open the file in the editor. - Edit(PathBuf), + Edit(PathBuf, Option), /// User pressed Esc — close the dialog and do nothing. Cancel, } @@ -231,13 +231,13 @@ impl FindDialog { return self .results .get(self.cursor) - .map_or(FindOutcome::Running, |h| FindOutcome::View(h.path.clone())); + .map_or(FindOutcome::Running, |h| FindOutcome::View(h.path.clone(), h.line)); } if key == Key::f(4) { return self .results .get(self.cursor) - .map_or(FindOutcome::Running, |h| FindOutcome::Edit(h.path.clone())); + .map_or(FindOutcome::Running, |h| FindOutcome::Edit(h.path.clone(), h.line)); } match key { Key::ESCAPE => FindOutcome::Cancel, @@ -630,7 +630,7 @@ mod tests { // "a.txt" (matches the `a.txt` fixture file). type_pattern(&mut d, "a.txt"); match d.handle_key(Key::f(3)) { - FindOutcome::View(p) => assert_eq!(p, dir.join("a.txt")), + FindOutcome::View(p, _) => assert_eq!(p, dir.join("a.txt")), other => panic!("expected View, got {other:?}"), } let _ = fs::remove_dir_all(&dir); @@ -642,7 +642,7 @@ mod tests { let mut d = FindDialog::new(dir.clone()); type_pattern(&mut d, "a.txt"); match d.handle_key(Key::f(4)) { - FindOutcome::Edit(p) => assert_eq!(p, dir.join("a.txt")), + FindOutcome::Edit(p, _) => assert_eq!(p, dir.join("a.txt")), other => panic!("expected Edit, got {other:?}"), } let _ = fs::remove_dir_all(&dir);