yazi_actor/
context.rs

1use std::ops::{Deref, DerefMut};
2
3use anyhow::{Result, anyhow};
4use yazi_core::{Core, mgr::Tabs, tab::{Folder, Tab}, tasks::Tasks};
5use yazi_fs::File;
6use yazi_shared::{Id, Source, event::Cmd, url::UrlBuf};
7
8pub struct Ctx<'a> {
9	pub core:      &'a mut Core,
10	pub tab:       usize,
11	pub level:     usize,
12	pub source:    Source,
13	#[cfg(debug_assertions)]
14	pub backtrace: Vec<&'static str>,
15}
16
17impl Deref for Ctx<'_> {
18	type Target = Core;
19
20	fn deref(&self) -> &Self::Target { self.core }
21}
22
23impl DerefMut for Ctx<'_> {
24	fn deref_mut(&mut self) -> &mut Self::Target { self.core }
25}
26
27impl<'a> Ctx<'a> {
28	#[inline]
29	pub fn new(core: &'a mut Core, cmd: &Cmd) -> Result<Self> {
30		let tab = if let Ok(id) = cmd.get::<Id>("tab") {
31			core
32				.mgr
33				.tabs
34				.iter()
35				.position(|t| t.id == id)
36				.ok_or_else(|| anyhow!("Tab with id {id} not found"))?
37		} else {
38			core.mgr.tabs.cursor
39		};
40
41		Ok(Self {
42			core,
43			tab,
44			level: 0,
45			source: cmd.source,
46			#[cfg(debug_assertions)]
47			backtrace: vec![],
48		})
49	}
50
51	#[inline]
52	pub fn renew<'b>(cx: &'a mut Ctx<'b>) -> Self {
53		let tab = cx.core.mgr.tabs.cursor;
54		Self {
55			core: cx.core,
56			tab,
57			level: cx.level,
58			source: cx.source,
59			#[cfg(debug_assertions)]
60			backtrace: vec![],
61		}
62	}
63
64	#[inline]
65	pub fn active(core: &'a mut Core) -> Self {
66		let tab = core.mgr.tabs.cursor;
67		Self {
68			core,
69			tab,
70			level: 0,
71			source: Source::Unknown,
72			#[cfg(debug_assertions)]
73			backtrace: vec![],
74		}
75	}
76}
77
78impl<'a> Ctx<'a> {
79	#[inline]
80	pub fn tabs(&self) -> &Tabs { &self.mgr.tabs }
81
82	#[inline]
83	pub fn tabs_mut(&mut self) -> &mut Tabs { &mut self.mgr.tabs }
84
85	#[inline]
86	pub fn tab(&self) -> &Tab { &self.tabs()[self.tab] }
87
88	#[inline]
89	pub fn tab_mut(&mut self) -> &mut Tab { &mut self.core.mgr.tabs[self.tab] }
90
91	#[inline]
92	pub fn cwd(&self) -> &UrlBuf { self.tab().cwd() }
93
94	#[inline]
95	pub fn parent(&self) -> Option<&Folder> { self.tab().parent.as_ref() }
96
97	#[inline]
98	pub fn parent_mut(&mut self) -> Option<&mut Folder> { self.tab_mut().parent.as_mut() }
99
100	#[inline]
101	pub fn current(&self) -> &Folder { &self.tab().current }
102
103	#[inline]
104	pub fn current_mut(&mut self) -> &mut Folder { &mut self.tab_mut().current }
105
106	#[inline]
107	pub fn hovered(&self) -> Option<&File> { self.tab().hovered() }
108
109	#[inline]
110	pub fn hovered_folder(&self) -> Option<&Folder> { self.tab().hovered_folder() }
111
112	#[inline]
113	pub fn hovered_folder_mut(&mut self) -> Option<&mut Folder> {
114		self.tab_mut().hovered_folder_mut()
115	}
116
117	#[inline]
118	pub fn tasks(&self) -> &Tasks { &self.tasks }
119
120	#[inline]
121	pub fn source(&self) -> Source { if self.level != 1 { Source::Ind } else { self.source } }
122}