feat(ux): improve multiple select (#4221)
* intercept/clear-intercept key APIs * allow opening a pinned unfocused floating pane * rework plugin * improve some apis * fix tests * tests for pane groups * more exact placement and tests * plugin command permission and cleanup * improve some multiselect ux * improve plugin ui * remove old status indicator * allow moving plugin out of the way * style(fmt): rustfmt * update plugins * remove old keybinding * cleanups * fix: only rename pane if needed * changelog and some cleanups * style(fmt): rustfmt
This commit is contained in:
parent
226f5dc854
commit
a9f8bbcd19
59 changed files with 2192 additions and 3972 deletions
|
|
@ -5,7 +5,7 @@ All notable changes to this project will be documented in this file.
|
||||||
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/)
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
* feat: multiple select and bulk pane actions (https://github.com/zellij-org/zellij/pull/4169 and https://github.com/zellij-org/zellij/pull/4171)
|
* feat: multiple select and bulk pane actions (https://github.com/zellij-org/zellij/pull/4169 and https://github.com/zellij-org/zellij/pull/4171 and https://github.com/zellij-org/zellij/pull/4221)
|
||||||
|
|
||||||
## [0.42.2] - 2025-04-15
|
## [0.42.2] - 2025-04-15
|
||||||
* refactor(terminal): track scroll_region as tuple rather than Option (https://github.com/zellij-org/zellij/pull/4082)
|
* refactor(terminal): track scroll_region as tuple rather than Option (https://github.com/zellij-org/zellij/pull/4082)
|
||||||
|
|
|
||||||
|
|
@ -2,7 +2,6 @@ use ansi_term::ANSIStrings;
|
||||||
use unicode_width::UnicodeWidthStr;
|
use unicode_width::UnicodeWidthStr;
|
||||||
|
|
||||||
use crate::{LinePart, ARROW_SEPARATOR};
|
use crate::{LinePart, ARROW_SEPARATOR};
|
||||||
use zellij_tile::prelude::actions::Action;
|
|
||||||
use zellij_tile::prelude::*;
|
use zellij_tile::prelude::*;
|
||||||
use zellij_tile_utils::style;
|
use zellij_tile_utils::style;
|
||||||
|
|
||||||
|
|
@ -252,8 +251,6 @@ pub fn tab_line(
|
||||||
mode: InputMode,
|
mode: InputMode,
|
||||||
active_swap_layout_name: &Option<String>,
|
active_swap_layout_name: &Option<String>,
|
||||||
is_swap_layout_dirty: bool,
|
is_swap_layout_dirty: bool,
|
||||||
mode_info: &ModeInfo,
|
|
||||||
grouped_pane_count: Option<usize>,
|
|
||||||
) -> Vec<LinePart> {
|
) -> Vec<LinePart> {
|
||||||
let mut tabs_after_active = all_tabs.split_off(active_tab_index);
|
let mut tabs_after_active = all_tabs.split_off(active_tab_index);
|
||||||
let mut tabs_before_active = all_tabs;
|
let mut tabs_before_active = all_tabs;
|
||||||
|
|
@ -289,21 +286,15 @@ pub fn tab_line(
|
||||||
if current_title_len < cols {
|
if current_title_len < cols {
|
||||||
let mut remaining_space = cols - current_title_len;
|
let mut remaining_space = cols - current_title_len;
|
||||||
let remaining_bg = palette.text_unselected.background;
|
let remaining_bg = palette.text_unselected.background;
|
||||||
let right_side_component = match grouped_pane_count {
|
if let Some(swap_layout_status) = swap_layout_status(
|
||||||
Some(grouped_pane_count) => {
|
|
||||||
render_group_controls(mode_info, grouped_pane_count, remaining_space)
|
|
||||||
},
|
|
||||||
None => swap_layout_status(
|
|
||||||
remaining_space,
|
remaining_space,
|
||||||
active_swap_layout_name,
|
active_swap_layout_name,
|
||||||
is_swap_layout_dirty,
|
is_swap_layout_dirty,
|
||||||
mode,
|
mode,
|
||||||
&palette,
|
&palette,
|
||||||
tab_separator(capabilities),
|
tab_separator(capabilities),
|
||||||
),
|
) {
|
||||||
};
|
remaining_space -= swap_layout_status.len;
|
||||||
if let Some(right_side_component) = right_side_component {
|
|
||||||
remaining_space -= right_side_component.len;
|
|
||||||
let mut buffer = String::new();
|
let mut buffer = String::new();
|
||||||
for _ in 0..remaining_space {
|
for _ in 0..remaining_space {
|
||||||
buffer.push_str(&style!(remaining_bg, remaining_bg).paint(" ").to_string());
|
buffer.push_str(&style!(remaining_bg, remaining_bg).paint(" ").to_string());
|
||||||
|
|
@ -313,7 +304,7 @@ pub fn tab_line(
|
||||||
len: remaining_space,
|
len: remaining_space,
|
||||||
tab_index: None,
|
tab_index: None,
|
||||||
});
|
});
|
||||||
prefix.push(right_side_component);
|
prefix.push(swap_layout_status);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -382,274 +373,3 @@ fn swap_layout_status(
|
||||||
None => None,
|
None => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_group_controls(
|
|
||||||
help: &ModeInfo,
|
|
||||||
grouped_pane_count: usize,
|
|
||||||
max_len: usize,
|
|
||||||
) -> Option<LinePart> {
|
|
||||||
let currently_marking_group = help.currently_marking_pane_group.unwrap_or(false);
|
|
||||||
let keymap = help.get_mode_keybinds();
|
|
||||||
let (common_modifiers, multiple_select_key, pane_group_toggle_key, group_mark_toggle_key) = {
|
|
||||||
let multiple_select_key = multiple_select_key(&keymap);
|
|
||||||
let pane_group_toggle_key = single_action_key(&keymap, &[Action::TogglePaneInGroup]);
|
|
||||||
let group_mark_toggle_key = single_action_key(&keymap, &[Action::ToggleGroupMarking]);
|
|
||||||
let common_modifiers = get_common_modifiers(
|
|
||||||
vec![
|
|
||||||
multiple_select_key.iter().next(),
|
|
||||||
pane_group_toggle_key.iter().next(),
|
|
||||||
group_mark_toggle_key.iter().next(),
|
|
||||||
]
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|k| k)
|
|
||||||
.collect(),
|
|
||||||
);
|
|
||||||
let multiple_select_key: Vec<KeyWithModifier> = multiple_select_key
|
|
||||||
.iter()
|
|
||||||
.map(|k| k.strip_common_modifiers(&common_modifiers))
|
|
||||||
.collect();
|
|
||||||
let pane_group_toggle_key: Vec<KeyWithModifier> = pane_group_toggle_key
|
|
||||||
.iter()
|
|
||||||
.map(|k| k.strip_common_modifiers(&common_modifiers))
|
|
||||||
.collect();
|
|
||||||
let group_mark_toggle_key: Vec<KeyWithModifier> = group_mark_toggle_key
|
|
||||||
.iter()
|
|
||||||
.map(|k| k.strip_common_modifiers(&common_modifiers))
|
|
||||||
.collect();
|
|
||||||
(
|
|
||||||
common_modifiers,
|
|
||||||
multiple_select_key,
|
|
||||||
pane_group_toggle_key,
|
|
||||||
group_mark_toggle_key,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let multiple_select_key = multiple_select_key
|
|
||||||
.iter()
|
|
||||||
.next()
|
|
||||||
.map(|key| format!("{}", key))
|
|
||||||
.unwrap_or("UNBOUND".to_owned());
|
|
||||||
let pane_group_toggle_key = pane_group_toggle_key
|
|
||||||
.iter()
|
|
||||||
.next()
|
|
||||||
.map(|key| format!("{}", key))
|
|
||||||
.unwrap_or("UNBOUND".to_owned());
|
|
||||||
let group_mark_toggle_key = group_mark_toggle_key
|
|
||||||
.iter()
|
|
||||||
.next()
|
|
||||||
.map(|key| format!("{}", key))
|
|
||||||
.unwrap_or("UNBOUND".to_owned());
|
|
||||||
let background = help.style.colors.text_unselected.background;
|
|
||||||
let foreground = help.style.colors.text_unselected.base;
|
|
||||||
let superkey_prefix_style = style!(foreground, background).bold();
|
|
||||||
let common_modifier_text = if common_modifiers.is_empty() {
|
|
||||||
"".to_owned()
|
|
||||||
} else {
|
|
||||||
format!(
|
|
||||||
"{} + ",
|
|
||||||
common_modifiers
|
|
||||||
.iter()
|
|
||||||
.map(|c| c.to_string())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("-")
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
// full
|
|
||||||
let full_selected_panes_text = if common_modifier_text.is_empty() {
|
|
||||||
format!("{} SELECTED PANES", grouped_pane_count)
|
|
||||||
} else {
|
|
||||||
format!("{} SELECTED PANES |", grouped_pane_count)
|
|
||||||
};
|
|
||||||
let full_group_actions_text = format!("<{}> Group Actions", &multiple_select_key);
|
|
||||||
let full_toggle_group_text = format!("<{}> Toggle Group", &pane_group_toggle_key);
|
|
||||||
let full_group_mark_toggle_text = format!("<{}> Follow Focus", &group_mark_toggle_key);
|
|
||||||
let ribbon_paddings_len = 12;
|
|
||||||
let full_controls_line_len = full_selected_panes_text.chars().count()
|
|
||||||
+ 1
|
|
||||||
+ common_modifier_text.chars().count()
|
|
||||||
+ full_group_actions_text.chars().count()
|
|
||||||
+ full_toggle_group_text.chars().count()
|
|
||||||
+ full_group_mark_toggle_text.chars().count()
|
|
||||||
+ ribbon_paddings_len
|
|
||||||
+ 1; // 1 for the end padding
|
|
||||||
|
|
||||||
// medium
|
|
||||||
let medium_selected_panes_text = if common_modifier_text.is_empty() {
|
|
||||||
format!("{} SELECTED", grouped_pane_count)
|
|
||||||
} else {
|
|
||||||
format!("{} SELECTED |", grouped_pane_count)
|
|
||||||
};
|
|
||||||
let medium_group_actions_text = format!("<{}> Actions", &multiple_select_key);
|
|
||||||
let medium_toggle_group_text = format!("<{}> Toggle", &pane_group_toggle_key);
|
|
||||||
let medium_group_mark_toggle_text = format!("<{}> Follow", &group_mark_toggle_key);
|
|
||||||
let ribbon_paddings_len = 12;
|
|
||||||
let medium_controls_line_len = medium_selected_panes_text.chars().count()
|
|
||||||
+ 1
|
|
||||||
+ common_modifier_text.chars().count()
|
|
||||||
+ medium_group_actions_text.chars().count()
|
|
||||||
+ medium_toggle_group_text.chars().count()
|
|
||||||
+ medium_group_mark_toggle_text.chars().count()
|
|
||||||
+ ribbon_paddings_len
|
|
||||||
+ 1; // 1 for the end padding
|
|
||||||
|
|
||||||
// short
|
|
||||||
let short_selected_panes_text = if common_modifier_text.is_empty() {
|
|
||||||
format!("{} SELECTED", grouped_pane_count)
|
|
||||||
} else {
|
|
||||||
format!("{} SELECTED |", grouped_pane_count)
|
|
||||||
};
|
|
||||||
let short_group_actions_text = format!("<{}>", &multiple_select_key);
|
|
||||||
let short_toggle_group_text = format!("<{}>", &pane_group_toggle_key);
|
|
||||||
let short_group_mark_toggle_text = format!("<{}>", &group_mark_toggle_key);
|
|
||||||
let color_emphasis_range_end = if common_modifier_text.is_empty() {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
2
|
|
||||||
};
|
|
||||||
let ribbon_paddings_len = 12;
|
|
||||||
let short_controls_line_len = short_selected_panes_text.chars().count()
|
|
||||||
+ 1
|
|
||||||
+ common_modifier_text.chars().count()
|
|
||||||
+ short_group_actions_text.chars().count()
|
|
||||||
+ short_toggle_group_text.chars().count()
|
|
||||||
+ short_group_mark_toggle_text.chars().count()
|
|
||||||
+ ribbon_paddings_len
|
|
||||||
+ 1; // 1 for the end padding
|
|
||||||
|
|
||||||
let (
|
|
||||||
selected_panes_text,
|
|
||||||
group_actions_text,
|
|
||||||
toggle_group_text,
|
|
||||||
group_mark_toggle_text,
|
|
||||||
controls_line_len,
|
|
||||||
) = if max_len >= full_controls_line_len {
|
|
||||||
(
|
|
||||||
full_selected_panes_text,
|
|
||||||
full_group_actions_text,
|
|
||||||
full_toggle_group_text,
|
|
||||||
full_group_mark_toggle_text,
|
|
||||||
full_controls_line_len,
|
|
||||||
)
|
|
||||||
} else if max_len >= medium_controls_line_len {
|
|
||||||
(
|
|
||||||
medium_selected_panes_text,
|
|
||||||
medium_group_actions_text,
|
|
||||||
medium_toggle_group_text,
|
|
||||||
medium_group_mark_toggle_text,
|
|
||||||
medium_controls_line_len,
|
|
||||||
)
|
|
||||||
} else if max_len >= short_controls_line_len {
|
|
||||||
(
|
|
||||||
short_selected_panes_text,
|
|
||||||
short_group_actions_text,
|
|
||||||
short_toggle_group_text,
|
|
||||||
short_group_mark_toggle_text,
|
|
||||||
short_controls_line_len,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
let selected_panes = serialize_text(
|
|
||||||
&Text::new(&selected_panes_text)
|
|
||||||
.color_range(
|
|
||||||
3,
|
|
||||||
..selected_panes_text
|
|
||||||
.chars()
|
|
||||||
.count()
|
|
||||||
.saturating_sub(color_emphasis_range_end),
|
|
||||||
)
|
|
||||||
.opaque(),
|
|
||||||
);
|
|
||||||
let group_actions_ribbon = serialize_ribbon(
|
|
||||||
&Text::new(&group_actions_text).color_range(0, 1..=multiple_select_key.chars().count()),
|
|
||||||
);
|
|
||||||
let toggle_group_ribbon = serialize_ribbon(
|
|
||||||
&Text::new(&toggle_group_text).color_range(0, 1..=pane_group_toggle_key.chars().count()),
|
|
||||||
);
|
|
||||||
let mut group_mark_toggle_ribbon = Text::new(&group_mark_toggle_text)
|
|
||||||
.color_range(0, 1..=group_mark_toggle_key.chars().count());
|
|
||||||
if currently_marking_group {
|
|
||||||
group_mark_toggle_ribbon = group_mark_toggle_ribbon.selected();
|
|
||||||
}
|
|
||||||
let group_mark_toggle_ribbon = serialize_ribbon(&group_mark_toggle_ribbon);
|
|
||||||
let controls_line = if common_modifiers.is_empty() {
|
|
||||||
format!(
|
|
||||||
"{} {}{}{}",
|
|
||||||
selected_panes, group_actions_ribbon, toggle_group_ribbon, group_mark_toggle_ribbon
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
let common_modifier =
|
|
||||||
serialize_text(&Text::new(&common_modifier_text).color_range(0, ..).opaque());
|
|
||||||
format!(
|
|
||||||
"{} {}{}{}{}",
|
|
||||||
selected_panes,
|
|
||||||
common_modifier,
|
|
||||||
group_actions_ribbon,
|
|
||||||
toggle_group_ribbon,
|
|
||||||
group_mark_toggle_ribbon
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let remaining_space = max_len.saturating_sub(controls_line_len);
|
|
||||||
let mut padding = String::new();
|
|
||||||
let mut padding_len = 0;
|
|
||||||
for _ in 0..remaining_space {
|
|
||||||
padding.push_str(&ANSIStrings(&[superkey_prefix_style.paint(" ")]).to_string());
|
|
||||||
padding_len += 1;
|
|
||||||
}
|
|
||||||
Some(LinePart {
|
|
||||||
part: format!("{}{}", padding, controls_line),
|
|
||||||
len: controls_line_len + padding_len,
|
|
||||||
tab_index: None,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn multiple_select_key(keymap: &[(KeyWithModifier, Vec<Action>)]) -> Vec<KeyWithModifier> {
|
|
||||||
let mut matching = keymap.iter().find_map(|(key, acvec)| {
|
|
||||||
let has_match = acvec
|
|
||||||
.iter()
|
|
||||||
.find(|a| a.launches_plugin("zellij:multiple-select")) // TODO: make this an alias
|
|
||||||
.is_some();
|
|
||||||
if has_match {
|
|
||||||
Some(key.clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if let Some(matching) = matching.take() {
|
|
||||||
vec![matching]
|
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn single_action_key(
|
|
||||||
keymap: &[(KeyWithModifier, Vec<Action>)],
|
|
||||||
action: &[Action],
|
|
||||||
) -> Vec<KeyWithModifier> {
|
|
||||||
let mut matching = keymap.iter().find_map(|(key, acvec)| {
|
|
||||||
if acvec.iter().next() == action.iter().next() {
|
|
||||||
Some(key.clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if let Some(matching) = matching.take() {
|
|
||||||
vec![matching]
|
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn get_common_modifiers(mut keyvec: Vec<&KeyWithModifier>) -> Vec<KeyModifier> {
|
|
||||||
if keyvec.is_empty() {
|
|
||||||
return vec![];
|
|
||||||
}
|
|
||||||
let mut common_modifiers = keyvec.pop().unwrap().key_modifiers.clone();
|
|
||||||
for key in keyvec {
|
|
||||||
common_modifiers = common_modifiers
|
|
||||||
.intersection(&key.key_modifiers)
|
|
||||||
.cloned()
|
|
||||||
.collect();
|
|
||||||
}
|
|
||||||
common_modifiers.into_iter().collect()
|
|
||||||
}
|
|
||||||
|
|
|
||||||
|
|
@ -26,8 +26,6 @@ struct State {
|
||||||
tab_line: Vec<LinePart>,
|
tab_line: Vec<LinePart>,
|
||||||
text_copy_destination: Option<CopyDestination>,
|
text_copy_destination: Option<CopyDestination>,
|
||||||
display_system_clipboard_failure: bool,
|
display_system_clipboard_failure: bool,
|
||||||
own_client_id: Option<ClientId>,
|
|
||||||
grouped_panes_count: Option<usize>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static ARROW_SEPARATOR: &str = "";
|
static ARROW_SEPARATOR: &str = "";
|
||||||
|
|
@ -46,7 +44,6 @@ impl ZellijPlugin for State {
|
||||||
EventType::SystemClipboardFailure,
|
EventType::SystemClipboardFailure,
|
||||||
EventType::PaneUpdate,
|
EventType::PaneUpdate,
|
||||||
]);
|
]);
|
||||||
self.own_client_id = Some(get_plugin_ids().client_id);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, event: Event) -> bool {
|
fn update(&mut self, event: Event) -> bool {
|
||||||
|
|
@ -112,28 +109,6 @@ impl ZellijPlugin for State {
|
||||||
self.text_copy_destination = None;
|
self.text_copy_destination = None;
|
||||||
self.display_system_clipboard_failure = false;
|
self.display_system_clipboard_failure = false;
|
||||||
},
|
},
|
||||||
Event::PaneUpdate(pane_manifest) => {
|
|
||||||
if let Some(own_client_id) = self.own_client_id {
|
|
||||||
let mut grouped_panes_count = 0;
|
|
||||||
for (_tab_index, pane_infos) in pane_manifest.panes {
|
|
||||||
for pane_info in pane_infos {
|
|
||||||
let is_in_pane_group =
|
|
||||||
pane_info.index_in_pane_group.get(&own_client_id).is_some();
|
|
||||||
if is_in_pane_group {
|
|
||||||
grouped_panes_count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if Some(grouped_panes_count) != self.grouped_panes_count {
|
|
||||||
if grouped_panes_count == 0 {
|
|
||||||
self.grouped_panes_count = None;
|
|
||||||
} else {
|
|
||||||
self.grouped_panes_count = Some(grouped_panes_count);
|
|
||||||
}
|
|
||||||
should_render = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {
|
_ => {
|
||||||
eprintln!("Got unrecognized event: {:?}", event);
|
eprintln!("Got unrecognized event: {:?}", event);
|
||||||
},
|
},
|
||||||
|
|
@ -207,8 +182,6 @@ impl ZellijPlugin for State {
|
||||||
self.mode_info.mode,
|
self.mode_info.mode,
|
||||||
&active_swap_layout_name,
|
&active_swap_layout_name,
|
||||||
is_swap_layout_dirty,
|
is_swap_layout_dirty,
|
||||||
&self.mode_info,
|
|
||||||
self.grouped_panes_count,
|
|
||||||
);
|
);
|
||||||
let output = self
|
let output = self
|
||||||
.tab_line
|
.tab_line
|
||||||
|
|
|
||||||
|
|
@ -168,12 +168,6 @@ keybinds clear-defaults=true {{
|
||||||
bind "{secondary_modifier} -" {{ Resize "Decrease"; }}
|
bind "{secondary_modifier} -" {{ Resize "Decrease"; }}
|
||||||
bind "{secondary_modifier} [" {{ PreviousSwapLayout; }}
|
bind "{secondary_modifier} [" {{ PreviousSwapLayout; }}
|
||||||
bind "{secondary_modifier} ]" {{ NextSwapLayout; }}
|
bind "{secondary_modifier} ]" {{ NextSwapLayout; }}
|
||||||
bind "{secondary_modifier} m" {{
|
|
||||||
LaunchOrFocusPlugin "zellij:multiple-select" {{
|
|
||||||
floating true
|
|
||||||
move_to_focused_tab true
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
bind "{secondary_modifier} p" {{ TogglePaneInGroup; }}
|
bind "{secondary_modifier} p" {{ TogglePaneInGroup; }}
|
||||||
bind "{secondary_modifier} Shift p" {{ ToggleGroupMarking; }}
|
bind "{secondary_modifier} Shift p" {{ ToggleGroupMarking; }}
|
||||||
}}
|
}}
|
||||||
|
|
@ -400,12 +394,6 @@ keybinds clear-defaults=true {{
|
||||||
bind "{secondary_modifier} -" {{ Resize "Decrease"; }}
|
bind "{secondary_modifier} -" {{ Resize "Decrease"; }}
|
||||||
bind "{secondary_modifier} [" {{ PreviousSwapLayout; }}
|
bind "{secondary_modifier} [" {{ PreviousSwapLayout; }}
|
||||||
bind "{secondary_modifier} ]" {{ NextSwapLayout; }}
|
bind "{secondary_modifier} ]" {{ NextSwapLayout; }}
|
||||||
bind "{secondary_modifier} m" {{
|
|
||||||
LaunchOrFocusPlugin "zellij:multiple-select" {{
|
|
||||||
floating true
|
|
||||||
move_to_focused_tab true
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
bind "{secondary_modifier} p" {{ TogglePaneInGroup; }}
|
bind "{secondary_modifier} p" {{ TogglePaneInGroup; }}
|
||||||
bind "{secondary_modifier} Shift p" {{ ToggleGroupMarking; }}
|
bind "{secondary_modifier} Shift p" {{ ToggleGroupMarking; }}
|
||||||
}}
|
}}
|
||||||
|
|
@ -611,12 +599,6 @@ keybinds clear-defaults=true {{
|
||||||
bind "{secondary_modifier} -" {{ Resize "Decrease"; }}
|
bind "{secondary_modifier} -" {{ Resize "Decrease"; }}
|
||||||
bind "{secondary_modifier} [" {{ PreviousSwapLayout; }}
|
bind "{secondary_modifier} [" {{ PreviousSwapLayout; }}
|
||||||
bind "{secondary_modifier} ]" {{ NextSwapLayout; }}
|
bind "{secondary_modifier} ]" {{ NextSwapLayout; }}
|
||||||
bind "{secondary_modifier} m" {{
|
|
||||||
LaunchOrFocusPlugin "zellij:multiple-select" {{
|
|
||||||
floating true
|
|
||||||
move_to_focused_tab true
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
bind "{secondary_modifier} p" {{ TogglePaneInGroup; }}
|
bind "{secondary_modifier} p" {{ TogglePaneInGroup; }}
|
||||||
bind "{secondary_modifier} Shift p" {{ ToggleGroupMarking; }}
|
bind "{secondary_modifier} Shift p" {{ ToggleGroupMarking; }}
|
||||||
}}
|
}}
|
||||||
|
|
@ -1182,12 +1164,6 @@ keybinds clear-defaults=true {{
|
||||||
bind "{secondary_modifier} -" {{ Resize "Decrease"; }}
|
bind "{secondary_modifier} -" {{ Resize "Decrease"; }}
|
||||||
bind "{secondary_modifier} [" {{ PreviousSwapLayout; }}
|
bind "{secondary_modifier} [" {{ PreviousSwapLayout; }}
|
||||||
bind "{secondary_modifier} ]" {{ NextSwapLayout; }}
|
bind "{secondary_modifier} ]" {{ NextSwapLayout; }}
|
||||||
bind "{secondary_modifier} m" {{
|
|
||||||
LaunchOrFocusPlugin "zellij:multiple-select" {{
|
|
||||||
floating true
|
|
||||||
move_to_focused_tab true
|
|
||||||
}}
|
|
||||||
}}
|
|
||||||
bind "{secondary_modifier} p" {{ TogglePaneInGroup; }}
|
bind "{secondary_modifier} p" {{ TogglePaneInGroup; }}
|
||||||
bind "{secondary_modifier} Shift p" {{ ToggleGroupMarking; }}
|
bind "{secondary_modifier} Shift p" {{ ToggleGroupMarking; }}
|
||||||
}}
|
}}
|
||||||
|
|
|
||||||
|
|
@ -1,9 +1,6 @@
|
||||||
pub mod state;
|
|
||||||
pub mod ui;
|
|
||||||
|
|
||||||
use state::{MarkedIndex, VisibilityAndFocus};
|
|
||||||
use std::collections::BTreeMap;
|
use std::collections::BTreeMap;
|
||||||
use ui::PaneItem;
|
use std::time::Instant;
|
||||||
|
use zellij_tile::prelude::actions::Action;
|
||||||
use zellij_tile::prelude::*;
|
use zellij_tile::prelude::*;
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
#[derive(Debug, Default)]
|
||||||
|
|
@ -12,13 +9,17 @@ pub struct App {
|
||||||
own_client_id: Option<ClientId>,
|
own_client_id: Option<ClientId>,
|
||||||
own_tab_index: Option<usize>,
|
own_tab_index: Option<usize>,
|
||||||
total_tabs_in_session: Option<usize>,
|
total_tabs_in_session: Option<usize>,
|
||||||
search_string: String,
|
grouped_panes: Vec<PaneId>,
|
||||||
previous_search_string: String, // used eg. for the new tab title when breaking panes
|
grouped_panes_count: usize,
|
||||||
left_side_panes: Vec<PaneItem>,
|
mode_info: ModeInfo,
|
||||||
right_side_panes: Vec<PaneItem>,
|
closing: bool,
|
||||||
search_results: Option<Vec<PaneItem>>,
|
highlighted_at: Option<Instant>,
|
||||||
visibility_and_focus: VisibilityAndFocus,
|
baseline_ui_width: usize,
|
||||||
marked_index: Option<MarkedIndex>,
|
current_rows: usize,
|
||||||
|
current_cols: usize,
|
||||||
|
display_area_rows: usize,
|
||||||
|
display_area_cols: usize,
|
||||||
|
alternate_coordinates: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
register_plugin!(App);
|
register_plugin!(App);
|
||||||
|
|
@ -27,186 +28,597 @@ impl ZellijPlugin for App {
|
||||||
fn load(&mut self, _configuration: BTreeMap<String, String>) {
|
fn load(&mut self, _configuration: BTreeMap<String, String>) {
|
||||||
subscribe(&[
|
subscribe(&[
|
||||||
EventType::Key,
|
EventType::Key,
|
||||||
EventType::Mouse,
|
EventType::InterceptedKeyPress,
|
||||||
EventType::ModeUpdate,
|
EventType::ModeUpdate,
|
||||||
EventType::RunCommandResult,
|
|
||||||
EventType::TabUpdate,
|
|
||||||
EventType::PaneUpdate,
|
EventType::PaneUpdate,
|
||||||
EventType::FailedToWriteConfigToDisk,
|
EventType::TabUpdate,
|
||||||
EventType::ConfigWasWrittenToDisk,
|
EventType::Timer,
|
||||||
EventType::BeforeClose,
|
|
||||||
]);
|
]);
|
||||||
|
|
||||||
let plugin_ids = get_plugin_ids();
|
let plugin_ids = get_plugin_ids();
|
||||||
self.own_plugin_id = Some(plugin_ids.plugin_id);
|
self.own_plugin_id = Some(plugin_ids.plugin_id);
|
||||||
self.own_client_id = Some(plugin_ids.client_id);
|
self.own_client_id = Some(plugin_ids.client_id);
|
||||||
rename_plugin_pane(plugin_ids.plugin_id, "Multiple Select");
|
|
||||||
|
intercept_key_presses();
|
||||||
|
set_selectable(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
fn update(&mut self, event: Event) -> bool {
|
fn update(&mut self, event: Event) -> bool {
|
||||||
let mut should_render = false;
|
if self.closing {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
match event {
|
match event {
|
||||||
Event::PaneUpdate(pane_manifest) => {
|
Event::ModeUpdate(mode_info) => self.handle_mode_update(mode_info),
|
||||||
self.react_to_zellij_state_update(pane_manifest);
|
Event::PaneUpdate(pane_manifest) => self.handle_pane_update(pane_manifest),
|
||||||
should_render = true;
|
Event::TabUpdate(tab_infos) => self.handle_tab_update(tab_infos),
|
||||||
},
|
Event::InterceptedKeyPress(key) => self.handle_key_press(key),
|
||||||
Event::Key(key) => {
|
Event::Timer(_) => self.handle_timer(),
|
||||||
match key.bare_key {
|
_ => false,
|
||||||
BareKey::Tab if key.has_no_modifiers() => {
|
|
||||||
self.visibility_and_focus.toggle_focus();
|
|
||||||
self.marked_index = None;
|
|
||||||
self.update_highlighted_panes();
|
|
||||||
should_render = true;
|
|
||||||
},
|
|
||||||
BareKey::Char(character)
|
|
||||||
if key.has_no_modifiers()
|
|
||||||
&& self.visibility_and_focus.left_side_is_focused()
|
|
||||||
&& self.marked_index.is_none() =>
|
|
||||||
{
|
|
||||||
self.search_string.push(character);
|
|
||||||
self.update_search_results();
|
|
||||||
should_render = true;
|
|
||||||
},
|
|
||||||
BareKey::Backspace
|
|
||||||
if key.has_no_modifiers()
|
|
||||||
&& self.visibility_and_focus.left_side_is_focused()
|
|
||||||
&& self.marked_index.is_none() =>
|
|
||||||
{
|
|
||||||
self.search_string.pop();
|
|
||||||
self.update_search_results();
|
|
||||||
should_render = true;
|
|
||||||
},
|
|
||||||
BareKey::Enter if key.has_no_modifiers() => {
|
|
||||||
if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
if let Some(marked_index) = self.marked_index.take() {
|
|
||||||
let keep_left_side_focused = false;
|
|
||||||
self.group_panes(marked_index, keep_left_side_focused);
|
|
||||||
} else {
|
|
||||||
match self.search_results.take() {
|
|
||||||
Some(search_results) => {
|
|
||||||
self.group_search_results(search_results)
|
|
||||||
},
|
|
||||||
None => self.group_all_panes(),
|
|
||||||
}
|
|
||||||
self.handle_left_side_emptied();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
should_render = true;
|
|
||||||
},
|
|
||||||
BareKey::Right
|
|
||||||
if key.has_no_modifiers()
|
|
||||||
&& self.visibility_and_focus.left_side_is_focused() =>
|
|
||||||
{
|
|
||||||
if let Some(marked_index) = self.marked_index.take() {
|
|
||||||
let keep_left_side_focused = true;
|
|
||||||
self.group_panes(marked_index, keep_left_side_focused);
|
|
||||||
should_render = true;
|
|
||||||
}
|
|
||||||
},
|
|
||||||
BareKey::Left
|
|
||||||
if key.has_no_modifiers()
|
|
||||||
&& self.visibility_and_focus.right_side_is_focused() =>
|
|
||||||
{
|
|
||||||
if self.visibility_and_focus.right_side_is_focused() {
|
|
||||||
if let Some(marked_index) = self.marked_index.take() {
|
|
||||||
self.ungroup_panes(marked_index);
|
|
||||||
should_render = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
BareKey::Char('c') if key.has_modifiers(&[KeyModifier::Ctrl]) => {
|
|
||||||
if self.visibility_and_focus.right_side_is_focused() {
|
|
||||||
// this means we're in the selection panes part and we want to clear
|
|
||||||
// them
|
|
||||||
self.ungroup_all_panes();
|
|
||||||
} else if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
if self.marked_index.is_some() {
|
|
||||||
self.marked_index = None;
|
|
||||||
self.update_highlighted_panes();
|
|
||||||
} else {
|
|
||||||
self.ungroup_all_panes_and_close_self();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
should_render = true;
|
|
||||||
},
|
|
||||||
BareKey::Down if key.has_no_modifiers() => {
|
|
||||||
self.move_marked_index_down();
|
|
||||||
should_render = true;
|
|
||||||
},
|
|
||||||
BareKey::Up if key.has_no_modifiers() => {
|
|
||||||
self.move_marked_index_up();
|
|
||||||
should_render = true;
|
|
||||||
},
|
|
||||||
BareKey::Char(' ') if key.has_no_modifiers() && self.marked_index.is_some() => {
|
|
||||||
self.mark_entry();
|
|
||||||
should_render = true;
|
|
||||||
},
|
|
||||||
BareKey::Char('b')
|
|
||||||
if key.has_no_modifiers()
|
|
||||||
&& self.visibility_and_focus.right_side_is_focused() =>
|
|
||||||
{
|
|
||||||
self.break_grouped_panes_to_new_tab();
|
|
||||||
},
|
|
||||||
BareKey::Char('s')
|
|
||||||
if key.has_no_modifiers()
|
|
||||||
&& self.visibility_and_focus.right_side_is_focused() =>
|
|
||||||
{
|
|
||||||
self.stack_grouped_panes();
|
|
||||||
},
|
|
||||||
BareKey::Char('f')
|
|
||||||
if key.has_no_modifiers()
|
|
||||||
&& self.visibility_and_focus.right_side_is_focused() =>
|
|
||||||
{
|
|
||||||
self.float_grouped_panes();
|
|
||||||
},
|
|
||||||
BareKey::Char('e')
|
|
||||||
if key.has_no_modifiers()
|
|
||||||
&& self.visibility_and_focus.right_side_is_focused() =>
|
|
||||||
{
|
|
||||||
self.embed_grouped_panes();
|
|
||||||
},
|
|
||||||
BareKey::Char('r')
|
|
||||||
if key.has_no_modifiers()
|
|
||||||
&& self.visibility_and_focus.right_side_is_focused() =>
|
|
||||||
{
|
|
||||||
self.break_grouped_panes_right();
|
|
||||||
},
|
|
||||||
BareKey::Char('l')
|
|
||||||
if key.has_no_modifiers()
|
|
||||||
&& self.visibility_and_focus.right_side_is_focused() =>
|
|
||||||
{
|
|
||||||
self.break_grouped_panes_left();
|
|
||||||
},
|
|
||||||
BareKey::Char('c')
|
|
||||||
if key.has_no_modifiers()
|
|
||||||
&& self.visibility_and_focus.right_side_is_focused() =>
|
|
||||||
{
|
|
||||||
self.close_grouped_panes();
|
|
||||||
},
|
|
||||||
_ => {},
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Event::BeforeClose => {
|
|
||||||
self.unhighlight_all_panes();
|
|
||||||
},
|
|
||||||
_ => {},
|
|
||||||
}
|
|
||||||
should_render
|
|
||||||
}
|
|
||||||
fn render(&mut self, rows: usize, cols: usize) {
|
fn render(&mut self, rows: usize, cols: usize) {
|
||||||
self.render_close_shortcut(cols);
|
self.update_current_size(rows, cols);
|
||||||
self.render_tab_shortcut(cols, rows);
|
let ui_width = self.calculate_ui_width();
|
||||||
match self.visibility_and_focus {
|
self.update_baseline_ui_width(ui_width);
|
||||||
VisibilityAndFocus::OnlyLeftSideVisible => self.render_left_side(rows, cols, true),
|
let base_x = cols.saturating_sub(self.baseline_ui_width) / 2;
|
||||||
VisibilityAndFocus::OnlyRightSideVisible => self.render_right_side(rows, cols, true),
|
let base_y = rows.saturating_sub(8) / 2;
|
||||||
VisibilityAndFocus::BothSidesVisibleLeftSideFocused => {
|
self.render_header(base_x, base_y);
|
||||||
self.render_left_side(rows, cols, true);
|
self.render_shortcuts(base_x, base_y + 2);
|
||||||
self.render_right_side(rows, cols, false);
|
self.render_controls(base_x, base_y + 7);
|
||||||
},
|
|
||||||
VisibilityAndFocus::BothSidesVisibleRightSideFocused => {
|
|
||||||
self.render_left_side(rows, cols, false);
|
|
||||||
self.render_right_side(rows, cols, true);
|
|
||||||
},
|
|
||||||
}
|
|
||||||
self.render_focus_boundary(rows, cols);
|
|
||||||
self.render_help_line(rows, cols);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
impl App {
|
||||||
|
fn update_current_size(&mut self, new_rows: usize, new_cols: usize) {
|
||||||
|
let size_changed = new_rows != self.current_rows || new_cols != self.current_cols;
|
||||||
|
self.current_rows = new_rows;
|
||||||
|
self.current_cols = new_cols;
|
||||||
|
if size_changed {
|
||||||
|
self.baseline_ui_width = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
fn update_baseline_ui_width(&mut self, current_ui_width: usize) {
|
||||||
|
if current_ui_width > self.baseline_ui_width {
|
||||||
|
self.baseline_ui_width = current_ui_width;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn calculate_ui_width(&self) -> usize {
|
||||||
|
let controls_width = group_controls_length(&self.mode_info);
|
||||||
|
|
||||||
|
let header_width = Self::header_text().0.len();
|
||||||
|
let shortcuts_max_width = Self::shortcuts_max_width();
|
||||||
|
|
||||||
|
std::cmp::max(
|
||||||
|
controls_width,
|
||||||
|
std::cmp::max(header_width, shortcuts_max_width),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn header_text() -> (&'static str, Text) {
|
||||||
|
let header_text = "<ESC> - cancel, <TAB> - move";
|
||||||
|
let header_text_component = Text::new(header_text)
|
||||||
|
.color_substring(3, "<ESC>")
|
||||||
|
.color_substring(3, "<TAB>");
|
||||||
|
(header_text, header_text_component)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn shortcuts_max_width() -> usize {
|
||||||
|
std::cmp::max(
|
||||||
|
std::cmp::max(
|
||||||
|
Self::group_actions_text().0.len(),
|
||||||
|
Self::shortcuts_line1_text().0.len(),
|
||||||
|
),
|
||||||
|
std::cmp::max(
|
||||||
|
Self::shortcuts_line2_text().0.len(),
|
||||||
|
Self::shortcuts_line3_text().0.len(),
|
||||||
|
),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn group_actions_text() -> (&'static str, Text) {
|
||||||
|
let text = "GROUP ACTIONS";
|
||||||
|
let component = Text::new(text).color_all(2);
|
||||||
|
(text, component)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn shortcuts_line1_text() -> (&'static str, Text) {
|
||||||
|
let text = "<b> - break out, <s> - stack, <c> - close";
|
||||||
|
let component = Text::new(text)
|
||||||
|
.color_substring(3, "<b>")
|
||||||
|
.color_substring(3, "<s>")
|
||||||
|
.color_substring(3, "<c>");
|
||||||
|
(text, component)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn shortcuts_line2_text() -> (&'static str, Text) {
|
||||||
|
let text = "<r> - break right, <l> - break left";
|
||||||
|
let component = Text::new(text)
|
||||||
|
.color_substring(3, "<r>")
|
||||||
|
.color_substring(3, "<l>");
|
||||||
|
(text, component)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn shortcuts_line3_text() -> (&'static str, Text) {
|
||||||
|
let text = "<e> - embed, <f> - float";
|
||||||
|
let component = Text::new(text)
|
||||||
|
.color_substring(3, "<e>")
|
||||||
|
.color_substring(3, "<f>");
|
||||||
|
(text, component)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_mode_update(&mut self, mode_info: ModeInfo) -> bool {
|
||||||
|
if self.mode_info != mode_info {
|
||||||
|
self.mode_info = mode_info;
|
||||||
|
let ui_width = self.calculate_ui_width();
|
||||||
|
self.update_baseline_ui_width(ui_width);
|
||||||
|
true
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_pane_update(&mut self, pane_manifest: PaneManifest) -> bool {
|
||||||
|
let Some(own_client_id) = self.own_client_id else {
|
||||||
|
return false;
|
||||||
|
};
|
||||||
|
|
||||||
|
self.update_grouped_panes(&pane_manifest, own_client_id);
|
||||||
|
self.update_tab_info(&pane_manifest);
|
||||||
|
self.total_tabs_in_session = Some(pane_manifest.panes.keys().count());
|
||||||
|
|
||||||
|
true
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_tab_update(&mut self, tab_infos: Vec<TabInfo>) -> bool {
|
||||||
|
for tab in tab_infos {
|
||||||
|
if tab.active {
|
||||||
|
self.display_area_rows = tab.display_area_rows;
|
||||||
|
self.display_area_cols = tab.display_area_columns;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_grouped_panes(&mut self, pane_manifest: &PaneManifest, own_client_id: ClientId) {
|
||||||
|
self.grouped_panes.clear();
|
||||||
|
let mut count = 0;
|
||||||
|
|
||||||
|
for (_tab_index, pane_infos) in &pane_manifest.panes {
|
||||||
|
for pane_info in pane_infos {
|
||||||
|
if pane_info.index_in_pane_group.get(&own_client_id).is_some() {
|
||||||
|
let pane_id = if pane_info.is_plugin {
|
||||||
|
PaneId::Plugin(pane_info.id)
|
||||||
|
} else {
|
||||||
|
PaneId::Terminal(pane_info.id)
|
||||||
|
};
|
||||||
|
self.grouped_panes.push(pane_id);
|
||||||
|
count += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if count == 0 {
|
||||||
|
self.close_self();
|
||||||
|
}
|
||||||
|
|
||||||
|
let previous_count = self.grouped_panes_count;
|
||||||
|
self.grouped_panes_count = count;
|
||||||
|
if let Some(own_plugin_id) = self.own_plugin_id {
|
||||||
|
let title = if count == 1 {
|
||||||
|
"SELECTED PANE"
|
||||||
|
} else {
|
||||||
|
"SELECTED PANES"
|
||||||
|
};
|
||||||
|
if previous_count != count {
|
||||||
|
rename_plugin_pane(own_plugin_id, format!("{} {}", count, title));
|
||||||
|
}
|
||||||
|
if previous_count != 0 && count != 0 && previous_count != count {
|
||||||
|
if self.doherty_threshold_elapsed_since_highlight() {
|
||||||
|
self.highlighted_at = Some(Instant::now());
|
||||||
|
highlight_and_unhighlight_panes(vec![PaneId::Plugin(own_plugin_id)], vec![]);
|
||||||
|
set_timeout(0.4);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn doherty_threshold_elapsed_since_highlight(&self) -> bool {
|
||||||
|
self.highlighted_at
|
||||||
|
.map(|h| h.elapsed() >= std::time::Duration::from_millis(400))
|
||||||
|
.unwrap_or(true)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn update_tab_info(&mut self, pane_manifest: &PaneManifest) {
|
||||||
|
for (tab_index, pane_infos) in &pane_manifest.panes {
|
||||||
|
for pane_info in pane_infos {
|
||||||
|
if pane_info.is_plugin && Some(pane_info.id) == self.own_plugin_id {
|
||||||
|
self.own_tab_index = Some(*tab_index);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn handle_key_press(&mut self, key: KeyWithModifier) -> bool {
|
||||||
|
if !key.has_no_modifiers() {
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
match key.bare_key {
|
||||||
|
BareKey::Char('b') => self.break_grouped_panes_to_new_tab(),
|
||||||
|
BareKey::Char('s') => self.stack_grouped_panes(),
|
||||||
|
BareKey::Char('f') => self.float_grouped_panes(),
|
||||||
|
BareKey::Char('e') => self.embed_grouped_panes(),
|
||||||
|
BareKey::Char('r') => self.break_grouped_panes_right(),
|
||||||
|
BareKey::Char('l') => self.break_grouped_panes_left(),
|
||||||
|
BareKey::Char('c') => self.close_grouped_panes(),
|
||||||
|
BareKey::Tab => self.next_coordinates(),
|
||||||
|
BareKey::Esc => {
|
||||||
|
self.ungroup_panes_in_zellij(&self.grouped_panes.clone());
|
||||||
|
self.close_self();
|
||||||
|
},
|
||||||
|
_ => return false,
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
fn handle_timer(&mut self) -> bool {
|
||||||
|
if let Some(own_plugin_id) = self.own_plugin_id {
|
||||||
|
if self.doherty_threshold_elapsed_since_highlight() {
|
||||||
|
highlight_and_unhighlight_panes(vec![], vec![PaneId::Plugin(own_plugin_id)]);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
false
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_header(&self, base_x: usize, base_y: usize) {
|
||||||
|
let header_text = Self::header_text();
|
||||||
|
|
||||||
|
print_text_with_coordinates(header_text.1, base_x, base_y, None, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_shortcuts(&self, base_x: usize, base_y: usize) {
|
||||||
|
let mut running_y = base_y;
|
||||||
|
print_text_with_coordinates(Self::group_actions_text().1, base_x, running_y, None, None);
|
||||||
|
running_y += 1;
|
||||||
|
|
||||||
|
print_text_with_coordinates(
|
||||||
|
Self::shortcuts_line1_text().1,
|
||||||
|
base_x,
|
||||||
|
running_y,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
running_y += 1;
|
||||||
|
|
||||||
|
print_text_with_coordinates(
|
||||||
|
Self::shortcuts_line2_text().1,
|
||||||
|
base_x,
|
||||||
|
running_y,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
running_y += 1;
|
||||||
|
|
||||||
|
print_text_with_coordinates(
|
||||||
|
Self::shortcuts_line3_text().1,
|
||||||
|
base_x,
|
||||||
|
running_y,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_controls(&self, base_x: usize, base_y: usize) {
|
||||||
|
render_group_controls(&self.mode_info, base_x, base_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn execute_action_and_close<F>(&mut self, action: F)
|
||||||
|
where
|
||||||
|
F: FnOnce(&[PaneId]),
|
||||||
|
{
|
||||||
|
let pane_ids = self.grouped_panes.clone();
|
||||||
|
action(&pane_ids);
|
||||||
|
self.close_self();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn break_grouped_panes_to_new_tab(&mut self) {
|
||||||
|
self.execute_action_and_close(|pane_ids| {
|
||||||
|
break_panes_to_new_tab(pane_ids, None, true);
|
||||||
|
});
|
||||||
|
self.ungroup_panes_in_zellij(&self.grouped_panes.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn stack_grouped_panes(&mut self) {
|
||||||
|
self.execute_action_and_close(|pane_ids| {
|
||||||
|
stack_panes(pane_ids.to_vec());
|
||||||
|
});
|
||||||
|
self.ungroup_panes_in_zellij(&self.grouped_panes.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn float_grouped_panes(&mut self) {
|
||||||
|
self.execute_action_and_close(|pane_ids| {
|
||||||
|
float_multiple_panes(pane_ids.to_vec());
|
||||||
|
});
|
||||||
|
self.ungroup_panes_in_zellij(&self.grouped_panes.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn embed_grouped_panes(&mut self) {
|
||||||
|
self.execute_action_and_close(|pane_ids| {
|
||||||
|
embed_multiple_panes(pane_ids.to_vec());
|
||||||
|
});
|
||||||
|
self.ungroup_panes_in_zellij(&self.grouped_panes.clone());
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn break_grouped_panes_right(&mut self) {
|
||||||
|
let Some(own_tab_index) = self.own_tab_index else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let pane_ids = self.grouped_panes.clone();
|
||||||
|
|
||||||
|
if Some(own_tab_index + 1) < self.total_tabs_in_session {
|
||||||
|
break_panes_to_tab_with_index(&pane_ids, own_tab_index + 1, true);
|
||||||
|
} else {
|
||||||
|
break_panes_to_new_tab(&pane_ids, None, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.close_self();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn break_grouped_panes_left(&mut self) {
|
||||||
|
let Some(own_tab_index) = self.own_tab_index else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
|
||||||
|
let pane_ids = self.grouped_panes.clone();
|
||||||
|
|
||||||
|
if own_tab_index > 0 {
|
||||||
|
break_panes_to_tab_with_index(&pane_ids, own_tab_index - 1, true);
|
||||||
|
} else {
|
||||||
|
break_panes_to_new_tab(&pane_ids, None, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
self.close_self();
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn close_grouped_panes(&mut self) {
|
||||||
|
self.execute_action_and_close(|pane_ids| {
|
||||||
|
close_multiple_panes(pane_ids.to_vec());
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn ungroup_panes_in_zellij(&mut self, pane_ids: &[PaneId]) {
|
||||||
|
group_and_ungroup_panes(vec![], pane_ids.to_vec());
|
||||||
|
}
|
||||||
|
pub fn close_self(&mut self) {
|
||||||
|
self.closing = true;
|
||||||
|
close_self();
|
||||||
|
}
|
||||||
|
pub fn next_coordinates(&mut self) {
|
||||||
|
let width_30_percent = (self.display_area_cols as f64 * 0.3) as usize;
|
||||||
|
let height_30_percent = (self.display_area_rows as f64 * 0.3) as usize;
|
||||||
|
let width = std::cmp::max(width_30_percent, 48);
|
||||||
|
let height = std::cmp::max(height_30_percent, 10);
|
||||||
|
let y_position = self.display_area_rows.saturating_sub(height + 2);
|
||||||
|
if let Some(own_plugin_id) = self.own_plugin_id {
|
||||||
|
if self.alternate_coordinates {
|
||||||
|
let x_position = 2;
|
||||||
|
let Some(next_coordinates) = FloatingPaneCoordinates::new(
|
||||||
|
Some(format!("{}", x_position)),
|
||||||
|
Some(format!("{}", y_position)),
|
||||||
|
Some(format!("{}", width)),
|
||||||
|
Some(format!("{}", height)),
|
||||||
|
Some(true),
|
||||||
|
) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
change_floating_panes_coordinates(vec![(
|
||||||
|
PaneId::Plugin(own_plugin_id),
|
||||||
|
next_coordinates,
|
||||||
|
)]);
|
||||||
|
self.alternate_coordinates = false;
|
||||||
|
} else {
|
||||||
|
let x_position = self
|
||||||
|
.display_area_cols
|
||||||
|
.saturating_sub(width)
|
||||||
|
.saturating_sub(2);
|
||||||
|
let Some(next_coordinates) = FloatingPaneCoordinates::new(
|
||||||
|
Some(format!("{}", x_position)),
|
||||||
|
Some(format!("{}", y_position)),
|
||||||
|
Some(format!("{}", width)),
|
||||||
|
Some(format!("{}", height)),
|
||||||
|
Some(true),
|
||||||
|
) else {
|
||||||
|
return;
|
||||||
|
};
|
||||||
|
change_floating_panes_coordinates(vec![(
|
||||||
|
PaneId::Plugin(own_plugin_id),
|
||||||
|
next_coordinates,
|
||||||
|
)]);
|
||||||
|
self.alternate_coordinates = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_group_controls(mode_info: &ModeInfo, base_x: usize, base_y: usize) {
|
||||||
|
let keymap = mode_info.get_mode_keybinds();
|
||||||
|
let (common_modifiers, pane_group_key, group_mark_key) = extract_key_bindings(&keymap);
|
||||||
|
|
||||||
|
let pane_group_bound = pane_group_key != "UNBOUND";
|
||||||
|
let group_mark_bound = group_mark_key != "UNBOUND";
|
||||||
|
|
||||||
|
if !pane_group_bound && !group_mark_bound {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
render_common_modifiers(&common_modifiers, base_x, base_y);
|
||||||
|
|
||||||
|
let mut next_x = base_x + render_common_modifiers(&common_modifiers, base_x, base_y);
|
||||||
|
|
||||||
|
if pane_group_bound {
|
||||||
|
next_x = render_toggle_group_ribbon(&pane_group_key, next_x, base_y);
|
||||||
|
}
|
||||||
|
|
||||||
|
if group_mark_bound {
|
||||||
|
render_follow_focus_ribbon(&group_mark_key, next_x, base_y, mode_info);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn group_controls_length(mode_info: &ModeInfo) -> usize {
|
||||||
|
let keymap = mode_info.get_mode_keybinds();
|
||||||
|
let (common_modifiers, pane_group_key, group_mark_key) = extract_key_bindings(&keymap);
|
||||||
|
|
||||||
|
let pane_group_bound = pane_group_key != "UNBOUND";
|
||||||
|
let group_mark_bound = group_mark_key != "UNBOUND";
|
||||||
|
|
||||||
|
let mut length = 0;
|
||||||
|
|
||||||
|
if !common_modifiers.is_empty() {
|
||||||
|
let modifiers_text = format!(
|
||||||
|
"{} + ",
|
||||||
|
common_modifiers
|
||||||
|
.iter()
|
||||||
|
.map(|m| m.to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(" ")
|
||||||
|
);
|
||||||
|
length += modifiers_text.chars().count();
|
||||||
|
}
|
||||||
|
|
||||||
|
if pane_group_bound {
|
||||||
|
let toggle_text = format!("<{}> Toggle", pane_group_key);
|
||||||
|
length += toggle_text.chars().count() + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
if group_mark_bound {
|
||||||
|
let follow_text = format!("<{}> Follow Focus", group_mark_key);
|
||||||
|
length += follow_text.chars().count() + 4;
|
||||||
|
}
|
||||||
|
|
||||||
|
length
|
||||||
|
}
|
||||||
|
|
||||||
|
fn extract_key_bindings(
|
||||||
|
keymap: &[(KeyWithModifier, Vec<Action>)],
|
||||||
|
) -> (Vec<KeyModifier>, String, String) {
|
||||||
|
let pane_group_keys = get_key_for_action(keymap, &[Action::TogglePaneInGroup]);
|
||||||
|
let group_mark_keys = get_key_for_action(keymap, &[Action::ToggleGroupMarking]);
|
||||||
|
|
||||||
|
let key_refs: Vec<&KeyWithModifier> = [pane_group_keys.first(), group_mark_keys.first()]
|
||||||
|
.into_iter()
|
||||||
|
.flatten()
|
||||||
|
.collect();
|
||||||
|
|
||||||
|
let common_modifiers = get_common_modifiers(key_refs);
|
||||||
|
|
||||||
|
let pane_group_key = format_key_without_modifiers(&pane_group_keys, &common_modifiers);
|
||||||
|
let group_mark_key = format_key_without_modifiers(&group_mark_keys, &common_modifiers);
|
||||||
|
|
||||||
|
(common_modifiers, pane_group_key, group_mark_key)
|
||||||
|
}
|
||||||
|
|
||||||
|
fn format_key_without_modifiers(
|
||||||
|
keys: &[KeyWithModifier],
|
||||||
|
common_modifiers: &[KeyModifier],
|
||||||
|
) -> String {
|
||||||
|
keys.first()
|
||||||
|
.map(|key| format!("{}", key.strip_common_modifiers(&common_modifiers.to_vec())))
|
||||||
|
.unwrap_or_else(|| "UNBOUND".to_string())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_common_modifiers(
|
||||||
|
common_modifiers: &[KeyModifier],
|
||||||
|
base_x: usize,
|
||||||
|
base_y: usize,
|
||||||
|
) -> usize {
|
||||||
|
if !common_modifiers.is_empty() {
|
||||||
|
let modifiers_text = format!(
|
||||||
|
"{} + ",
|
||||||
|
common_modifiers
|
||||||
|
.iter()
|
||||||
|
.map(|m| m.to_string())
|
||||||
|
.collect::<Vec<_>>()
|
||||||
|
.join(" ")
|
||||||
|
);
|
||||||
|
|
||||||
|
print_text_with_coordinates(
|
||||||
|
Text::new(&modifiers_text).color_all(0),
|
||||||
|
base_x,
|
||||||
|
base_y,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
modifiers_text.chars().count()
|
||||||
|
} else {
|
||||||
|
0
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_key_for_action(
|
||||||
|
keymap: &[(KeyWithModifier, Vec<Action>)],
|
||||||
|
target_action: &[Action],
|
||||||
|
) -> Vec<KeyWithModifier> {
|
||||||
|
keymap
|
||||||
|
.iter()
|
||||||
|
.find_map(|(key, actions)| {
|
||||||
|
if actions.first() == target_action.first() {
|
||||||
|
Some(key.clone())
|
||||||
|
} else {
|
||||||
|
None
|
||||||
|
}
|
||||||
|
})
|
||||||
|
.map(|key| vec![key])
|
||||||
|
.unwrap_or_default()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn get_common_modifiers(keys: Vec<&KeyWithModifier>) -> Vec<KeyModifier> {
|
||||||
|
if keys.is_empty() {
|
||||||
|
return vec![];
|
||||||
|
}
|
||||||
|
|
||||||
|
let mut common = keys[0].key_modifiers.clone();
|
||||||
|
|
||||||
|
for key in keys.iter().skip(1) {
|
||||||
|
common = common.intersection(&key.key_modifiers).cloned().collect();
|
||||||
|
}
|
||||||
|
|
||||||
|
common.into_iter().collect()
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_follow_focus_ribbon(
|
||||||
|
group_mark_key: &str,
|
||||||
|
x_position: usize,
|
||||||
|
base_y: usize,
|
||||||
|
mode_info: &ModeInfo,
|
||||||
|
) {
|
||||||
|
let follow_text = format!("<{}> Follow Focus", group_mark_key);
|
||||||
|
let key_highlight = format!("{}", group_mark_key);
|
||||||
|
|
||||||
|
let mut ribbon = Text::new(&follow_text).color_substring(0, &key_highlight);
|
||||||
|
|
||||||
|
if mode_info.currently_marking_pane_group.unwrap_or(false) {
|
||||||
|
ribbon = ribbon.selected();
|
||||||
|
}
|
||||||
|
|
||||||
|
print_ribbon_with_coordinates(ribbon, x_position, base_y, None, None);
|
||||||
|
}
|
||||||
|
|
||||||
|
fn render_toggle_group_ribbon(pane_group_key: &str, base_x: usize, base_y: usize) -> usize {
|
||||||
|
let toggle_text = format!("<{}> Toggle", pane_group_key);
|
||||||
|
let key_highlight = format!("{}", pane_group_key);
|
||||||
|
|
||||||
|
print_ribbon_with_coordinates(
|
||||||
|
Text::new(&toggle_text).color_substring(0, &key_highlight),
|
||||||
|
base_x,
|
||||||
|
base_y,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
);
|
||||||
|
|
||||||
|
base_x + toggle_text.len() + 4
|
||||||
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,634 +0,0 @@
|
||||||
use crate::{ui::PaneItem, App};
|
|
||||||
use std::collections::{BTreeMap, BTreeSet, HashSet};
|
|
||||||
|
|
||||||
use fuzzy_matcher::skim::SkimMatcherV2;
|
|
||||||
use fuzzy_matcher::FuzzyMatcher;
|
|
||||||
|
|
||||||
use zellij_tile::prelude::*;
|
|
||||||
|
|
||||||
#[derive(Debug, Default)]
|
|
||||||
pub struct MarkedIndex {
|
|
||||||
pub main_index: usize,
|
|
||||||
pub additional_indices: HashSet<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MarkedIndex {
|
|
||||||
pub fn new(main_index: usize) -> Self {
|
|
||||||
MarkedIndex {
|
|
||||||
main_index,
|
|
||||||
additional_indices: HashSet::new(),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl MarkedIndex {
|
|
||||||
pub fn toggle_additional_mark(&mut self) {
|
|
||||||
if self.additional_indices.contains(&self.main_index) {
|
|
||||||
self.additional_indices.retain(|a| a != &self.main_index);
|
|
||||||
} else {
|
|
||||||
self.additional_indices.insert(self.main_index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug)]
|
|
||||||
pub enum VisibilityAndFocus {
|
|
||||||
OnlyLeftSideVisible,
|
|
||||||
OnlyRightSideVisible,
|
|
||||||
BothSidesVisibleLeftSideFocused,
|
|
||||||
BothSidesVisibleRightSideFocused,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for VisibilityAndFocus {
|
|
||||||
fn default() -> Self {
|
|
||||||
VisibilityAndFocus::OnlyLeftSideVisible
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl VisibilityAndFocus {
|
|
||||||
pub fn only_left_side_is_focused(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
VisibilityAndFocus::OnlyLeftSideVisible => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn left_side_is_focused(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
VisibilityAndFocus::OnlyLeftSideVisible
|
|
||||||
| VisibilityAndFocus::BothSidesVisibleLeftSideFocused => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn right_side_is_focused(&self) -> bool {
|
|
||||||
match self {
|
|
||||||
VisibilityAndFocus::OnlyRightSideVisible
|
|
||||||
| VisibilityAndFocus::BothSidesVisibleRightSideFocused => true,
|
|
||||||
_ => false,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn hide_left_side(&mut self) {
|
|
||||||
*self = VisibilityAndFocus::OnlyRightSideVisible
|
|
||||||
}
|
|
||||||
pub fn hide_right_side(&mut self) {
|
|
||||||
*self = VisibilityAndFocus::OnlyLeftSideVisible
|
|
||||||
}
|
|
||||||
pub fn focus_right_side(&mut self) {
|
|
||||||
*self = VisibilityAndFocus::BothSidesVisibleRightSideFocused
|
|
||||||
}
|
|
||||||
pub fn toggle_focus(&mut self) {
|
|
||||||
match self {
|
|
||||||
VisibilityAndFocus::BothSidesVisibleLeftSideFocused => {
|
|
||||||
*self = VisibilityAndFocus::BothSidesVisibleRightSideFocused
|
|
||||||
},
|
|
||||||
VisibilityAndFocus::BothSidesVisibleRightSideFocused => {
|
|
||||||
*self = VisibilityAndFocus::BothSidesVisibleLeftSideFocused
|
|
||||||
},
|
|
||||||
VisibilityAndFocus::OnlyLeftSideVisible => {
|
|
||||||
*self = VisibilityAndFocus::BothSidesVisibleRightSideFocused
|
|
||||||
},
|
|
||||||
VisibilityAndFocus::OnlyRightSideVisible => {
|
|
||||||
*self = VisibilityAndFocus::BothSidesVisibleLeftSideFocused
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn show_both_sides(&mut self) {
|
|
||||||
match self {
|
|
||||||
VisibilityAndFocus::OnlyLeftSideVisible => {
|
|
||||||
*self = VisibilityAndFocus::BothSidesVisibleLeftSideFocused
|
|
||||||
},
|
|
||||||
VisibilityAndFocus::OnlyRightSideVisible => {
|
|
||||||
*self = VisibilityAndFocus::BothSidesVisibleRightSideFocused
|
|
||||||
},
|
|
||||||
VisibilityAndFocus::BothSidesVisibleLeftSideFocused
|
|
||||||
| VisibilityAndFocus::BothSidesVisibleRightSideFocused => {
|
|
||||||
// no-op
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl App {
|
|
||||||
pub fn react_to_zellij_state_update(&mut self, pane_manifest: PaneManifest) {
|
|
||||||
let is_first_update = self.right_side_panes.is_empty() && self.left_side_panes.is_empty();
|
|
||||||
let panes_on_the_left_before = self.left_side_panes.len();
|
|
||||||
let panes_on_the_right_before = self.right_side_panes.len();
|
|
||||||
self.update_tab_info(&pane_manifest);
|
|
||||||
self.update_panes(pane_manifest);
|
|
||||||
if is_first_update && !self.right_side_panes.is_empty() {
|
|
||||||
// in this case, the plugin was started with an existing group
|
|
||||||
// most likely, the user wants to perform operations just on this group, so we
|
|
||||||
// only show the group, giving the option to add more panes
|
|
||||||
self.visibility_and_focus.hide_left_side();
|
|
||||||
}
|
|
||||||
let pane_count_changed = (panes_on_the_left_before != self.left_side_panes.len())
|
|
||||||
|| (panes_on_the_right_before != self.right_side_panes.len());
|
|
||||||
if !is_first_update && pane_count_changed {
|
|
||||||
let has_panes_on_the_right = !self.right_side_panes.is_empty();
|
|
||||||
let has_panes_on_the_left = !self.left_side_panes.is_empty();
|
|
||||||
if has_panes_on_the_right && has_panes_on_the_left {
|
|
||||||
self.visibility_and_focus.show_both_sides();
|
|
||||||
} else if has_panes_on_the_right {
|
|
||||||
self.visibility_and_focus.hide_left_side();
|
|
||||||
} else if has_panes_on_the_left {
|
|
||||||
self.visibility_and_focus.hide_right_side();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn update_panes(&mut self, pane_manifest: PaneManifest) {
|
|
||||||
let mut all_panes = BTreeMap::new();
|
|
||||||
for (_tab_index, pane_infos) in pane_manifest.panes {
|
|
||||||
for pane_info in pane_infos {
|
|
||||||
if pane_info.is_selectable {
|
|
||||||
if pane_info.is_plugin {
|
|
||||||
all_panes.insert(PaneId::Plugin(pane_info.id), pane_info);
|
|
||||||
} else {
|
|
||||||
all_panes.insert(PaneId::Terminal(pane_info.id), pane_info);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.left_side_panes
|
|
||||||
.retain(|p| all_panes.contains_key(&p.id));
|
|
||||||
self.right_side_panes
|
|
||||||
.retain(|p| all_panes.contains_key(&p.id));
|
|
||||||
let mut new_selected_panes: BTreeMap<usize, PaneItem> = BTreeMap::new(); // usize -> index_in_pane_group
|
|
||||||
for (pane_id, pane) in all_panes.into_iter() {
|
|
||||||
let is_known = self
|
|
||||||
.left_side_panes
|
|
||||||
.iter()
|
|
||||||
.find(|p| p.id == pane_id)
|
|
||||||
.is_some()
|
|
||||||
|| self
|
|
||||||
.right_side_panes
|
|
||||||
.iter()
|
|
||||||
.find(|p| p.id == pane_id)
|
|
||||||
.is_some();
|
|
||||||
let index_in_pane_group = self
|
|
||||||
.own_client_id
|
|
||||||
.and_then(|own_client_id| pane.index_in_pane_group.get(&own_client_id));
|
|
||||||
let is_grouped_for_own_client_id = index_in_pane_group.is_some();
|
|
||||||
if !is_known {
|
|
||||||
if is_grouped_for_own_client_id {
|
|
||||||
if let Some(index_in_pane_group) = index_in_pane_group {
|
|
||||||
// we do this rather than adding them directly to right_side_panes so that
|
|
||||||
// we can make sure they're in the same order as the group is so that
|
|
||||||
// things like stacking order will do the right thing
|
|
||||||
new_selected_panes.insert(
|
|
||||||
*index_in_pane_group,
|
|
||||||
PaneItem {
|
|
||||||
text: pane.title,
|
|
||||||
id: pane_id,
|
|
||||||
color_indices: vec![],
|
|
||||||
},
|
|
||||||
);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
self.left_side_panes.push(PaneItem {
|
|
||||||
text: pane.title,
|
|
||||||
id: pane_id,
|
|
||||||
color_indices: vec![],
|
|
||||||
});
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if is_grouped_for_own_client_id {
|
|
||||||
if let Some(position) =
|
|
||||||
self.left_side_panes.iter().position(|p| p.id == pane_id)
|
|
||||||
{
|
|
||||||
// pane was added to a pane group outside the plugin (eg. with mouse selection)
|
|
||||||
let mut pane = self.left_side_panes.remove(position);
|
|
||||||
pane.clear();
|
|
||||||
self.right_side_panes.push(pane);
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let Some(position) =
|
|
||||||
self.right_side_panes.iter().position(|p| p.id == pane_id)
|
|
||||||
{
|
|
||||||
// pane was removed from a pane group outside the plugin (eg. with mouse selection)
|
|
||||||
let mut pane = self.right_side_panes.remove(position);
|
|
||||||
pane.clear();
|
|
||||||
self.left_side_panes.push(pane);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (_index_in_pane_group, pane_item) in new_selected_panes.into_iter() {
|
|
||||||
self.right_side_panes.push(pane_item);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn update_tab_info(&mut self, pane_manifest: &PaneManifest) {
|
|
||||||
for (tab_index, pane_infos) in &pane_manifest.panes {
|
|
||||||
for pane_info in pane_infos {
|
|
||||||
if pane_info.is_plugin && Some(pane_info.id) == self.own_plugin_id {
|
|
||||||
self.own_tab_index = Some(*tab_index);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.total_tabs_in_session = Some(pane_manifest.panes.keys().count());
|
|
||||||
}
|
|
||||||
pub fn update_search_results(&mut self) {
|
|
||||||
let mut matches = vec![];
|
|
||||||
let matcher = SkimMatcherV2::default().use_cache(true);
|
|
||||||
for pane_item in &self.left_side_panes {
|
|
||||||
if let Some((score, indices)) =
|
|
||||||
matcher.fuzzy_indices(&pane_item.text, &self.search_string)
|
|
||||||
{
|
|
||||||
let mut pane_item = pane_item.clone();
|
|
||||||
pane_item.color_indices = indices;
|
|
||||||
matches.push((score, pane_item));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
matches.sort_by(|(a_score, _a), (b_score, _b)| b_score.cmp(&a_score));
|
|
||||||
if self.search_string.is_empty() {
|
|
||||||
self.search_results = None;
|
|
||||||
} else {
|
|
||||||
self.search_results = Some(
|
|
||||||
matches
|
|
||||||
.into_iter()
|
|
||||||
.map(|(_s, pane_item)| pane_item)
|
|
||||||
.collect(),
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn group_panes_in_zellij(&mut self, pane_ids: Vec<PaneId>) {
|
|
||||||
group_and_ungroup_panes(pane_ids, vec![]);
|
|
||||||
}
|
|
||||||
pub fn ungroup_panes_in_zellij(&mut self, pane_ids: Vec<PaneId>) {
|
|
||||||
group_and_ungroup_panes(vec![], pane_ids);
|
|
||||||
}
|
|
||||||
pub fn update_highlighted_panes(&self) {
|
|
||||||
let mut pane_ids_to_highlight = vec![];
|
|
||||||
let mut pane_ids_to_unhighlight = vec![];
|
|
||||||
if let Some(marked_index) = &self.marked_index {
|
|
||||||
if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
if let Some(main_index_pane_id) = self
|
|
||||||
.search_results
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|s| s.get(marked_index.main_index))
|
|
||||||
.or_else(|| self.left_side_panes.get(marked_index.main_index))
|
|
||||||
.map(|p| p.id)
|
|
||||||
{
|
|
||||||
pane_ids_to_highlight.push(main_index_pane_id);
|
|
||||||
}
|
|
||||||
for index in &marked_index.additional_indices {
|
|
||||||
if let Some(pane_id) = self
|
|
||||||
.search_results
|
|
||||||
.as_ref()
|
|
||||||
.and_then(|s| s.get(*index))
|
|
||||||
.or_else(|| self.left_side_panes.get(*index))
|
|
||||||
.map(|p| p.id)
|
|
||||||
{
|
|
||||||
pane_ids_to_highlight.push(pane_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
if let Some(main_index_pane_id) = self
|
|
||||||
.right_side_panes
|
|
||||||
.get(marked_index.main_index)
|
|
||||||
.map(|p| p.id)
|
|
||||||
{
|
|
||||||
pane_ids_to_highlight.push(main_index_pane_id);
|
|
||||||
}
|
|
||||||
for index in &marked_index.additional_indices {
|
|
||||||
if let Some(pane_id) = self.right_side_panes.get(*index).map(|p| p.id) {
|
|
||||||
pane_ids_to_highlight.push(pane_id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for pane in &self.left_side_panes {
|
|
||||||
if !pane_ids_to_highlight.contains(&pane.id) {
|
|
||||||
pane_ids_to_unhighlight.push(pane.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for pane in &self.right_side_panes {
|
|
||||||
if !pane_ids_to_highlight.contains(&pane.id) {
|
|
||||||
pane_ids_to_unhighlight.push(pane.id);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
highlight_and_unhighlight_panes(pane_ids_to_highlight, pane_ids_to_unhighlight);
|
|
||||||
}
|
|
||||||
pub fn unhighlight_all_panes(&mut self) {
|
|
||||||
let mut pane_ids_to_unhighlight = HashSet::new();
|
|
||||||
for pane_item in &self.left_side_panes {
|
|
||||||
pane_ids_to_unhighlight.insert(pane_item.id);
|
|
||||||
}
|
|
||||||
for pane_item in &self.right_side_panes {
|
|
||||||
pane_ids_to_unhighlight.insert(pane_item.id);
|
|
||||||
}
|
|
||||||
highlight_and_unhighlight_panes(vec![], pane_ids_to_unhighlight.into_iter().collect());
|
|
||||||
}
|
|
||||||
pub fn ungroup_all_panes(&mut self) {
|
|
||||||
let mut unselected_panes = vec![];
|
|
||||||
for pane_item in self.right_side_panes.iter_mut() {
|
|
||||||
pane_item.clear();
|
|
||||||
unselected_panes.push(pane_item.id);
|
|
||||||
}
|
|
||||||
self.left_side_panes.append(&mut self.right_side_panes);
|
|
||||||
self.ungroup_panes_in_zellij(unselected_panes);
|
|
||||||
self.visibility_and_focus.hide_right_side();
|
|
||||||
self.marked_index = None;
|
|
||||||
}
|
|
||||||
pub fn ungroup_all_panes_and_close_self(&mut self) {
|
|
||||||
let mut pane_ids_to_ungroup = HashSet::new();
|
|
||||||
for pane_item in &self.left_side_panes {
|
|
||||||
pane_ids_to_ungroup.insert(pane_item.id);
|
|
||||||
}
|
|
||||||
for pane_item in &self.right_side_panes {
|
|
||||||
pane_ids_to_ungroup.insert(pane_item.id);
|
|
||||||
}
|
|
||||||
group_and_ungroup_panes(vec![], pane_ids_to_ungroup.into_iter().collect());
|
|
||||||
close_self();
|
|
||||||
}
|
|
||||||
pub fn group_panes(&mut self, mut marked_index: MarkedIndex, keep_left_side_focused: bool) {
|
|
||||||
let mut all_selected_indices: BTreeSet<usize> =
|
|
||||||
marked_index.additional_indices.drain().collect();
|
|
||||||
all_selected_indices.insert(marked_index.main_index);
|
|
||||||
|
|
||||||
// reverse so that the indices will remain consistent while
|
|
||||||
// removing
|
|
||||||
let mut selected_panes = vec![];
|
|
||||||
for index in all_selected_indices.iter().rev() {
|
|
||||||
let index = self
|
|
||||||
.search_results
|
|
||||||
.as_mut()
|
|
||||||
.and_then(|search_results| {
|
|
||||||
if search_results.len() > *index {
|
|
||||||
Some(search_results.remove(*index))
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.and_then(|selected_search_result| {
|
|
||||||
self.left_side_panes
|
|
||||||
.iter()
|
|
||||||
.position(|p| p.id == selected_search_result.id)
|
|
||||||
})
|
|
||||||
.unwrap_or(*index);
|
|
||||||
if self.left_side_panes.len() > index {
|
|
||||||
let selected_pane = self.left_side_panes.remove(index);
|
|
||||||
selected_panes.push(selected_pane);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
let pane_ids_to_make_selected: Vec<PaneId> = selected_panes.iter().map(|p| p.id).collect();
|
|
||||||
self.right_side_panes
|
|
||||||
.append(&mut selected_panes.into_iter().rev().collect());
|
|
||||||
|
|
||||||
let displayed_list_len = match self.search_results.as_ref() {
|
|
||||||
Some(search_results) => search_results.len(),
|
|
||||||
None => self.left_side_panes.len(),
|
|
||||||
};
|
|
||||||
|
|
||||||
if displayed_list_len == 0 {
|
|
||||||
self.handle_left_side_emptied();
|
|
||||||
} else if keep_left_side_focused {
|
|
||||||
if marked_index.main_index > displayed_list_len.saturating_sub(1) {
|
|
||||||
self.marked_index = Some(MarkedIndex::new(displayed_list_len.saturating_sub(1)));
|
|
||||||
} else {
|
|
||||||
self.marked_index = Some(marked_index);
|
|
||||||
}
|
|
||||||
self.visibility_and_focus.show_both_sides();
|
|
||||||
} else {
|
|
||||||
self.visibility_and_focus.focus_right_side();
|
|
||||||
}
|
|
||||||
|
|
||||||
self.group_panes_in_zellij(pane_ids_to_make_selected);
|
|
||||||
self.update_highlighted_panes();
|
|
||||||
}
|
|
||||||
pub fn ungroup_panes(&mut self, mut marked_index: MarkedIndex) {
|
|
||||||
let mut all_selected_indices: BTreeSet<usize> =
|
|
||||||
marked_index.additional_indices.drain().collect();
|
|
||||||
all_selected_indices.insert(marked_index.main_index);
|
|
||||||
|
|
||||||
// reverse so that the indices will remain consistent while
|
|
||||||
// removing
|
|
||||||
let mut selected_panes = vec![];
|
|
||||||
for index in all_selected_indices.iter().rev() {
|
|
||||||
if self.right_side_panes.len() > *index {
|
|
||||||
let mut selected_pane = self.right_side_panes.remove(*index);
|
|
||||||
selected_pane.clear();
|
|
||||||
selected_panes.push(selected_pane);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
self.ungroup_panes_in_zellij(selected_panes.iter().map(|p| p.id).collect());
|
|
||||||
self.left_side_panes
|
|
||||||
.append(&mut selected_panes.into_iter().rev().collect());
|
|
||||||
|
|
||||||
if self.right_side_panes.is_empty() {
|
|
||||||
self.marked_index = None;
|
|
||||||
self.visibility_and_focus.hide_right_side();
|
|
||||||
} else if marked_index.main_index > self.right_side_panes.len().saturating_sub(1) {
|
|
||||||
self.marked_index = Some(MarkedIndex::new(
|
|
||||||
self.right_side_panes.len().saturating_sub(1),
|
|
||||||
));
|
|
||||||
self.visibility_and_focus.show_both_sides();
|
|
||||||
} else {
|
|
||||||
self.marked_index = Some(marked_index);
|
|
||||||
self.visibility_and_focus.show_both_sides();
|
|
||||||
}
|
|
||||||
self.update_highlighted_panes();
|
|
||||||
}
|
|
||||||
pub fn group_search_results(&mut self, search_results: Vec<PaneItem>) {
|
|
||||||
let mut pane_ids_to_make_selected = vec![];
|
|
||||||
for search_result in search_results {
|
|
||||||
let pane_id = search_result.id;
|
|
||||||
pane_ids_to_make_selected.push(pane_id);
|
|
||||||
self.left_side_panes.retain(|p| p.id != pane_id);
|
|
||||||
self.right_side_panes.push(search_result);
|
|
||||||
}
|
|
||||||
self.group_panes_in_zellij(pane_ids_to_make_selected);
|
|
||||||
}
|
|
||||||
pub fn group_all_panes(&mut self) {
|
|
||||||
let pane_ids_to_make_selected: Vec<PaneId> =
|
|
||||||
self.left_side_panes.iter().map(|p| p.id).collect();
|
|
||||||
self.right_side_panes.append(&mut self.left_side_panes);
|
|
||||||
self.group_panes_in_zellij(pane_ids_to_make_selected);
|
|
||||||
}
|
|
||||||
pub fn handle_left_side_emptied(&mut self) {
|
|
||||||
self.visibility_and_focus.hide_left_side();
|
|
||||||
self.previous_search_string = self.search_string.drain(..).collect();
|
|
||||||
self.marked_index = None;
|
|
||||||
self.search_results = None;
|
|
||||||
self.update_highlighted_panes();
|
|
||||||
}
|
|
||||||
pub fn move_marked_index_down(&mut self) {
|
|
||||||
match self.marked_index.as_mut() {
|
|
||||||
Some(marked_index) => {
|
|
||||||
let is_searching = self.search_results.is_some();
|
|
||||||
let search_result_count =
|
|
||||||
self.search_results.as_ref().map(|s| s.len()).unwrap_or(0);
|
|
||||||
if self.visibility_and_focus.left_side_is_focused()
|
|
||||||
&& is_searching
|
|
||||||
&& marked_index.main_index == search_result_count.saturating_sub(1)
|
|
||||||
{
|
|
||||||
marked_index.main_index = 0;
|
|
||||||
} else if self.visibility_and_focus.left_side_is_focused()
|
|
||||||
&& !is_searching
|
|
||||||
&& marked_index.main_index == self.left_side_panes.len().saturating_sub(1)
|
|
||||||
{
|
|
||||||
marked_index.main_index = 0;
|
|
||||||
} else if self.visibility_and_focus.right_side_is_focused()
|
|
||||||
&& marked_index.main_index == self.right_side_panes.len().saturating_sub(1)
|
|
||||||
{
|
|
||||||
marked_index.main_index = 0;
|
|
||||||
} else {
|
|
||||||
marked_index.main_index += 1
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
let is_searching = self.search_results.is_some();
|
|
||||||
let has_search_results = self
|
|
||||||
.search_results
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| !s.is_empty())
|
|
||||||
.unwrap_or(false);
|
|
||||||
if is_searching && has_search_results {
|
|
||||||
self.marked_index = Some(MarkedIndex::new(0));
|
|
||||||
} else if !is_searching && !self.left_side_panes.is_empty() {
|
|
||||||
self.marked_index = Some(MarkedIndex::new(0));
|
|
||||||
}
|
|
||||||
} else if self.visibility_and_focus.right_side_is_focused()
|
|
||||||
&& !self.right_side_panes.is_empty()
|
|
||||||
{
|
|
||||||
self.marked_index = Some(MarkedIndex::new(0));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
self.update_highlighted_panes();
|
|
||||||
}
|
|
||||||
pub fn move_marked_index_up(&mut self) {
|
|
||||||
match self.marked_index.as_mut() {
|
|
||||||
Some(marked_index) => {
|
|
||||||
if self.visibility_and_focus.left_side_is_focused() && marked_index.main_index == 0
|
|
||||||
{
|
|
||||||
if let Some(search_result_count) = self.search_results.as_ref().map(|s| s.len())
|
|
||||||
{
|
|
||||||
marked_index.main_index = search_result_count.saturating_sub(1);
|
|
||||||
} else {
|
|
||||||
marked_index.main_index = self.left_side_panes.len().saturating_sub(1);
|
|
||||||
}
|
|
||||||
} else if self.visibility_and_focus.right_side_is_focused()
|
|
||||||
&& marked_index.main_index == 0
|
|
||||||
{
|
|
||||||
marked_index.main_index = self.right_side_panes.len().saturating_sub(1);
|
|
||||||
} else {
|
|
||||||
marked_index.main_index = marked_index.main_index.saturating_sub(1);
|
|
||||||
}
|
|
||||||
},
|
|
||||||
None => {
|
|
||||||
if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
let is_searching = self.search_results.is_some();
|
|
||||||
let has_search_results = self
|
|
||||||
.search_results
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| !s.is_empty())
|
|
||||||
.unwrap_or(false);
|
|
||||||
if is_searching && has_search_results {
|
|
||||||
let search_results_count =
|
|
||||||
self.search_results.as_ref().map(|s| s.len()).unwrap_or(0);
|
|
||||||
self.marked_index =
|
|
||||||
Some(MarkedIndex::new(search_results_count.saturating_sub(1)));
|
|
||||||
} else if !is_searching && !self.left_side_panes.is_empty() {
|
|
||||||
self.marked_index = Some(MarkedIndex::new(
|
|
||||||
self.left_side_panes.len().saturating_sub(1),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
} else if self.visibility_and_focus.right_side_is_focused()
|
|
||||||
&& !self.right_side_panes.is_empty()
|
|
||||||
{
|
|
||||||
self.marked_index = Some(MarkedIndex::new(
|
|
||||||
self.right_side_panes.len().saturating_sub(1),
|
|
||||||
));
|
|
||||||
}
|
|
||||||
},
|
|
||||||
}
|
|
||||||
self.update_highlighted_panes();
|
|
||||||
}
|
|
||||||
pub fn mark_entry(&mut self) {
|
|
||||||
if let Some(marked_index) = self.marked_index.as_mut() {
|
|
||||||
marked_index.toggle_additional_mark();
|
|
||||||
self.update_highlighted_panes();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn break_grouped_panes_to_new_tab(&mut self) {
|
|
||||||
let pane_ids_to_break_to_new_tab: Vec<PaneId> =
|
|
||||||
self.right_side_panes.drain(..).map(|p| p.id).collect();
|
|
||||||
let title_for_new_tab = if !self.previous_search_string.is_empty() {
|
|
||||||
Some(self.previous_search_string.clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
break_panes_to_new_tab(&pane_ids_to_break_to_new_tab, title_for_new_tab, true);
|
|
||||||
self.ungroup_panes_in_zellij(pane_ids_to_break_to_new_tab);
|
|
||||||
close_self();
|
|
||||||
}
|
|
||||||
pub fn stack_grouped_panes(&mut self) {
|
|
||||||
let pane_ids_to_stack: Vec<PaneId> =
|
|
||||||
self.right_side_panes.drain(..).map(|p| p.id).collect();
|
|
||||||
stack_panes(pane_ids_to_stack.clone());
|
|
||||||
self.ungroup_panes_in_zellij(pane_ids_to_stack);
|
|
||||||
close_self();
|
|
||||||
}
|
|
||||||
pub fn float_grouped_panes(&mut self) {
|
|
||||||
let pane_ids_to_float: Vec<PaneId> =
|
|
||||||
self.right_side_panes.drain(..).map(|p| p.id).collect();
|
|
||||||
float_multiple_panes(pane_ids_to_float.clone());
|
|
||||||
self.ungroup_panes_in_zellij(pane_ids_to_float);
|
|
||||||
close_self();
|
|
||||||
}
|
|
||||||
pub fn embed_grouped_panes(&mut self) {
|
|
||||||
let pane_ids_to_embed: Vec<PaneId> =
|
|
||||||
self.right_side_panes.drain(..).map(|p| p.id).collect();
|
|
||||||
embed_multiple_panes(pane_ids_to_embed.clone());
|
|
||||||
self.ungroup_panes_in_zellij(pane_ids_to_embed);
|
|
||||||
close_self();
|
|
||||||
}
|
|
||||||
pub fn break_grouped_panes_right(&mut self) {
|
|
||||||
if let Some(own_tab_index) = self.own_tab_index {
|
|
||||||
if Some(own_tab_index + 1) < self.total_tabs_in_session {
|
|
||||||
let pane_ids_to_break_right: Vec<PaneId> =
|
|
||||||
self.right_side_panes.drain(..).map(|p| p.id).collect();
|
|
||||||
break_panes_to_tab_with_index(&pane_ids_to_break_right, own_tab_index + 1, true);
|
|
||||||
} else {
|
|
||||||
let pane_ids_to_break_to_new_tab: Vec<PaneId> =
|
|
||||||
self.right_side_panes.drain(..).map(|p| p.id).collect();
|
|
||||||
let title_for_new_tab = if !self.previous_search_string.is_empty() {
|
|
||||||
Some(self.previous_search_string.clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
break_panes_to_new_tab(&pane_ids_to_break_to_new_tab, title_for_new_tab, true);
|
|
||||||
}
|
|
||||||
close_self();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn break_grouped_panes_left(&mut self) {
|
|
||||||
if let Some(own_tab_index) = self.own_tab_index {
|
|
||||||
if own_tab_index > 0 {
|
|
||||||
let pane_ids_to_break_left: Vec<PaneId> =
|
|
||||||
self.right_side_panes.drain(..).map(|p| p.id).collect();
|
|
||||||
break_panes_to_tab_with_index(
|
|
||||||
&pane_ids_to_break_left,
|
|
||||||
own_tab_index.saturating_sub(1),
|
|
||||||
true,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
let pane_ids_to_break_to_new_tab: Vec<PaneId> =
|
|
||||||
self.right_side_panes.drain(..).map(|p| p.id).collect();
|
|
||||||
let title_for_new_tab = if !self.previous_search_string.is_empty() {
|
|
||||||
Some(self.previous_search_string.clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
};
|
|
||||||
break_panes_to_new_tab(&pane_ids_to_break_to_new_tab, title_for_new_tab, true);
|
|
||||||
}
|
|
||||||
close_self();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn close_grouped_panes(&mut self) {
|
|
||||||
let pane_ids_to_close: Vec<PaneId> =
|
|
||||||
self.right_side_panes.drain(..).map(|p| p.id).collect();
|
|
||||||
close_multiple_panes(pane_ids_to_close);
|
|
||||||
close_self();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -1,873 +0,0 @@
|
||||||
use crate::{App, VisibilityAndFocus};
|
|
||||||
use zellij_tile::prelude::*;
|
|
||||||
|
|
||||||
const TOP_LEFT_CORNER_CHARACTER: &'static str = "┌";
|
|
||||||
const TOP_RIGHT_CORNER_CHARACTER: &'static str = "┐";
|
|
||||||
const BOTTOM_LEFT_CORNER_CHARACTER: &'static str = "└";
|
|
||||||
const BOTTOM_RIGHT_CORNER_CHARACTER: &'static str = "┘";
|
|
||||||
const BOUNDARY_CHARACTER: &'static str = "│";
|
|
||||||
const HORIZONTAL_BOUNDARY_CHARACTER: &'static str = "─";
|
|
||||||
|
|
||||||
#[derive(Debug, Clone)]
|
|
||||||
pub struct PaneItem {
|
|
||||||
pub text: String,
|
|
||||||
pub id: PaneId,
|
|
||||||
pub color_indices: Vec<usize>,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl PaneItem {
|
|
||||||
pub fn clear(&mut self) {
|
|
||||||
self.color_indices.clear();
|
|
||||||
}
|
|
||||||
pub fn render(&self, max_width_for_item: usize) -> NestedListItem {
|
|
||||||
let pane_item_text_len = self.text.chars().count();
|
|
||||||
if pane_item_text_len <= max_width_for_item {
|
|
||||||
NestedListItem::new(&self.text)
|
|
||||||
.color_range(0, ..)
|
|
||||||
.color_indices(3, self.color_indices.iter().copied().collect())
|
|
||||||
} else {
|
|
||||||
let length_of_each_half = max_width_for_item.saturating_sub(3) / 2;
|
|
||||||
let first_half: String = self.text.chars().take(length_of_each_half).collect();
|
|
||||||
let second_half: String = self
|
|
||||||
.text
|
|
||||||
.chars()
|
|
||||||
.rev()
|
|
||||||
.take(length_of_each_half)
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.collect();
|
|
||||||
let second_half_start_index = pane_item_text_len.saturating_sub(length_of_each_half);
|
|
||||||
let adjusted_indices: Vec<usize> = self
|
|
||||||
.color_indices
|
|
||||||
.iter()
|
|
||||||
.filter_map(|i| {
|
|
||||||
if i < &length_of_each_half {
|
|
||||||
Some(*i)
|
|
||||||
} else if i >= &second_half_start_index {
|
|
||||||
Some(i.saturating_sub(second_half_start_index) + length_of_each_half + 3)
|
|
||||||
//3 for the bulletin
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
})
|
|
||||||
.collect();
|
|
||||||
NestedListItem::new(format!("{}...{}", first_half, second_half))
|
|
||||||
.color_range(0, ..)
|
|
||||||
.color_indices(3, adjusted_indices)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// rendering code
|
|
||||||
impl App {
|
|
||||||
pub fn render_close_shortcut(&self, cols: usize) {
|
|
||||||
let should_render_close_shortcut =
|
|
||||||
self.visibility_and_focus.left_side_is_focused() && self.marked_index.is_none();
|
|
||||||
if should_render_close_shortcut {
|
|
||||||
let x_coordinates_right_padding =
|
|
||||||
if self.visibility_and_focus.only_left_side_is_focused() {
|
|
||||||
5
|
|
||||||
} else {
|
|
||||||
1
|
|
||||||
};
|
|
||||||
let ctrl_c_shortcut_text = "<Ctrl c> - Close";
|
|
||||||
let ctrl_c_shortcut = Text::new(ctrl_c_shortcut_text).color_range(3, ..=7);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
ctrl_c_shortcut,
|
|
||||||
cols.saturating_sub(ctrl_c_shortcut_text.chars().count())
|
|
||||||
.saturating_sub(x_coordinates_right_padding),
|
|
||||||
0,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn render_tab_shortcut(&self, cols: usize, rows: usize) {
|
|
||||||
match self.visibility_and_focus {
|
|
||||||
VisibilityAndFocus::BothSidesVisibleRightSideFocused => {
|
|
||||||
let side_width = self.calculate_side_width(cols);
|
|
||||||
let tab_shortcut = Text::new("<TAB> - select more panes").color_range(3, ..=4);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
tab_shortcut,
|
|
||||||
side_width + 6,
|
|
||||||
rows.saturating_sub(2),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
VisibilityAndFocus::BothSidesVisibleLeftSideFocused => {
|
|
||||||
let side_width = self.calculate_side_width(cols);
|
|
||||||
let tab_shortcut_text = "<TAB> - browse selected panes";
|
|
||||||
let tab_shortcut = Text::new(tab_shortcut_text).color_range(3, ..=4);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
tab_shortcut,
|
|
||||||
side_width.saturating_sub(tab_shortcut_text.chars().count() + 1),
|
|
||||||
rows.saturating_sub(2),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
},
|
|
||||||
VisibilityAndFocus::OnlyRightSideVisible => {
|
|
||||||
let tab_shortcut = Text::new("<TAB> - select more panes").color_range(3, ..=4);
|
|
||||||
print_text_with_coordinates(tab_shortcut, 4, rows.saturating_sub(2), None, None);
|
|
||||||
},
|
|
||||||
VisibilityAndFocus::OnlyLeftSideVisible => {
|
|
||||||
// not visible
|
|
||||||
},
|
|
||||||
};
|
|
||||||
}
|
|
||||||
pub fn render_left_side(&self, rows: usize, cols: usize, is_focused: bool) {
|
|
||||||
let title_y = 0;
|
|
||||||
let left_side_base_x = 1;
|
|
||||||
let list_y = 2;
|
|
||||||
let side_width = self.calculate_side_width(cols);
|
|
||||||
let max_left_list_height = rows.saturating_sub(8);
|
|
||||||
let (
|
|
||||||
extra_pane_count_on_top_left,
|
|
||||||
extra_pane_count_on_bottom_left,
|
|
||||||
extra_selected_item_count_on_top_left,
|
|
||||||
extra_selected_item_count_on_bottom_left,
|
|
||||||
left_side_panes,
|
|
||||||
) = self.left_side_panes_list(side_width, max_left_list_height);
|
|
||||||
let (filter_prompt_text, filter_prompt) = self.filter_panes_prompt();
|
|
||||||
let filter = self.filter(side_width.saturating_sub(filter_prompt_text.chars().count() + 1));
|
|
||||||
let (
|
|
||||||
_enter_select_panes_text,
|
|
||||||
enter_select_panes,
|
|
||||||
space_shortcut_text,
|
|
||||||
space_shortcut,
|
|
||||||
_escape_shortcut_text,
|
|
||||||
escape_shortcut,
|
|
||||||
) = self.left_side_controls(side_width);
|
|
||||||
print_text_with_coordinates(filter_prompt, left_side_base_x, title_y, None, None);
|
|
||||||
if is_focused {
|
|
||||||
print_text_with_coordinates(
|
|
||||||
filter,
|
|
||||||
left_side_base_x + filter_prompt_text.chars().count(),
|
|
||||||
title_y,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
print_nested_list_with_coordinates(
|
|
||||||
left_side_panes.clone(),
|
|
||||||
left_side_base_x,
|
|
||||||
list_y,
|
|
||||||
Some(side_width),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
if is_focused {
|
|
||||||
if let Some(marked_index) = self.marked_index.as_ref().map(|i| i.main_index) {
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(">").color_range(3, ..).selected(),
|
|
||||||
left_side_base_x + 1,
|
|
||||||
(list_y + marked_index).saturating_sub(extra_pane_count_on_top_left),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if extra_pane_count_on_top_left > 0 {
|
|
||||||
self.print_extra_pane_count(
|
|
||||||
extra_pane_count_on_top_left,
|
|
||||||
extra_selected_item_count_on_top_left,
|
|
||||||
list_y.saturating_sub(1),
|
|
||||||
left_side_base_x,
|
|
||||||
side_width,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if extra_pane_count_on_bottom_left > 0 {
|
|
||||||
self.print_extra_pane_count(
|
|
||||||
extra_pane_count_on_bottom_left,
|
|
||||||
extra_selected_item_count_on_bottom_left,
|
|
||||||
list_y + left_side_panes.len(),
|
|
||||||
left_side_base_x,
|
|
||||||
side_width,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if is_focused && !left_side_panes.is_empty() {
|
|
||||||
let controls_x = 1;
|
|
||||||
print_text_with_coordinates(
|
|
||||||
enter_select_panes,
|
|
||||||
controls_x,
|
|
||||||
list_y + left_side_panes.len() + 1,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
if self.marked_index.is_some() {
|
|
||||||
print_text_with_coordinates(
|
|
||||||
space_shortcut.clone(),
|
|
||||||
controls_x,
|
|
||||||
list_y + left_side_panes.len() + 2,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
escape_shortcut.clone(),
|
|
||||||
controls_x + space_shortcut_text.chars().count() + 1,
|
|
||||||
list_y + left_side_panes.len() + 2,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn render_right_side(&self, rows: usize, cols: usize, is_focused: bool) {
|
|
||||||
let side_width = self.calculate_side_width(cols);
|
|
||||||
let right_side_base_x = match self.visibility_and_focus {
|
|
||||||
VisibilityAndFocus::OnlyLeftSideVisible | VisibilityAndFocus::OnlyRightSideVisible => 1,
|
|
||||||
VisibilityAndFocus::BothSidesVisibleLeftSideFocused
|
|
||||||
| VisibilityAndFocus::BothSidesVisibleRightSideFocused => side_width + 4,
|
|
||||||
};
|
|
||||||
let title_y = 0;
|
|
||||||
let list_y: usize = 2;
|
|
||||||
let max_right_list_height = rows.saturating_sub(11);
|
|
||||||
let selected_prompt = self.selected_panes_title();
|
|
||||||
let (
|
|
||||||
extra_pane_count_on_top_right,
|
|
||||||
extra_pane_count_on_bottom_right,
|
|
||||||
extra_selected_item_count_on_top_right,
|
|
||||||
extra_selected_item_count_on_bottom_right,
|
|
||||||
right_side_panes,
|
|
||||||
) = self.right_side_panes_list(side_width, max_right_list_height);
|
|
||||||
let right_side_pane_count = right_side_panes.len();
|
|
||||||
let (
|
|
||||||
right_side_controls_1,
|
|
||||||
right_side_controls_2,
|
|
||||||
right_side_controls_3,
|
|
||||||
right_side_controls_4,
|
|
||||||
) = self.right_side_controls(side_width);
|
|
||||||
if extra_pane_count_on_top_right > 0 {
|
|
||||||
self.print_extra_pane_count(
|
|
||||||
extra_pane_count_on_top_right,
|
|
||||||
extra_selected_item_count_on_top_right,
|
|
||||||
list_y.saturating_sub(1),
|
|
||||||
right_side_base_x,
|
|
||||||
side_width,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
if extra_pane_count_on_bottom_right > 0 {
|
|
||||||
self.print_extra_pane_count(
|
|
||||||
extra_pane_count_on_bottom_right,
|
|
||||||
extra_selected_item_count_on_bottom_right,
|
|
||||||
list_y + right_side_panes.len(),
|
|
||||||
right_side_base_x,
|
|
||||||
side_width,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
print_text_with_coordinates(selected_prompt, right_side_base_x + 3, title_y, None, None);
|
|
||||||
print_nested_list_with_coordinates(
|
|
||||||
right_side_panes,
|
|
||||||
right_side_base_x,
|
|
||||||
list_y,
|
|
||||||
Some(side_width),
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
if is_focused {
|
|
||||||
if let Some(marked_index) = self.marked_index.as_ref().map(|i| i.main_index) {
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(">").color_range(3, ..).selected(),
|
|
||||||
right_side_base_x + 1,
|
|
||||||
(list_y + marked_index).saturating_sub(extra_pane_count_on_top_right),
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if is_focused && !self.right_side_panes.is_empty() {
|
|
||||||
print_text_with_coordinates(
|
|
||||||
right_side_controls_1,
|
|
||||||
right_side_base_x + 1,
|
|
||||||
list_y + right_side_pane_count + 1,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
right_side_controls_2,
|
|
||||||
right_side_base_x + 1,
|
|
||||||
list_y + right_side_pane_count + 3,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
right_side_controls_3,
|
|
||||||
right_side_base_x + 1,
|
|
||||||
list_y + right_side_pane_count + 4,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
right_side_controls_4,
|
|
||||||
right_side_base_x + 1,
|
|
||||||
list_y + right_side_pane_count + 5,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn render_help_line(&self, rows: usize, cols: usize) {
|
|
||||||
let help_line_text = match self.visibility_and_focus {
|
|
||||||
VisibilityAndFocus::OnlyLeftSideVisible => {
|
|
||||||
let full_help_line = "Help: Select one or more panes to group for bulk operations";
|
|
||||||
let short_help_line = "Help: Select panes to group";
|
|
||||||
if cols >= full_help_line.chars().count() {
|
|
||||||
full_help_line
|
|
||||||
} else {
|
|
||||||
short_help_line
|
|
||||||
}
|
|
||||||
},
|
|
||||||
VisibilityAndFocus::OnlyRightSideVisible => {
|
|
||||||
let full_help_line = "Help: Perform bulk operations on all selected panes";
|
|
||||||
let short_help_line = "Help: Perform bulk operations";
|
|
||||||
if cols >= full_help_line.chars().count() {
|
|
||||||
full_help_line
|
|
||||||
} else {
|
|
||||||
short_help_line
|
|
||||||
}
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
let full_help_line =
|
|
||||||
"Help: Select panes on the left, then perform operations on the right.";
|
|
||||||
let short_help_line = "Help: Group panes for bulk operations";
|
|
||||||
if cols >= full_help_line.chars().count() {
|
|
||||||
full_help_line
|
|
||||||
} else {
|
|
||||||
short_help_line
|
|
||||||
}
|
|
||||||
},
|
|
||||||
};
|
|
||||||
let help_line = Text::new(help_line_text);
|
|
||||||
print_text_with_coordinates(help_line, 0, rows, None, None);
|
|
||||||
}
|
|
||||||
pub fn render_focus_boundary(&self, rows: usize, cols: usize) {
|
|
||||||
let side_width = self.calculate_side_width(cols);
|
|
||||||
let x = match self.visibility_and_focus {
|
|
||||||
VisibilityAndFocus::OnlyRightSideVisible => 0,
|
|
||||||
VisibilityAndFocus::BothSidesVisibleLeftSideFocused
|
|
||||||
| VisibilityAndFocus::BothSidesVisibleRightSideFocused
|
|
||||||
| VisibilityAndFocus::OnlyLeftSideVisible => side_width + 2,
|
|
||||||
};
|
|
||||||
let y = 0;
|
|
||||||
let height = rows.saturating_sub(2);
|
|
||||||
for i in y..=height {
|
|
||||||
if i == y && self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(TOP_RIGHT_CORNER_CHARACTER),
|
|
||||||
x,
|
|
||||||
i,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(HORIZONTAL_BOUNDARY_CHARACTER),
|
|
||||||
x.saturating_sub(1),
|
|
||||||
i,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(HORIZONTAL_BOUNDARY_CHARACTER),
|
|
||||||
x.saturating_sub(2),
|
|
||||||
i,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
} else if i == y && !self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
print_text_with_coordinates(Text::new(TOP_LEFT_CORNER_CHARACTER), x, i, None, None);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(HORIZONTAL_BOUNDARY_CHARACTER),
|
|
||||||
x + 1,
|
|
||||||
i,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(HORIZONTAL_BOUNDARY_CHARACTER),
|
|
||||||
x + 2,
|
|
||||||
i,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
} else if i == height && self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(BOTTOM_RIGHT_CORNER_CHARACTER),
|
|
||||||
x,
|
|
||||||
i,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(HORIZONTAL_BOUNDARY_CHARACTER),
|
|
||||||
x.saturating_sub(1),
|
|
||||||
i,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(HORIZONTAL_BOUNDARY_CHARACTER),
|
|
||||||
x.saturating_sub(2),
|
|
||||||
i,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
} else if i == height && !self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(BOTTOM_LEFT_CORNER_CHARACTER),
|
|
||||||
x,
|
|
||||||
i,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(HORIZONTAL_BOUNDARY_CHARACTER),
|
|
||||||
x + 1,
|
|
||||||
i,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
Text::new(HORIZONTAL_BOUNDARY_CHARACTER),
|
|
||||||
x + 2,
|
|
||||||
i,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
} else {
|
|
||||||
print_text_with_coordinates(Text::new(BOUNDARY_CHARACTER), x, i, None, None);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
pub fn calculate_side_width(&self, cols: usize) -> usize {
|
|
||||||
match self.visibility_and_focus {
|
|
||||||
VisibilityAndFocus::OnlyLeftSideVisible | VisibilityAndFocus::OnlyRightSideVisible => {
|
|
||||||
cols.saturating_sub(4)
|
|
||||||
},
|
|
||||||
VisibilityAndFocus::BothSidesVisibleLeftSideFocused
|
|
||||||
| VisibilityAndFocus::BothSidesVisibleRightSideFocused => (cols / 2).saturating_sub(3),
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// ui components
|
|
||||||
impl App {
|
|
||||||
fn filter_panes_prompt(&self) -> (&'static str, Text) {
|
|
||||||
let search_prompt_text = if self.search_string.is_empty() {
|
|
||||||
"ALL PANES "
|
|
||||||
} else {
|
|
||||||
"FILTER: "
|
|
||||||
};
|
|
||||||
let search_prompt = if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
Text::new(&search_prompt_text).color_range(2, ..)
|
|
||||||
} else {
|
|
||||||
Text::new(&search_prompt_text)
|
|
||||||
};
|
|
||||||
(search_prompt_text, search_prompt)
|
|
||||||
}
|
|
||||||
fn filter(&self, max_width: usize) -> Text {
|
|
||||||
let search_string_text = if self.marked_index.is_none() && self.search_string.is_empty() {
|
|
||||||
let full = "[Type filter term...]";
|
|
||||||
let short = "[...]";
|
|
||||||
if max_width >= full.chars().count() {
|
|
||||||
full.to_owned()
|
|
||||||
} else {
|
|
||||||
short.to_owned()
|
|
||||||
}
|
|
||||||
} else if self.marked_index.is_none() && !self.search_string.is_empty() {
|
|
||||||
if max_width >= self.search_string.chars().count() + 1 {
|
|
||||||
format!("{}_", self.search_string)
|
|
||||||
} else {
|
|
||||||
let truncated: String = self
|
|
||||||
.search_string
|
|
||||||
.chars()
|
|
||||||
.rev()
|
|
||||||
.take(max_width.saturating_sub(4))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.collect();
|
|
||||||
format!("...{}_", truncated)
|
|
||||||
}
|
|
||||||
} else if self.marked_index.is_some() && !self.search_string.is_empty() {
|
|
||||||
if max_width >= self.search_string.chars().count() {
|
|
||||||
format!("{}", self.search_string)
|
|
||||||
} else {
|
|
||||||
let truncated: String = self
|
|
||||||
.search_string
|
|
||||||
.chars()
|
|
||||||
.rev()
|
|
||||||
.take(max_width.saturating_sub(4))
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.iter()
|
|
||||||
.rev()
|
|
||||||
.collect();
|
|
||||||
format!("...{}", truncated)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
format!("")
|
|
||||||
};
|
|
||||||
Text::new(&search_string_text).color_range(3, ..)
|
|
||||||
}
|
|
||||||
fn left_side_panes_list(
|
|
||||||
&self,
|
|
||||||
max_width: usize,
|
|
||||||
max_list_height: usize,
|
|
||||||
) -> (usize, usize, usize, usize, Vec<NestedListItem>) {
|
|
||||||
// returns: extra_pane_count_on_top, extra_pane_count_on_bottom,
|
|
||||||
// extra_selected_item_count_on_top, extra_selected_item_count_on_bottom, list
|
|
||||||
let mut left_side_panes = vec![];
|
|
||||||
let pane_items_on_the_left = self
|
|
||||||
.search_results
|
|
||||||
.as_ref()
|
|
||||||
.unwrap_or_else(|| &self.left_side_panes);
|
|
||||||
let max_width_for_item = max_width.saturating_sub(3); // 3 for the list bulletin
|
|
||||||
let item_count = pane_items_on_the_left.iter().count();
|
|
||||||
let first_item_index = if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
self.marked_index
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| s.main_index.saturating_sub(max_list_height / 2))
|
|
||||||
.unwrap_or(0)
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
let last_item_index = std::cmp::min(
|
|
||||||
(max_list_height + first_item_index).saturating_sub(1),
|
|
||||||
item_count.saturating_sub(1),
|
|
||||||
);
|
|
||||||
for (i, pane_item) in pane_items_on_the_left
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.skip(first_item_index)
|
|
||||||
{
|
|
||||||
if i > last_item_index {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let mut item = pane_item.render(max_width_for_item);
|
|
||||||
if Some(i) == self.marked_index.as_ref().map(|s| s.main_index)
|
|
||||||
&& self.visibility_and_focus.left_side_is_focused()
|
|
||||||
{
|
|
||||||
item = item.selected();
|
|
||||||
if self
|
|
||||||
.marked_index
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| s.additional_indices.contains(&i))
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
item = item.selected().color_range(1, ..);
|
|
||||||
}
|
|
||||||
} else if self
|
|
||||||
.marked_index
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| s.additional_indices.contains(&i))
|
|
||||||
.unwrap_or(false)
|
|
||||||
&& self.visibility_and_focus.left_side_is_focused()
|
|
||||||
{
|
|
||||||
item = item.selected();
|
|
||||||
}
|
|
||||||
left_side_panes.push(item);
|
|
||||||
}
|
|
||||||
let extra_panes_on_top = first_item_index;
|
|
||||||
let extra_panes_on_bottom = item_count.saturating_sub(last_item_index + 1);
|
|
||||||
let extra_selected_item_count_on_top = if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
self.marked_index
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| {
|
|
||||||
s.additional_indices
|
|
||||||
.iter()
|
|
||||||
.filter(|a| a < &&first_item_index)
|
|
||||||
.count()
|
|
||||||
})
|
|
||||||
.unwrap_or(0)
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
let extra_selected_item_count_on_bottom =
|
|
||||||
if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
self.marked_index
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| {
|
|
||||||
s.additional_indices
|
|
||||||
.iter()
|
|
||||||
.filter(|a| a > &&last_item_index)
|
|
||||||
.count()
|
|
||||||
})
|
|
||||||
.unwrap_or(0)
|
|
||||||
} else {
|
|
||||||
0
|
|
||||||
};
|
|
||||||
(
|
|
||||||
extra_panes_on_top,
|
|
||||||
extra_panes_on_bottom,
|
|
||||||
extra_selected_item_count_on_top,
|
|
||||||
extra_selected_item_count_on_bottom,
|
|
||||||
left_side_panes,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fn left_side_controls(
|
|
||||||
&self,
|
|
||||||
max_width: usize,
|
|
||||||
) -> (&'static str, Text, &'static str, Text, &'static str, Text) {
|
|
||||||
// returns three components and their text
|
|
||||||
let (enter_select_panes_text, enter_select_panes) = if self.marked_index.is_some() {
|
|
||||||
let enter_select_panes_text_full = "<ENTER> - select, <↓↑→> - navigate";
|
|
||||||
let enter_select_panes_text_short = "<ENTER> / <↓↑→>...";
|
|
||||||
if max_width >= enter_select_panes_text_full.chars().count() {
|
|
||||||
let enter_select_panes_full = Text::new(enter_select_panes_text_full)
|
|
||||||
.color_range(3, ..=6)
|
|
||||||
.color_range(3, 18..=22);
|
|
||||||
(enter_select_panes_text_full, enter_select_panes_full)
|
|
||||||
} else {
|
|
||||||
let enter_select_panes_short = Text::new(enter_select_panes_text_short)
|
|
||||||
.color_range(3, ..=6)
|
|
||||||
.color_range(3, 10..=14);
|
|
||||||
(enter_select_panes_text_short, enter_select_panes_short)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
let enter_select_panes_text_full = "<ENTER> - select all, <↓↑> - navigate";
|
|
||||||
let enter_select_panes_text_short = "<ENTER> / <↓↑>...";
|
|
||||||
if max_width >= enter_select_panes_text_full.chars().count() {
|
|
||||||
let enter_select_panes_full = Text::new(enter_select_panes_text_full)
|
|
||||||
.color_range(3, ..=6)
|
|
||||||
.color_range(3, 21..=25);
|
|
||||||
(enter_select_panes_text_full, enter_select_panes_full)
|
|
||||||
} else {
|
|
||||||
let enter_select_panes_short = Text::new(enter_select_panes_text_short)
|
|
||||||
.color_range(3, ..=6)
|
|
||||||
.color_range(3, 10..=13);
|
|
||||||
(enter_select_panes_text_short, enter_select_panes_short)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
let space_shortcut_text_full = "<SPACE> - mark many,";
|
|
||||||
let space_shortcut_text_short = "<SPACE> /";
|
|
||||||
if self.marked_index.is_some() {
|
|
||||||
let escape_shortcut_text_full = "<Ctrl c> - remove marks";
|
|
||||||
let escape_shortcut_text_short = "<Ctrl c>...";
|
|
||||||
let (escape_shortcut, space_shortcut, escape_shortcut_text, space_shortcut_text) =
|
|
||||||
if max_width
|
|
||||||
>= space_shortcut_text_full.chars().count()
|
|
||||||
+ escape_shortcut_text_full.chars().count()
|
|
||||||
{
|
|
||||||
(
|
|
||||||
Text::new(escape_shortcut_text_full).color_range(3, ..=7),
|
|
||||||
Text::new(space_shortcut_text_full).color_range(3, ..=6),
|
|
||||||
escape_shortcut_text_full,
|
|
||||||
space_shortcut_text_full,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
(
|
|
||||||
Text::new(escape_shortcut_text_short).color_range(3, ..=7),
|
|
||||||
Text::new(space_shortcut_text_short).color_range(3, ..=6),
|
|
||||||
escape_shortcut_text_short,
|
|
||||||
space_shortcut_text_short,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
(
|
|
||||||
enter_select_panes_text,
|
|
||||||
enter_select_panes,
|
|
||||||
space_shortcut_text,
|
|
||||||
space_shortcut,
|
|
||||||
escape_shortcut_text,
|
|
||||||
escape_shortcut,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
let escape_shortcut_text = if self.right_side_panes.is_empty() {
|
|
||||||
"<Ctrl c> - Close"
|
|
||||||
} else {
|
|
||||||
""
|
|
||||||
};
|
|
||||||
let escape_shortcut = Text::new(escape_shortcut_text).color_range(3, ..=7);
|
|
||||||
let space_shortcut = Text::new(space_shortcut_text_full).color_range(3, ..=6);
|
|
||||||
(
|
|
||||||
enter_select_panes_text,
|
|
||||||
enter_select_panes,
|
|
||||||
space_shortcut_text_full,
|
|
||||||
space_shortcut,
|
|
||||||
escape_shortcut_text,
|
|
||||||
escape_shortcut,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
fn selected_panes_title(&self) -> Text {
|
|
||||||
let selected_prompt_text = "SELECTED PANES: ";
|
|
||||||
let selected_prompt = if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
Text::new(selected_prompt_text)
|
|
||||||
} else {
|
|
||||||
Text::new(selected_prompt_text).color_range(2, ..)
|
|
||||||
};
|
|
||||||
selected_prompt
|
|
||||||
}
|
|
||||||
fn right_side_panes_list(
|
|
||||||
&self,
|
|
||||||
max_width: usize,
|
|
||||||
max_list_height: usize,
|
|
||||||
) -> (usize, usize, usize, usize, Vec<NestedListItem>) {
|
|
||||||
// returns: extra_pane_count_on_top, extra_pane_count_on_bottom,
|
|
||||||
// extra_selected_item_count_on_top, extra_selected_item_count_on_bottom, list
|
|
||||||
let mut right_side_panes = vec![];
|
|
||||||
let item_count = self.right_side_panes.iter().count();
|
|
||||||
let first_item_index = if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
self.marked_index
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| s.main_index.saturating_sub(max_list_height / 2))
|
|
||||||
.unwrap_or(0)
|
|
||||||
};
|
|
||||||
let last_item_index = std::cmp::min(
|
|
||||||
(max_list_height + first_item_index).saturating_sub(1),
|
|
||||||
item_count.saturating_sub(1),
|
|
||||||
);
|
|
||||||
|
|
||||||
let max_width_for_item = max_width.saturating_sub(3); // 3 for the list bulletin
|
|
||||||
for (i, pane_item) in self
|
|
||||||
.right_side_panes
|
|
||||||
.iter()
|
|
||||||
.enumerate()
|
|
||||||
.skip(first_item_index)
|
|
||||||
{
|
|
||||||
if i > last_item_index {
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
let mut item = pane_item.render(max_width_for_item);
|
|
||||||
if &Some(i) == &self.marked_index.as_ref().map(|s| s.main_index)
|
|
||||||
&& self.visibility_and_focus.right_side_is_focused()
|
|
||||||
{
|
|
||||||
item = item.selected();
|
|
||||||
if self
|
|
||||||
.marked_index
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| s.additional_indices.contains(&i))
|
|
||||||
.unwrap_or(false)
|
|
||||||
{
|
|
||||||
item = item.selected().color_range(1, ..);
|
|
||||||
}
|
|
||||||
} else if self
|
|
||||||
.marked_index
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| s.additional_indices.contains(&i))
|
|
||||||
.unwrap_or(false)
|
|
||||||
&& self.visibility_and_focus.right_side_is_focused()
|
|
||||||
{
|
|
||||||
item = item.selected();
|
|
||||||
}
|
|
||||||
right_side_panes.push(item);
|
|
||||||
}
|
|
||||||
|
|
||||||
let extra_panes_on_top = first_item_index;
|
|
||||||
let extra_panes_on_bottom = self
|
|
||||||
.right_side_panes
|
|
||||||
.iter()
|
|
||||||
.len()
|
|
||||||
.saturating_sub(last_item_index + 1);
|
|
||||||
let extra_selected_item_count_on_top = if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
self.marked_index
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| {
|
|
||||||
s.additional_indices
|
|
||||||
.iter()
|
|
||||||
.filter(|a| a < &&first_item_index)
|
|
||||||
.count()
|
|
||||||
})
|
|
||||||
.unwrap_or(0)
|
|
||||||
};
|
|
||||||
let extra_selected_item_count_on_bottom =
|
|
||||||
if self.visibility_and_focus.left_side_is_focused() {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
self.marked_index
|
|
||||||
.as_ref()
|
|
||||||
.map(|s| {
|
|
||||||
s.additional_indices
|
|
||||||
.iter()
|
|
||||||
.filter(|a| a > &&last_item_index)
|
|
||||||
.count()
|
|
||||||
})
|
|
||||||
.unwrap_or(0)
|
|
||||||
};
|
|
||||||
(
|
|
||||||
extra_panes_on_top,
|
|
||||||
extra_panes_on_bottom,
|
|
||||||
extra_selected_item_count_on_top,
|
|
||||||
extra_selected_item_count_on_bottom,
|
|
||||||
right_side_panes,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fn right_side_controls(&self, cols: usize) -> (Text, Text, Text, Text) {
|
|
||||||
let right_side_controls_text_1_full = "<←↓↑> - navigate, <Ctrl c> - clear";
|
|
||||||
let right_side_controls_text_1_short = "<←↓↑>/<Ctrl c>...";
|
|
||||||
let right_side_controls_1 = if cols >= right_side_controls_text_1_full.chars().count() {
|
|
||||||
Text::new(right_side_controls_text_1_full)
|
|
||||||
.color_range(3, ..=4)
|
|
||||||
.color_range(3, 18..=25)
|
|
||||||
} else {
|
|
||||||
Text::new(right_side_controls_text_1_short)
|
|
||||||
.color_range(3, ..=4)
|
|
||||||
.color_range(3, 6..=13)
|
|
||||||
};
|
|
||||||
let right_side_controls_text_2_full = "<b> - break out, <s> - stack, <c> - close";
|
|
||||||
let right_side_controls_text_2_short = "<b>/<s>/<c>...";
|
|
||||||
let right_side_controls_2 = if cols >= right_side_controls_text_2_full.chars().count() {
|
|
||||||
Text::new(right_side_controls_text_2_full)
|
|
||||||
.color_range(3, ..=2)
|
|
||||||
.color_range(3, 17..=19)
|
|
||||||
.color_range(3, 30..=32)
|
|
||||||
} else {
|
|
||||||
Text::new(right_side_controls_text_2_short)
|
|
||||||
.color_range(3, ..=2)
|
|
||||||
.color_range(3, 4..=6)
|
|
||||||
.color_range(3, 8..=10)
|
|
||||||
};
|
|
||||||
let right_side_controls_text_3_full = "<r> - break right, <l> - break left";
|
|
||||||
let right_side_controls_text_3_short = "<r>/<l>...";
|
|
||||||
let right_side_controls_3 = if cols >= right_side_controls_text_3_full.chars().count() {
|
|
||||||
Text::new(right_side_controls_text_3_full)
|
|
||||||
.color_range(3, ..=2)
|
|
||||||
.color_range(3, 19..=21)
|
|
||||||
} else {
|
|
||||||
Text::new(right_side_controls_text_3_short)
|
|
||||||
.color_range(3, ..=2)
|
|
||||||
.color_range(3, 4..=6)
|
|
||||||
};
|
|
||||||
let right_side_controls_text_4_full = "<e> - embed, <f> - float";
|
|
||||||
let right_side_controls_text_4_short = "<e>/<f>...";
|
|
||||||
let right_side_controls_4 = if cols >= right_side_controls_text_4_full.chars().count() {
|
|
||||||
Text::new(right_side_controls_text_4_full)
|
|
||||||
.color_range(3, ..=2)
|
|
||||||
.color_range(3, 13..=15)
|
|
||||||
} else {
|
|
||||||
Text::new(right_side_controls_text_4_short)
|
|
||||||
.color_range(3, ..=2)
|
|
||||||
.color_range(3, 4..=6)
|
|
||||||
};
|
|
||||||
(
|
|
||||||
right_side_controls_1,
|
|
||||||
right_side_controls_2,
|
|
||||||
right_side_controls_3,
|
|
||||||
right_side_controls_4,
|
|
||||||
)
|
|
||||||
}
|
|
||||||
fn print_extra_pane_count(
|
|
||||||
&self,
|
|
||||||
count: usize,
|
|
||||||
selected_count: usize,
|
|
||||||
y: usize,
|
|
||||||
list_x: usize,
|
|
||||||
list_width: usize,
|
|
||||||
) {
|
|
||||||
let extra_count_text = if selected_count > 0 {
|
|
||||||
format!("[+{} ({} selected)]", count, selected_count)
|
|
||||||
} else {
|
|
||||||
format!("[+{}]", count)
|
|
||||||
};
|
|
||||||
let extra_count = Text::new(&extra_count_text).color_range(1, ..);
|
|
||||||
print_text_with_coordinates(
|
|
||||||
extra_count,
|
|
||||||
(list_x + list_width).saturating_sub(extra_count_text.chars().count()),
|
|
||||||
y,
|
|
||||||
None,
|
|
||||||
None,
|
|
||||||
);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -39,8 +39,6 @@ struct State {
|
||||||
display_system_clipboard_failure: bool,
|
display_system_clipboard_failure: bool,
|
||||||
classic_ui: bool,
|
classic_ui: bool,
|
||||||
base_mode_is_locked: bool,
|
base_mode_is_locked: bool,
|
||||||
own_client_id: Option<ClientId>,
|
|
||||||
grouped_panes_count: Option<usize>,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
register_plugin!(State);
|
register_plugin!(State);
|
||||||
|
|
@ -199,7 +197,6 @@ impl ZellijPlugin for State {
|
||||||
.get("classic")
|
.get("classic")
|
||||||
.map(|c| c == "true")
|
.map(|c| c == "true")
|
||||||
.unwrap_or(false);
|
.unwrap_or(false);
|
||||||
self.own_client_id = Some(get_plugin_ids().client_id);
|
|
||||||
set_selectable(false);
|
set_selectable(false);
|
||||||
subscribe(&[
|
subscribe(&[
|
||||||
EventType::ModeUpdate,
|
EventType::ModeUpdate,
|
||||||
|
|
@ -227,28 +224,6 @@ impl ZellijPlugin for State {
|
||||||
}
|
}
|
||||||
self.tabs = tabs;
|
self.tabs = tabs;
|
||||||
},
|
},
|
||||||
Event::PaneUpdate(pane_manifest) => {
|
|
||||||
if let Some(own_client_id) = self.own_client_id {
|
|
||||||
let mut grouped_panes_count = 0;
|
|
||||||
for (_tab_index, pane_infos) in pane_manifest.panes {
|
|
||||||
for pane_info in pane_infos {
|
|
||||||
let is_in_pane_group =
|
|
||||||
pane_info.index_in_pane_group.get(&own_client_id).is_some();
|
|
||||||
if is_in_pane_group {
|
|
||||||
grouped_panes_count += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if Some(grouped_panes_count) != self.grouped_panes_count {
|
|
||||||
if grouped_panes_count == 0 {
|
|
||||||
self.grouped_panes_count = None;
|
|
||||||
} else {
|
|
||||||
self.grouped_panes_count = Some(grouped_panes_count);
|
|
||||||
}
|
|
||||||
should_render = true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
Event::CopyToClipboard(copy_destination) => {
|
Event::CopyToClipboard(copy_destination) => {
|
||||||
match self.text_copy_destination {
|
match self.text_copy_destination {
|
||||||
Some(text_copy_destination) => {
|
Some(text_copy_destination) => {
|
||||||
|
|
@ -306,7 +281,6 @@ impl ZellijPlugin for State {
|
||||||
self.base_mode_is_locked,
|
self.base_mode_is_locked,
|
||||||
self.text_copy_destination,
|
self.text_copy_destination,
|
||||||
self.display_system_clipboard_failure,
|
self.display_system_clipboard_failure,
|
||||||
self.grouped_panes_count,
|
|
||||||
),
|
),
|
||||||
fill_bg,
|
fill_bg,
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -6,7 +6,7 @@ use ansi_term::{
|
||||||
use std::collections::HashMap;
|
use std::collections::HashMap;
|
||||||
use zellij_tile::prelude::actions::Action;
|
use zellij_tile::prelude::actions::Action;
|
||||||
use zellij_tile::prelude::*;
|
use zellij_tile::prelude::*;
|
||||||
use zellij_tile_utils::{palette_match, style};
|
use zellij_tile_utils::palette_match;
|
||||||
|
|
||||||
use crate::first_line::{to_char, KeyAction, KeyMode, KeyShortcut};
|
use crate::first_line::{to_char, KeyAction, KeyMode, KeyShortcut};
|
||||||
use crate::second_line::{system_clipboard_error, text_copied_hint};
|
use crate::second_line::{system_clipboard_error, text_copied_hint};
|
||||||
|
|
@ -22,7 +22,6 @@ pub fn one_line_ui(
|
||||||
base_mode_is_locked: bool,
|
base_mode_is_locked: bool,
|
||||||
text_copied_to_clipboard_destination: Option<CopyDestination>,
|
text_copied_to_clipboard_destination: Option<CopyDestination>,
|
||||||
clipboard_failure: bool,
|
clipboard_failure: bool,
|
||||||
grouped_pane_count: Option<usize>,
|
|
||||||
) -> LinePart {
|
) -> LinePart {
|
||||||
if let Some(text_copied_to_clipboard_destination) = text_copied_to_clipboard_destination {
|
if let Some(text_copied_to_clipboard_destination) = text_copied_to_clipboard_destination {
|
||||||
return text_copied_hint(text_copied_to_clipboard_destination);
|
return text_copied_hint(text_copied_to_clipboard_destination);
|
||||||
|
|
@ -36,17 +35,10 @@ pub fn one_line_ui(
|
||||||
*max_len = max_len.saturating_sub(line_part.len);
|
*max_len = max_len.saturating_sub(line_part.len);
|
||||||
};
|
};
|
||||||
|
|
||||||
let currently_marking_pane_group = help.currently_marking_pane_group.unwrap_or(false);
|
|
||||||
render_mode_key_indicators(help, max_len, separator, base_mode_is_locked)
|
render_mode_key_indicators(help, max_len, separator, base_mode_is_locked)
|
||||||
.map(|mode_key_indicators| append(&mode_key_indicators, &mut max_len))
|
.map(|mode_key_indicators| append(&mode_key_indicators, &mut max_len))
|
||||||
.and_then(|_| match help.mode {
|
.and_then(|_| match help.mode {
|
||||||
InputMode::Normal | InputMode::Locked => match grouped_pane_count {
|
InputMode::Normal | InputMode::Locked => render_secondary_info(help, tab_info, max_len)
|
||||||
Some(grouped_pane_count) => {
|
|
||||||
render_group_controls(help, grouped_pane_count, max_len)
|
|
||||||
},
|
|
||||||
None if currently_marking_pane_group => render_group_controls(help, 0, max_len),
|
|
||||||
None => render_secondary_info(help, tab_info, max_len),
|
|
||||||
}
|
|
||||||
.map(|secondary_info| append(&secondary_info, &mut max_len)),
|
.map(|secondary_info| append(&secondary_info, &mut max_len)),
|
||||||
_ => add_keygroup_separator(help, max_len)
|
_ => add_keygroup_separator(help, max_len)
|
||||||
.map(|key_group_separator| append(&key_group_separator, &mut max_len))
|
.map(|key_group_separator| append(&key_group_separator, &mut max_len))
|
||||||
|
|
@ -664,225 +656,6 @@ fn render_common_modifiers(
|
||||||
line_part_to_render.len += prefix_text.chars().count() + separator.chars().count();
|
line_part_to_render.len += prefix_text.chars().count() + separator.chars().count();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn render_group_controls(
|
|
||||||
help: &ModeInfo,
|
|
||||||
grouped_pane_count: usize,
|
|
||||||
max_len: usize,
|
|
||||||
) -> Option<LinePart> {
|
|
||||||
let currently_marking_group = help.currently_marking_pane_group.unwrap_or(false);
|
|
||||||
let keymap = help.get_mode_keybinds();
|
|
||||||
let (common_modifiers, multiple_select_key, pane_group_toggle_key, group_mark_toggle_key) = {
|
|
||||||
let multiple_select_key = multiple_select_key(&keymap);
|
|
||||||
let pane_group_toggle_key = single_action_key(&keymap, &[Action::TogglePaneInGroup]);
|
|
||||||
let group_mark_toggle_key = single_action_key(&keymap, &[Action::ToggleGroupMarking]);
|
|
||||||
let common_modifiers = get_common_modifiers(
|
|
||||||
vec![
|
|
||||||
multiple_select_key.iter().next(),
|
|
||||||
pane_group_toggle_key.iter().next(),
|
|
||||||
group_mark_toggle_key.iter().next(),
|
|
||||||
]
|
|
||||||
.into_iter()
|
|
||||||
.filter_map(|k| k)
|
|
||||||
.collect(),
|
|
||||||
);
|
|
||||||
let multiple_select_key: Vec<KeyWithModifier> = multiple_select_key
|
|
||||||
.iter()
|
|
||||||
.map(|k| k.strip_common_modifiers(&common_modifiers))
|
|
||||||
.collect();
|
|
||||||
let pane_group_toggle_key: Vec<KeyWithModifier> = pane_group_toggle_key
|
|
||||||
.iter()
|
|
||||||
.map(|k| k.strip_common_modifiers(&common_modifiers))
|
|
||||||
.collect();
|
|
||||||
let group_mark_toggle_key: Vec<KeyWithModifier> = group_mark_toggle_key
|
|
||||||
.iter()
|
|
||||||
.map(|k| k.strip_common_modifiers(&common_modifiers))
|
|
||||||
.collect();
|
|
||||||
(
|
|
||||||
common_modifiers,
|
|
||||||
multiple_select_key,
|
|
||||||
pane_group_toggle_key,
|
|
||||||
group_mark_toggle_key,
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let multiple_select_key = multiple_select_key
|
|
||||||
.iter()
|
|
||||||
.next()
|
|
||||||
.map(|key| format!("{}", key))
|
|
||||||
.unwrap_or("UNBOUND".to_owned());
|
|
||||||
let pane_group_toggle_key = pane_group_toggle_key
|
|
||||||
.iter()
|
|
||||||
.next()
|
|
||||||
.map(|key| format!("{}", key))
|
|
||||||
.unwrap_or("UNBOUND".to_owned());
|
|
||||||
let group_mark_toggle_key = group_mark_toggle_key
|
|
||||||
.iter()
|
|
||||||
.next()
|
|
||||||
.map(|key| format!("{}", key))
|
|
||||||
.unwrap_or("UNBOUND".to_owned());
|
|
||||||
let background = help.style.colors.text_unselected.background;
|
|
||||||
let foreground = help.style.colors.text_unselected.base;
|
|
||||||
let superkey_prefix_style = style!(foreground, background).bold();
|
|
||||||
let common_modifier_text = if common_modifiers.is_empty() {
|
|
||||||
"".to_owned()
|
|
||||||
} else {
|
|
||||||
format!(
|
|
||||||
"{} + ",
|
|
||||||
common_modifiers
|
|
||||||
.iter()
|
|
||||||
.map(|c| c.to_string())
|
|
||||||
.collect::<Vec<_>>()
|
|
||||||
.join("-")
|
|
||||||
)
|
|
||||||
};
|
|
||||||
|
|
||||||
// full
|
|
||||||
let full_selected_panes_text = if common_modifier_text.is_empty() {
|
|
||||||
format!("{} SELECTED PANES", grouped_pane_count)
|
|
||||||
} else {
|
|
||||||
format!("{} SELECTED PANES |", grouped_pane_count)
|
|
||||||
};
|
|
||||||
let full_group_actions_text = format!("<{}> Group Actions", &multiple_select_key);
|
|
||||||
let full_toggle_group_text = format!("<{}> Toggle Group", &pane_group_toggle_key);
|
|
||||||
let full_group_mark_toggle_text = format!("<{}> Follow Focus", &group_mark_toggle_key);
|
|
||||||
let ribbon_paddings_len = 12;
|
|
||||||
let full_controls_line_len = full_selected_panes_text.chars().count()
|
|
||||||
+ 1
|
|
||||||
+ common_modifier_text.chars().count()
|
|
||||||
+ full_group_actions_text.chars().count()
|
|
||||||
+ full_toggle_group_text.chars().count()
|
|
||||||
+ full_group_mark_toggle_text.chars().count()
|
|
||||||
+ ribbon_paddings_len
|
|
||||||
+ 1; // 1 for the end padding
|
|
||||||
|
|
||||||
// medium
|
|
||||||
let medium_selected_panes_text = if common_modifier_text.is_empty() {
|
|
||||||
format!("{} SELECTED", grouped_pane_count)
|
|
||||||
} else {
|
|
||||||
format!("{} SELECTED |", grouped_pane_count)
|
|
||||||
};
|
|
||||||
let medium_group_actions_text = format!("<{}> Actions", &multiple_select_key);
|
|
||||||
let medium_toggle_group_text = format!("<{}> Toggle", &pane_group_toggle_key);
|
|
||||||
let medium_group_mark_toggle_text = format!("<{}> Follow", &group_mark_toggle_key);
|
|
||||||
let ribbon_paddings_len = 12;
|
|
||||||
let medium_controls_line_len = medium_selected_panes_text.chars().count()
|
|
||||||
+ 1
|
|
||||||
+ common_modifier_text.chars().count()
|
|
||||||
+ medium_group_actions_text.chars().count()
|
|
||||||
+ medium_toggle_group_text.chars().count()
|
|
||||||
+ medium_group_mark_toggle_text.chars().count()
|
|
||||||
+ ribbon_paddings_len
|
|
||||||
+ 1; // 1 for the end padding
|
|
||||||
|
|
||||||
// short
|
|
||||||
let short_selected_panes_text = if common_modifier_text.is_empty() {
|
|
||||||
format!("{} SELECTED", grouped_pane_count)
|
|
||||||
} else {
|
|
||||||
format!("{} SELECTED |", grouped_pane_count)
|
|
||||||
};
|
|
||||||
let short_group_actions_text = format!("<{}>", &multiple_select_key);
|
|
||||||
let short_toggle_group_text = format!("<{}>", &pane_group_toggle_key);
|
|
||||||
let short_group_mark_toggle_text = format!("<{}>", &group_mark_toggle_key);
|
|
||||||
let color_emphasis_range_end = if common_modifier_text.is_empty() {
|
|
||||||
0
|
|
||||||
} else {
|
|
||||||
2
|
|
||||||
};
|
|
||||||
let ribbon_paddings_len = 12;
|
|
||||||
let short_controls_line_len = short_selected_panes_text.chars().count()
|
|
||||||
+ 1
|
|
||||||
+ common_modifier_text.chars().count()
|
|
||||||
+ short_group_actions_text.chars().count()
|
|
||||||
+ short_toggle_group_text.chars().count()
|
|
||||||
+ short_group_mark_toggle_text.chars().count()
|
|
||||||
+ ribbon_paddings_len
|
|
||||||
+ 1; // 1 for the end padding
|
|
||||||
|
|
||||||
let (
|
|
||||||
selected_panes_text,
|
|
||||||
group_actions_text,
|
|
||||||
toggle_group_text,
|
|
||||||
group_mark_toggle_text,
|
|
||||||
controls_line_len,
|
|
||||||
) = if max_len >= full_controls_line_len {
|
|
||||||
(
|
|
||||||
full_selected_panes_text,
|
|
||||||
full_group_actions_text,
|
|
||||||
full_toggle_group_text,
|
|
||||||
full_group_mark_toggle_text,
|
|
||||||
full_controls_line_len,
|
|
||||||
)
|
|
||||||
} else if max_len >= medium_controls_line_len {
|
|
||||||
(
|
|
||||||
medium_selected_panes_text,
|
|
||||||
medium_group_actions_text,
|
|
||||||
medium_toggle_group_text,
|
|
||||||
medium_group_mark_toggle_text,
|
|
||||||
medium_controls_line_len,
|
|
||||||
)
|
|
||||||
} else if max_len >= short_controls_line_len {
|
|
||||||
(
|
|
||||||
short_selected_panes_text,
|
|
||||||
short_group_actions_text,
|
|
||||||
short_toggle_group_text,
|
|
||||||
short_group_mark_toggle_text,
|
|
||||||
short_controls_line_len,
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
return None;
|
|
||||||
};
|
|
||||||
let selected_panes = serialize_text(
|
|
||||||
&Text::new(&selected_panes_text)
|
|
||||||
.color_range(
|
|
||||||
3,
|
|
||||||
..selected_panes_text
|
|
||||||
.chars()
|
|
||||||
.count()
|
|
||||||
.saturating_sub(color_emphasis_range_end),
|
|
||||||
)
|
|
||||||
.opaque(),
|
|
||||||
);
|
|
||||||
let group_actions_ribbon = serialize_ribbon(
|
|
||||||
&Text::new(&group_actions_text).color_range(0, 1..=multiple_select_key.chars().count()),
|
|
||||||
);
|
|
||||||
let toggle_group_ribbon = serialize_ribbon(
|
|
||||||
&Text::new(&toggle_group_text).color_range(0, 1..=pane_group_toggle_key.chars().count()),
|
|
||||||
);
|
|
||||||
let mut group_mark_toggle_ribbon = Text::new(&group_mark_toggle_text)
|
|
||||||
.color_range(0, 1..=group_mark_toggle_key.chars().count());
|
|
||||||
if currently_marking_group {
|
|
||||||
group_mark_toggle_ribbon = group_mark_toggle_ribbon.selected();
|
|
||||||
}
|
|
||||||
let group_mark_toggle_ribbon = serialize_ribbon(&group_mark_toggle_ribbon);
|
|
||||||
let controls_line = if common_modifiers.is_empty() {
|
|
||||||
format!(
|
|
||||||
"{} {}{}{}",
|
|
||||||
selected_panes, group_actions_ribbon, toggle_group_ribbon, group_mark_toggle_ribbon
|
|
||||||
)
|
|
||||||
} else {
|
|
||||||
let common_modifier =
|
|
||||||
serialize_text(&Text::new(&common_modifier_text).color_range(0, ..).opaque());
|
|
||||||
format!(
|
|
||||||
"{} {}{}{}{}",
|
|
||||||
selected_panes,
|
|
||||||
common_modifier,
|
|
||||||
group_actions_ribbon,
|
|
||||||
toggle_group_ribbon,
|
|
||||||
group_mark_toggle_ribbon
|
|
||||||
)
|
|
||||||
};
|
|
||||||
let remaining_space = max_len.saturating_sub(controls_line_len);
|
|
||||||
let mut padding = String::new();
|
|
||||||
let mut padding_len = 0;
|
|
||||||
for _ in 0..remaining_space {
|
|
||||||
padding.push_str(&ANSIStrings(&[superkey_prefix_style.paint(" ")]).to_string());
|
|
||||||
padding_len += 1;
|
|
||||||
}
|
|
||||||
Some(LinePart {
|
|
||||||
part: format!("{}{}", padding, controls_line),
|
|
||||||
len: controls_line_len + padding_len,
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
fn render_secondary_info(
|
fn render_secondary_info(
|
||||||
help: &ModeInfo,
|
help: &ModeInfo,
|
||||||
tab_info: Option<&TabInfo>,
|
tab_info: Option<&TabInfo>,
|
||||||
|
|
@ -1745,25 +1518,6 @@ fn configuration_key(keymap: &[(KeyWithModifier, Vec<Action>)]) -> Vec<KeyWithMo
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fn multiple_select_key(keymap: &[(KeyWithModifier, Vec<Action>)]) -> Vec<KeyWithModifier> {
|
|
||||||
let mut matching = keymap.iter().find_map(|(key, acvec)| {
|
|
||||||
let has_match = acvec
|
|
||||||
.iter()
|
|
||||||
.find(|a| a.launches_plugin("zellij:multiple-select")) // TODO: make this an alias
|
|
||||||
.is_some();
|
|
||||||
if has_match {
|
|
||||||
Some(key.clone())
|
|
||||||
} else {
|
|
||||||
None
|
|
||||||
}
|
|
||||||
});
|
|
||||||
if let Some(matching) = matching.take() {
|
|
||||||
vec![matching]
|
|
||||||
} else {
|
|
||||||
vec![]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fn style_key_with_modifier(keyvec: &[KeyWithModifier], color_index: Option<usize>) -> LinePart {
|
fn style_key_with_modifier(keyvec: &[KeyWithModifier], color_index: Option<usize>) -> LinePart {
|
||||||
if keyvec.is_empty() {
|
if keyvec.is_empty() {
|
||||||
return LinePart::default();
|
return LinePart::default();
|
||||||
|
|
|
||||||
|
|
@ -138,12 +138,6 @@ keybinds {
|
||||||
bind "Alt k" "Alt Up" { MoveFocus "Up"; }
|
bind "Alt k" "Alt Up" { MoveFocus "Up"; }
|
||||||
bind "Alt =" "Alt +" { Resize "Increase"; }
|
bind "Alt =" "Alt +" { Resize "Increase"; }
|
||||||
bind "Alt -" { Resize "Decrease"; }
|
bind "Alt -" { Resize "Decrease"; }
|
||||||
bind "Alt m" {
|
|
||||||
LaunchOrFocusPlugin "zellij:multiple-select" {
|
|
||||||
floating true
|
|
||||||
move_to_focused_tab true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bind "Alt p" { TogglePaneInGroup; }
|
bind "Alt p" { TogglePaneInGroup; }
|
||||||
bind "Alt Shift p" { ToggleGroupMarking; }
|
bind "Alt Shift p" { ToggleGroupMarking; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -5,6 +5,7 @@ pub mod tab;
|
||||||
|
|
||||||
mod background_jobs;
|
mod background_jobs;
|
||||||
mod logging_pipe;
|
mod logging_pipe;
|
||||||
|
mod pane_groups;
|
||||||
mod plugins;
|
mod plugins;
|
||||||
mod pty;
|
mod pty;
|
||||||
mod pty_writer;
|
mod pty_writer;
|
||||||
|
|
|
||||||
469
zellij-server/src/pane_groups.rs
Normal file
469
zellij-server/src/pane_groups.rs
Normal file
|
|
@ -0,0 +1,469 @@
|
||||||
|
use std::collections::{HashMap, HashSet};
|
||||||
|
|
||||||
|
use zellij_utils::data::FloatingPaneCoordinates;
|
||||||
|
use zellij_utils::input::layout::{RunPluginOrAlias, SplitSize};
|
||||||
|
use zellij_utils::pane_size::Size;
|
||||||
|
|
||||||
|
use crate::{panes::PaneId, pty::PtyInstruction, thread_bus::ThreadSenders, ClientId};
|
||||||
|
|
||||||
|
pub struct PaneGroups {
|
||||||
|
panes_in_group: HashMap<ClientId, Vec<PaneId>>,
|
||||||
|
senders: ThreadSenders,
|
||||||
|
}
|
||||||
|
|
||||||
|
impl std::fmt::Debug for PaneGroups {
|
||||||
|
fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
|
||||||
|
f.debug_struct("PaneGroups")
|
||||||
|
.field("panes_in_group", &self.panes_in_group)
|
||||||
|
.finish_non_exhaustive()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
impl PaneGroups {
|
||||||
|
pub fn new(senders: ThreadSenders) -> Self {
|
||||||
|
PaneGroups {
|
||||||
|
panes_in_group: HashMap::new(),
|
||||||
|
senders,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn clone_inner(&self) -> HashMap<ClientId, Vec<PaneId>> {
|
||||||
|
self.panes_in_group.clone()
|
||||||
|
}
|
||||||
|
pub fn get_client_pane_group(&self, client_id: &ClientId) -> HashSet<PaneId> {
|
||||||
|
self.panes_in_group
|
||||||
|
.get(client_id)
|
||||||
|
.map(|p| p.iter().copied().collect())
|
||||||
|
.unwrap_or_else(|| HashSet::new())
|
||||||
|
}
|
||||||
|
pub fn clear_pane_group(&mut self, client_id: &ClientId) {
|
||||||
|
self.panes_in_group.get_mut(client_id).map(|p| p.clear());
|
||||||
|
}
|
||||||
|
pub fn toggle_pane_id_in_group(
|
||||||
|
&mut self,
|
||||||
|
pane_id: PaneId,
|
||||||
|
screen_size: Size,
|
||||||
|
client_id: &ClientId,
|
||||||
|
) {
|
||||||
|
let previous_groups = self.clone_inner();
|
||||||
|
let client_pane_group = self
|
||||||
|
.panes_in_group
|
||||||
|
.entry(*client_id)
|
||||||
|
.or_insert_with(|| vec![]);
|
||||||
|
if client_pane_group.contains(&pane_id) {
|
||||||
|
client_pane_group.retain(|p| p != &pane_id);
|
||||||
|
} else {
|
||||||
|
client_pane_group.push(pane_id);
|
||||||
|
};
|
||||||
|
if self.should_launch_plugin(&previous_groups, client_id) {
|
||||||
|
self.launch_plugin(screen_size, client_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn add_pane_id_to_group(
|
||||||
|
&mut self,
|
||||||
|
pane_id: PaneId,
|
||||||
|
screen_size: Size,
|
||||||
|
client_id: &ClientId,
|
||||||
|
) {
|
||||||
|
let previous_groups = self.clone_inner();
|
||||||
|
let client_pane_group = self
|
||||||
|
.panes_in_group
|
||||||
|
.entry(*client_id)
|
||||||
|
.or_insert_with(|| vec![]);
|
||||||
|
if !client_pane_group.contains(&pane_id) {
|
||||||
|
client_pane_group.push(pane_id);
|
||||||
|
}
|
||||||
|
if self.should_launch_plugin(&previous_groups, client_id) {
|
||||||
|
self.launch_plugin(screen_size, client_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn group_and_ungroup_panes(
|
||||||
|
&mut self,
|
||||||
|
mut pane_ids_to_group: Vec<PaneId>,
|
||||||
|
pane_ids_to_ungroup: Vec<PaneId>,
|
||||||
|
screen_size: Size,
|
||||||
|
client_id: &ClientId,
|
||||||
|
) {
|
||||||
|
let previous_groups = self.clone_inner();
|
||||||
|
let client_pane_group = self
|
||||||
|
.panes_in_group
|
||||||
|
.entry(*client_id)
|
||||||
|
.or_insert_with(|| vec![]);
|
||||||
|
client_pane_group.append(&mut pane_ids_to_group);
|
||||||
|
client_pane_group.retain(|p| !pane_ids_to_ungroup.contains(p));
|
||||||
|
if self.should_launch_plugin(&previous_groups, client_id) {
|
||||||
|
self.launch_plugin(screen_size, client_id);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
pub fn override_groups_with(&mut self, new_pane_groups: HashMap<ClientId, Vec<PaneId>>) {
|
||||||
|
self.panes_in_group = new_pane_groups;
|
||||||
|
}
|
||||||
|
fn should_launch_plugin(
|
||||||
|
&self,
|
||||||
|
previous_groups: &HashMap<ClientId, Vec<PaneId>>,
|
||||||
|
client_id: &ClientId,
|
||||||
|
) -> bool {
|
||||||
|
let mut should_launch = false;
|
||||||
|
for (client_id, previous_panes) in previous_groups {
|
||||||
|
let previous_panes_has_panes = !previous_panes.is_empty();
|
||||||
|
let current_panes_has_panes = self
|
||||||
|
.panes_in_group
|
||||||
|
.get(&client_id)
|
||||||
|
.map(|g| !g.is_empty())
|
||||||
|
.unwrap_or(false);
|
||||||
|
if !previous_panes_has_panes && current_panes_has_panes {
|
||||||
|
should_launch = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
should_launch || previous_groups.get(&client_id).is_none()
|
||||||
|
}
|
||||||
|
fn launch_plugin(&self, screen_size: Size, client_id: &ClientId) {
|
||||||
|
if let Ok(run_plugin) =
|
||||||
|
RunPluginOrAlias::from_url("zellij:multiple-select", &None, None, None)
|
||||||
|
{
|
||||||
|
let tab_index = 1;
|
||||||
|
let size = Size::default();
|
||||||
|
let should_float = Some(true);
|
||||||
|
let should_be_opened_in_place = false;
|
||||||
|
let pane_title = None;
|
||||||
|
let skip_cache = false;
|
||||||
|
let cwd = None;
|
||||||
|
let should_focus_plugin = Some(false);
|
||||||
|
let width_30_percent = (screen_size.cols as f64 * 0.3) as usize;
|
||||||
|
let height_30_percent = (screen_size.rows as f64 * 0.3) as usize;
|
||||||
|
let width = std::cmp::max(width_30_percent, 48);
|
||||||
|
let height = std::cmp::max(height_30_percent, 10);
|
||||||
|
let y_position = screen_size.rows.saturating_sub(height + 2);
|
||||||
|
let floating_pane_coordinates = FloatingPaneCoordinates {
|
||||||
|
x: Some(SplitSize::Fixed(2)),
|
||||||
|
y: Some(SplitSize::Fixed(y_position)),
|
||||||
|
width: Some(SplitSize::Fixed(width)),
|
||||||
|
height: Some(SplitSize::Fixed(height)),
|
||||||
|
pinned: Some(true),
|
||||||
|
};
|
||||||
|
let _ = self.senders.send_to_pty(PtyInstruction::FillPluginCwd(
|
||||||
|
should_float,
|
||||||
|
should_be_opened_in_place,
|
||||||
|
pane_title,
|
||||||
|
run_plugin,
|
||||||
|
tab_index,
|
||||||
|
None,
|
||||||
|
*client_id,
|
||||||
|
size,
|
||||||
|
skip_cache,
|
||||||
|
cwd,
|
||||||
|
should_focus_plugin,
|
||||||
|
Some(floating_pane_coordinates),
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[cfg(test)]
|
||||||
|
mod tests {
|
||||||
|
use super::*;
|
||||||
|
use std::collections::HashMap;
|
||||||
|
|
||||||
|
fn create_mock_senders() -> ThreadSenders {
|
||||||
|
let mut mock = ThreadSenders::default();
|
||||||
|
mock.should_silently_fail = true;
|
||||||
|
mock
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_test_pane_groups() -> PaneGroups {
|
||||||
|
PaneGroups::new(create_mock_senders())
|
||||||
|
}
|
||||||
|
|
||||||
|
fn create_test_screen_size() -> Size {
|
||||||
|
Size { rows: 24, cols: 80 }
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn new_creates_empty_pane_groups() {
|
||||||
|
let pane_groups = create_test_pane_groups();
|
||||||
|
assert!(pane_groups.panes_in_group.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn clone_inner_returns_copy_of_internal_map() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
let pane_id = PaneId::Terminal(10);
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
pane_groups.add_pane_id_to_group(pane_id, screen_size, &client_id);
|
||||||
|
let cloned = pane_groups.clone_inner();
|
||||||
|
|
||||||
|
assert_eq!(cloned.len(), 1);
|
||||||
|
assert!(cloned.contains_key(&client_id));
|
||||||
|
assert_eq!(cloned[&client_id], vec![pane_id]);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_client_pane_group_returns_empty_set_for_nonexistent_client() {
|
||||||
|
let pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 999;
|
||||||
|
|
||||||
|
let result = pane_groups.get_client_pane_group(&client_id);
|
||||||
|
assert!(result.is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn get_client_pane_group_returns_correct_panes() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
let pane_ids = vec![
|
||||||
|
PaneId::Terminal(10),
|
||||||
|
PaneId::Plugin(20),
|
||||||
|
PaneId::Terminal(30),
|
||||||
|
];
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
for pane_id in &pane_ids {
|
||||||
|
pane_groups.add_pane_id_to_group(*pane_id, screen_size, &client_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let result = pane_groups.get_client_pane_group(&client_id);
|
||||||
|
assert_eq!(result.len(), 3);
|
||||||
|
for pane_id in pane_ids {
|
||||||
|
assert!(result.contains(&pane_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn clear_pane_group_clears_existing_group() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
let pane_ids = vec![
|
||||||
|
PaneId::Terminal(10),
|
||||||
|
PaneId::Plugin(20),
|
||||||
|
PaneId::Terminal(30),
|
||||||
|
];
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
for pane_id in pane_ids {
|
||||||
|
pane_groups.add_pane_id_to_group(pane_id, screen_size, &client_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
assert!(!pane_groups.get_client_pane_group(&client_id).is_empty());
|
||||||
|
|
||||||
|
pane_groups.clear_pane_group(&client_id);
|
||||||
|
|
||||||
|
assert!(pane_groups.get_client_pane_group(&client_id).is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn clear_pane_group_handles_nonexistent_client() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 999;
|
||||||
|
|
||||||
|
pane_groups.clear_pane_group(&client_id);
|
||||||
|
assert!(pane_groups.get_client_pane_group(&client_id).is_empty());
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn toggle_pane_id_adds_new_pane() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
let pane_id = PaneId::Terminal(10);
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
pane_groups.toggle_pane_id_in_group(pane_id, screen_size, &client_id);
|
||||||
|
|
||||||
|
let result = pane_groups.get_client_pane_group(&client_id);
|
||||||
|
assert!(result.contains(&pane_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn toggle_pane_id_removes_existing_pane() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
let pane_id = PaneId::Plugin(10);
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
pane_groups.add_pane_id_to_group(pane_id, screen_size, &client_id);
|
||||||
|
assert!(pane_groups
|
||||||
|
.get_client_pane_group(&client_id)
|
||||||
|
.contains(&pane_id));
|
||||||
|
|
||||||
|
pane_groups.toggle_pane_id_in_group(pane_id, screen_size, &client_id);
|
||||||
|
assert!(!pane_groups
|
||||||
|
.get_client_pane_group(&client_id)
|
||||||
|
.contains(&pane_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_pane_id_to_group_adds_new_pane() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
let pane_id = PaneId::Terminal(10);
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
pane_groups.add_pane_id_to_group(pane_id, screen_size, &client_id);
|
||||||
|
|
||||||
|
let result = pane_groups.get_client_pane_group(&client_id);
|
||||||
|
assert!(result.contains(&pane_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn add_pane_id_to_group_does_not_duplicate() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
let pane_id = PaneId::Plugin(10);
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
pane_groups.add_pane_id_to_group(pane_id, screen_size, &client_id);
|
||||||
|
pane_groups.add_pane_id_to_group(pane_id, screen_size, &client_id);
|
||||||
|
|
||||||
|
let result = pane_groups.get_client_pane_group(&client_id);
|
||||||
|
assert_eq!(result.len(), 1);
|
||||||
|
assert!(result.contains(&pane_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn group_and_ungroup_panes_adds_and_removes_correctly() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
let initial_panes = vec![PaneId::Terminal(1), PaneId::Plugin(2), PaneId::Terminal(3)];
|
||||||
|
for pane_id in &initial_panes {
|
||||||
|
pane_groups.add_pane_id_to_group(*pane_id, screen_size, &client_id);
|
||||||
|
}
|
||||||
|
|
||||||
|
let panes_to_add = vec![PaneId::Plugin(4), PaneId::Terminal(5)];
|
||||||
|
let panes_to_remove = vec![PaneId::Plugin(2), PaneId::Terminal(3)];
|
||||||
|
|
||||||
|
pane_groups.group_and_ungroup_panes(panes_to_add, panes_to_remove, screen_size, &client_id);
|
||||||
|
|
||||||
|
let result = pane_groups.get_client_pane_group(&client_id);
|
||||||
|
|
||||||
|
assert!(result.contains(&PaneId::Terminal(1)));
|
||||||
|
assert!(result.contains(&PaneId::Plugin(4)));
|
||||||
|
assert!(result.contains(&PaneId::Terminal(5)));
|
||||||
|
assert!(!result.contains(&PaneId::Plugin(2)));
|
||||||
|
assert!(!result.contains(&PaneId::Terminal(3)));
|
||||||
|
assert_eq!(result.len(), 3);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn override_groups_with_replaces_all_groups() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id1: ClientId = 1;
|
||||||
|
let client_id2: ClientId = 2;
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
pane_groups.add_pane_id_to_group(PaneId::Terminal(10), screen_size, &client_id1);
|
||||||
|
|
||||||
|
let mut new_groups = HashMap::new();
|
||||||
|
new_groups.insert(client_id2, vec![PaneId::Plugin(20), PaneId::Terminal(30)]);
|
||||||
|
|
||||||
|
pane_groups.override_groups_with(new_groups);
|
||||||
|
|
||||||
|
assert!(pane_groups.get_client_pane_group(&client_id1).is_empty());
|
||||||
|
|
||||||
|
let result = pane_groups.get_client_pane_group(&client_id2);
|
||||||
|
assert!(result.contains(&PaneId::Plugin(20)));
|
||||||
|
assert!(result.contains(&PaneId::Terminal(30)));
|
||||||
|
assert_eq!(result.len(), 2);
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn multiple_clients_independent_groups() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id1: ClientId = 1;
|
||||||
|
let client_id2: ClientId = 2;
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
pane_groups.add_pane_id_to_group(PaneId::Terminal(10), screen_size, &client_id1);
|
||||||
|
pane_groups.add_pane_id_to_group(PaneId::Plugin(20), screen_size, &client_id2);
|
||||||
|
|
||||||
|
let group1 = pane_groups.get_client_pane_group(&client_id1);
|
||||||
|
let group2 = pane_groups.get_client_pane_group(&client_id2);
|
||||||
|
|
||||||
|
assert!(group1.contains(&PaneId::Terminal(10)));
|
||||||
|
assert!(!group1.contains(&PaneId::Plugin(20)));
|
||||||
|
|
||||||
|
assert!(group2.contains(&PaneId::Plugin(20)));
|
||||||
|
assert!(!group2.contains(&PaneId::Terminal(10)));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn pane_id_variants_work_correctly() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
let terminal_pane = PaneId::Terminal(100);
|
||||||
|
let plugin_pane = PaneId::Plugin(200);
|
||||||
|
|
||||||
|
pane_groups.add_pane_id_to_group(terminal_pane, screen_size, &client_id);
|
||||||
|
pane_groups.add_pane_id_to_group(plugin_pane, screen_size, &client_id);
|
||||||
|
|
||||||
|
let result = pane_groups.get_client_pane_group(&client_id);
|
||||||
|
assert!(result.contains(&terminal_pane));
|
||||||
|
assert!(result.contains(&plugin_pane));
|
||||||
|
assert_eq!(result.len(), 2);
|
||||||
|
|
||||||
|
let another_terminal = PaneId::Terminal(200);
|
||||||
|
assert!(!result.contains(&another_terminal));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_launch_plugin_returns_true_when_first_pane_added() {
|
||||||
|
let pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
let previous_groups = HashMap::new();
|
||||||
|
|
||||||
|
assert!(pane_groups.should_launch_plugin(&previous_groups, &client_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_launch_plugin_returns_true_when_empty_to_non_empty() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
let mut previous_groups = HashMap::new();
|
||||||
|
previous_groups.insert(client_id, vec![]);
|
||||||
|
|
||||||
|
pane_groups.add_pane_id_to_group(PaneId::Terminal(10), screen_size, &client_id);
|
||||||
|
|
||||||
|
assert!(pane_groups.should_launch_plugin(&previous_groups, &client_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_launch_plugin_returns_false_when_non_empty_to_non_empty() {
|
||||||
|
let mut pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
let screen_size = create_test_screen_size();
|
||||||
|
|
||||||
|
pane_groups.add_pane_id_to_group(PaneId::Terminal(10), screen_size, &client_id);
|
||||||
|
let previous_groups = pane_groups.clone_inner();
|
||||||
|
|
||||||
|
pane_groups.add_pane_id_to_group(PaneId::Plugin(20), screen_size, &client_id);
|
||||||
|
|
||||||
|
assert!(!pane_groups.should_launch_plugin(&previous_groups, &client_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_launch_plugin_returns_false_when_non_empty_to_empty() {
|
||||||
|
let pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
|
||||||
|
let mut previous_groups = HashMap::new();
|
||||||
|
previous_groups.insert(client_id, vec![PaneId::Terminal(10)]);
|
||||||
|
|
||||||
|
assert!(!pane_groups.should_launch_plugin(&previous_groups, &client_id));
|
||||||
|
}
|
||||||
|
|
||||||
|
#[test]
|
||||||
|
fn should_launch_plugin_returns_false_when_empty_to_empty() {
|
||||||
|
let pane_groups = create_test_pane_groups();
|
||||||
|
let client_id: ClientId = 1;
|
||||||
|
|
||||||
|
let mut previous_groups = HashMap::new();
|
||||||
|
previous_groups.insert(client_id, vec![]);
|
||||||
|
|
||||||
|
assert!(!pane_groups.should_launch_plugin(&previous_groups, &client_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -316,6 +316,20 @@ impl FloatingPanes {
|
||||||
pub fn last_floating_pane_id(&self) -> Option<PaneId> {
|
pub fn last_floating_pane_id(&self) -> Option<PaneId> {
|
||||||
self.panes.keys().last().copied()
|
self.panes.keys().last().copied()
|
||||||
}
|
}
|
||||||
|
pub fn last_selectable_floating_pane_id(&self) -> Option<PaneId> {
|
||||||
|
self.panes
|
||||||
|
.iter()
|
||||||
|
.filter(|(_p_id, p)| p.selectable())
|
||||||
|
.last()
|
||||||
|
.map(|(p_id, _p)| *p_id)
|
||||||
|
}
|
||||||
|
pub fn has_selectable_panes(&self) -> bool {
|
||||||
|
self.panes
|
||||||
|
.iter()
|
||||||
|
.filter(|(_p_id, p)| p.selectable())
|
||||||
|
.last()
|
||||||
|
.is_some()
|
||||||
|
}
|
||||||
pub fn first_active_floating_pane_id(&self) -> Option<PaneId> {
|
pub fn first_active_floating_pane_id(&self) -> Option<PaneId> {
|
||||||
self.active_panes.values().next().copied()
|
self.active_panes.values().next().copied()
|
||||||
}
|
}
|
||||||
|
|
@ -388,6 +402,7 @@ impl FloatingPanes {
|
||||||
let multiple_users_exist_in_session =
|
let multiple_users_exist_in_session =
|
||||||
{ self.connected_clients_in_app.borrow().len() > 1 };
|
{ self.connected_clients_in_app.borrow().len() > 1 };
|
||||||
active_panes.retain(|c_id, _| self.connected_clients.borrow().contains(c_id));
|
active_panes.retain(|c_id, _| self.connected_clients.borrow().contains(c_id));
|
||||||
|
let pane_is_selectable = pane.selectable();
|
||||||
let mut pane_contents_and_ui = PaneContentsAndUi::new(
|
let mut pane_contents_and_ui = PaneContentsAndUi::new(
|
||||||
pane,
|
pane,
|
||||||
output,
|
output,
|
||||||
|
|
@ -415,6 +430,7 @@ impl FloatingPanes {
|
||||||
client_mode,
|
client_mode,
|
||||||
self.session_is_mirrored,
|
self.session_is_mirrored,
|
||||||
is_floating,
|
is_floating,
|
||||||
|
pane_is_selectable,
|
||||||
)
|
)
|
||||||
.with_context(err_context)?;
|
.with_context(err_context)?;
|
||||||
if let PaneId::Plugin(..) = kind {
|
if let PaneId::Plugin(..) = kind {
|
||||||
|
|
|
||||||
|
|
@ -967,6 +967,7 @@ impl TiledPanes {
|
||||||
let pane_is_stacked = pane.current_geom().is_stacked();
|
let pane_is_stacked = pane.current_geom().is_stacked();
|
||||||
let pane_is_one_liner_in_stack =
|
let pane_is_one_liner_in_stack =
|
||||||
pane_is_stacked && pane.current_geom().rows.is_fixed();
|
pane_is_stacked && pane.current_geom().rows.is_fixed();
|
||||||
|
let pane_is_selectable = pane.selectable();
|
||||||
let mut pane_contents_and_ui = PaneContentsAndUi::new(
|
let mut pane_contents_and_ui = PaneContentsAndUi::new(
|
||||||
pane,
|
pane,
|
||||||
output,
|
output,
|
||||||
|
|
@ -1004,6 +1005,7 @@ impl TiledPanes {
|
||||||
client_mode,
|
client_mode,
|
||||||
self.session_is_mirrored,
|
self.session_is_mirrored,
|
||||||
is_floating,
|
is_floating,
|
||||||
|
pane_is_selectable,
|
||||||
)
|
)
|
||||||
.with_context(err_context)?;
|
.with_context(err_context)?;
|
||||||
} else if pane_is_stacked {
|
} else if pane_is_stacked {
|
||||||
|
|
@ -1015,6 +1017,7 @@ impl TiledPanes {
|
||||||
client_mode,
|
client_mode,
|
||||||
self.session_is_mirrored,
|
self.session_is_mirrored,
|
||||||
is_floating,
|
is_floating,
|
||||||
|
pane_is_selectable,
|
||||||
)
|
)
|
||||||
.with_context(err_context)?;
|
.with_context(err_context)?;
|
||||||
// we also need to render its boundaries as normal
|
// we also need to render its boundaries as normal
|
||||||
|
|
|
||||||
|
|
@ -25,8 +25,8 @@ use wasm_bridge::WasmBridge;
|
||||||
use async_std::{channel, future::timeout, task};
|
use async_std::{channel, future::timeout, task};
|
||||||
use zellij_utils::{
|
use zellij_utils::{
|
||||||
data::{
|
data::{
|
||||||
ClientInfo, Event, EventType, InputMode, MessageToPlugin, PermissionStatus, PermissionType,
|
ClientInfo, Event, EventType, FloatingPaneCoordinates, InputMode, MessageToPlugin,
|
||||||
PipeMessage, PipeSource, PluginCapabilities,
|
PermissionStatus, PermissionType, PipeMessage, PipeSource, PluginCapabilities,
|
||||||
},
|
},
|
||||||
errors::{prelude::*, ContextType, PluginContext},
|
errors::{prelude::*, ContextType, PluginContext},
|
||||||
input::{
|
input::{
|
||||||
|
|
@ -55,6 +55,8 @@ pub enum PluginInstruction {
|
||||||
Size,
|
Size,
|
||||||
Option<PathBuf>, // cwd
|
Option<PathBuf>, // cwd
|
||||||
bool, // skip cache
|
bool, // skip cache
|
||||||
|
Option<bool>, // should focus plugin
|
||||||
|
Option<FloatingPaneCoordinates>,
|
||||||
),
|
),
|
||||||
LoadBackgroundPlugin(RunPluginOrAlias, ClientId),
|
LoadBackgroundPlugin(RunPluginOrAlias, ClientId),
|
||||||
Update(Vec<(Option<PluginId>, Option<ClientId>, Event)>), // Focused plugin / broadcast, client_id, event data
|
Update(Vec<(Option<PluginId>, Option<ClientId>, Event)>), // Focused plugin / broadcast, client_id, event data
|
||||||
|
|
@ -281,6 +283,8 @@ pub(crate) fn plugin_thread_main(
|
||||||
size,
|
size,
|
||||||
cwd,
|
cwd,
|
||||||
skip_cache,
|
skip_cache,
|
||||||
|
should_focus_plugin,
|
||||||
|
floating_pane_coordinates,
|
||||||
) => {
|
) => {
|
||||||
run_plugin_or_alias.populate_run_plugin_if_needed(&plugin_aliases);
|
run_plugin_or_alias.populate_run_plugin_if_needed(&plugin_aliases);
|
||||||
let cwd = run_plugin_or_alias.get_initial_cwd().or(cwd);
|
let cwd = run_plugin_or_alias.get_initial_cwd().or(cwd);
|
||||||
|
|
@ -306,6 +310,8 @@ pub(crate) fn plugin_thread_main(
|
||||||
pane_id_to_replace,
|
pane_id_to_replace,
|
||||||
cwd,
|
cwd,
|
||||||
start_suppressed,
|
start_suppressed,
|
||||||
|
floating_pane_coordinates,
|
||||||
|
should_focus_plugin,
|
||||||
Some(client_id),
|
Some(client_id),
|
||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
|
|
@ -378,6 +384,8 @@ pub(crate) fn plugin_thread_main(
|
||||||
None,
|
None,
|
||||||
start_suppressed,
|
start_suppressed,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
),
|
),
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
|
|
@ -1070,7 +1078,8 @@ fn load_background_plugin(
|
||||||
pane_id_to_replace,
|
pane_id_to_replace,
|
||||||
cwd,
|
cwd,
|
||||||
start_suppressed,
|
start_suppressed,
|
||||||
// None,
|
None,
|
||||||
|
None,
|
||||||
Some(client_id),
|
Some(client_id),
|
||||||
)));
|
)));
|
||||||
},
|
},
|
||||||
|
|
|
||||||
|
|
@ -868,6 +868,7 @@ impl<'a> PluginLoader<'a> {
|
||||||
default_mode: self.default_mode.clone(),
|
default_mode: self.default_mode.clone(),
|
||||||
subscriptions: Arc::new(Mutex::new(HashSet::new())),
|
subscriptions: Arc::new(Mutex::new(HashSet::new())),
|
||||||
keybinds: self.keybinds.clone(),
|
keybinds: self.keybinds.clone(),
|
||||||
|
intercepting_key_presses: false,
|
||||||
stdin_pipe,
|
stdin_pipe,
|
||||||
stdout_pipe,
|
stdout_pipe,
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -313,6 +313,7 @@ pub struct PluginEnv {
|
||||||
pub stdin_pipe: Arc<Mutex<VecDeque<u8>>>,
|
pub stdin_pipe: Arc<Mutex<VecDeque<u8>>>,
|
||||||
pub stdout_pipe: Arc<Mutex<VecDeque<u8>>>,
|
pub stdout_pipe: Arc<Mutex<VecDeque<u8>>>,
|
||||||
pub keybinds: Keybinds,
|
pub keybinds: Keybinds,
|
||||||
|
pub intercepting_key_presses: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Clone)]
|
#[derive(Clone)]
|
||||||
|
|
@ -457,4 +458,7 @@ impl RunningPlugin {
|
||||||
pub fn update_default_shell(&mut self, default_shell: Option<TerminalAction>) {
|
pub fn update_default_shell(&mut self, default_shell: Option<TerminalAction>) {
|
||||||
self.store.data_mut().default_shell = default_shell;
|
self.store.data_mut().default_shell = default_shell;
|
||||||
}
|
}
|
||||||
|
pub fn intercepting_key_presses(&self) -> bool {
|
||||||
|
self.store.data().intercepting_key_presses
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -714,6 +714,8 @@ pub fn load_new_plugin_from_hd() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -794,6 +796,8 @@ pub fn load_new_plugin_with_plugin_alias() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -870,6 +874,8 @@ pub fn plugin_workers() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
// we send a SystemClipboardFailure to trigger the custom handler in the fixture plugin that
|
// we send a SystemClipboardFailure to trigger the custom handler in the fixture plugin that
|
||||||
|
|
@ -950,6 +956,8 @@ pub fn plugin_workers_persist_state() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
// we send a SystemClipboardFailure to trigger the custom handler in the fixture plugin that
|
// we send a SystemClipboardFailure to trigger the custom handler in the fixture plugin that
|
||||||
|
|
@ -1040,6 +1048,8 @@ pub fn can_subscribe_to_hd_events() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
// extra long time because we only start the fs watcher on plugin load
|
// extra long time because we only start the fs watcher on plugin load
|
||||||
std::thread::sleep(std::time::Duration::from_millis(5000));
|
std::thread::sleep(std::time::Duration::from_millis(5000));
|
||||||
|
|
@ -1118,6 +1128,8 @@ pub fn switch_to_mode_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -1190,6 +1202,8 @@ pub fn switch_to_mode_plugin_command_permission_denied() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -1262,6 +1276,8 @@ pub fn new_tabs_with_layout_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -1348,6 +1364,8 @@ pub fn new_tab_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -1420,6 +1438,8 @@ pub fn go_to_next_tab_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -1491,6 +1511,8 @@ pub fn go_to_previous_tab_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -1562,6 +1584,8 @@ pub fn resize_focused_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -1633,6 +1657,8 @@ pub fn resize_focused_pane_with_direction_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -1704,6 +1730,8 @@ pub fn focus_next_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -1775,6 +1803,8 @@ pub fn focus_previous_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -1846,6 +1876,8 @@ pub fn move_focus_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -1917,6 +1949,8 @@ pub fn move_focus_or_tab_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -1988,6 +2022,8 @@ pub fn edit_scrollback_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2059,6 +2095,8 @@ pub fn write_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2130,6 +2168,8 @@ pub fn write_chars_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2201,6 +2241,8 @@ pub fn toggle_tab_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2272,6 +2314,8 @@ pub fn move_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2343,6 +2387,8 @@ pub fn move_pane_with_direction_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2415,6 +2461,8 @@ pub fn clear_screen_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2487,6 +2535,8 @@ pub fn scroll_up_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2558,6 +2608,8 @@ pub fn scroll_down_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2629,6 +2681,8 @@ pub fn scroll_to_top_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2700,6 +2754,8 @@ pub fn scroll_to_bottom_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2771,6 +2827,8 @@ pub fn page_scroll_up_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2842,6 +2900,8 @@ pub fn page_scroll_down_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2913,6 +2973,8 @@ pub fn toggle_focus_fullscreen_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -2984,6 +3046,8 @@ pub fn toggle_pane_frames_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3055,6 +3119,8 @@ pub fn toggle_pane_embed_or_eject_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3126,6 +3192,8 @@ pub fn undo_rename_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3197,6 +3265,8 @@ pub fn close_focus_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3268,6 +3338,8 @@ pub fn toggle_active_tab_sync_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3339,6 +3411,8 @@ pub fn close_focused_tab_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3410,6 +3484,8 @@ pub fn undo_rename_tab_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3481,6 +3557,8 @@ pub fn previous_swap_layout_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3552,6 +3630,8 @@ pub fn next_swap_layout_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3623,6 +3703,8 @@ pub fn go_to_tab_name_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3694,6 +3776,8 @@ pub fn focus_or_create_tab_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3765,6 +3849,8 @@ pub fn go_to_tab() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3836,6 +3922,8 @@ pub fn start_or_reload_plugin() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3914,6 +4002,8 @@ pub fn quit_zellij_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -3992,6 +4082,8 @@ pub fn detach_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4070,6 +4162,8 @@ pub fn open_file_floating_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4152,6 +4246,8 @@ pub fn open_file_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4235,6 +4331,8 @@ pub fn open_file_with_line_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4317,6 +4415,8 @@ pub fn open_file_with_line_floating_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4399,6 +4499,8 @@ pub fn open_terminal_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4477,6 +4579,8 @@ pub fn open_terminal_floating_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4555,6 +4659,8 @@ pub fn open_command_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4633,6 +4739,8 @@ pub fn open_command_pane_floating_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4704,6 +4812,8 @@ pub fn switch_to_tab_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4775,6 +4885,8 @@ pub fn hide_self_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4845,6 +4957,8 @@ pub fn show_self_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4916,6 +5030,8 @@ pub fn close_terminal_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -4987,6 +5103,8 @@ pub fn close_plugin_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5058,6 +5176,8 @@ pub fn focus_terminal_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5129,6 +5249,8 @@ pub fn focus_plugin_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5200,6 +5322,8 @@ pub fn rename_terminal_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5271,6 +5395,8 @@ pub fn rename_plugin_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5342,6 +5468,8 @@ pub fn rename_tab_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5422,6 +5550,8 @@ pub fn send_configuration_to_plugins() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5490,6 +5620,8 @@ pub fn request_plugin_permissions() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5582,6 +5714,8 @@ pub fn granted_permission_request_result() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5673,6 +5807,8 @@ pub fn denied_permission_request_result() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5744,6 +5880,8 @@ pub fn run_command_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5822,6 +5960,8 @@ pub fn run_command_with_env_vars_and_cwd_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5900,6 +6040,8 @@ pub fn web_request_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -5971,6 +6113,8 @@ pub fn unblock_input_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
|
||||||
|
|
@ -6053,6 +6197,8 @@ pub fn block_input_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
// extra long time because we only start the fs watcher on plugin load
|
// extra long time because we only start the fs watcher on plugin load
|
||||||
std::thread::sleep(std::time::Duration::from_millis(5000));
|
std::thread::sleep(std::time::Duration::from_millis(5000));
|
||||||
|
|
@ -6143,6 +6289,8 @@ pub fn pipe_output_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
|
||||||
|
|
@ -6226,6 +6374,8 @@ pub fn pipe_message_to_plugin_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::CliPipe {
|
let _ = plugin_thread_sender.send(PluginInstruction::CliPipe {
|
||||||
|
|
@ -6320,6 +6470,8 @@ pub fn switch_session_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
|
||||||
|
|
@ -6401,6 +6553,8 @@ pub fn switch_session_with_layout_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
|
||||||
|
|
@ -6482,6 +6636,8 @@ pub fn switch_session_with_layout_and_cwd_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
|
||||||
|
|
@ -6563,6 +6719,8 @@ pub fn disconnect_other_clients_plugins_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
|
||||||
|
|
@ -6644,6 +6802,8 @@ pub fn reconfigure_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
|
||||||
|
|
@ -6729,6 +6889,8 @@ pub fn run_plugin_in_specific_cwd() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
|
||||||
|
|
@ -6803,6 +6965,8 @@ pub fn hide_pane_with_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -6874,6 +7038,8 @@ pub fn show_pane_with_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -6952,6 +7118,8 @@ pub fn open_command_pane_background_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7027,6 +7195,8 @@ pub fn rerun_command_pane_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7098,6 +7268,8 @@ pub fn resize_pane_with_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7169,6 +7341,8 @@ pub fn edit_scrollback_for_pane_with_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7240,6 +7414,8 @@ pub fn write_to_pane_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7311,6 +7487,8 @@ pub fn write_chars_to_pane_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7382,6 +7560,8 @@ pub fn move_pane_with_pane_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7453,6 +7633,8 @@ pub fn move_pane_with_pane_id_in_direction_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7524,6 +7706,8 @@ pub fn clear_screen_for_pane_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7595,6 +7779,8 @@ pub fn scroll_up_in_pane_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7666,6 +7852,8 @@ pub fn scroll_down_in_pane_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7737,6 +7925,8 @@ pub fn scroll_to_top_in_pane_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7808,6 +7998,8 @@ pub fn scroll_to_bottom_in_pane_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7879,6 +8071,8 @@ pub fn page_scroll_up_in_pane_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -7950,6 +8144,8 @@ pub fn page_scroll_down_in_pane_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -8021,6 +8217,8 @@ pub fn toggle_pane_id_fullscreen_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -8092,6 +8290,8 @@ pub fn toggle_pane_embed_or_eject_for_pane_id_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -8163,6 +8363,8 @@ pub fn close_tab_with_index_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -8234,6 +8436,8 @@ pub fn break_panes_to_new_tab_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -8305,6 +8509,8 @@ pub fn break_panes_to_tab_with_index_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -8376,6 +8582,8 @@ pub fn reload_plugin_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -8447,6 +8655,8 @@ pub fn load_new_plugin_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -8525,6 +8735,8 @@ pub fn rebind_keys_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
|
|
||||||
|
|
@ -8599,6 +8811,8 @@ pub fn list_clients_plugin_command() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(500));
|
std::thread::sleep(std::time::Duration::from_millis(500));
|
||||||
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
let _ = plugin_thread_sender.send(PluginInstruction::Update(vec![(
|
||||||
|
|
@ -8670,6 +8884,8 @@ pub fn before_close_plugin_event() {
|
||||||
size,
|
size,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
std::thread::sleep(std::time::Duration::from_millis(5000));
|
std::thread::sleep(std::time::Duration::from_millis(5000));
|
||||||
// here we send an unload to plugin id 0 (the first plugin id, presumably this plugin)
|
// here we send an unload to plugin id 0 (the first plugin id, presumably this plugin)
|
||||||
|
|
|
||||||
|
|
@ -324,6 +324,15 @@ impl WasmBridge {
|
||||||
for (_worker_name, worker_sender) in workers {
|
for (_worker_name, worker_sender) in workers {
|
||||||
drop(worker_sender.send(MessageToWorker::Exit));
|
drop(worker_sender.send(MessageToWorker::Exit));
|
||||||
}
|
}
|
||||||
|
{
|
||||||
|
// if the plugin was intercepting key presses and for some reason did not clear
|
||||||
|
// this state, we make sure to do it ourselves so that the user will not get stuck
|
||||||
|
if running_plugin.lock().unwrap().intercepting_key_presses() {
|
||||||
|
let _ = self
|
||||||
|
.senders
|
||||||
|
.send_to_screen(ScreenInstruction::ClearKeyPressesIntercepts(client_id));
|
||||||
|
}
|
||||||
|
}
|
||||||
let subscriptions = subscriptions.lock().unwrap();
|
let subscriptions = subscriptions.lock().unwrap();
|
||||||
if subscriptions.contains(&EventType::BeforeClose) {
|
if subscriptions.contains(&EventType::BeforeClose) {
|
||||||
let mut running_plugin = running_plugin.lock().unwrap();
|
let mut running_plugin = running_plugin.lock().unwrap();
|
||||||
|
|
@ -1436,6 +1445,8 @@ impl WasmBridge {
|
||||||
pane_id_to_replace,
|
pane_id_to_replace,
|
||||||
cwd,
|
cwd,
|
||||||
start_suppressed,
|
start_suppressed,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
Some(client_id),
|
Some(client_id),
|
||||||
)));
|
)));
|
||||||
vec![(plugin_id, Some(client_id))]
|
vec![(plugin_id, Some(client_id))]
|
||||||
|
|
|
||||||
|
|
@ -73,9 +73,10 @@ pub fn zellij_exports(linker: &mut Linker<PluginEnv>) {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
|
|
||||||
fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) {
|
fn host_run_plugin_command(mut caller: Caller<'_, PluginEnv>) {
|
||||||
let env = caller.data();
|
let mut env = caller.data_mut();
|
||||||
let err_context = || format!("failed to run plugin command {}", env.name());
|
let plugin_command = env.name();
|
||||||
|
let err_context = || format!("failed to run plugin command {}", plugin_command);
|
||||||
wasi_read_bytes(env)
|
wasi_read_bytes(env)
|
||||||
.and_then(|bytes| {
|
.and_then(|bytes| {
|
||||||
let command: ProtobufPluginCommand = ProtobufPluginCommand::decode(bytes.as_slice())?;
|
let command: ProtobufPluginCommand = ProtobufPluginCommand::decode(bytes.as_slice())?;
|
||||||
|
|
@ -455,6 +456,10 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) {
|
||||||
PluginCommand::EmbedMultiplePanes(pane_ids) => {
|
PluginCommand::EmbedMultiplePanes(pane_ids) => {
|
||||||
embed_multiple_panes(env, pane_ids.into_iter().map(|p| p.into()).collect())
|
embed_multiple_panes(env, pane_ids.into_iter().map(|p| p.into()).collect())
|
||||||
},
|
},
|
||||||
|
PluginCommand::InterceptKeyPresses => intercept_key_presses(&mut env),
|
||||||
|
PluginCommand::ClearKeyPressesIntercepts => {
|
||||||
|
clear_key_presses_intercepts(&mut env)
|
||||||
|
},
|
||||||
},
|
},
|
||||||
(PermissionStatus::Denied, permission) => {
|
(PermissionStatus::Denied, permission) => {
|
||||||
log::error!(
|
log::error!(
|
||||||
|
|
@ -2163,6 +2168,8 @@ fn load_new_plugin(
|
||||||
size,
|
size,
|
||||||
cwd,
|
cwd,
|
||||||
skip_cache,
|
skip_cache,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
));
|
));
|
||||||
},
|
},
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
|
|
@ -2231,6 +2238,23 @@ fn embed_multiple_panes(env: &PluginEnv, pane_ids: Vec<PaneId>) {
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
fn intercept_key_presses(env: &mut PluginEnv) {
|
||||||
|
env.intercepting_key_presses = true;
|
||||||
|
let _ = env
|
||||||
|
.senders
|
||||||
|
.send_to_screen(ScreenInstruction::InterceptKeyPresses(
|
||||||
|
env.plugin_id,
|
||||||
|
env.client_id,
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
fn clear_key_presses_intercepts(env: &mut PluginEnv) {
|
||||||
|
env.intercepting_key_presses = false;
|
||||||
|
let _ = env
|
||||||
|
.senders
|
||||||
|
.send_to_screen(ScreenInstruction::ClearKeyPressesIntercepts(env.client_id));
|
||||||
|
}
|
||||||
|
|
||||||
// Custom panic handler for plugins.
|
// Custom panic handler for plugins.
|
||||||
//
|
//
|
||||||
// This is called when a panic occurs in a plugin. Since most panics will likely originate in the
|
// This is called when a panic occurs in a plugin. Since most panics will likely originate in the
|
||||||
|
|
@ -2409,6 +2433,9 @@ fn check_command_permission(
|
||||||
PermissionType::Reconfigure
|
PermissionType::Reconfigure
|
||||||
},
|
},
|
||||||
PluginCommand::ChangeHostFolder(..) => PermissionType::FullHdAccess,
|
PluginCommand::ChangeHostFolder(..) => PermissionType::FullHdAccess,
|
||||||
|
PluginCommand::InterceptKeyPresses | PluginCommand::ClearKeyPressesIntercepts => {
|
||||||
|
PermissionType::InterceptInput
|
||||||
|
},
|
||||||
_ => return (PermissionStatus::Granted, None),
|
_ => return (PermissionStatus::Granted, None),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -97,6 +97,7 @@ pub enum PtyInstruction {
|
||||||
Size,
|
Size,
|
||||||
bool, // skip cache
|
bool, // skip cache
|
||||||
Option<PathBuf>, // if Some, will not fill cwd but just forward the message
|
Option<PathBuf>, // if Some, will not fill cwd but just forward the message
|
||||||
|
Option<bool>, // should focus plugin
|
||||||
Option<FloatingPaneCoordinates>,
|
Option<FloatingPaneCoordinates>,
|
||||||
),
|
),
|
||||||
ListClientsMetadata(SessionLayoutMetadata, ClientId),
|
ListClientsMetadata(SessionLayoutMetadata, ClientId),
|
||||||
|
|
@ -771,6 +772,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
|
||||||
size,
|
size,
|
||||||
skip_cache,
|
skip_cache,
|
||||||
cwd,
|
cwd,
|
||||||
|
should_focus_plugin,
|
||||||
floating_pane_coordinates,
|
floating_pane_coordinates,
|
||||||
) => {
|
) => {
|
||||||
pty.fill_plugin_cwd(
|
pty.fill_plugin_cwd(
|
||||||
|
|
@ -784,6 +786,7 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
|
||||||
size,
|
size,
|
||||||
skip_cache,
|
skip_cache,
|
||||||
cwd,
|
cwd,
|
||||||
|
should_focus_plugin,
|
||||||
floating_pane_coordinates,
|
floating_pane_coordinates,
|
||||||
)?;
|
)?;
|
||||||
},
|
},
|
||||||
|
|
@ -1527,9 +1530,8 @@ impl Pty {
|
||||||
size: Size,
|
size: Size,
|
||||||
skip_cache: bool,
|
skip_cache: bool,
|
||||||
cwd: Option<PathBuf>,
|
cwd: Option<PathBuf>,
|
||||||
// left here for historical and potential future reasons since we might change the ordering
|
should_focus_plugin: Option<bool>,
|
||||||
// of the pipeline between threads and end up needing to forward this
|
floating_pane_coordinates: Option<FloatingPaneCoordinates>,
|
||||||
_floating_pane_coordinates: Option<FloatingPaneCoordinates>,
|
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let get_focused_cwd = || {
|
let get_focused_cwd = || {
|
||||||
self.active_panes
|
self.active_panes
|
||||||
|
|
@ -1563,6 +1565,8 @@ impl Pty {
|
||||||
size,
|
size,
|
||||||
cwd,
|
cwd,
|
||||||
skip_cache,
|
skip_cache,
|
||||||
|
should_focus_plugin,
|
||||||
|
floating_pane_coordinates,
|
||||||
))?;
|
))?;
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -9,8 +9,8 @@ use std::time::Duration;
|
||||||
|
|
||||||
use log::{debug, warn};
|
use log::{debug, warn};
|
||||||
use zellij_utils::data::{
|
use zellij_utils::data::{
|
||||||
Direction, KeyWithModifier, PaneManifest, PluginPermission, Resize, ResizeStrategy,
|
Direction, FloatingPaneCoordinates, KeyWithModifier, PaneManifest, PluginPermission, Resize,
|
||||||
SessionInfo, Styling,
|
ResizeStrategy, SessionInfo, Styling,
|
||||||
};
|
};
|
||||||
use zellij_utils::errors::prelude::*;
|
use zellij_utils::errors::prelude::*;
|
||||||
use zellij_utils::input::command::RunCommand;
|
use zellij_utils::input::command::RunCommand;
|
||||||
|
|
@ -32,6 +32,7 @@ use zellij_utils::{
|
||||||
|
|
||||||
use crate::background_jobs::BackgroundJob;
|
use crate::background_jobs::BackgroundJob;
|
||||||
use crate::os_input_output::ResizeCache;
|
use crate::os_input_output::ResizeCache;
|
||||||
|
use crate::pane_groups::PaneGroups;
|
||||||
use crate::panes::alacritty_functions::xparse_color;
|
use crate::panes::alacritty_functions::xparse_color;
|
||||||
use crate::panes::terminal_character::AnsiCode;
|
use crate::panes::terminal_character::AnsiCode;
|
||||||
use crate::session_layout_metadata::{PaneLayoutMetadata, SessionLayoutMetadata};
|
use crate::session_layout_metadata::{PaneLayoutMetadata, SessionLayoutMetadata};
|
||||||
|
|
@ -51,10 +52,7 @@ use crate::{
|
||||||
ClientId, ServerInstruction,
|
ClientId, ServerInstruction,
|
||||||
};
|
};
|
||||||
use zellij_utils::{
|
use zellij_utils::{
|
||||||
data::{
|
data::{Event, InputMode, ModeInfo, Palette, PaletteColor, PluginCapabilities, Style, TabInfo},
|
||||||
Event, FloatingPaneCoordinates, InputMode, ModeInfo, Palette, PaletteColor,
|
|
||||||
PluginCapabilities, Style, TabInfo,
|
|
||||||
},
|
|
||||||
errors::{ContextType, ScreenContext},
|
errors::{ContextType, ScreenContext},
|
||||||
input::get_mode_info,
|
input::get_mode_info,
|
||||||
ipc::{ClientAttributes, PixelDimensions, ServerToClientMsg},
|
ipc::{ClientAttributes, PixelDimensions, ServerToClientMsg},
|
||||||
|
|
@ -305,6 +303,8 @@ pub enum ScreenInstruction {
|
||||||
Option<PaneId>,
|
Option<PaneId>,
|
||||||
Option<PathBuf>, // cwd
|
Option<PathBuf>, // cwd
|
||||||
bool, // start suppressed
|
bool, // start suppressed
|
||||||
|
Option<FloatingPaneCoordinates>,
|
||||||
|
Option<bool>, // should focus plugin
|
||||||
Option<ClientId>,
|
Option<ClientId>,
|
||||||
),
|
),
|
||||||
UpdatePluginLoadingStage(u32, LoadingIndication), // u32 - plugin_id
|
UpdatePluginLoadingStage(u32, LoadingIndication), // u32 - plugin_id
|
||||||
|
|
@ -415,6 +415,8 @@ pub enum ScreenInstruction {
|
||||||
EmbedMultiplePanes(Vec<PaneId>, ClientId),
|
EmbedMultiplePanes(Vec<PaneId>, ClientId),
|
||||||
TogglePaneInGroup(ClientId),
|
TogglePaneInGroup(ClientId),
|
||||||
ToggleGroupMarking(ClientId),
|
ToggleGroupMarking(ClientId),
|
||||||
|
InterceptKeyPresses(PluginId, ClientId),
|
||||||
|
ClearKeyPressesIntercepts(ClientId),
|
||||||
}
|
}
|
||||||
|
|
||||||
impl From<&ScreenInstruction> for ScreenContext {
|
impl From<&ScreenInstruction> for ScreenContext {
|
||||||
|
|
@ -636,6 +638,10 @@ impl From<&ScreenInstruction> for ScreenContext {
|
||||||
ScreenInstruction::EmbedMultiplePanes(..) => ScreenContext::EmbedMultiplePanes,
|
ScreenInstruction::EmbedMultiplePanes(..) => ScreenContext::EmbedMultiplePanes,
|
||||||
ScreenInstruction::TogglePaneInGroup(..) => ScreenContext::TogglePaneInGroup,
|
ScreenInstruction::TogglePaneInGroup(..) => ScreenContext::TogglePaneInGroup,
|
||||||
ScreenInstruction::ToggleGroupMarking(..) => ScreenContext::ToggleGroupMarking,
|
ScreenInstruction::ToggleGroupMarking(..) => ScreenContext::ToggleGroupMarking,
|
||||||
|
ScreenInstruction::InterceptKeyPresses(..) => ScreenContext::InterceptKeyPresses,
|
||||||
|
ScreenInstruction::ClearKeyPressesIntercepts(..) => {
|
||||||
|
ScreenContext::ClearKeyPressesIntercepts
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -717,7 +723,7 @@ pub(crate) struct Screen {
|
||||||
default_layout_name: Option<String>,
|
default_layout_name: Option<String>,
|
||||||
explicitly_disable_kitty_keyboard_protocol: bool,
|
explicitly_disable_kitty_keyboard_protocol: bool,
|
||||||
default_editor: Option<PathBuf>,
|
default_editor: Option<PathBuf>,
|
||||||
current_pane_group: Rc<RefCell<HashMap<ClientId, Vec<PaneId>>>>,
|
current_pane_group: Rc<RefCell<PaneGroups>>,
|
||||||
advanced_mouse_actions: bool,
|
advanced_mouse_actions: bool,
|
||||||
currently_marking_pane_group: Rc<RefCell<HashMap<ClientId, bool>>>,
|
currently_marking_pane_group: Rc<RefCell<HashMap<ClientId, bool>>>,
|
||||||
}
|
}
|
||||||
|
|
@ -753,6 +759,7 @@ impl Screen {
|
||||||
let mut session_infos_on_machine = BTreeMap::new();
|
let mut session_infos_on_machine = BTreeMap::new();
|
||||||
let resurrectable_sessions = BTreeMap::new();
|
let resurrectable_sessions = BTreeMap::new();
|
||||||
session_infos_on_machine.insert(session_name.clone(), session_info);
|
session_infos_on_machine.insert(session_name.clone(), session_info);
|
||||||
|
let current_pane_group = PaneGroups::new(bus.senders.clone());
|
||||||
Screen {
|
Screen {
|
||||||
bus,
|
bus,
|
||||||
max_panes,
|
max_panes,
|
||||||
|
|
@ -790,7 +797,7 @@ impl Screen {
|
||||||
layout_dir,
|
layout_dir,
|
||||||
explicitly_disable_kitty_keyboard_protocol,
|
explicitly_disable_kitty_keyboard_protocol,
|
||||||
default_editor,
|
default_editor,
|
||||||
current_pane_group: Rc::new(RefCell::new(HashMap::new())),
|
current_pane_group: Rc::new(RefCell::new(current_pane_group)),
|
||||||
currently_marking_pane_group: Rc::new(RefCell::new(HashMap::new())),
|
currently_marking_pane_group: Rc::new(RefCell::new(HashMap::new())),
|
||||||
advanced_mouse_actions,
|
advanced_mouse_actions,
|
||||||
}
|
}
|
||||||
|
|
@ -2897,15 +2904,12 @@ impl Screen {
|
||||||
fn get_client_pane_group(&self, client_id: &ClientId) -> HashSet<PaneId> {
|
fn get_client_pane_group(&self, client_id: &ClientId) -> HashSet<PaneId> {
|
||||||
self.current_pane_group
|
self.current_pane_group
|
||||||
.borrow()
|
.borrow()
|
||||||
.get(client_id)
|
.get_client_pane_group(client_id)
|
||||||
.map(|p| p.iter().copied().collect())
|
|
||||||
.unwrap_or_else(|| HashSet::new())
|
|
||||||
}
|
}
|
||||||
fn clear_pane_group(&mut self, client_id: &ClientId) {
|
fn clear_pane_group(&mut self, client_id: &ClientId) {
|
||||||
self.current_pane_group
|
self.current_pane_group
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.get_mut(client_id)
|
.clear_pane_group(client_id);
|
||||||
.map(|p| p.clear());
|
|
||||||
self.currently_marking_pane_group
|
self.currently_marking_pane_group
|
||||||
.borrow_mut()
|
.borrow_mut()
|
||||||
.remove(client_id);
|
.remove(client_id);
|
||||||
|
|
@ -2913,22 +2917,14 @@ impl Screen {
|
||||||
fn toggle_pane_id_in_group(&mut self, pane_id: PaneId, client_id: &ClientId) {
|
fn toggle_pane_id_in_group(&mut self, pane_id: PaneId, client_id: &ClientId) {
|
||||||
{
|
{
|
||||||
let mut pane_groups = self.current_pane_group.borrow_mut();
|
let mut pane_groups = self.current_pane_group.borrow_mut();
|
||||||
let client_pane_group = pane_groups.entry(*client_id).or_insert_with(|| vec![]);
|
pane_groups.toggle_pane_id_in_group(pane_id, self.size, client_id);
|
||||||
if client_pane_group.contains(&pane_id) {
|
|
||||||
client_pane_group.retain(|p| p != &pane_id);
|
|
||||||
} else {
|
|
||||||
client_pane_group.push(pane_id);
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
self.retain_only_existing_panes_in_pane_groups();
|
self.retain_only_existing_panes_in_pane_groups();
|
||||||
}
|
}
|
||||||
fn add_pane_id_to_group(&mut self, pane_id: PaneId, client_id: &ClientId) {
|
fn add_pane_id_to_group(&mut self, pane_id: PaneId, client_id: &ClientId) {
|
||||||
{
|
{
|
||||||
let mut pane_groups = self.current_pane_group.borrow_mut();
|
let mut pane_groups = self.current_pane_group.borrow_mut();
|
||||||
let client_pane_group = pane_groups.entry(*client_id).or_insert_with(|| vec![]);
|
pane_groups.add_pane_id_to_group(pane_id, self.size, client_id);
|
||||||
if !client_pane_group.contains(&pane_id) {
|
|
||||||
client_pane_group.push(pane_id);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
self.retain_only_existing_panes_in_pane_groups();
|
self.retain_only_existing_panes_in_pane_groups();
|
||||||
}
|
}
|
||||||
|
|
@ -2956,17 +2952,18 @@ impl Screen {
|
||||||
|
|
||||||
fn group_and_ungroup_panes(
|
fn group_and_ungroup_panes(
|
||||||
&mut self,
|
&mut self,
|
||||||
mut pane_ids_to_group: Vec<PaneId>,
|
pane_ids_to_group: Vec<PaneId>,
|
||||||
pane_ids_to_ungroup: Vec<PaneId>,
|
pane_ids_to_ungroup: Vec<PaneId>,
|
||||||
client_id: ClientId,
|
client_id: ClientId,
|
||||||
) {
|
) {
|
||||||
{
|
{
|
||||||
let mut current_pane_group = self.current_pane_group.borrow_mut();
|
let mut current_pane_group = self.current_pane_group.borrow_mut();
|
||||||
let client_pane_group = current_pane_group
|
current_pane_group.group_and_ungroup_panes(
|
||||||
.entry(client_id)
|
pane_ids_to_group,
|
||||||
.or_insert_with(|| vec![]);
|
pane_ids_to_ungroup,
|
||||||
client_pane_group.append(&mut pane_ids_to_group);
|
self.size,
|
||||||
client_pane_group.retain(|p| !pane_ids_to_ungroup.contains(p));
|
&client_id,
|
||||||
|
);
|
||||||
}
|
}
|
||||||
self.retain_only_existing_panes_in_pane_groups();
|
self.retain_only_existing_panes_in_pane_groups();
|
||||||
let _ = self.log_and_report_session_state();
|
let _ = self.log_and_report_session_state();
|
||||||
|
|
@ -2974,7 +2971,7 @@ impl Screen {
|
||||||
fn retain_only_existing_panes_in_pane_groups(&mut self) {
|
fn retain_only_existing_panes_in_pane_groups(&mut self) {
|
||||||
let clients_with_empty_group = {
|
let clients_with_empty_group = {
|
||||||
let mut clients_with_empty_group = vec![];
|
let mut clients_with_empty_group = vec![];
|
||||||
let mut current_pane_group = self.current_pane_group.borrow_mut();
|
let mut current_pane_group = { self.current_pane_group.borrow().clone_inner() };
|
||||||
for (client_id, panes_in_group) in current_pane_group.iter_mut() {
|
for (client_id, panes_in_group) in current_pane_group.iter_mut() {
|
||||||
let all_tabs = self.get_tabs();
|
let all_tabs = self.get_tabs();
|
||||||
panes_in_group.retain(|p_id| {
|
panes_in_group.retain(|p_id| {
|
||||||
|
|
@ -2991,6 +2988,9 @@ impl Screen {
|
||||||
clients_with_empty_group.push(*client_id)
|
clients_with_empty_group.push(*client_id)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
self.current_pane_group
|
||||||
|
.borrow_mut()
|
||||||
|
.override_groups_with(current_pane_group);
|
||||||
clients_with_empty_group
|
clients_with_empty_group
|
||||||
};
|
};
|
||||||
for client_id in &clients_with_empty_group {
|
for client_id in &clients_with_empty_group {
|
||||||
|
|
@ -3114,6 +3114,7 @@ pub(crate) fn screen_thread_main(
|
||||||
let mut pending_events_waiting_for_tab: Vec<ScreenInstruction> = vec![];
|
let mut pending_events_waiting_for_tab: Vec<ScreenInstruction> = vec![];
|
||||||
let mut pending_events_waiting_for_client: Vec<ScreenInstruction> = vec![];
|
let mut pending_events_waiting_for_client: Vec<ScreenInstruction> = vec![];
|
||||||
let mut plugin_loading_message_cache = HashMap::new();
|
let mut plugin_loading_message_cache = HashMap::new();
|
||||||
|
let mut keybind_intercepts = HashMap::new();
|
||||||
loop {
|
loop {
|
||||||
let (event, mut err_ctx) = screen
|
let (event, mut err_ctx) = screen
|
||||||
.bus
|
.bus
|
||||||
|
|
@ -3178,6 +3179,7 @@ pub(crate) fn screen_thread_main(
|
||||||
invoked_with,
|
invoked_with,
|
||||||
floating_pane_coordinates,
|
floating_pane_coordinates,
|
||||||
start_suppressed,
|
start_suppressed,
|
||||||
|
true,
|
||||||
Some(client_id)
|
Some(client_id)
|
||||||
)
|
)
|
||||||
}, ?);
|
}, ?);
|
||||||
|
|
@ -3204,6 +3206,7 @@ pub(crate) fn screen_thread_main(
|
||||||
invoked_with,
|
invoked_with,
|
||||||
floating_pane_coordinates,
|
floating_pane_coordinates,
|
||||||
start_suppressed,
|
start_suppressed,
|
||||||
|
true,
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
if let Some(hold_for_command) = hold_for_command {
|
if let Some(hold_for_command) = hold_for_command {
|
||||||
|
|
@ -3226,6 +3229,7 @@ pub(crate) fn screen_thread_main(
|
||||||
invoked_with,
|
invoked_with,
|
||||||
floating_pane_coordinates,
|
floating_pane_coordinates,
|
||||||
start_suppressed,
|
start_suppressed,
|
||||||
|
true,
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
if let Some(hold_for_command) = hold_for_command {
|
if let Some(hold_for_command) = hold_for_command {
|
||||||
|
|
@ -3361,6 +3365,19 @@ pub(crate) fn screen_thread_main(
|
||||||
is_kitty_keyboard_protocol,
|
is_kitty_keyboard_protocol,
|
||||||
client_id,
|
client_id,
|
||||||
) => {
|
) => {
|
||||||
|
if let Some(plugin_id) = keybind_intercepts.get(&client_id) {
|
||||||
|
if let Some(key_with_modifier) = key_with_modifier {
|
||||||
|
let _ = screen
|
||||||
|
.bus
|
||||||
|
.senders
|
||||||
|
.send_to_plugin(PluginInstruction::Update(vec![(
|
||||||
|
Some(*plugin_id),
|
||||||
|
Some(client_id),
|
||||||
|
Event::InterceptedKeyPress(key_with_modifier),
|
||||||
|
)]));
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
}
|
||||||
let mut state_changed = false;
|
let mut state_changed = false;
|
||||||
active_tab_and_connected_client_id!(
|
active_tab_and_connected_client_id!(
|
||||||
screen,
|
screen,
|
||||||
|
|
@ -4322,6 +4339,7 @@ pub(crate) fn screen_thread_main(
|
||||||
skip_cache,
|
skip_cache,
|
||||||
cwd,
|
cwd,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
))?;
|
))?;
|
||||||
},
|
},
|
||||||
ScreenInstruction::NewFloatingPluginPane(
|
ScreenInstruction::NewFloatingPluginPane(
|
||||||
|
|
@ -4350,6 +4368,7 @@ pub(crate) fn screen_thread_main(
|
||||||
size,
|
size,
|
||||||
skip_cache,
|
skip_cache,
|
||||||
cwd,
|
cwd,
|
||||||
|
None,
|
||||||
floating_pane_coordinates,
|
floating_pane_coordinates,
|
||||||
))?;
|
))?;
|
||||||
},
|
},
|
||||||
|
|
@ -4385,6 +4404,7 @@ pub(crate) fn screen_thread_main(
|
||||||
skip_cache,
|
skip_cache,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
))?;
|
))?;
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -4419,6 +4439,8 @@ pub(crate) fn screen_thread_main(
|
||||||
pane_id_to_replace,
|
pane_id_to_replace,
|
||||||
cwd,
|
cwd,
|
||||||
start_suppressed,
|
start_suppressed,
|
||||||
|
floating_pane_coordinates,
|
||||||
|
should_focus_plugin,
|
||||||
client_id,
|
client_id,
|
||||||
) => {
|
) => {
|
||||||
if screen.active_tab_indices.is_empty() && tab_index.is_none() {
|
if screen.active_tab_indices.is_empty() && tab_index.is_none() {
|
||||||
|
|
@ -4432,6 +4454,8 @@ pub(crate) fn screen_thread_main(
|
||||||
pane_id_to_replace,
|
pane_id_to_replace,
|
||||||
cwd,
|
cwd,
|
||||||
start_suppressed,
|
start_suppressed,
|
||||||
|
floating_pane_coordinates,
|
||||||
|
should_focus_plugin,
|
||||||
client_id,
|
client_id,
|
||||||
));
|
));
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -4480,8 +4504,9 @@ pub(crate) fn screen_thread_main(
|
||||||
Some(pane_title),
|
Some(pane_title),
|
||||||
should_float,
|
should_float,
|
||||||
Some(run_plugin),
|
Some(run_plugin),
|
||||||
None,
|
floating_pane_coordinates,
|
||||||
start_suppressed,
|
start_suppressed,
|
||||||
|
should_focus_plugin.unwrap_or(true),
|
||||||
Some(client_id),
|
Some(client_id),
|
||||||
)
|
)
|
||||||
}, ?);
|
}, ?);
|
||||||
|
|
@ -4495,6 +4520,7 @@ pub(crate) fn screen_thread_main(
|
||||||
Some(run_plugin),
|
Some(run_plugin),
|
||||||
None,
|
None,
|
||||||
start_suppressed,
|
start_suppressed,
|
||||||
|
should_focus_plugin.unwrap_or(true),
|
||||||
None,
|
None,
|
||||||
)?;
|
)?;
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -4571,6 +4597,7 @@ pub(crate) fn screen_thread_main(
|
||||||
skip_cache,
|
skip_cache,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
))?;
|
))?;
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -4618,6 +4645,7 @@ pub(crate) fn screen_thread_main(
|
||||||
skip_cache,
|
skip_cache,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
))?;
|
))?;
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
@ -4654,6 +4682,7 @@ pub(crate) fn screen_thread_main(
|
||||||
skip_cache,
|
skip_cache,
|
||||||
cwd,
|
cwd,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
))?;
|
))?;
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -4691,6 +4720,7 @@ pub(crate) fn screen_thread_main(
|
||||||
skip_cache,
|
skip_cache,
|
||||||
cwd,
|
cwd,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
))?;
|
))?;
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -5271,6 +5301,12 @@ pub(crate) fn screen_thread_main(
|
||||||
}
|
}
|
||||||
let _ = screen.log_and_report_session_state();
|
let _ = screen.log_and_report_session_state();
|
||||||
},
|
},
|
||||||
|
ScreenInstruction::InterceptKeyPresses(plugin_id, client_id) => {
|
||||||
|
keybind_intercepts.insert(client_id, plugin_id);
|
||||||
|
},
|
||||||
|
ScreenInstruction::ClearKeyPressesIntercepts(client_id) => {
|
||||||
|
keybind_intercepts.remove(&client_id);
|
||||||
|
},
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
|
|
|
||||||
|
|
@ -22,6 +22,7 @@ use zellij_utils::position::Position;
|
||||||
use zellij_utils::position::{Column, Line};
|
use zellij_utils::position::{Column, Line};
|
||||||
|
|
||||||
use crate::background_jobs::BackgroundJob;
|
use crate::background_jobs::BackgroundJob;
|
||||||
|
use crate::pane_groups::PaneGroups;
|
||||||
use crate::pty_writer::PtyWriteInstruction;
|
use crate::pty_writer::PtyWriteInstruction;
|
||||||
use crate::screen::CopyOptions;
|
use crate::screen::CopyOptions;
|
||||||
use crate::ui::{loading_indication::LoadingIndication, pane_boundaries_frame::FrameParams};
|
use crate::ui::{loading_indication::LoadingIndication, pane_boundaries_frame::FrameParams};
|
||||||
|
|
@ -262,7 +263,7 @@ pub(crate) struct Tab {
|
||||||
styled_underlines: bool,
|
styled_underlines: bool,
|
||||||
explicitly_disable_kitty_keyboard_protocol: bool,
|
explicitly_disable_kitty_keyboard_protocol: bool,
|
||||||
mouse_hover_pane_id: HashMap<ClientId, PaneId>,
|
mouse_hover_pane_id: HashMap<ClientId, PaneId>,
|
||||||
current_pane_group: Rc<RefCell<HashMap<ClientId, Vec<PaneId>>>>,
|
current_pane_group: Rc<RefCell<PaneGroups>>,
|
||||||
advanced_mouse_actions: bool,
|
advanced_mouse_actions: bool,
|
||||||
currently_marking_pane_group: Rc<RefCell<HashMap<ClientId, bool>>>,
|
currently_marking_pane_group: Rc<RefCell<HashMap<ClientId, bool>>>,
|
||||||
}
|
}
|
||||||
|
|
@ -675,7 +676,7 @@ impl Tab {
|
||||||
styled_underlines: bool,
|
styled_underlines: bool,
|
||||||
explicitly_disable_kitty_keyboard_protocol: bool,
|
explicitly_disable_kitty_keyboard_protocol: bool,
|
||||||
default_editor: Option<PathBuf>,
|
default_editor: Option<PathBuf>,
|
||||||
current_pane_group: Rc<RefCell<HashMap<ClientId, Vec<PaneId>>>>,
|
current_pane_group: Rc<RefCell<PaneGroups>>,
|
||||||
currently_marking_pane_group: Rc<RefCell<HashMap<ClientId, bool>>>,
|
currently_marking_pane_group: Rc<RefCell<HashMap<ClientId, bool>>>,
|
||||||
advanced_mouse_actions: bool,
|
advanced_mouse_actions: bool,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
|
|
@ -1187,17 +1188,17 @@ impl Tab {
|
||||||
self.set_force_render();
|
self.set_force_render();
|
||||||
} else {
|
} else {
|
||||||
self.show_floating_panes();
|
self.show_floating_panes();
|
||||||
match self.floating_panes.last_floating_pane_id() {
|
match self.floating_panes.last_selectable_floating_pane_id() {
|
||||||
Some(first_floating_pane_id) => match client_id {
|
Some(last_selectable_floating_pane_id) => match client_id {
|
||||||
Some(client_id) => {
|
Some(client_id) => {
|
||||||
if !self.floating_panes.active_panes_contain(&client_id) {
|
if !self.floating_panes.active_panes_contain(&client_id) {
|
||||||
self.floating_panes
|
self.floating_panes
|
||||||
.focus_pane(first_floating_pane_id, client_id);
|
.focus_pane(last_selectable_floating_pane_id, client_id);
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
self.floating_panes
|
self.floating_panes
|
||||||
.focus_pane_for_all_clients(first_floating_pane_id);
|
.focus_pane_for_all_clients(last_selectable_floating_pane_id);
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
None => {
|
None => {
|
||||||
|
|
@ -1234,14 +1235,17 @@ impl Tab {
|
||||||
invoked_with: Option<Run>,
|
invoked_with: Option<Run>,
|
||||||
floating_pane_coordinates: Option<FloatingPaneCoordinates>,
|
floating_pane_coordinates: Option<FloatingPaneCoordinates>,
|
||||||
start_suppressed: bool,
|
start_suppressed: bool,
|
||||||
|
should_focus_pane: bool,
|
||||||
client_id: Option<ClientId>,
|
client_id: Option<ClientId>,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let err_context = || format!("failed to create new pane with id {pid:?}");
|
let err_context = || format!("failed to create new pane with id {pid:?}");
|
||||||
|
if should_focus_pane {
|
||||||
match should_float {
|
match should_float {
|
||||||
Some(true) => self.show_floating_panes(),
|
Some(true) => self.show_floating_panes(),
|
||||||
Some(false) => self.hide_floating_panes(),
|
Some(false) => self.hide_floating_panes(),
|
||||||
None => {},
|
None => {},
|
||||||
};
|
};
|
||||||
|
}
|
||||||
self.close_down_to_max_terminals()
|
self.close_down_to_max_terminals()
|
||||||
.with_context(err_context)?;
|
.with_context(err_context)?;
|
||||||
let mut new_pane = match pid {
|
let mut new_pane = match pid {
|
||||||
|
|
@ -1316,11 +1320,27 @@ impl Tab {
|
||||||
self.suppressed_panes
|
self.suppressed_panes
|
||||||
.insert(pid, (is_scrollback_editor, new_pane));
|
.insert(pid, (is_scrollback_editor, new_pane));
|
||||||
Ok(())
|
Ok(())
|
||||||
} else if self.floating_panes.panes_are_visible() {
|
} else if should_focus_pane {
|
||||||
|
if self.floating_panes.panes_are_visible() {
|
||||||
self.add_floating_pane(new_pane, pid, floating_pane_coordinates, true)
|
self.add_floating_pane(new_pane, pid, floating_pane_coordinates, true)
|
||||||
} else {
|
} else {
|
||||||
self.add_tiled_pane(new_pane, pid, client_id)
|
self.add_tiled_pane(new_pane, pid, client_id)
|
||||||
}
|
}
|
||||||
|
} else {
|
||||||
|
match should_float {
|
||||||
|
Some(true) => {
|
||||||
|
self.add_floating_pane(new_pane, pid, floating_pane_coordinates, false)
|
||||||
|
},
|
||||||
|
Some(false) => self.add_tiled_pane(new_pane, pid, client_id),
|
||||||
|
None => {
|
||||||
|
if self.floating_panes.panes_are_visible() {
|
||||||
|
self.add_floating_pane(new_pane, pid, floating_pane_coordinates, false)
|
||||||
|
} else {
|
||||||
|
self.add_tiled_pane(new_pane, pid, client_id)
|
||||||
|
}
|
||||||
|
},
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
pub fn replace_active_pane_with_editor_pane(
|
pub fn replace_active_pane_with_editor_pane(
|
||||||
&mut self,
|
&mut self,
|
||||||
|
|
@ -2277,7 +2297,7 @@ impl Tab {
|
||||||
);
|
);
|
||||||
|
|
||||||
let current_pane_group: HashMap<ClientId, Vec<PaneId>> =
|
let current_pane_group: HashMap<ClientId, Vec<PaneId>> =
|
||||||
{ self.current_pane_group.borrow().clone() };
|
{ self.current_pane_group.borrow().clone_inner() };
|
||||||
self.tiled_panes
|
self.tiled_panes
|
||||||
.render(
|
.render(
|
||||||
output,
|
output,
|
||||||
|
|
@ -2851,6 +2871,8 @@ impl Tab {
|
||||||
// is opened
|
// is opened
|
||||||
self.tiled_panes.move_clients_out_of_pane(id);
|
self.tiled_panes.move_clients_out_of_pane(id);
|
||||||
}
|
}
|
||||||
|
} else if let Some(pane) = self.floating_panes.get_pane_mut(id) {
|
||||||
|
pane.set_selectable(selectable);
|
||||||
}
|
}
|
||||||
// we do this here because if there is a non-selectable pane on the edge, we consider it
|
// we do this here because if there is a non-selectable pane on the edge, we consider it
|
||||||
// outside the viewport (a ui-pane, eg. the status-bar and tab-bar) and need to adjust for it
|
// outside the viewport (a ui-pane, eg. the status-bar and tab-bar) and need to adjust for it
|
||||||
|
|
@ -2877,7 +2899,7 @@ impl Tab {
|
||||||
if self.floating_panes.panes_contain(&id) {
|
if self.floating_panes.panes_contain(&id) {
|
||||||
let _closed_pane = self.floating_panes.remove_pane(id);
|
let _closed_pane = self.floating_panes.remove_pane(id);
|
||||||
self.floating_panes.move_clients_out_of_pane(id);
|
self.floating_panes.move_clients_out_of_pane(id);
|
||||||
if !self.floating_panes.has_panes() {
|
if !self.floating_panes.has_selectable_panes() {
|
||||||
self.swap_layouts.reset_floating_damage();
|
self.swap_layouts.reset_floating_damage();
|
||||||
self.hide_floating_panes();
|
self.hide_floating_panes();
|
||||||
}
|
}
|
||||||
|
|
@ -3663,10 +3685,9 @@ impl Tab {
|
||||||
let err_context =
|
let err_context =
|
||||||
|| format!("failed to handle mouse event {event:?} for client {client_id}");
|
|| format!("failed to handle mouse event {event:?} for client {client_id}");
|
||||||
if !self.floating_panes.panes_are_visible() {
|
if !self.floating_panes.panes_are_visible() {
|
||||||
let search_selectable = false;
|
|
||||||
if let Ok(Some(pane_id)) = self
|
if let Ok(Some(pane_id)) = self
|
||||||
.floating_panes
|
.floating_panes
|
||||||
.get_pinned_pane_id_at(&event.position, search_selectable)
|
.get_pinned_pane_id_at(&event.position, true)
|
||||||
{
|
{
|
||||||
// here, the floating panes are not visible, but there is a pinned pane (always
|
// here, the floating panes are not visible, but there is a pinned pane (always
|
||||||
// visible) that has been clicked on - so we make the entire surface visible and
|
// visible) that has been clicked on - so we make the entire surface visible and
|
||||||
|
|
@ -3674,6 +3695,15 @@ impl Tab {
|
||||||
self.show_floating_panes();
|
self.show_floating_panes();
|
||||||
self.floating_panes.focus_pane(pane_id, client_id);
|
self.floating_panes.focus_pane(pane_id, client_id);
|
||||||
return Ok(MouseEffect::state_changed());
|
return Ok(MouseEffect::state_changed());
|
||||||
|
} else if let Ok(Some(_pane_id)) = self
|
||||||
|
.floating_panes
|
||||||
|
.get_pinned_pane_id_at(&event.position, false)
|
||||||
|
{
|
||||||
|
// here, the floating panes are not visible, but there is a pinned pane (always
|
||||||
|
// visible) that has been clicked on - this pane however is not selectable
|
||||||
|
// (we know this because we passed "false" to get_pinned_pane_id_at)
|
||||||
|
// so we don't do anything
|
||||||
|
return Ok(MouseEffect::default());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
let active_pane_id_before_click = self
|
let active_pane_id_before_click = self
|
||||||
|
|
@ -3924,8 +3954,13 @@ impl Tab {
|
||||||
self.mouse_hover_pane_id.remove(&client_id);
|
self.mouse_hover_pane_id.remove(&client_id);
|
||||||
} else {
|
} else {
|
||||||
let pane_id = pane.pid();
|
let pane_id = pane.pid();
|
||||||
if self.advanced_mouse_actions {
|
// if the pane is not selectable, we don't want to create a hover effect over it
|
||||||
|
// we do however want to remove the hover effect from other panes
|
||||||
|
let pane_is_selectable = pane.selectable();
|
||||||
|
if self.advanced_mouse_actions && pane_is_selectable {
|
||||||
self.mouse_hover_pane_id.insert(client_id, pane_id);
|
self.mouse_hover_pane_id.insert(client_id, pane_id);
|
||||||
|
} else if self.advanced_mouse_actions {
|
||||||
|
self.mouse_hover_pane_id.remove(&client_id);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -4467,7 +4502,7 @@ impl Tab {
|
||||||
}
|
}
|
||||||
pub fn pane_infos(&self) -> Vec<PaneInfo> {
|
pub fn pane_infos(&self) -> Vec<PaneInfo> {
|
||||||
let mut pane_info = vec![];
|
let mut pane_info = vec![];
|
||||||
let current_pane_group = { self.current_pane_group.borrow().clone() };
|
let current_pane_group = { self.current_pane_group.borrow().clone_inner() };
|
||||||
let mut tiled_pane_info = self.tiled_panes.pane_info(¤t_pane_group);
|
let mut tiled_pane_info = self.tiled_panes.pane_info(¤t_pane_group);
|
||||||
let mut floating_pane_info = self.floating_panes.pane_info(¤t_pane_group);
|
let mut floating_pane_info = self.floating_panes.pane_info(¤t_pane_group);
|
||||||
pane_info.append(&mut tiled_pane_info);
|
pane_info.append(&mut tiled_pane_info);
|
||||||
|
|
|
||||||
File diff suppressed because it is too large
Load diff
|
|
@ -1,4 +1,5 @@
|
||||||
use super::Tab;
|
use super::Tab;
|
||||||
|
use crate::pane_groups::PaneGroups;
|
||||||
use crate::panes::sixel::SixelImageStore;
|
use crate::panes::sixel::SixelImageStore;
|
||||||
use crate::screen::CopyOptions;
|
use crate::screen::CopyOptions;
|
||||||
use crate::{
|
use crate::{
|
||||||
|
|
@ -165,7 +166,7 @@ fn create_new_tab(size: Size, stacked_resize: bool) -> Tab {
|
||||||
let copy_options = CopyOptions::default();
|
let copy_options = CopyOptions::default();
|
||||||
let sixel_image_store = Rc::new(RefCell::new(SixelImageStore::default()));
|
let sixel_image_store = Rc::new(RefCell::new(SixelImageStore::default()));
|
||||||
let terminal_emulator_color_codes = Rc::new(RefCell::new(HashMap::new()));
|
let terminal_emulator_color_codes = Rc::new(RefCell::new(HashMap::new()));
|
||||||
let current_pane_group = Rc::new(RefCell::new(HashMap::new()));
|
let current_pane_group = Rc::new(RefCell::new(PaneGroups::new(ThreadSenders::default())));
|
||||||
let currently_marking_pane_group = Rc::new(RefCell::new(HashMap::new()));
|
let currently_marking_pane_group = Rc::new(RefCell::new(HashMap::new()));
|
||||||
let debug = false;
|
let debug = false;
|
||||||
let arrow_fonts = true;
|
let arrow_fonts = true;
|
||||||
|
|
@ -238,7 +239,7 @@ fn create_new_tab_with_layout(size: Size, layout: TiledPaneLayout) -> Tab {
|
||||||
let copy_options = CopyOptions::default();
|
let copy_options = CopyOptions::default();
|
||||||
let sixel_image_store = Rc::new(RefCell::new(SixelImageStore::default()));
|
let sixel_image_store = Rc::new(RefCell::new(SixelImageStore::default()));
|
||||||
let terminal_emulator_color_codes = Rc::new(RefCell::new(HashMap::new()));
|
let terminal_emulator_color_codes = Rc::new(RefCell::new(HashMap::new()));
|
||||||
let current_pane_group = Rc::new(RefCell::new(HashMap::new()));
|
let current_pane_group = Rc::new(RefCell::new(PaneGroups::new(ThreadSenders::default())));
|
||||||
let currently_marking_pane_group = Rc::new(RefCell::new(HashMap::new()));
|
let currently_marking_pane_group = Rc::new(RefCell::new(HashMap::new()));
|
||||||
let debug = false;
|
let debug = false;
|
||||||
let arrow_fonts = true;
|
let arrow_fonts = true;
|
||||||
|
|
@ -317,7 +318,7 @@ fn create_new_tab_with_cell_size(
|
||||||
let sixel_image_store = Rc::new(RefCell::new(SixelImageStore::default()));
|
let sixel_image_store = Rc::new(RefCell::new(SixelImageStore::default()));
|
||||||
let terminal_emulator_color_codes = Rc::new(RefCell::new(HashMap::new()));
|
let terminal_emulator_color_codes = Rc::new(RefCell::new(HashMap::new()));
|
||||||
let stacked_resize = Rc::new(RefCell::new(true));
|
let stacked_resize = Rc::new(RefCell::new(true));
|
||||||
let current_pane_group = Rc::new(RefCell::new(HashMap::new()));
|
let current_pane_group = Rc::new(RefCell::new(PaneGroups::new(ThreadSenders::default())));
|
||||||
let currently_marking_pane_group = Rc::new(RefCell::new(HashMap::new()));
|
let currently_marking_pane_group = Rc::new(RefCell::new(HashMap::new()));
|
||||||
let debug = false;
|
let debug = false;
|
||||||
let arrow_fonts = true;
|
let arrow_fonts = true;
|
||||||
|
|
@ -602,7 +603,7 @@ fn split_largest_pane() {
|
||||||
let mut tab = create_new_tab(size, stacked_resize);
|
let mut tab = create_new_tab(size, stacked_resize);
|
||||||
for i in 2..5 {
|
for i in 2..5 {
|
||||||
let new_pane_id = PaneId::Terminal(i);
|
let new_pane_id = PaneId::Terminal(i);
|
||||||
tab.new_pane(new_pane_id, None, None, None, None, false, Some(1))
|
tab.new_pane(new_pane_id, None, None, None, None, false, true, Some(1))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
assert_eq!(tab.tiled_panes.panes.len(), 4, "The tab has four panes");
|
assert_eq!(tab.tiled_panes.panes.len(), 4, "The tab has four panes");
|
||||||
|
|
@ -811,7 +812,16 @@ pub fn cannot_split_largest_pane_when_there_is_no_room() {
|
||||||
let size = Size { cols: 8, rows: 4 };
|
let size = Size { cols: 8, rows: 4 };
|
||||||
let stacked_resize = true;
|
let stacked_resize = true;
|
||||||
let mut tab = create_new_tab(size, stacked_resize);
|
let mut tab = create_new_tab(size, stacked_resize);
|
||||||
tab.new_pane(PaneId::Terminal(2), None, None, None, None, false, Some(1))
|
tab.new_pane(
|
||||||
|
PaneId::Terminal(2),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Some(1),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
tab.tiled_panes.panes.len(),
|
tab.tiled_panes.panes.len(),
|
||||||
|
|
@ -856,7 +866,7 @@ pub fn toggle_focused_pane_fullscreen() {
|
||||||
let mut tab = create_new_tab(size, stacked_resize);
|
let mut tab = create_new_tab(size, stacked_resize);
|
||||||
for i in 2..5 {
|
for i in 2..5 {
|
||||||
let new_pane_id = PaneId::Terminal(i);
|
let new_pane_id = PaneId::Terminal(i);
|
||||||
tab.new_pane(new_pane_id, None, None, None, None, false, Some(1))
|
tab.new_pane(new_pane_id, None, None, None, None, false, true, Some(1))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
tab.toggle_active_pane_fullscreen(1);
|
tab.toggle_active_pane_fullscreen(1);
|
||||||
|
|
@ -932,7 +942,7 @@ pub fn toggle_focused_pane_fullscreen_with_stacked_resizes() {
|
||||||
let mut tab = create_new_tab(size, stacked_resize);
|
let mut tab = create_new_tab(size, stacked_resize);
|
||||||
for i in 2..5 {
|
for i in 2..5 {
|
||||||
let new_pane_id = PaneId::Terminal(i);
|
let new_pane_id = PaneId::Terminal(i);
|
||||||
tab.new_pane(new_pane_id, None, None, None, None, false, Some(1))
|
tab.new_pane(new_pane_id, None, None, None, None, false, true, Some(1))
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
tab.toggle_active_pane_fullscreen(1);
|
tab.toggle_active_pane_fullscreen(1);
|
||||||
|
|
@ -1008,16 +1018,52 @@ fn switch_to_next_pane_fullscreen() {
|
||||||
let mut active_tab = create_new_tab(size, stacked_resize);
|
let mut active_tab = create_new_tab(size, stacked_resize);
|
||||||
|
|
||||||
active_tab
|
active_tab
|
||||||
.new_pane(PaneId::Terminal(1), None, None, None, None, false, Some(1))
|
.new_pane(
|
||||||
|
PaneId::Terminal(1),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Some(1),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
active_tab
|
active_tab
|
||||||
.new_pane(PaneId::Terminal(2), None, None, None, None, false, Some(1))
|
.new_pane(
|
||||||
|
PaneId::Terminal(2),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Some(1),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
active_tab
|
active_tab
|
||||||
.new_pane(PaneId::Terminal(3), None, None, None, None, false, Some(1))
|
.new_pane(
|
||||||
|
PaneId::Terminal(3),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Some(1),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
active_tab
|
active_tab
|
||||||
.new_pane(PaneId::Terminal(4), None, None, None, None, false, Some(1))
|
.new_pane(
|
||||||
|
PaneId::Terminal(4),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Some(1),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
active_tab.toggle_active_pane_fullscreen(1);
|
active_tab.toggle_active_pane_fullscreen(1);
|
||||||
|
|
||||||
|
|
@ -1049,16 +1095,52 @@ fn switch_to_prev_pane_fullscreen() {
|
||||||
//testing four consecutive switches in fullscreen mode
|
//testing four consecutive switches in fullscreen mode
|
||||||
|
|
||||||
active_tab
|
active_tab
|
||||||
.new_pane(PaneId::Terminal(1), None, None, None, None, false, Some(1))
|
.new_pane(
|
||||||
|
PaneId::Terminal(1),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Some(1),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
active_tab
|
active_tab
|
||||||
.new_pane(PaneId::Terminal(2), None, None, None, None, false, Some(1))
|
.new_pane(
|
||||||
|
PaneId::Terminal(2),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Some(1),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
active_tab
|
active_tab
|
||||||
.new_pane(PaneId::Terminal(3), None, None, None, None, false, Some(1))
|
.new_pane(
|
||||||
|
PaneId::Terminal(3),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Some(1),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
active_tab
|
active_tab
|
||||||
.new_pane(PaneId::Terminal(4), None, None, None, None, false, Some(1))
|
.new_pane(
|
||||||
|
PaneId::Terminal(4),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Some(1),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
active_tab.toggle_active_pane_fullscreen(1);
|
active_tab.toggle_active_pane_fullscreen(1);
|
||||||
// order is now 1 2 3 4
|
// order is now 1 2 3 4
|
||||||
|
|
@ -14650,7 +14732,16 @@ fn correctly_resize_frameless_panes_on_pane_close() {
|
||||||
let content_size = (pane.get_content_columns(), pane.get_content_rows());
|
let content_size = (pane.get_content_columns(), pane.get_content_rows());
|
||||||
assert_eq!(content_size, (cols, rows));
|
assert_eq!(content_size, (cols, rows));
|
||||||
|
|
||||||
tab.new_pane(PaneId::Terminal(2), None, None, None, None, false, Some(1))
|
tab.new_pane(
|
||||||
|
PaneId::Terminal(2),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Some(1),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
tab.close_pane(PaneId::Terminal(2), true);
|
tab.close_pane(PaneId::Terminal(2), true);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -64,6 +64,7 @@ pub struct FrameParams {
|
||||||
pub pane_is_floating: bool,
|
pub pane_is_floating: bool,
|
||||||
pub content_offset: Offset,
|
pub content_offset: Offset,
|
||||||
pub mouse_is_hovering_over_pane: bool,
|
pub mouse_is_hovering_over_pane: bool,
|
||||||
|
pub pane_is_selectable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Default, PartialEq)]
|
#[derive(Default, PartialEq)]
|
||||||
|
|
@ -86,6 +87,7 @@ pub struct PaneFrame {
|
||||||
is_floating: bool,
|
is_floating: bool,
|
||||||
content_offset: Offset,
|
content_offset: Offset,
|
||||||
mouse_is_hovering_over_pane: bool,
|
mouse_is_hovering_over_pane: bool,
|
||||||
|
is_selectable: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PaneFrame {
|
impl PaneFrame {
|
||||||
|
|
@ -114,6 +116,7 @@ impl PaneFrame {
|
||||||
is_floating: frame_params.pane_is_floating,
|
is_floating: frame_params.pane_is_floating,
|
||||||
content_offset: frame_params.content_offset,
|
content_offset: frame_params.content_offset,
|
||||||
mouse_is_hovering_over_pane: frame_params.mouse_is_hovering_over_pane,
|
mouse_is_hovering_over_pane: frame_params.mouse_is_hovering_over_pane,
|
||||||
|
is_selectable: frame_params.pane_is_selectable,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
pub fn is_pinned(mut self, is_pinned: bool) -> Self {
|
pub fn is_pinned(mut self, is_pinned: bool) -> Self {
|
||||||
|
|
@ -167,7 +170,7 @@ impl PaneFrame {
|
||||||
// string and length because of color
|
// string and length because of color
|
||||||
let has_scroll = self.scroll_position.0 > 0 || self.scroll_position.1 > 0;
|
let has_scroll = self.scroll_position.0 > 0 || self.scroll_position.1 > 0;
|
||||||
if has_scroll {
|
if has_scroll {
|
||||||
let pin_indication = if self.is_floating {
|
let pin_indication = if self.is_floating && self.is_selectable {
|
||||||
self.render_pinned_indication(max_length)
|
self.render_pinned_indication(max_length)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
@ -192,7 +195,7 @@ impl PaneFrame {
|
||||||
(None, Some(scroll_indication)) => Some(scroll_indication),
|
(None, Some(scroll_indication)) => Some(scroll_indication),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
} else if self.is_floating {
|
} else if self.is_floating && self.is_selectable {
|
||||||
self.render_pinned_indication(max_length)
|
self.render_pinned_indication(max_length)
|
||||||
} else {
|
} else {
|
||||||
None
|
None
|
||||||
|
|
|
||||||
|
|
@ -207,6 +207,7 @@ impl<'a> PaneContentsAndUi<'a> {
|
||||||
client_mode: InputMode,
|
client_mode: InputMode,
|
||||||
session_is_mirrored: bool,
|
session_is_mirrored: bool,
|
||||||
pane_is_floating: bool,
|
pane_is_floating: bool,
|
||||||
|
pane_is_selectable: bool,
|
||||||
) -> Result<()> {
|
) -> Result<()> {
|
||||||
let err_context = || format!("failed to render pane frame for client {client_id}");
|
let err_context = || format!("failed to render pane frame for client {client_id}");
|
||||||
|
|
||||||
|
|
@ -243,6 +244,7 @@ impl<'a> PaneContentsAndUi<'a> {
|
||||||
mouse_is_hovering_over_pane: self
|
mouse_is_hovering_over_pane: self
|
||||||
.mouse_is_hovering_over_pane_for_clients
|
.mouse_is_hovering_over_pane_for_clients
|
||||||
.contains(&client_id),
|
.contains(&client_id),
|
||||||
|
pane_is_selectable,
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
FrameParams {
|
FrameParams {
|
||||||
|
|
@ -260,6 +262,7 @@ impl<'a> PaneContentsAndUi<'a> {
|
||||||
mouse_is_hovering_over_pane: self
|
mouse_is_hovering_over_pane: self
|
||||||
.mouse_is_hovering_over_pane_for_clients
|
.mouse_is_hovering_over_pane_for_clients
|
||||||
.contains(&client_id),
|
.contains(&client_id),
|
||||||
|
pane_is_selectable,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1194,7 +1194,16 @@ fn switch_to_tab_with_fullscreen() {
|
||||||
{
|
{
|
||||||
let active_tab = screen.get_active_tab_mut(1).unwrap();
|
let active_tab = screen.get_active_tab_mut(1).unwrap();
|
||||||
active_tab
|
active_tab
|
||||||
.new_pane(PaneId::Terminal(2), None, None, None, None, false, Some(1))
|
.new_pane(
|
||||||
|
PaneId::Terminal(2),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Some(1),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
active_tab.toggle_active_pane_fullscreen(1);
|
active_tab.toggle_active_pane_fullscreen(1);
|
||||||
}
|
}
|
||||||
|
|
@ -1309,7 +1318,16 @@ fn attach_after_first_tab_closed() {
|
||||||
{
|
{
|
||||||
let active_tab = screen.get_active_tab_mut(1).unwrap();
|
let active_tab = screen.get_active_tab_mut(1).unwrap();
|
||||||
active_tab
|
active_tab
|
||||||
.new_pane(PaneId::Terminal(2), None, None, None, None, false, Some(1))
|
.new_pane(
|
||||||
|
PaneId::Terminal(2),
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
None,
|
||||||
|
false,
|
||||||
|
true,
|
||||||
|
Some(1),
|
||||||
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
active_tab.toggle_active_pane_fullscreen(1);
|
active_tab.toggle_active_pane_fullscreen(1);
|
||||||
}
|
}
|
||||||
|
|
@ -1345,6 +1363,7 @@ fn open_new_floating_pane_with_custom_coordinates() {
|
||||||
pinned: None,
|
pinned: None,
|
||||||
}),
|
}),
|
||||||
false,
|
false,
|
||||||
|
true,
|
||||||
Some(1),
|
Some(1),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -1380,6 +1399,7 @@ fn open_new_floating_pane_with_custom_coordinates_exceeding_viewport() {
|
||||||
pinned: None,
|
pinned: None,
|
||||||
}),
|
}),
|
||||||
false,
|
false,
|
||||||
|
true,
|
||||||
Some(1),
|
Some(1),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -1478,7 +1498,11 @@ fn group_panes_with_mouse() {
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
screen.current_pane_group.borrow().get(&client_id),
|
screen
|
||||||
|
.current_pane_group
|
||||||
|
.borrow()
|
||||||
|
.clone_inner()
|
||||||
|
.get(&client_id),
|
||||||
Some(&vec![PaneId::Terminal(2)]),
|
Some(&vec![PaneId::Terminal(2)]),
|
||||||
"Pane Id added to client's pane group"
|
"Pane Id added to client's pane group"
|
||||||
);
|
);
|
||||||
|
|
@ -1489,7 +1513,11 @@ fn group_panes_with_mouse() {
|
||||||
);
|
);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
screen.current_pane_group.borrow().get(&client_id),
|
screen
|
||||||
|
.current_pane_group
|
||||||
|
.borrow()
|
||||||
|
.clone_inner()
|
||||||
|
.get(&client_id),
|
||||||
Some(&vec![]),
|
Some(&vec![]),
|
||||||
"Pane Id removed from client's pane group"
|
"Pane Id removed from client's pane group"
|
||||||
);
|
);
|
||||||
|
|
@ -1509,7 +1537,11 @@ fn group_panes_with_keyboard() {
|
||||||
let _ = screen.toggle_pane_in_group(client_id);
|
let _ = screen.toggle_pane_in_group(client_id);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
screen.current_pane_group.borrow().get(&client_id),
|
screen
|
||||||
|
.current_pane_group
|
||||||
|
.borrow()
|
||||||
|
.clone_inner()
|
||||||
|
.get(&client_id),
|
||||||
Some(&vec![PaneId::Terminal(2)]),
|
Some(&vec![PaneId::Terminal(2)]),
|
||||||
"Pane Id added to client's pane group"
|
"Pane Id added to client's pane group"
|
||||||
);
|
);
|
||||||
|
|
@ -1517,7 +1549,11 @@ fn group_panes_with_keyboard() {
|
||||||
let _ = screen.toggle_pane_in_group(client_id);
|
let _ = screen.toggle_pane_in_group(client_id);
|
||||||
|
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
screen.current_pane_group.borrow().get(&client_id),
|
screen
|
||||||
|
.current_pane_group
|
||||||
|
.borrow()
|
||||||
|
.clone_inner()
|
||||||
|
.get(&client_id),
|
||||||
Some(&vec![]),
|
Some(&vec![]),
|
||||||
"Pane Id removed from client's pane group"
|
"Pane Id removed from client's pane group"
|
||||||
);
|
);
|
||||||
|
|
@ -1546,6 +1582,7 @@ fn group_panes_following_focus() {
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
true,
|
||||||
Some(client_id),
|
Some(client_id),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -1560,7 +1597,11 @@ fn group_panes_following_focus() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
screen.add_active_pane_to_group_if_marking(&client_id);
|
screen.add_active_pane_to_group_if_marking(&client_id);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
screen.current_pane_group.borrow().get(&client_id),
|
screen
|
||||||
|
.current_pane_group
|
||||||
|
.borrow()
|
||||||
|
.clone_inner()
|
||||||
|
.get(&client_id),
|
||||||
Some(&vec![PaneId::Terminal(4), PaneId::Terminal(3)]),
|
Some(&vec![PaneId::Terminal(4), PaneId::Terminal(3)]),
|
||||||
"Pane Id of focused pane and newly focused pane above added to pane group"
|
"Pane Id of focused pane and newly focused pane above added to pane group"
|
||||||
);
|
);
|
||||||
|
|
@ -1573,7 +1614,7 @@ fn group_panes_following_focus() {
|
||||||
.move_focus_up(client_id)
|
.move_focus_up(client_id)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
let _ = screen.add_active_pane_to_group_if_marking(&client_id);
|
let _ = screen.add_active_pane_to_group_if_marking(&client_id);
|
||||||
assert_eq!(screen.current_pane_group.borrow().get(&client_id), Some(&vec![PaneId::Terminal(4), PaneId::Terminal(3)]), "Pane Id of newly focused pane not added to group after the group marking was toggled off");
|
assert_eq!(screen.current_pane_group.borrow().clone_inner().get(&client_id), Some(&vec![PaneId::Terminal(4), PaneId::Terminal(3)]), "Pane Id of newly focused pane not added to group after the group marking was toggled off");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -1600,6 +1641,7 @@ fn break_group_with_mouse() {
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
false,
|
false,
|
||||||
|
true,
|
||||||
Some(client_id),
|
Some(client_id),
|
||||||
)
|
)
|
||||||
.unwrap();
|
.unwrap();
|
||||||
|
|
@ -1620,7 +1662,11 @@ fn break_group_with_mouse() {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
screen.add_active_pane_to_group_if_marking(&client_id);
|
screen.add_active_pane_to_group_if_marking(&client_id);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
screen.current_pane_group.borrow().get(&client_id),
|
screen
|
||||||
|
.current_pane_group
|
||||||
|
.borrow()
|
||||||
|
.clone_inner()
|
||||||
|
.get(&client_id),
|
||||||
Some(&vec![
|
Some(&vec![
|
||||||
PaneId::Terminal(4),
|
PaneId::Terminal(4),
|
||||||
PaneId::Terminal(3),
|
PaneId::Terminal(3),
|
||||||
|
|
@ -1635,7 +1681,11 @@ fn break_group_with_mouse() {
|
||||||
client_id,
|
client_id,
|
||||||
);
|
);
|
||||||
assert_eq!(
|
assert_eq!(
|
||||||
screen.current_pane_group.borrow().get(&client_id),
|
screen
|
||||||
|
.current_pane_group
|
||||||
|
.borrow()
|
||||||
|
.clone_inner()
|
||||||
|
.get(&client_id),
|
||||||
Some(&vec![]),
|
Some(&vec![]),
|
||||||
"Group cleared by mouse event"
|
"Group cleared by mouse event"
|
||||||
);
|
);
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
---
|
---
|
||||||
source: zellij-server/src/./unit/screen_tests.rs
|
source: zellij-server/src/./unit/screen_tests.rs
|
||||||
assertion_line: 2983
|
|
||||||
expression: "format!(\"{:#?}\", pty_fill_plugin_cwd_instruction)"
|
expression: "format!(\"{:#?}\", pty_fill_plugin_cwd_instruction)"
|
||||||
---
|
---
|
||||||
Some(
|
Some(
|
||||||
|
|
@ -32,5 +31,6 @@ Some(
|
||||||
false,
|
false,
|
||||||
None,
|
None,
|
||||||
None,
|
None,
|
||||||
|
None,
|
||||||
),
|
),
|
||||||
)
|
)
|
||||||
|
|
|
||||||
|
|
@ -1313,6 +1313,20 @@ pub fn embed_multiple_panes(pane_ids: Vec<PaneId>) {
|
||||||
unsafe { host_run_plugin_command() };
|
unsafe { host_run_plugin_command() };
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn intercept_key_presses() {
|
||||||
|
let plugin_command = PluginCommand::InterceptKeyPresses;
|
||||||
|
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||||
|
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||||
|
unsafe { host_run_plugin_command() };
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn clear_key_presses_intercepts() {
|
||||||
|
let plugin_command = PluginCommand::ClearKeyPressesIntercepts;
|
||||||
|
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||||
|
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||||
|
unsafe { host_run_plugin_command() };
|
||||||
|
}
|
||||||
|
|
||||||
// Utility Functions
|
// Utility Functions
|
||||||
|
|
||||||
#[allow(unused)]
|
#[allow(unused)]
|
||||||
|
|
|
||||||
|
|
@ -54,6 +54,44 @@ impl Text {
|
||||||
.map(|i| i.append(&mut indices.into_iter().collect()));
|
.map(|i| i.append(&mut indices.into_iter().collect()));
|
||||||
self
|
self
|
||||||
}
|
}
|
||||||
|
pub fn color_substring<S: AsRef<str>>(mut self, index_level: usize, substr: S) -> Self {
|
||||||
|
let substr = substr.as_ref();
|
||||||
|
let mut start = 0;
|
||||||
|
|
||||||
|
while let Some(pos) = self.text[start..].find(substr) {
|
||||||
|
let abs_pos = start + pos;
|
||||||
|
self = self.color_range(index_level, abs_pos..abs_pos + substr.len());
|
||||||
|
start = abs_pos + substr.len();
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn color_all(self, index_level: usize) -> Self {
|
||||||
|
self.color_range(index_level, ..)
|
||||||
|
}
|
||||||
|
|
||||||
|
pub fn color_nth_substring<S: AsRef<str>>(
|
||||||
|
self,
|
||||||
|
index_level: usize,
|
||||||
|
substr: S,
|
||||||
|
occurrence_index: usize,
|
||||||
|
) -> Self {
|
||||||
|
let substr = substr.as_ref();
|
||||||
|
let mut start = 0;
|
||||||
|
let mut count = 0;
|
||||||
|
|
||||||
|
while let Some(pos) = self.text[start..].find(substr) {
|
||||||
|
if count == occurrence_index {
|
||||||
|
let abs_pos = start + pos;
|
||||||
|
return self.color_range(index_level, abs_pos..abs_pos + substr.len());
|
||||||
|
}
|
||||||
|
count += 1;
|
||||||
|
start = start + pos + substr.len();
|
||||||
|
}
|
||||||
|
|
||||||
|
self
|
||||||
|
}
|
||||||
fn pad_indices(&mut self, index_level: usize) {
|
fn pad_indices(&mut self, index_level: usize) {
|
||||||
if self.indices.get(index_level).is_none() {
|
if self.indices.get(index_level).is_none() {
|
||||||
for _ in self.indices.len()..=index_level {
|
for _ in self.indices.len()..=index_level {
|
||||||
|
|
|
||||||
|
|
@ -181,12 +181,6 @@ keybinds {
|
||||||
bind "Alt -" { Resize "Decrease"; }
|
bind "Alt -" { Resize "Decrease"; }
|
||||||
bind "Alt [" { PreviousSwapLayout; }
|
bind "Alt [" { PreviousSwapLayout; }
|
||||||
bind "Alt ]" { NextSwapLayout; }
|
bind "Alt ]" { NextSwapLayout; }
|
||||||
bind "Alt m" {
|
|
||||||
LaunchOrFocusPlugin "zellij:multiple-select" {
|
|
||||||
floating true
|
|
||||||
move_to_focused_tab true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bind "Alt p" { TogglePaneInGroup; }
|
bind "Alt p" { TogglePaneInGroup; }
|
||||||
bind "Alt Shift p" { ToggleGroupMarking; }
|
bind "Alt Shift p" { ToggleGroupMarking; }
|
||||||
}
|
}
|
||||||
|
|
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
|
@ -9,7 +9,7 @@ pub struct EventNameList {
|
||||||
pub struct Event {
|
pub struct Event {
|
||||||
#[prost(enumeration="EventType", tag="1")]
|
#[prost(enumeration="EventType", tag="1")]
|
||||||
pub name: i32,
|
pub name: i32,
|
||||||
#[prost(oneof="event::Payload", tags="2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26")]
|
#[prost(oneof="event::Payload", tags="2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15, 16, 17, 18, 19, 20, 21, 22, 23, 24, 25, 26, 27")]
|
||||||
pub payload: ::core::option::Option<event::Payload>,
|
pub payload: ::core::option::Option<event::Payload>,
|
||||||
}
|
}
|
||||||
/// Nested message and enum types in `Event`.
|
/// Nested message and enum types in `Event`.
|
||||||
|
|
@ -67,6 +67,8 @@ pub mod event {
|
||||||
FailedToChangeHostFolderPayload(super::FailedToChangeHostFolderPayload),
|
FailedToChangeHostFolderPayload(super::FailedToChangeHostFolderPayload),
|
||||||
#[prost(message, tag="26")]
|
#[prost(message, tag="26")]
|
||||||
PastedTextPayload(super::PastedTextPayload),
|
PastedTextPayload(super::PastedTextPayload),
|
||||||
|
#[prost(message, tag="27")]
|
||||||
|
InterceptedKeyPayload(super::super::key::Key),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||||
|
|
@ -530,6 +532,7 @@ pub enum EventType {
|
||||||
PastedText = 29,
|
PastedText = 29,
|
||||||
ConfigWasWrittenToDisk = 30,
|
ConfigWasWrittenToDisk = 30,
|
||||||
BeforeClose = 31,
|
BeforeClose = 31,
|
||||||
|
InterceptedKeyPress = 32,
|
||||||
}
|
}
|
||||||
impl EventType {
|
impl EventType {
|
||||||
/// String value of the enum field names used in the ProtoBuf definition.
|
/// String value of the enum field names used in the ProtoBuf definition.
|
||||||
|
|
@ -570,6 +573,7 @@ impl EventType {
|
||||||
EventType::PastedText => "PastedText",
|
EventType::PastedText => "PastedText",
|
||||||
EventType::ConfigWasWrittenToDisk => "ConfigWasWrittenToDisk",
|
EventType::ConfigWasWrittenToDisk => "ConfigWasWrittenToDisk",
|
||||||
EventType::BeforeClose => "BeforeClose",
|
EventType::BeforeClose => "BeforeClose",
|
||||||
|
EventType::InterceptedKeyPress => "InterceptedKeyPress",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||||
|
|
@ -607,6 +611,7 @@ impl EventType {
|
||||||
"PastedText" => Some(Self::PastedText),
|
"PastedText" => Some(Self::PastedText),
|
||||||
"ConfigWasWrittenToDisk" => Some(Self::ConfigWasWrittenToDisk),
|
"ConfigWasWrittenToDisk" => Some(Self::ConfigWasWrittenToDisk),
|
||||||
"BeforeClose" => Some(Self::BeforeClose),
|
"BeforeClose" => Some(Self::BeforeClose),
|
||||||
|
"InterceptedKeyPress" => Some(Self::InterceptedKeyPress),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -919,6 +919,8 @@ pub enum CommandName {
|
||||||
CloseMultiplePanes = 129,
|
CloseMultiplePanes = 129,
|
||||||
FloatMultiplePanes = 130,
|
FloatMultiplePanes = 130,
|
||||||
EmbedMultiplePanes = 131,
|
EmbedMultiplePanes = 131,
|
||||||
|
InterceptKeyPresses = 132,
|
||||||
|
ClearKeyPressesIntercepts = 133,
|
||||||
}
|
}
|
||||||
impl CommandName {
|
impl CommandName {
|
||||||
/// String value of the enum field names used in the ProtoBuf definition.
|
/// String value of the enum field names used in the ProtoBuf definition.
|
||||||
|
|
@ -1059,6 +1061,8 @@ impl CommandName {
|
||||||
CommandName::CloseMultiplePanes => "CloseMultiplePanes",
|
CommandName::CloseMultiplePanes => "CloseMultiplePanes",
|
||||||
CommandName::FloatMultiplePanes => "FloatMultiplePanes",
|
CommandName::FloatMultiplePanes => "FloatMultiplePanes",
|
||||||
CommandName::EmbedMultiplePanes => "EmbedMultiplePanes",
|
CommandName::EmbedMultiplePanes => "EmbedMultiplePanes",
|
||||||
|
CommandName::InterceptKeyPresses => "InterceptKeyPresses",
|
||||||
|
CommandName::ClearKeyPressesIntercepts => "ClearKeyPressesIntercepts",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||||
|
|
@ -1196,6 +1200,8 @@ impl CommandName {
|
||||||
"CloseMultiplePanes" => Some(Self::CloseMultiplePanes),
|
"CloseMultiplePanes" => Some(Self::CloseMultiplePanes),
|
||||||
"FloatMultiplePanes" => Some(Self::FloatMultiplePanes),
|
"FloatMultiplePanes" => Some(Self::FloatMultiplePanes),
|
||||||
"EmbedMultiplePanes" => Some(Self::EmbedMultiplePanes),
|
"EmbedMultiplePanes" => Some(Self::EmbedMultiplePanes),
|
||||||
|
"InterceptKeyPresses" => Some(Self::InterceptKeyPresses),
|
||||||
|
"ClearKeyPressesIntercepts" => Some(Self::ClearKeyPressesIntercepts),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -12,6 +12,7 @@ pub enum PermissionType {
|
||||||
MessageAndLaunchOtherPlugins = 8,
|
MessageAndLaunchOtherPlugins = 8,
|
||||||
Reconfigure = 9,
|
Reconfigure = 9,
|
||||||
FullHdAccess = 10,
|
FullHdAccess = 10,
|
||||||
|
InterceptInput = 11,
|
||||||
}
|
}
|
||||||
impl PermissionType {
|
impl PermissionType {
|
||||||
/// String value of the enum field names used in the ProtoBuf definition.
|
/// String value of the enum field names used in the ProtoBuf definition.
|
||||||
|
|
@ -31,6 +32,7 @@ impl PermissionType {
|
||||||
PermissionType::MessageAndLaunchOtherPlugins => "MessageAndLaunchOtherPlugins",
|
PermissionType::MessageAndLaunchOtherPlugins => "MessageAndLaunchOtherPlugins",
|
||||||
PermissionType::Reconfigure => "Reconfigure",
|
PermissionType::Reconfigure => "Reconfigure",
|
||||||
PermissionType::FullHdAccess => "FullHdAccess",
|
PermissionType::FullHdAccess => "FullHdAccess",
|
||||||
|
PermissionType::InterceptInput => "InterceptInput",
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||||
|
|
@ -47,6 +49,7 @@ impl PermissionType {
|
||||||
"MessageAndLaunchOtherPlugins" => Some(Self::MessageAndLaunchOtherPlugins),
|
"MessageAndLaunchOtherPlugins" => Some(Self::MessageAndLaunchOtherPlugins),
|
||||||
"Reconfigure" => Some(Self::Reconfigure),
|
"Reconfigure" => Some(Self::Reconfigure),
|
||||||
"FullHdAccess" => Some(Self::FullHdAccess),
|
"FullHdAccess" => Some(Self::FullHdAccess),
|
||||||
|
"InterceptInput" => Some(Self::InterceptInput),
|
||||||
_ => None,
|
_ => None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -938,6 +938,7 @@ pub enum Event {
|
||||||
PastedText(String),
|
PastedText(String),
|
||||||
ConfigWasWrittenToDisk,
|
ConfigWasWrittenToDisk,
|
||||||
BeforeClose,
|
BeforeClose,
|
||||||
|
InterceptedKeyPress(KeyWithModifier),
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(
|
#[derive(
|
||||||
|
|
@ -969,6 +970,7 @@ pub enum Permission {
|
||||||
MessageAndLaunchOtherPlugins,
|
MessageAndLaunchOtherPlugins,
|
||||||
Reconfigure,
|
Reconfigure,
|
||||||
FullHdAccess,
|
FullHdAccess,
|
||||||
|
InterceptInput,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl PermissionType {
|
impl PermissionType {
|
||||||
|
|
@ -991,6 +993,7 @@ impl PermissionType {
|
||||||
},
|
},
|
||||||
PermissionType::Reconfigure => "Change Zellij runtime configuration".to_owned(),
|
PermissionType::Reconfigure => "Change Zellij runtime configuration".to_owned(),
|
||||||
PermissionType::FullHdAccess => "Full access to the hard-drive".to_owned(),
|
PermissionType::FullHdAccess => "Full access to the hard-drive".to_owned(),
|
||||||
|
PermissionType::InterceptInput => "Intercept Input (keyboard & mouse)".to_owned(),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2323,4 +2326,6 @@ pub enum PluginCommand {
|
||||||
CloseMultiplePanes(Vec<PaneId>),
|
CloseMultiplePanes(Vec<PaneId>),
|
||||||
FloatMultiplePanes(Vec<PaneId>),
|
FloatMultiplePanes(Vec<PaneId>),
|
||||||
EmbedMultiplePanes(Vec<PaneId>),
|
EmbedMultiplePanes(Vec<PaneId>),
|
||||||
|
InterceptKeyPresses,
|
||||||
|
ClearKeyPressesIntercepts,
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -382,6 +382,8 @@ pub enum ScreenContext {
|
||||||
EmbedMultiplePanes,
|
EmbedMultiplePanes,
|
||||||
TogglePaneInGroup,
|
TogglePaneInGroup,
|
||||||
ToggleGroupMarking,
|
ToggleGroupMarking,
|
||||||
|
InterceptKeyPresses,
|
||||||
|
ClearKeyPressesIntercepts,
|
||||||
}
|
}
|
||||||
|
|
||||||
/// Stack call representations corresponding to the different types of [`PtyInstruction`]s.
|
/// Stack call representations corresponding to the different types of [`PtyInstruction`]s.
|
||||||
|
|
|
||||||
|
|
@ -146,12 +146,6 @@ keybinds clear-defaults=true {
|
||||||
bind "Alt j" { MoveFocus "down"; }
|
bind "Alt j" { MoveFocus "down"; }
|
||||||
bind "Alt k" { MoveFocus "up"; }
|
bind "Alt k" { MoveFocus "up"; }
|
||||||
bind "Alt l" { MoveFocusOrTab "right"; }
|
bind "Alt l" { MoveFocusOrTab "right"; }
|
||||||
bind "Alt m" {
|
|
||||||
LaunchOrFocusPlugin "zellij:multiple-select" {
|
|
||||||
floating true
|
|
||||||
move_to_focused_tab true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bind "Alt n" { NewPane; }
|
bind "Alt n" { NewPane; }
|
||||||
bind "Alt o" { MoveTab "right"; }
|
bind "Alt o" { MoveTab "right"; }
|
||||||
bind "Alt p" { TogglePaneInGroup; }
|
bind "Alt p" { TogglePaneInGroup; }
|
||||||
|
|
|
||||||
|
|
@ -146,12 +146,6 @@ keybinds clear-defaults=true {
|
||||||
bind "Alt j" { MoveFocus "down"; }
|
bind "Alt j" { MoveFocus "down"; }
|
||||||
bind "Alt k" { MoveFocus "up"; }
|
bind "Alt k" { MoveFocus "up"; }
|
||||||
bind "Alt l" { MoveFocusOrTab "right"; }
|
bind "Alt l" { MoveFocusOrTab "right"; }
|
||||||
bind "Alt m" {
|
|
||||||
LaunchOrFocusPlugin "zellij:multiple-select" {
|
|
||||||
floating true
|
|
||||||
move_to_focused_tab true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
bind "Alt n" { NewPane; }
|
bind "Alt n" { NewPane; }
|
||||||
bind "Alt o" { MoveTab "right"; }
|
bind "Alt o" { MoveTab "right"; }
|
||||||
bind "Alt p" { TogglePaneInGroup; }
|
bind "Alt p" { TogglePaneInGroup; }
|
||||||
|
|
|
||||||
|
|
@ -55,6 +55,7 @@ enum EventType {
|
||||||
PastedText = 29;
|
PastedText = 29;
|
||||||
ConfigWasWrittenToDisk = 30;
|
ConfigWasWrittenToDisk = 30;
|
||||||
BeforeClose = 31;
|
BeforeClose = 31;
|
||||||
|
InterceptedKeyPress = 32;
|
||||||
}
|
}
|
||||||
|
|
||||||
message EventNameList {
|
message EventNameList {
|
||||||
|
|
@ -89,6 +90,7 @@ message Event {
|
||||||
HostFolderChangedPayload host_folder_changed_payload = 24;
|
HostFolderChangedPayload host_folder_changed_payload = 24;
|
||||||
FailedToChangeHostFolderPayload failed_to_change_host_folder_payload = 25;
|
FailedToChangeHostFolderPayload failed_to_change_host_folder_payload = 25;
|
||||||
PastedTextPayload pasted_text_payload = 26;
|
PastedTextPayload pasted_text_payload = 26;
|
||||||
|
key.Key intercepted_key_payload = 27;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -363,6 +363,12 @@ impl TryFrom<ProtobufEvent> for Event {
|
||||||
None => Ok(Event::BeforeClose),
|
None => Ok(Event::BeforeClose),
|
||||||
_ => Err("Malformed payload for the BeforeClose Event"),
|
_ => Err("Malformed payload for the BeforeClose Event"),
|
||||||
},
|
},
|
||||||
|
Some(ProtobufEventType::InterceptedKeyPress) => match protobuf_event.payload {
|
||||||
|
Some(ProtobufEventPayload::KeyPayload(protobuf_key)) => {
|
||||||
|
Ok(Event::InterceptedKeyPress(protobuf_key.try_into()?))
|
||||||
|
},
|
||||||
|
_ => Err("Malformed payload for the InterceptedKeyPress Event"),
|
||||||
|
},
|
||||||
None => Err("Unknown Protobuf Event"),
|
None => Err("Unknown Protobuf Event"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -741,6 +747,10 @@ impl TryFrom<Event> for ProtobufEvent {
|
||||||
name: ProtobufEventType::BeforeClose as i32,
|
name: ProtobufEventType::BeforeClose as i32,
|
||||||
payload: None,
|
payload: None,
|
||||||
}),
|
}),
|
||||||
|
Event::InterceptedKeyPress(key) => Ok(ProtobufEvent {
|
||||||
|
name: ProtobufEventType::InterceptedKeyPress as i32,
|
||||||
|
payload: Some(event::Payload::KeyPayload(key.try_into()?)),
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1376,6 +1386,7 @@ impl TryFrom<ProtobufEventType> for EventType {
|
||||||
ProtobufEventType::PastedText => EventType::PastedText,
|
ProtobufEventType::PastedText => EventType::PastedText,
|
||||||
ProtobufEventType::ConfigWasWrittenToDisk => EventType::ConfigWasWrittenToDisk,
|
ProtobufEventType::ConfigWasWrittenToDisk => EventType::ConfigWasWrittenToDisk,
|
||||||
ProtobufEventType::BeforeClose => EventType::BeforeClose,
|
ProtobufEventType::BeforeClose => EventType::BeforeClose,
|
||||||
|
ProtobufEventType::InterceptedKeyPress => EventType::InterceptedKeyPress,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1416,6 +1427,7 @@ impl TryFrom<EventType> for ProtobufEventType {
|
||||||
EventType::PastedText => ProtobufEventType::PastedText,
|
EventType::PastedText => ProtobufEventType::PastedText,
|
||||||
EventType::ConfigWasWrittenToDisk => ProtobufEventType::ConfigWasWrittenToDisk,
|
EventType::ConfigWasWrittenToDisk => ProtobufEventType::ConfigWasWrittenToDisk,
|
||||||
EventType::BeforeClose => ProtobufEventType::BeforeClose,
|
EventType::BeforeClose => ProtobufEventType::BeforeClose,
|
||||||
|
EventType::InterceptedKeyPress => ProtobufEventType::InterceptedKeyPress,
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -145,6 +145,8 @@ enum CommandName {
|
||||||
CloseMultiplePanes = 129;
|
CloseMultiplePanes = 129;
|
||||||
FloatMultiplePanes = 130;
|
FloatMultiplePanes = 130;
|
||||||
EmbedMultiplePanes = 131;
|
EmbedMultiplePanes = 131;
|
||||||
|
InterceptKeyPresses = 132;
|
||||||
|
ClearKeyPressesIntercepts = 133;
|
||||||
}
|
}
|
||||||
|
|
||||||
message PluginCommand {
|
message PluginCommand {
|
||||||
|
|
|
||||||
|
|
@ -1614,6 +1614,14 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
|
||||||
},
|
},
|
||||||
_ => Err("Mismatched payload for EmbedMultiplePanes"),
|
_ => Err("Mismatched payload for EmbedMultiplePanes"),
|
||||||
},
|
},
|
||||||
|
Some(CommandName::InterceptKeyPresses) => match protobuf_plugin_command.payload {
|
||||||
|
Some(_) => Err("InterceptKeyPresses should have no payload, found a payload"),
|
||||||
|
None => Ok(PluginCommand::InterceptKeyPresses),
|
||||||
|
},
|
||||||
|
Some(CommandName::ClearKeyPressesIntercepts) => match protobuf_plugin_command.payload {
|
||||||
|
Some(_) => Err("ClearKeyPressesIntercepts should have no payload, found a payload"),
|
||||||
|
None => Ok(PluginCommand::ClearKeyPressesIntercepts),
|
||||||
|
},
|
||||||
None => Err("Unrecognized plugin command"),
|
None => Err("Unrecognized plugin command"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -2684,6 +2692,14 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
|
||||||
},
|
},
|
||||||
)),
|
)),
|
||||||
}),
|
}),
|
||||||
|
PluginCommand::InterceptKeyPresses => Ok(ProtobufPluginCommand {
|
||||||
|
name: CommandName::InterceptKeyPresses as i32,
|
||||||
|
payload: None,
|
||||||
|
}),
|
||||||
|
PluginCommand::ClearKeyPressesIntercepts => Ok(ProtobufPluginCommand {
|
||||||
|
name: CommandName::ClearKeyPressesIntercepts as i32,
|
||||||
|
payload: None,
|
||||||
|
}),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,4 +14,5 @@ enum PermissionType {
|
||||||
MessageAndLaunchOtherPlugins = 8;
|
MessageAndLaunchOtherPlugins = 8;
|
||||||
Reconfigure = 9;
|
Reconfigure = 9;
|
||||||
FullHdAccess = 10;
|
FullHdAccess = 10;
|
||||||
|
InterceptInput = 11;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -26,6 +26,7 @@ impl TryFrom<ProtobufPermissionType> for PermissionType {
|
||||||
},
|
},
|
||||||
ProtobufPermissionType::Reconfigure => Ok(PermissionType::Reconfigure),
|
ProtobufPermissionType::Reconfigure => Ok(PermissionType::Reconfigure),
|
||||||
ProtobufPermissionType::FullHdAccess => Ok(PermissionType::FullHdAccess),
|
ProtobufPermissionType::FullHdAccess => Ok(PermissionType::FullHdAccess),
|
||||||
|
ProtobufPermissionType::InterceptInput => Ok(PermissionType::InterceptInput),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -53,6 +54,7 @@ impl TryFrom<PermissionType> for ProtobufPermissionType {
|
||||||
},
|
},
|
||||||
PermissionType::Reconfigure => Ok(ProtobufPermissionType::Reconfigure),
|
PermissionType::Reconfigure => Ok(ProtobufPermissionType::Reconfigure),
|
||||||
PermissionType::FullHdAccess => Ok(ProtobufPermissionType::FullHdAccess),
|
PermissionType::FullHdAccess => Ok(ProtobufPermissionType::FullHdAccess),
|
||||||
|
PermissionType::InterceptInput => Ok(ProtobufPermissionType::InterceptInput),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -210,35 +210,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -758,35 +729,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -1264,35 +1206,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -1912,35 +1825,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -2450,35 +2334,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -2854,35 +2709,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -3330,35 +3156,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -3759,35 +3556,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -4141,35 +3909,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -4577,35 +4316,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -5090,35 +4800,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -5485,35 +5166,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -6045,35 +5697,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
|
||||||
|
|
@ -210,35 +210,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -758,35 +729,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -1264,35 +1206,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -1912,35 +1825,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -2450,35 +2334,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -2854,35 +2709,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -3330,35 +3156,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -3759,35 +3556,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -4141,35 +3909,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -4577,35 +4316,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -5090,35 +4800,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -5485,35 +5166,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -6045,35 +5697,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
|
||||||
|
|
@ -210,35 +210,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -758,35 +729,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -1264,35 +1206,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -1912,35 +1825,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -2450,35 +2334,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -2854,35 +2709,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -3330,35 +3156,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -3759,35 +3556,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -4141,35 +3909,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -4577,35 +4316,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -5090,35 +4800,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -5485,35 +5166,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -6045,35 +5697,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
|
||||||
|
|
@ -210,35 +210,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -758,35 +729,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -1264,35 +1206,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -1912,35 +1825,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -2450,35 +2334,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -2854,35 +2709,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -3330,35 +3156,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -3759,35 +3556,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -4141,35 +3909,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -4577,35 +4316,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -5090,35 +4800,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -5485,35 +5166,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
@ -6045,35 +5697,6 @@ Config {
|
||||||
Right,
|
Right,
|
||||||
),
|
),
|
||||||
],
|
],
|
||||||
KeyWithModifier {
|
|
||||||
bare_key: Char(
|
|
||||||
'm',
|
|
||||||
),
|
|
||||||
key_modifiers: {
|
|
||||||
Alt,
|
|
||||||
},
|
|
||||||
}: [
|
|
||||||
LaunchOrFocusPlugin(
|
|
||||||
RunPlugin(
|
|
||||||
RunPlugin {
|
|
||||||
_allow_exec_host_cmd: false,
|
|
||||||
location: Zellij(
|
|
||||||
PluginTag(
|
|
||||||
"multiple-select",
|
|
||||||
),
|
|
||||||
),
|
|
||||||
configuration: PluginUserConfiguration(
|
|
||||||
{},
|
|
||||||
),
|
|
||||||
initial_cwd: None,
|
|
||||||
},
|
|
||||||
),
|
|
||||||
true,
|
|
||||||
true,
|
|
||||||
false,
|
|
||||||
false,
|
|
||||||
),
|
|
||||||
],
|
|
||||||
KeyWithModifier {
|
KeyWithModifier {
|
||||||
bare_key: Char(
|
bare_key: Char(
|
||||||
'n',
|
'n',
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue