tlc: FM→editor/viewer handoff with line numbers
FindOutcome::View/Edit now carry Option<u64> line number from FindHit. FileManager gains open_editor_at_line() and open_viewer_at_line() that jump to the target line after opening.
This commit is contained in:
@@ -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()));
|
||||
}
|
||||
|
||||
@@ -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<u64>),
|
||||
/// User pressed F4 on a hit — open the file in the editor.
|
||||
Edit(PathBuf),
|
||||
Edit(PathBuf, Option<u64>),
|
||||
/// 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);
|
||||
|
||||
Reference in New Issue
Block a user