diff options
Diffstat (limited to 'src/app/ids.rs')
| -rw-r--r-- | src/app/ids.rs | 82 |
1 files changed, 82 insertions, 0 deletions
diff --git a/src/app/ids.rs b/src/app/ids.rs new file mode 100644 index 00000000..490e6051 --- /dev/null +++ b/src/app/ids.rs @@ -0,0 +1,82 @@ +use super::App; + +impl App { + pub(super) fn find_pane( + &self, + pane_id: crate::layout::PaneId, + ) -> Option<(usize, &crate::pane::PaneState)> { + self.state + .workspaces + .iter() + .enumerate() + .find_map(|(ws_idx, ws)| ws.pane_state(pane_id).map(|pane| (ws_idx, pane))) + } + + pub(super) fn public_workspace_id(&self, ws_idx: usize) -> String { + self.state.workspaces[ws_idx].id.clone() + } + + pub(super) fn public_tab_id(&self, ws_idx: usize, tab_idx: usize) -> Option<String> { + let ws = self.state.workspaces.get(ws_idx)?; + ws.tabs.get(tab_idx)?; + Some(format!("{}:{}", ws.id, tab_idx + 1)) + } + + pub(super) fn public_pane_id( + &self, + ws_idx: usize, + pane_id: crate::layout::PaneId, + ) -> Option<String> { + let ws = self.state.workspaces.get(ws_idx)?; + let pane_number = ws.public_pane_number(pane_id)?; + Some(format!("{}-{pane_number}", ws.id)) + } + + pub(super) fn parse_workspace_id(&self, id: &str) -> Option<usize> { + self.state + .workspaces + .iter() + .position(|workspace| workspace.id == id) + .or_else(|| id.strip_prefix("w_")?.parse::<usize>().ok()?.checked_sub(1)) + .or_else(|| id.parse::<usize>().ok()?.checked_sub(1)) + } + + pub(super) fn parse_tab_id(&self, id: &str) -> Option<(usize, usize)> { + if let Some(rest) = id.strip_prefix("t_") { + let (ws_raw, tab_raw) = rest.rsplit_once('_')?; + let ws_idx = self.parse_workspace_id(ws_raw)?; + let tab_idx = tab_raw.parse::<usize>().ok()?.checked_sub(1)?; + self.state.workspaces.get(ws_idx)?.tabs.get(tab_idx)?; + return Some((ws_idx, tab_idx)); + } + + let (ws_raw, tab_raw) = id.rsplit_once(':')?; + let ws_idx = self.parse_workspace_id(ws_raw)?; + let tab_idx = tab_raw.parse::<usize>().ok()?.checked_sub(1)?; + self.state.workspaces.get(ws_idx)?.tabs.get(tab_idx)?; + Some((ws_idx, tab_idx)) + } + + pub(super) fn parse_pane_id(&self, id: &str) -> Option<(usize, crate::layout::PaneId)> { + if let Some(rest) = id.strip_prefix("p_") { + if let Some((ws_raw, pane_raw)) = rest.rsplit_once('_') { + let ws_idx = self.parse_workspace_id(ws_raw)?; + let pane_id = crate::layout::PaneId::from_raw(pane_raw.parse::<u32>().ok()?); + return Some((ws_idx, pane_id)); + } + + let pane_id = crate::layout::PaneId::from_raw(rest.parse::<u32>().ok()?); + return self.find_pane(pane_id).map(|(ws_idx, _)| (ws_idx, pane_id)); + } + + let (ws_raw, pane_number_raw) = id.rsplit_once('-')?; + let ws_idx = self.parse_workspace_id(ws_raw)?; + let pane_number = pane_number_raw.parse::<usize>().ok()?; + let ws = self.state.workspaces.get(ws_idx)?; + let pane_id = ws + .public_pane_numbers + .iter() + .find_map(|(pane_id, number)| (*number == pane_number).then_some(*pane_id))?; + Some((ws_idx, pane_id)) + } +} |
