1use nvim_oxi::Dictionary;
2use ytil_zellij::Direction;
3
4use crate::buffer::token_under_cursor;
5use crate::buffer::token_under_cursor::TokenUnderCursor;
6
7pub fn dict() -> Dictionary {
8 dict! {
9 "open_token_under_cursor": fn_from!(open_token_under_cursor),
10 "copy_enclosing_function": fn_from!(copy_enclosing_function),
11 "reveal_in_finder": fn_from!(reveal_in_finder),
12 }
13}
14
15fn copy_enclosing_function(_: ()) -> Option<()> {
16 let file_path = ytil_noxi::buffer::get_absolute_path(Some(&nvim_oxi::api::get_current_buf()))?;
17 let enclosing_fn = ytil_noxi::tree_sitter::get_enclosing_fn_name_of_position(&file_path)?;
18 ytil_sys::file::cp_to_system_clipboard(&mut enclosing_fn.as_bytes())
19 .inspect_err(|err| {
20 ytil_noxi::notify::error(format!(
21 "error copying content to system clipboard | content={enclosing_fn:?} error={err:#?}"
22 ));
23 })
24 .ok()?;
25 nvim_oxi::print!("Enclosing fn name copied to clipboard: {enclosing_fn}");
26 Some(())
27}
28
29fn open_token_under_cursor(_: ()) -> Option<()> {
30 let token_under_cursor = token_under_cursor::get(())?;
31
32 match token_under_cursor {
33 TokenUnderCursor::BinaryFile(_) | TokenUnderCursor::MaybeTextFile { .. } => None,
34 TokenUnderCursor::TextFile { path, lnum, col } => {
35 let open = if ytil_zellij::is_active() {
36 open_in_zellij_pane
37 } else {
38 open_in_nvim_split
39 };
40 open(&path, lnum, col)
41 }
42 TokenUnderCursor::Url(arg) | TokenUnderCursor::Directory(arg) => ytil_sys::open(&arg)
43 .inspect_err(|err| {
44 ytil_noxi::notify::error(format!("{err:?}"));
45 })
46 .ok(),
47 }
48}
49
50fn open_in_zellij_pane(path: &str, lnum: Option<i64>, col: Option<i64>) -> Option<()> {
51 let cursor_cmd = format!("call cursor({}, {})", lnum.unwrap_or_default(), col.unwrap_or_default());
52
53 let result = ytil_zellij::pane_count().and_then(|pane_count| {
54 if pane_count > 1 {
55 ytil_zellij::move_focus(Direction::Right)?;
56 let is_nvim =
57 ytil_zellij::focused_pane_command()?.is_some_and(|cmd| cmd.contains("nvim") || cmd.contains("vim"));
58 if is_nvim {
59 ytil_zellij::write_byte(0x1b)?;
60 ytil_zellij::write_chars(&format!(":edit {path} | {cursor_cmd}\r"))?;
61 } else {
62 let cursor_arg = format!("+'{cursor_cmd}'");
63 ytil_zellij::write_chars(&format!("nvim {cursor_arg} {path}\r"))?;
64 }
65 return Ok(());
66 }
67 let cursor_arg = format!("+'{cursor_cmd}'");
68 ytil_zellij::new_pane(Direction::Right, &["nvim", &cursor_arg, path])?;
69 ytil_zellij::resize_increase(Direction::Left, 3)?;
70 Ok(())
71 });
72
73 result
74 .inspect_err(|err| ytil_noxi::notify::error(format!("{err:#?}")))
75 .ok()
76}
77
78fn open_in_nvim_split(path: &str, lnum: Option<i64>, col: Option<i64>) -> Option<()> {
79 let open_path_cmd = format!(
80 "edit {path} | call cursor({}, {})",
81 lnum.unwrap_or_default(),
82 col.unwrap_or_default()
83 );
84
85 let vim_script = if let Some(win_num) =
86 ytil_noxi::window::find_with_buffer("").and_then(|(win, _)| ytil_noxi::window::get_number(&win))
87 {
88 format!("{win_num} wincmd w | {open_path_cmd}")
89 } else {
90 let width = crate::layout::compute_width(70)?;
91 format!("vsplit | vertical resize {width} | {open_path_cmd}")
92 };
93
94 ytil_noxi::common::exec_vim_script(&vim_script, None);
95 Some(())
96}
97
98fn reveal_in_finder(_: ()) -> Option<()> {
99 let file_path = ytil_noxi::buffer::get_absolute_path(Some(&nvim_oxi::api::get_current_buf()))?;
100 let Some(parent) = file_path.parent() else {
101 ytil_noxi::notify::error(format!(
102 "error no parent for current buffer file path | file_path={}",
103 file_path.display()
104 ));
105 return None;
106 };
107 let Some(parent_str) = parent.to_str() else {
108 ytil_noxi::notify::error(format!(
109 "error parent path is not valid UTF-8 | path={}",
110 parent.display()
111 ));
112 return None;
113 };
114 ytil_sys::open(parent_str)
115 .inspect_err(|err| {
116 ytil_noxi::notify::error(format!("error opening path | path={} error={err:#?}", parent.display()));
117 })
118 .ok()?;
119 Some(())
120}