1use std::path::Path;
2
3#[derive(Debug, Clone, PartialEq, Eq)]
5pub struct EditorCommand {
6 pub program: String,
7 pub args: Vec<String>,
8 pub in_terminal: bool,
10}
11
12pub fn editor_command(editor: Option<&str>, file: &Path, line: usize) -> EditorCommand {
15 let file = file.display().to_string();
16 let mut words = editor.unwrap_or("").split_whitespace().map(str::to_string);
17 let Some(program) = words.next() else {
18 let opener = if cfg!(target_os = "macos") {
19 "open"
20 } else {
21 "xdg-open"
22 };
23 return EditorCommand {
24 program: opener.to_string(),
25 args: vec![file],
26 in_terminal: false,
27 };
28 };
29 let mut args: Vec<String> = words.collect();
30 let name = Path::new(&program)
31 .file_name()
32 .map(|name| name.to_string_lossy().into_owned())
33 .unwrap_or_default();
34
35 let in_terminal = matches!(
36 name.as_str(),
37 "vim" | "nvim" | "vi" | "nano" | "emacs" | "micro" | "hx" | "helix" | "kak"
38 );
39 match name.as_str() {
40 "code" | "code-insiders" | "cursor" | "windsurf" | "codium" => {
41 args.extend(["-g".to_string(), format!("{file}:{line}")])
42 }
43 "subl" | "zed" | "hx" | "helix" => args.push(format!("{file}:{line}")),
44 "vim" | "nvim" | "vi" | "nano" | "emacs" | "micro" | "kak" => {
45 args.extend([format!("+{line}"), file])
46 }
47 "xed" | "idea" | "pycharm" | "webstorm" | "fleet" | "mate" => {
48 args.extend(["--line".to_string(), line.to_string(), file])
49 }
50 _ => args.push(file),
51 }
52 EditorCommand {
53 program,
54 args,
55 in_terminal,
56 }
57}