feat(plugins): add plugin APIs to affect other panes (#3576)
* resize_pane_with_id and close_pane_with_id * focus_pane_with_id and edit_scrollback_for_pane_with_id * write_to_pane_id and write_chars_to_pane_id * lots more commands * style(fmt): rustfmt
This commit is contained in:
parent
240a53aa1a
commit
1776d240da
33 changed files with 3469 additions and 431 deletions
|
|
@ -364,6 +364,57 @@ impl ZellijPlugin for State {
|
|||
BareKey::Char('d') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
rerun_command_pane(1);
|
||||
},
|
||||
BareKey::Char('e') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
resize_pane_with_id(
|
||||
ResizeStrategy::new(Resize::Increase, Some(Direction::Left)),
|
||||
PaneId::Terminal(2),
|
||||
);
|
||||
},
|
||||
BareKey::Char('f') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
edit_scrollback_for_pane_with_id(PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('g') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
write_to_pane_id(vec![102, 111, 111], PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('h') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
write_chars_to_pane_id("foo\n", PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('i') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
move_pane_with_pane_id(PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('j') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
move_pane_with_pane_id_in_direction(PaneId::Terminal(2), Direction::Left);
|
||||
},
|
||||
BareKey::Char('k') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
clear_screen_for_pane_id(PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('l') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
scroll_up_in_pane_id(PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('m') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
scroll_down_in_pane_id(PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('n') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
scroll_to_top_in_pane_id(PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('o') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
scroll_to_bottom_in_pane_id(PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('p') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
page_scroll_up_in_pane_id(PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('q') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
page_scroll_down_in_pane_id(PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('r') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
toggle_pane_id_fullscreen(PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('s') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
toggle_pane_embed_or_eject_for_pane_id(PaneId::Terminal(2));
|
||||
},
|
||||
BareKey::Char('t') if key.has_modifiers(&[KeyModifier::Alt]) => {
|
||||
close_tab_with_index(2);
|
||||
},
|
||||
_ => {},
|
||||
},
|
||||
Event::CustomMessage(message, payload) => {
|
||||
|
|
|
|||
|
|
@ -408,35 +408,41 @@ impl FloatingPanes {
|
|||
strategy: &ResizeStrategy,
|
||||
) -> Result<bool> {
|
||||
// true => successfully resized
|
||||
let err_context =
|
||||
|| format!("failed to {strategy} for active floating pane for client {client_id}");
|
||||
|
||||
let display_area = *self.display_area.borrow();
|
||||
let viewport = *self.viewport.borrow();
|
||||
if let Some(active_floating_pane_id) = self.active_panes.get(&client_id) {
|
||||
let mut floating_pane_grid = FloatingPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&mut self.desired_pane_positions,
|
||||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid
|
||||
.change_pane_size(
|
||||
active_floating_pane_id,
|
||||
strategy,
|
||||
(RESIZE_INCREMENT_WIDTH, RESIZE_INCREMENT_HEIGHT),
|
||||
)
|
||||
.with_context(err_context)?;
|
||||
|
||||
for pane in self.panes.values_mut() {
|
||||
resize_pty!(pane, os_api, self.senders, self.character_cell_size)
|
||||
.with_context(err_context)?;
|
||||
}
|
||||
self.set_force_render();
|
||||
return Ok(true);
|
||||
return self.resize_pane_with_id(*strategy, *active_floating_pane_id);
|
||||
}
|
||||
Ok(false)
|
||||
}
|
||||
pub fn resize_pane_with_id(
|
||||
&mut self,
|
||||
strategy: ResizeStrategy,
|
||||
pane_id: PaneId,
|
||||
) -> Result<bool> {
|
||||
// true => successfully resized
|
||||
let err_context = || format!("Failed to resize pane with id: {:?}", pane_id);
|
||||
let display_area = *self.display_area.borrow();
|
||||
let viewport = *self.viewport.borrow();
|
||||
let mut floating_pane_grid = FloatingPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&mut self.desired_pane_positions,
|
||||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid
|
||||
.change_pane_size(
|
||||
&pane_id,
|
||||
&strategy,
|
||||
(RESIZE_INCREMENT_WIDTH, RESIZE_INCREMENT_HEIGHT),
|
||||
)
|
||||
.with_context(err_context)?;
|
||||
|
||||
for pane in self.panes.values_mut() {
|
||||
resize_pty!(pane, os_api, self.senders, self.character_cell_size)
|
||||
.with_context(err_context)?;
|
||||
}
|
||||
self.set_force_render();
|
||||
Ok(true)
|
||||
}
|
||||
|
||||
fn set_pane_active_at(&mut self, pane_id: PaneId) {
|
||||
if let Some(pane) = self.panes.get_mut(&pane_id) {
|
||||
|
|
@ -545,61 +551,73 @@ impl FloatingPanes {
|
|||
}
|
||||
|
||||
pub fn move_active_pane_down(&mut self, client_id: ClientId) {
|
||||
if let Some(active_pane_id) = self.active_panes.get(&client_id) {
|
||||
self.move_pane_down(*active_pane_id);
|
||||
}
|
||||
}
|
||||
pub fn move_pane_down(&mut self, pane_id: PaneId) {
|
||||
let display_area = *self.display_area.borrow();
|
||||
let viewport = *self.viewport.borrow();
|
||||
if let Some(active_pane_id) = self.active_panes.get(&client_id) {
|
||||
let mut floating_pane_grid = FloatingPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&mut self.desired_pane_positions,
|
||||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid.move_pane_down(active_pane_id).unwrap();
|
||||
self.set_force_render();
|
||||
}
|
||||
let mut floating_pane_grid = FloatingPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&mut self.desired_pane_positions,
|
||||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid.move_pane_down(&pane_id).non_fatal();
|
||||
self.set_force_render();
|
||||
}
|
||||
pub fn move_active_pane_up(&mut self, client_id: ClientId) {
|
||||
if let Some(active_pane_id) = self.active_panes.get(&client_id) {
|
||||
self.move_pane_up(*active_pane_id);
|
||||
}
|
||||
}
|
||||
pub fn move_pane_up(&mut self, pane_id: PaneId) {
|
||||
let display_area = *self.display_area.borrow();
|
||||
let viewport = *self.viewport.borrow();
|
||||
if let Some(active_pane_id) = self.active_panes.get(&client_id) {
|
||||
let mut floating_pane_grid = FloatingPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&mut self.desired_pane_positions,
|
||||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid.move_pane_up(active_pane_id).unwrap();
|
||||
self.set_force_render();
|
||||
}
|
||||
let mut floating_pane_grid = FloatingPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&mut self.desired_pane_positions,
|
||||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid.move_pane_up(&pane_id).non_fatal();
|
||||
self.set_force_render();
|
||||
}
|
||||
pub fn move_active_pane_left(&mut self, client_id: ClientId) {
|
||||
let display_area = *self.display_area.borrow();
|
||||
let viewport = *self.viewport.borrow();
|
||||
if let Some(active_pane_id) = self.active_panes.get(&client_id) {
|
||||
let mut floating_pane_grid = FloatingPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&mut self.desired_pane_positions,
|
||||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid.move_pane_left(active_pane_id).unwrap();
|
||||
self.set_force_render();
|
||||
self.move_pane_left(*active_pane_id);
|
||||
}
|
||||
}
|
||||
pub fn move_active_pane_right(&mut self, client_id: ClientId) {
|
||||
pub fn move_pane_left(&mut self, pane_id: PaneId) {
|
||||
let display_area = *self.display_area.borrow();
|
||||
let viewport = *self.viewport.borrow();
|
||||
let mut floating_pane_grid = FloatingPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&mut self.desired_pane_positions,
|
||||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid.move_pane_left(&pane_id).unwrap();
|
||||
self.set_force_render();
|
||||
}
|
||||
pub fn move_active_pane_right(&mut self, client_id: ClientId) {
|
||||
if let Some(active_pane_id) = self.active_panes.get(&client_id) {
|
||||
let mut floating_pane_grid = FloatingPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&mut self.desired_pane_positions,
|
||||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid.move_pane_right(active_pane_id).unwrap();
|
||||
self.set_force_render();
|
||||
self.move_pane_right(*active_pane_id);
|
||||
}
|
||||
}
|
||||
pub fn move_pane_right(&mut self, pane_id: PaneId) {
|
||||
let display_area = *self.display_area.borrow();
|
||||
let viewport = *self.viewport.borrow();
|
||||
let mut floating_pane_grid = FloatingPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&mut self.desired_pane_positions,
|
||||
display_area,
|
||||
viewport,
|
||||
);
|
||||
floating_pane_grid.move_pane_right(&pane_id).unwrap();
|
||||
self.set_force_render();
|
||||
}
|
||||
pub fn move_active_pane(
|
||||
&mut self,
|
||||
search_backwards: bool,
|
||||
|
|
@ -607,7 +625,9 @@ impl FloatingPanes {
|
|||
client_id: ClientId,
|
||||
) {
|
||||
let active_pane_id = self.get_active_pane_id(client_id).unwrap();
|
||||
|
||||
self.move_pane(search_backwards, active_pane_id)
|
||||
}
|
||||
pub fn move_pane(&mut self, search_backwards: bool, pane_id: PaneId) {
|
||||
let new_position_id = {
|
||||
let pane_grid = FloatingPaneGrid::new(
|
||||
&mut self.panes,
|
||||
|
|
@ -616,13 +636,13 @@ impl FloatingPanes {
|
|||
*self.viewport.borrow(),
|
||||
);
|
||||
if search_backwards {
|
||||
pane_grid.previous_selectable_pane_id(&active_pane_id)
|
||||
pane_grid.previous_selectable_pane_id(&pane_id)
|
||||
} else {
|
||||
pane_grid.next_selectable_pane_id(&active_pane_id)
|
||||
pane_grid.next_selectable_pane_id(&pane_id)
|
||||
}
|
||||
};
|
||||
if let Some(new_position_id) = new_position_id {
|
||||
let current_position = self.panes.get(&active_pane_id).unwrap();
|
||||
let current_position = self.panes.get(&pane_id).unwrap();
|
||||
let prev_geom = current_position.position_and_size();
|
||||
let prev_geom_override = current_position.geom_override();
|
||||
|
||||
|
|
@ -635,7 +655,7 @@ impl FloatingPanes {
|
|||
}
|
||||
new_position.set_should_render(true);
|
||||
|
||||
let current_position = self.panes.get_mut(&active_pane_id).unwrap();
|
||||
let current_position = self.panes.get_mut(&pane_id).unwrap();
|
||||
current_position.set_geom(next_geom);
|
||||
if let Some(geom) = next_geom_override {
|
||||
current_position.set_geom_override(geom);
|
||||
|
|
|
|||
|
|
@ -1155,7 +1155,7 @@ impl Grid {
|
|||
self.mark_for_rerender();
|
||||
}
|
||||
/// Dumps all lines above terminal vieport and the viewport itself to a string
|
||||
pub fn dump_screen(&mut self, full: bool) -> String {
|
||||
pub fn dump_screen(&self, full: bool) -> String {
|
||||
let viewport: String = dump_screen!(self.viewport);
|
||||
if !full {
|
||||
return viewport;
|
||||
|
|
|
|||
|
|
@ -515,7 +515,7 @@ impl Pane for TerminalPane {
|
|||
self.geom.y -= count;
|
||||
self.reflow_lines();
|
||||
}
|
||||
fn dump_screen(&mut self, _client_id: ClientId, full: bool) -> String {
|
||||
fn dump_screen(&self, full: bool) -> String {
|
||||
self.grid.dump_screen(full)
|
||||
}
|
||||
fn clear_screen(&mut self) {
|
||||
|
|
|
|||
|
|
@ -67,7 +67,7 @@ pub struct TiledPanes {
|
|||
active_panes: ActivePanes,
|
||||
draw_pane_frames: bool,
|
||||
panes_to_hide: HashSet<PaneId>,
|
||||
fullscreen_is_active: bool,
|
||||
fullscreen_is_active: Option<PaneId>,
|
||||
senders: ThreadSenders,
|
||||
window_title: Option<String>,
|
||||
client_id_to_boundaries: HashMap<ClientId, Boundaries>,
|
||||
|
|
@ -103,7 +103,7 @@ impl TiledPanes {
|
|||
active_panes: ActivePanes::new(&os_api),
|
||||
draw_pane_frames,
|
||||
panes_to_hide: HashSet::new(),
|
||||
fullscreen_is_active: false,
|
||||
fullscreen_is_active: None,
|
||||
senders,
|
||||
window_title: None,
|
||||
client_id_to_boundaries: HashMap::new(),
|
||||
|
|
@ -833,58 +833,59 @@ impl TiledPanes {
|
|||
client_id: ClientId,
|
||||
strategy: &ResizeStrategy,
|
||||
) -> Result<()> {
|
||||
let err_context =
|
||||
|| format!("failed to {strategy} for active tiled pane for client {client_id}");
|
||||
|
||||
if let Some(active_pane_id) = self.get_active_pane_id(client_id) {
|
||||
let mut pane_grid = TiledPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&self.panes_to_hide,
|
||||
*self.display_area.borrow(),
|
||||
*self.viewport.borrow(),
|
||||
);
|
||||
|
||||
match pane_grid
|
||||
.change_pane_size(&active_pane_id, strategy, (RESIZE_PERCENT, RESIZE_PERCENT))
|
||||
.with_context(err_context)
|
||||
{
|
||||
Ok(_) => {},
|
||||
Err(err) => match err.downcast_ref::<ZellijError>() {
|
||||
Some(ZellijError::PaneSizeUnchanged) => {
|
||||
// try once more with double the resize percent, but let's keep it at that
|
||||
match pane_grid
|
||||
.change_pane_size(
|
||||
&active_pane_id,
|
||||
strategy,
|
||||
(RESIZE_PERCENT * 2.0, RESIZE_PERCENT * 2.0),
|
||||
)
|
||||
.with_context(err_context)
|
||||
{
|
||||
Ok(_) => {},
|
||||
Err(err) => match err.downcast_ref::<ZellijError>() {
|
||||
Some(ZellijError::PaneSizeUnchanged) => {
|
||||
Err::<(), _>(err).non_fatal()
|
||||
},
|
||||
_ => {
|
||||
return Err(err);
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(err);
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for pane in self.panes.values_mut() {
|
||||
resize_pty!(pane, self.os_api, self.senders, self.character_cell_size).unwrap();
|
||||
}
|
||||
self.reset_boundaries();
|
||||
self.resize_pane_with_id(*strategy, active_pane_id)?;
|
||||
}
|
||||
|
||||
Ok(())
|
||||
}
|
||||
pub fn resize_pane_with_id(&mut self, strategy: ResizeStrategy, pane_id: PaneId) -> Result<()> {
|
||||
let err_context = || format!("failed to resize pand with id: {:?}", pane_id);
|
||||
|
||||
let mut pane_grid = TiledPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&self.panes_to_hide,
|
||||
*self.display_area.borrow(),
|
||||
*self.viewport.borrow(),
|
||||
);
|
||||
|
||||
match pane_grid
|
||||
.change_pane_size(&pane_id, &strategy, (RESIZE_PERCENT, RESIZE_PERCENT))
|
||||
.with_context(err_context)
|
||||
{
|
||||
Ok(_) => {},
|
||||
Err(err) => match err.downcast_ref::<ZellijError>() {
|
||||
Some(ZellijError::PaneSizeUnchanged) => {
|
||||
// try once more with double the resize percent, but let's keep it at that
|
||||
match pane_grid
|
||||
.change_pane_size(
|
||||
&pane_id,
|
||||
&strategy,
|
||||
(RESIZE_PERCENT * 2.0, RESIZE_PERCENT * 2.0),
|
||||
)
|
||||
.with_context(err_context)
|
||||
{
|
||||
Ok(_) => {},
|
||||
Err(err) => match err.downcast_ref::<ZellijError>() {
|
||||
Some(ZellijError::PaneSizeUnchanged) => Err::<(), _>(err).non_fatal(),
|
||||
_ => {
|
||||
return Err(err);
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
_ => {
|
||||
return Err(err);
|
||||
},
|
||||
},
|
||||
}
|
||||
|
||||
for pane in self.panes.values_mut() {
|
||||
resize_pty!(pane, self.os_api, self.senders, self.character_cell_size).unwrap();
|
||||
}
|
||||
self.reset_boundaries();
|
||||
Ok(())
|
||||
}
|
||||
|
||||
pub fn focus_next_pane(&mut self, client_id: ClientId) {
|
||||
let connected_clients: Vec<ClientId> =
|
||||
|
|
@ -1225,7 +1226,9 @@ impl TiledPanes {
|
|||
}
|
||||
pub fn move_active_pane(&mut self, search_backwards: bool, client_id: ClientId) {
|
||||
let active_pane_id = self.get_active_pane_id(client_id).unwrap();
|
||||
|
||||
self.move_pane(search_backwards, active_pane_id)
|
||||
}
|
||||
pub fn move_pane(&mut self, search_backwards: bool, pane_id: PaneId) {
|
||||
let new_position_id = {
|
||||
let pane_grid = TiledPaneGrid::new(
|
||||
&mut self.panes,
|
||||
|
|
@ -1234,9 +1237,9 @@ impl TiledPanes {
|
|||
*self.viewport.borrow(),
|
||||
);
|
||||
if search_backwards {
|
||||
pane_grid.previous_selectable_pane_id(&active_pane_id)
|
||||
pane_grid.previous_selectable_pane_id(&pane_id)
|
||||
} else {
|
||||
pane_grid.next_selectable_pane_id(&active_pane_id)
|
||||
pane_grid.next_selectable_pane_id(&pane_id)
|
||||
}
|
||||
};
|
||||
if self
|
||||
|
|
@ -1250,7 +1253,7 @@ impl TiledPanes {
|
|||
self.reapply_pane_frames();
|
||||
}
|
||||
|
||||
let current_position = self.panes.get(&active_pane_id).unwrap();
|
||||
let current_position = self.panes.get(&pane_id).unwrap();
|
||||
let prev_geom = current_position.position_and_size();
|
||||
let prev_geom_override = current_position.geom_override();
|
||||
|
||||
|
|
@ -1270,7 +1273,7 @@ impl TiledPanes {
|
|||
.unwrap();
|
||||
new_position.set_should_render(true);
|
||||
|
||||
let current_position = self.panes.get_mut(&active_pane_id).unwrap();
|
||||
let current_position = self.panes.get_mut(&pane_id).unwrap();
|
||||
current_position.set_geom(next_geom);
|
||||
if let Some(geom) = next_geom_override {
|
||||
current_position.set_geom_override(geom);
|
||||
|
|
@ -1283,202 +1286,215 @@ impl TiledPanes {
|
|||
)
|
||||
.unwrap();
|
||||
current_position.set_should_render(true);
|
||||
self.reapply_pane_focus();
|
||||
self.set_pane_frames(self.draw_pane_frames);
|
||||
}
|
||||
pub fn move_active_pane_down(&mut self, client_id: ClientId) {
|
||||
if let Some(active_pane_id) = self.get_active_pane_id(client_id) {
|
||||
let mut pane_grid = TiledPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&self.panes_to_hide,
|
||||
*self.display_area.borrow(),
|
||||
*self.viewport.borrow(),
|
||||
);
|
||||
let next_index = pane_grid
|
||||
.next_selectable_pane_id_below(&active_pane_id)
|
||||
.or_else(|| pane_grid.progress_stack_down_if_in_stack(&active_pane_id));
|
||||
if let Some(p) = next_index {
|
||||
let active_pane_id = self.active_panes.get(&client_id).unwrap();
|
||||
let current_position = self.panes.get(active_pane_id).unwrap();
|
||||
let prev_geom = current_position.position_and_size();
|
||||
let prev_geom_override = current_position.geom_override();
|
||||
self.move_pane_down(active_pane_id);
|
||||
}
|
||||
}
|
||||
pub fn move_pane_down(&mut self, pane_id: PaneId) {
|
||||
let mut pane_grid = TiledPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&self.panes_to_hide,
|
||||
*self.display_area.borrow(),
|
||||
*self.viewport.borrow(),
|
||||
);
|
||||
let next_index = pane_grid
|
||||
.next_selectable_pane_id_below(&pane_id)
|
||||
.or_else(|| pane_grid.progress_stack_down_if_in_stack(&pane_id));
|
||||
if let Some(p) = next_index {
|
||||
let current_position = self.panes.get(&pane_id).unwrap();
|
||||
let prev_geom = current_position.position_and_size();
|
||||
let prev_geom_override = current_position.geom_override();
|
||||
|
||||
let new_position = self.panes.get_mut(&p).unwrap();
|
||||
let next_geom = new_position.position_and_size();
|
||||
let next_geom_override = new_position.geom_override();
|
||||
new_position.set_geom(prev_geom);
|
||||
if let Some(geom) = prev_geom_override {
|
||||
new_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
new_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
new_position.set_should_render(true);
|
||||
|
||||
let current_position = self.panes.get_mut(active_pane_id).unwrap();
|
||||
current_position.set_geom(next_geom);
|
||||
if let Some(geom) = next_geom_override {
|
||||
current_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
current_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
current_position.set_should_render(true);
|
||||
self.set_pane_frames(self.draw_pane_frames);
|
||||
let new_position = self.panes.get_mut(&p).unwrap();
|
||||
let next_geom = new_position.position_and_size();
|
||||
let next_geom_override = new_position.geom_override();
|
||||
new_position.set_geom(prev_geom);
|
||||
if let Some(geom) = prev_geom_override {
|
||||
new_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
new_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
new_position.set_should_render(true);
|
||||
|
||||
let current_position = self.panes.get_mut(&pane_id).unwrap();
|
||||
current_position.set_geom(next_geom);
|
||||
if let Some(geom) = next_geom_override {
|
||||
current_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
current_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
current_position.set_should_render(true);
|
||||
self.reapply_pane_focus();
|
||||
self.set_pane_frames(self.draw_pane_frames);
|
||||
}
|
||||
}
|
||||
pub fn move_active_pane_left(&mut self, client_id: ClientId) {
|
||||
if let Some(active_pane_id) = self.get_active_pane_id(client_id) {
|
||||
let pane_grid = TiledPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&self.panes_to_hide,
|
||||
*self.display_area.borrow(),
|
||||
*self.viewport.borrow(),
|
||||
);
|
||||
let next_index = pane_grid.next_selectable_pane_id_to_the_left(&active_pane_id);
|
||||
if let Some(p) = next_index {
|
||||
let active_pane_id = self.active_panes.get(&client_id).unwrap();
|
||||
let current_position = self.panes.get(active_pane_id).unwrap();
|
||||
let prev_geom = current_position.position_and_size();
|
||||
let prev_geom_override = current_position.geom_override();
|
||||
self.move_pane_left(active_pane_id);
|
||||
}
|
||||
}
|
||||
pub fn move_pane_left(&mut self, pane_id: PaneId) {
|
||||
let pane_grid = TiledPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&self.panes_to_hide,
|
||||
*self.display_area.borrow(),
|
||||
*self.viewport.borrow(),
|
||||
);
|
||||
let next_index = pane_grid.next_selectable_pane_id_to_the_left(&pane_id);
|
||||
if let Some(p) = next_index {
|
||||
let current_position = self.panes.get(&pane_id).unwrap();
|
||||
let prev_geom = current_position.position_and_size();
|
||||
let prev_geom_override = current_position.geom_override();
|
||||
|
||||
let new_position = self.panes.get_mut(&p).unwrap();
|
||||
let next_geom = new_position.position_and_size();
|
||||
let next_geom_override = new_position.geom_override();
|
||||
new_position.set_geom(prev_geom);
|
||||
if let Some(geom) = prev_geom_override {
|
||||
new_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
new_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
new_position.set_should_render(true);
|
||||
|
||||
let current_position = self.panes.get_mut(active_pane_id).unwrap();
|
||||
current_position.set_geom(next_geom);
|
||||
if let Some(geom) = next_geom_override {
|
||||
current_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
current_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
current_position.set_should_render(true);
|
||||
self.set_pane_frames(self.draw_pane_frames);
|
||||
let new_position = self.panes.get_mut(&p).unwrap();
|
||||
let next_geom = new_position.position_and_size();
|
||||
let next_geom_override = new_position.geom_override();
|
||||
new_position.set_geom(prev_geom);
|
||||
if let Some(geom) = prev_geom_override {
|
||||
new_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
new_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
new_position.set_should_render(true);
|
||||
|
||||
let current_position = self.panes.get_mut(&pane_id).unwrap();
|
||||
current_position.set_geom(next_geom);
|
||||
if let Some(geom) = next_geom_override {
|
||||
current_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
current_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
current_position.set_should_render(true);
|
||||
self.reapply_pane_focus();
|
||||
self.set_pane_frames(self.draw_pane_frames);
|
||||
}
|
||||
}
|
||||
pub fn move_active_pane_right(&mut self, client_id: ClientId) {
|
||||
if let Some(active_pane_id) = self.get_active_pane_id(client_id) {
|
||||
let pane_grid = TiledPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&self.panes_to_hide,
|
||||
*self.display_area.borrow(),
|
||||
*self.viewport.borrow(),
|
||||
);
|
||||
let next_index = pane_grid.next_selectable_pane_id_to_the_right(&active_pane_id);
|
||||
if let Some(p) = next_index {
|
||||
let active_pane_id = self.active_panes.get(&client_id).unwrap();
|
||||
let current_position = self.panes.get(active_pane_id).unwrap();
|
||||
let prev_geom = current_position.position_and_size();
|
||||
let prev_geom_override = current_position.geom_override();
|
||||
self.move_pane_right(active_pane_id);
|
||||
}
|
||||
}
|
||||
pub fn move_pane_right(&mut self, pane_id: PaneId) {
|
||||
let pane_grid = TiledPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&self.panes_to_hide,
|
||||
*self.display_area.borrow(),
|
||||
*self.viewport.borrow(),
|
||||
);
|
||||
let next_index = pane_grid.next_selectable_pane_id_to_the_right(&pane_id);
|
||||
if let Some(p) = next_index {
|
||||
let current_position = self.panes.get(&pane_id).unwrap();
|
||||
let prev_geom = current_position.position_and_size();
|
||||
let prev_geom_override = current_position.geom_override();
|
||||
|
||||
let new_position = self.panes.get_mut(&p).unwrap();
|
||||
let next_geom = new_position.position_and_size();
|
||||
let next_geom_override = new_position.geom_override();
|
||||
new_position.set_geom(prev_geom);
|
||||
if let Some(geom) = prev_geom_override {
|
||||
new_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
new_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
new_position.set_should_render(true);
|
||||
|
||||
let current_position = self.panes.get_mut(active_pane_id).unwrap();
|
||||
current_position.set_geom(next_geom);
|
||||
if let Some(geom) = next_geom_override {
|
||||
current_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
current_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
current_position.set_should_render(true);
|
||||
self.set_pane_frames(self.draw_pane_frames);
|
||||
let new_position = self.panes.get_mut(&p).unwrap();
|
||||
let next_geom = new_position.position_and_size();
|
||||
let next_geom_override = new_position.geom_override();
|
||||
new_position.set_geom(prev_geom);
|
||||
if let Some(geom) = prev_geom_override {
|
||||
new_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
new_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
new_position.set_should_render(true);
|
||||
|
||||
let current_position = self.panes.get_mut(&pane_id).unwrap();
|
||||
current_position.set_geom(next_geom);
|
||||
if let Some(geom) = next_geom_override {
|
||||
current_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
current_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
current_position.set_should_render(true);
|
||||
self.reapply_pane_focus();
|
||||
self.set_pane_frames(self.draw_pane_frames);
|
||||
}
|
||||
}
|
||||
pub fn move_active_pane_up(&mut self, client_id: ClientId) {
|
||||
if let Some(active_pane_id) = self.get_active_pane_id(client_id) {
|
||||
let mut pane_grid = TiledPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&self.panes_to_hide,
|
||||
*self.display_area.borrow(),
|
||||
*self.viewport.borrow(),
|
||||
);
|
||||
let next_index = pane_grid
|
||||
.next_selectable_pane_id_above(&active_pane_id)
|
||||
.or_else(|| pane_grid.progress_stack_up_if_in_stack(&active_pane_id));
|
||||
if let Some(p) = next_index {
|
||||
let active_pane_id = self.active_panes.get(&client_id).unwrap();
|
||||
let current_position = self.panes.get(active_pane_id).unwrap();
|
||||
let prev_geom = current_position.position_and_size();
|
||||
let prev_geom_override = current_position.geom_override();
|
||||
self.move_pane_up(active_pane_id);
|
||||
}
|
||||
}
|
||||
pub fn move_pane_up(&mut self, pane_id: PaneId) {
|
||||
let mut pane_grid = TiledPaneGrid::new(
|
||||
&mut self.panes,
|
||||
&self.panes_to_hide,
|
||||
*self.display_area.borrow(),
|
||||
*self.viewport.borrow(),
|
||||
);
|
||||
let next_index = pane_grid
|
||||
.next_selectable_pane_id_above(&pane_id)
|
||||
.or_else(|| pane_grid.progress_stack_up_if_in_stack(&pane_id));
|
||||
if let Some(p) = next_index {
|
||||
let current_position = self.panes.get(&pane_id).unwrap();
|
||||
let prev_geom = current_position.position_and_size();
|
||||
let prev_geom_override = current_position.geom_override();
|
||||
|
||||
let new_position = self.panes.get_mut(&p).unwrap();
|
||||
let next_geom = new_position.position_and_size();
|
||||
let next_geom_override = new_position.geom_override();
|
||||
new_position.set_geom(prev_geom);
|
||||
if let Some(geom) = prev_geom_override {
|
||||
new_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
new_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
new_position.set_should_render(true);
|
||||
|
||||
let current_position = self.panes.get_mut(active_pane_id).unwrap();
|
||||
current_position.set_geom(next_geom);
|
||||
if let Some(geom) = next_geom_override {
|
||||
current_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
current_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
current_position.set_should_render(true);
|
||||
self.set_pane_frames(self.draw_pane_frames);
|
||||
let new_position = self.panes.get_mut(&p).unwrap();
|
||||
let next_geom = new_position.position_and_size();
|
||||
let next_geom_override = new_position.geom_override();
|
||||
new_position.set_geom(prev_geom);
|
||||
if let Some(geom) = prev_geom_override {
|
||||
new_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
new_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
new_position.set_should_render(true);
|
||||
|
||||
let current_position = self.panes.get_mut(&pane_id).unwrap();
|
||||
current_position.set_geom(next_geom);
|
||||
if let Some(geom) = next_geom_override {
|
||||
current_position.set_geom_override(geom);
|
||||
}
|
||||
resize_pty!(
|
||||
current_position,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
)
|
||||
.unwrap();
|
||||
current_position.set_should_render(true);
|
||||
self.reapply_pane_focus();
|
||||
self.set_pane_frames(self.draw_pane_frames);
|
||||
}
|
||||
}
|
||||
pub fn move_clients_out_of_pane(&mut self, pane_id: PaneId) {
|
||||
|
|
@ -1565,23 +1581,65 @@ impl TiledPanes {
|
|||
self.panes_to_hide.contains(&pane_id)
|
||||
}
|
||||
pub fn fullscreen_is_active(&self) -> bool {
|
||||
self.fullscreen_is_active
|
||||
self.fullscreen_is_active.is_some()
|
||||
}
|
||||
pub fn unset_fullscreen(&mut self) {
|
||||
if self.fullscreen_is_active {
|
||||
let first_client_id = {
|
||||
let connected_clients = self.connected_clients.borrow();
|
||||
connected_clients.iter().next().copied()
|
||||
};
|
||||
if let Some(active_pane_id) =
|
||||
first_client_id.and_then(|first_client_id| self.get_active_pane_id(first_client_id))
|
||||
{
|
||||
let panes_to_hide: Vec<_> = self.panes_to_hide.iter().copied().collect();
|
||||
for pane_id in panes_to_hide {
|
||||
let pane = self.get_pane_mut(pane_id).unwrap();
|
||||
pane.set_should_render(true);
|
||||
pane.set_should_render_boundaries(true);
|
||||
if let Some(fullscreen_pane_id) = self.fullscreen_is_active {
|
||||
let panes_to_hide: Vec<_> = self.panes_to_hide.iter().copied().collect();
|
||||
for pane_id in panes_to_hide {
|
||||
let pane = self.get_pane_mut(pane_id).unwrap();
|
||||
pane.set_should_render(true);
|
||||
pane.set_should_render_boundaries(true);
|
||||
}
|
||||
let viewport_pane_ids: Vec<_> = self
|
||||
.panes
|
||||
.keys()
|
||||
.copied()
|
||||
.into_iter()
|
||||
.filter(|id| {
|
||||
!is_inside_viewport(&*self.viewport.borrow(), self.get_pane(*id).unwrap())
|
||||
})
|
||||
.collect();
|
||||
for pid in viewport_pane_ids {
|
||||
let viewport_pane = self.get_pane_mut(pid).unwrap();
|
||||
viewport_pane.reset_size_and_position_override();
|
||||
}
|
||||
self.panes_to_hide.clear();
|
||||
let fullscreen_pane = self.get_pane_mut(fullscreen_pane_id).unwrap();
|
||||
fullscreen_pane.reset_size_and_position_override();
|
||||
self.set_force_render();
|
||||
let display_area = *self.display_area.borrow();
|
||||
self.resize(display_area);
|
||||
self.fullscreen_is_active = None;
|
||||
}
|
||||
}
|
||||
pub fn toggle_active_pane_fullscreen(&mut self, client_id: ClientId) {
|
||||
if let Some(active_pane_id) = self.get_active_pane_id(client_id) {
|
||||
self.toggle_pane_fullscreen(active_pane_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn toggle_pane_fullscreen(&mut self, pane_id: PaneId) {
|
||||
if self.fullscreen_is_active.is_some() {
|
||||
self.unset_fullscreen();
|
||||
} else {
|
||||
let pane_ids_to_hide = self.panes.iter().filter_map(|(&id, _pane)| {
|
||||
if id != pane_id
|
||||
&& is_inside_viewport(&*self.viewport.borrow(), self.get_pane(id).unwrap())
|
||||
{
|
||||
Some(id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
self.panes_to_hide = pane_ids_to_hide.collect();
|
||||
if self.panes_to_hide.is_empty() {
|
||||
// nothing to do, pane is already as fullscreen as it can be, let's bail
|
||||
return;
|
||||
} else {
|
||||
// For all of the panes outside of the viewport staying on the fullscreen
|
||||
// screen, switch them to using override positions as well so that the resize
|
||||
// system doesn't get confused by viewport and old panes that no longer line up
|
||||
let viewport_pane_ids: Vec<_> = self
|
||||
.panes
|
||||
.keys()
|
||||
|
|
@ -1592,59 +1650,12 @@ impl TiledPanes {
|
|||
})
|
||||
.collect();
|
||||
for pid in viewport_pane_ids {
|
||||
let viewport_pane = self.get_pane_mut(pid).unwrap();
|
||||
viewport_pane.reset_size_and_position_override();
|
||||
}
|
||||
self.panes_to_hide.clear();
|
||||
let active_terminal = self.get_pane_mut(active_pane_id).unwrap();
|
||||
active_terminal.reset_size_and_position_override();
|
||||
self.set_force_render();
|
||||
let display_area = *self.display_area.borrow();
|
||||
self.resize(display_area);
|
||||
self.fullscreen_is_active = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
pub fn toggle_active_pane_fullscreen(&mut self, client_id: ClientId) {
|
||||
if let Some(active_pane_id) = self.get_active_pane_id(client_id) {
|
||||
if self.fullscreen_is_active {
|
||||
self.unset_fullscreen();
|
||||
} else {
|
||||
let pane_ids_to_hide = self.panes.iter().filter_map(|(&id, _pane)| {
|
||||
if id != active_pane_id
|
||||
&& is_inside_viewport(&*self.viewport.borrow(), self.get_pane(id).unwrap())
|
||||
{
|
||||
Some(id)
|
||||
} else {
|
||||
None
|
||||
}
|
||||
});
|
||||
self.panes_to_hide = pane_ids_to_hide.collect();
|
||||
if self.panes_to_hide.is_empty() {
|
||||
// nothing to do, pane is already as fullscreen as it can be, let's bail
|
||||
return;
|
||||
} else {
|
||||
// For all of the panes outside of the viewport staying on the fullscreen
|
||||
// screen, switch them to using override positions as well so that the resize
|
||||
// system doesn't get confused by viewport and old panes that no longer line up
|
||||
let viewport_pane_ids: Vec<_> = self
|
||||
.panes
|
||||
.keys()
|
||||
.copied()
|
||||
.into_iter()
|
||||
.filter(|id| {
|
||||
!is_inside_viewport(
|
||||
&*self.viewport.borrow(),
|
||||
self.get_pane(*id).unwrap(),
|
||||
)
|
||||
})
|
||||
.collect();
|
||||
for pid in viewport_pane_ids {
|
||||
let viewport_pane = self.get_pane_mut(pid).unwrap();
|
||||
if let Some(viewport_pane) = self.get_pane_mut(pid) {
|
||||
viewport_pane.set_geom_override(viewport_pane.position_and_size());
|
||||
}
|
||||
let viewport = { *self.viewport.borrow() };
|
||||
let active_pane = self.get_pane_mut(active_pane_id).unwrap();
|
||||
}
|
||||
let viewport = { *self.viewport.borrow() };
|
||||
if let Some(active_pane) = self.get_pane_mut(pane_id) {
|
||||
let full_screen_geom = PaneGeom {
|
||||
x: viewport.x,
|
||||
y: viewport.y,
|
||||
|
|
@ -1652,16 +1663,16 @@ impl TiledPanes {
|
|||
};
|
||||
active_pane.set_geom_override(full_screen_geom);
|
||||
}
|
||||
let connected_client_list: Vec<ClientId> =
|
||||
{ self.connected_clients.borrow().iter().copied().collect() };
|
||||
for client_id in connected_client_list {
|
||||
self.focus_pane(active_pane_id, client_id);
|
||||
}
|
||||
self.set_force_render();
|
||||
let display_area = *self.display_area.borrow();
|
||||
self.resize(display_area);
|
||||
self.fullscreen_is_active = true;
|
||||
}
|
||||
let connected_client_list: Vec<ClientId> =
|
||||
{ self.connected_clients.borrow().iter().copied().collect() };
|
||||
for client_id in connected_client_list {
|
||||
self.focus_pane(pane_id, client_id);
|
||||
}
|
||||
self.set_force_render();
|
||||
let display_area = *self.display_area.borrow();
|
||||
self.resize(display_area);
|
||||
self.fullscreen_is_active = Some(pane_id);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
File diff suppressed because it is too large
Load diff
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7482
|
||||
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||
---
|
||||
Some(
|
||||
ClearScreenForPaneId(
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,10 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 8121
|
||||
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||
---
|
||||
Some(
|
||||
CloseTabWithIndex(
|
||||
2,
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7127
|
||||
expression: "format!(\"{:#?}\", rerun_command_pane_event)"
|
||||
---
|
||||
Some(
|
||||
EditScrollbackForPaneWithId(
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,13 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7411
|
||||
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||
---
|
||||
Some(
|
||||
MovePaneWithPaneIdInDirection(
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
Left,
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7340
|
||||
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||
---
|
||||
Some(
|
||||
MovePaneWithPaneId(
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7908
|
||||
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||
---
|
||||
Some(
|
||||
PageScrollDownInPaneId(
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7837
|
||||
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||
---
|
||||
Some(
|
||||
PageScrollUpInPaneId(
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,19 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7056
|
||||
expression: "format!(\"{:#?}\", rerun_command_pane_event)"
|
||||
---
|
||||
Some(
|
||||
ResizePaneWithId(
|
||||
ResizeStrategy {
|
||||
resize: Increase,
|
||||
direction: Some(
|
||||
Left,
|
||||
),
|
||||
invert_on_boundaries: false,
|
||||
},
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7624
|
||||
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||
---
|
||||
Some(
|
||||
ScrollDownInPaneId(
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7766
|
||||
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||
---
|
||||
Some(
|
||||
ScrollToBottomInPaneId(
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7695
|
||||
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||
---
|
||||
Some(
|
||||
ScrollToTopInPaneId(
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7553
|
||||
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||
---
|
||||
Some(
|
||||
ScrollUpInPaneId(
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 8050
|
||||
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||
---
|
||||
Some(
|
||||
TogglePaneEmbedOrEjectForPaneId(
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,12 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7979
|
||||
expression: "format!(\"{:#?}\", screen_instruction)"
|
||||
---
|
||||
Some(
|
||||
TogglePaneIdFullscreen(
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,18 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7269
|
||||
expression: "format!(\"{:#?}\", rerun_command_pane_event)"
|
||||
---
|
||||
Some(
|
||||
WriteToPaneId(
|
||||
[
|
||||
102,
|
||||
111,
|
||||
111,
|
||||
10,
|
||||
],
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -0,0 +1,17 @@
|
|||
---
|
||||
source: zellij-server/src/plugins/./unit/plugin_tests.rs
|
||||
assertion_line: 7198
|
||||
expression: "format!(\"{:#?}\", rerun_command_pane_event)"
|
||||
---
|
||||
Some(
|
||||
WriteToPaneId(
|
||||
[
|
||||
102,
|
||||
111,
|
||||
111,
|
||||
],
|
||||
Terminal(
|
||||
2,
|
||||
),
|
||||
),
|
||||
)
|
||||
|
|
@ -272,6 +272,54 @@ fn host_run_plugin_command(caller: Caller<'_, PluginEnv>) {
|
|||
PluginCommand::RerunCommandPane(terminal_pane_id) => {
|
||||
rerun_command_pane(env, terminal_pane_id)
|
||||
},
|
||||
PluginCommand::ResizePaneIdWithDirection(resize, pane_id) => {
|
||||
resize_pane_with_id(env, resize, pane_id.into())
|
||||
},
|
||||
PluginCommand::EditScrollbackForPaneWithId(pane_id) => {
|
||||
edit_scrollback_for_pane_with_id(env, pane_id.into())
|
||||
},
|
||||
PluginCommand::WriteToPaneId(bytes, pane_id) => {
|
||||
write_to_pane_id(env, bytes, pane_id.into())
|
||||
},
|
||||
PluginCommand::WriteCharsToPaneId(chars, pane_id) => {
|
||||
write_chars_to_pane_id(env, chars, pane_id.into())
|
||||
},
|
||||
PluginCommand::MovePaneWithPaneId(pane_id) => {
|
||||
move_pane_with_pane_id(env, pane_id.into())
|
||||
},
|
||||
PluginCommand::MovePaneWithPaneIdInDirection(pane_id, direction) => {
|
||||
move_pane_with_pane_id_in_direction(env, pane_id.into(), direction)
|
||||
},
|
||||
PluginCommand::ClearScreenForPaneId(pane_id) => {
|
||||
clear_screen_for_pane_id(env, pane_id.into())
|
||||
},
|
||||
PluginCommand::ScrollUpInPaneId(pane_id) => {
|
||||
scroll_up_in_pane_id(env, pane_id.into())
|
||||
},
|
||||
PluginCommand::ScrollDownInPaneId(pane_id) => {
|
||||
scroll_down_in_pane_id(env, pane_id.into())
|
||||
},
|
||||
PluginCommand::ScrollToTopInPaneId(pane_id) => {
|
||||
scroll_to_top_in_pane_id(env, pane_id.into())
|
||||
},
|
||||
PluginCommand::ScrollToBottomInPaneId(pane_id) => {
|
||||
scroll_to_bottom_in_pane_id(env, pane_id.into())
|
||||
},
|
||||
PluginCommand::PageScrollUpInPaneId(pane_id) => {
|
||||
page_scroll_up_in_pane_id(env, pane_id.into())
|
||||
},
|
||||
PluginCommand::PageScrollDownInPaneId(pane_id) => {
|
||||
page_scroll_down_in_pane_id(env, pane_id.into())
|
||||
},
|
||||
PluginCommand::TogglePaneIdFullscreen(pane_id) => {
|
||||
toggle_pane_id_fullscreen(env, pane_id.into())
|
||||
},
|
||||
PluginCommand::TogglePaneEmbedOrEjectForPaneId(pane_id) => {
|
||||
toggle_pane_embed_or_eject_for_pane_id(env, pane_id.into())
|
||||
},
|
||||
PluginCommand::CloseTabWithIndex(tab_index) => {
|
||||
close_tab_with_index(env, tab_index)
|
||||
},
|
||||
},
|
||||
(PermissionStatus::Denied, permission) => {
|
||||
log::error!(
|
||||
|
|
@ -1442,6 +1490,105 @@ fn scan_host_folder(env: &PluginEnv, folder_to_scan: PathBuf) {
|
|||
}
|
||||
}
|
||||
|
||||
fn resize_pane_with_id(env: &PluginEnv, resize: ResizeStrategy, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::ResizePaneWithId(resize, pane_id));
|
||||
}
|
||||
|
||||
fn edit_scrollback_for_pane_with_id(env: &PluginEnv, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::EditScrollbackForPaneWithId(pane_id));
|
||||
}
|
||||
|
||||
fn write_to_pane_id(env: &PluginEnv, bytes: Vec<u8>, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::WriteToPaneId(bytes, pane_id));
|
||||
}
|
||||
|
||||
fn write_chars_to_pane_id(env: &PluginEnv, chars: String, pane_id: PaneId) {
|
||||
let bytes = chars.into_bytes();
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::WriteToPaneId(bytes, pane_id));
|
||||
}
|
||||
|
||||
fn move_pane_with_pane_id(env: &PluginEnv, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::MovePaneWithPaneId(pane_id));
|
||||
}
|
||||
|
||||
fn move_pane_with_pane_id_in_direction(env: &PluginEnv, pane_id: PaneId, direction: Direction) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::MovePaneWithPaneIdInDirection(
|
||||
pane_id, direction,
|
||||
));
|
||||
}
|
||||
|
||||
fn clear_screen_for_pane_id(env: &PluginEnv, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::ClearScreenForPaneId(pane_id));
|
||||
}
|
||||
|
||||
fn scroll_up_in_pane_id(env: &PluginEnv, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::ScrollUpInPaneId(pane_id));
|
||||
}
|
||||
|
||||
fn scroll_down_in_pane_id(env: &PluginEnv, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::ScrollDownInPaneId(pane_id));
|
||||
}
|
||||
|
||||
fn scroll_to_top_in_pane_id(env: &PluginEnv, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::ScrollToTopInPaneId(pane_id));
|
||||
}
|
||||
|
||||
fn scroll_to_bottom_in_pane_id(env: &PluginEnv, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::ScrollToBottomInPaneId(pane_id));
|
||||
}
|
||||
|
||||
fn page_scroll_up_in_pane_id(env: &PluginEnv, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::PageScrollUpInPaneId(pane_id));
|
||||
}
|
||||
|
||||
fn page_scroll_down_in_pane_id(env: &PluginEnv, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::PageScrollDownInPaneId(pane_id));
|
||||
}
|
||||
|
||||
fn toggle_pane_id_fullscreen(env: &PluginEnv, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::TogglePaneIdFullscreen(pane_id));
|
||||
}
|
||||
|
||||
fn toggle_pane_embed_or_eject_for_pane_id(env: &PluginEnv, pane_id: PaneId) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::TogglePaneEmbedOrEjectForPaneId(pane_id));
|
||||
}
|
||||
|
||||
fn close_tab_with_index(env: &PluginEnv, tab_index: usize) {
|
||||
let _ = env
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::CloseTabWithIndex(tab_index));
|
||||
}
|
||||
|
||||
// Custom panic handler for plugins.
|
||||
//
|
||||
// This is called when a panic occurs in a plugin. Since most panics will likely originate in the
|
||||
|
|
@ -1516,7 +1663,10 @@ fn check_command_permission(
|
|||
| PluginCommand::RunCommand(..)
|
||||
| PluginCommand::ExecCmd(..) => PermissionType::RunCommands,
|
||||
PluginCommand::WebRequest(..) => PermissionType::WebAccess,
|
||||
PluginCommand::Write(..) | PluginCommand::WriteChars(..) => PermissionType::WriteToStdin,
|
||||
PluginCommand::Write(..)
|
||||
| PluginCommand::WriteChars(..)
|
||||
| PluginCommand::WriteToPaneId(..)
|
||||
| PluginCommand::WriteCharsToPaneId(..) => PermissionType::WriteToStdin,
|
||||
PluginCommand::SwitchTabTo(..)
|
||||
| PluginCommand::SwitchToMode(..)
|
||||
| PluginCommand::NewTabsWithLayout(..)
|
||||
|
|
@ -1531,19 +1681,31 @@ fn check_command_permission(
|
|||
| PluginCommand::MoveFocusOrTab(..)
|
||||
| PluginCommand::Detach
|
||||
| PluginCommand::EditScrollback
|
||||
| PluginCommand::EditScrollbackForPaneWithId(..)
|
||||
| PluginCommand::ToggleTab
|
||||
| PluginCommand::MovePane
|
||||
| PluginCommand::MovePaneWithDirection(..)
|
||||
| PluginCommand::MovePaneWithPaneId(..)
|
||||
| PluginCommand::MovePaneWithPaneIdInDirection(..)
|
||||
| PluginCommand::ClearScreen
|
||||
| PluginCommand::ClearScreenForPaneId(..)
|
||||
| PluginCommand::ScrollUp
|
||||
| PluginCommand::ScrollUpInPaneId(..)
|
||||
| PluginCommand::ScrollDown
|
||||
| PluginCommand::ScrollDownInPaneId(..)
|
||||
| PluginCommand::ScrollToTop
|
||||
| PluginCommand::ScrollToTopInPaneId(..)
|
||||
| PluginCommand::ScrollToBottom
|
||||
| PluginCommand::ScrollToBottomInPaneId(..)
|
||||
| PluginCommand::PageScrollUp
|
||||
| PluginCommand::PageScrollUpInPaneId(..)
|
||||
| PluginCommand::PageScrollDown
|
||||
| PluginCommand::PageScrollDownInPaneId(..)
|
||||
| PluginCommand::ToggleFocusFullscreen
|
||||
| PluginCommand::TogglePaneIdFullscreen(..)
|
||||
| PluginCommand::TogglePaneFrames
|
||||
| PluginCommand::TogglePaneEmbedOrEject
|
||||
| PluginCommand::TogglePaneEmbedOrEjectForPaneId(..)
|
||||
| PluginCommand::UndoRenamePane
|
||||
| PluginCommand::CloseFocus
|
||||
| PluginCommand::ToggleActiveTabSync
|
||||
|
|
@ -1570,6 +1732,8 @@ fn check_command_permission(
|
|||
| PluginCommand::ShowPaneWithId(..)
|
||||
| PluginCommand::HidePaneWithId(..)
|
||||
| PluginCommand::RerunCommandPane(..)
|
||||
| PluginCommand::ResizePaneIdWithDirection(..)
|
||||
| PluginCommand::CloseTabWithIndex(..)
|
||||
| PluginCommand::KillSessions(..) => PermissionType::ChangeApplicationState,
|
||||
PluginCommand::UnblockCliPipeInput(..)
|
||||
| PluginCommand::BlockCliPipeInput(..)
|
||||
|
|
|
|||
|
|
@ -10,11 +10,7 @@ use crate::{
|
|||
};
|
||||
use async_std::task::{self, JoinHandle};
|
||||
use std::sync::Arc;
|
||||
use std::{
|
||||
collections::{BTreeMap, HashMap},
|
||||
os::unix::io::RawFd,
|
||||
path::PathBuf,
|
||||
};
|
||||
use std::{collections::HashMap, os::unix::io::RawFd, path::PathBuf};
|
||||
use zellij_utils::nix::unistd::Pid;
|
||||
use zellij_utils::{
|
||||
async_std,
|
||||
|
|
@ -32,7 +28,7 @@ use zellij_utils::{
|
|||
pub type VteBytes = Vec<u8>;
|
||||
pub type TabIndex = u32;
|
||||
|
||||
#[derive(Clone, Copy, Debug)]
|
||||
#[derive(Clone, Copy, Debug, Eq, PartialEq)]
|
||||
pub enum ClientTabIndexOrPaneId {
|
||||
ClientId(ClientId),
|
||||
TabIndex(usize),
|
||||
|
|
@ -51,7 +47,7 @@ pub enum PtyInstruction {
|
|||
ClientTabIndexOrPaneId,
|
||||
), // bool (if Some) is
|
||||
// should_float, String is an optional pane name
|
||||
OpenInPlaceEditor(PathBuf, Option<usize>, ClientId), // Option<usize> is the optional line number
|
||||
OpenInPlaceEditor(PathBuf, Option<usize>, ClientTabIndexOrPaneId), // Option<usize> is the optional line number
|
||||
SpawnTerminalVertically(Option<TerminalAction>, Option<String>, ClientId), // String is an
|
||||
// optional pane
|
||||
// name
|
||||
|
|
@ -357,9 +353,12 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
|
|||
},
|
||||
}
|
||||
},
|
||||
PtyInstruction::OpenInPlaceEditor(temp_file, line_number, client_id) => {
|
||||
let err_context =
|
||||
|| format!("failed to open in-place editor for client {}", client_id);
|
||||
PtyInstruction::OpenInPlaceEditor(
|
||||
temp_file,
|
||||
line_number,
|
||||
client_tab_index_or_pane_id,
|
||||
) => {
|
||||
let err_context = || format!("failed to open in-place editor for client");
|
||||
|
||||
match pty.spawn_terminal(
|
||||
Some(TerminalAction::OpenFile(OpenFilePayload::new(
|
||||
|
|
@ -367,14 +366,14 @@ pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<Layout>) -> Result<()> {
|
|||
line_number,
|
||||
None,
|
||||
))),
|
||||
ClientTabIndexOrPaneId::ClientId(client_id),
|
||||
client_tab_index_or_pane_id,
|
||||
) {
|
||||
Ok((pid, _starts_held)) => {
|
||||
pty.bus
|
||||
.senders
|
||||
.send_to_screen(ScreenInstruction::OpenInPlaceEditor(
|
||||
PaneId::Terminal(pid),
|
||||
client_id,
|
||||
client_tab_index_or_pane_id,
|
||||
))
|
||||
.with_context(err_context)?;
|
||||
},
|
||||
|
|
|
|||
|
|
@ -156,7 +156,7 @@ pub enum ScreenInstruction {
|
|||
bool, // start suppressed
|
||||
ClientTabIndexOrPaneId,
|
||||
),
|
||||
OpenInPlaceEditor(PaneId, ClientId),
|
||||
OpenInPlaceEditor(PaneId, ClientTabIndexOrPaneId),
|
||||
TogglePaneEmbedOrFloating(ClientId),
|
||||
ToggleFloatingPanes(ClientId, Option<TerminalAction>),
|
||||
HorizontalSplit(PaneId, Option<InitialTitle>, HoldForCommand, ClientId),
|
||||
|
|
@ -380,6 +380,21 @@ pub enum ScreenInstruction {
|
|||
hide_session_name: bool,
|
||||
},
|
||||
RerunCommandPane(u32), // u32 - terminal pane id
|
||||
ResizePaneWithId(ResizeStrategy, PaneId),
|
||||
EditScrollbackForPaneWithId(PaneId),
|
||||
WriteToPaneId(Vec<u8>, PaneId),
|
||||
MovePaneWithPaneId(PaneId),
|
||||
MovePaneWithPaneIdInDirection(PaneId, Direction),
|
||||
ClearScreenForPaneId(PaneId),
|
||||
ScrollUpInPaneId(PaneId),
|
||||
ScrollDownInPaneId(PaneId),
|
||||
ScrollToTopInPaneId(PaneId),
|
||||
ScrollToBottomInPaneId(PaneId),
|
||||
PageScrollUpInPaneId(PaneId),
|
||||
PageScrollDownInPaneId(PaneId),
|
||||
TogglePaneIdFullscreen(PaneId),
|
||||
TogglePaneEmbedOrEjectForPaneId(PaneId),
|
||||
CloseTabWithIndex(usize),
|
||||
}
|
||||
|
||||
impl From<&ScreenInstruction> for ScreenContext {
|
||||
|
|
@ -566,6 +581,27 @@ impl From<&ScreenInstruction> for ScreenContext {
|
|||
ScreenInstruction::ListClientsMetadata(..) => ScreenContext::ListClientsMetadata,
|
||||
ScreenInstruction::Reconfigure { .. } => ScreenContext::Reconfigure,
|
||||
ScreenInstruction::RerunCommandPane { .. } => ScreenContext::RerunCommandPane,
|
||||
ScreenInstruction::ResizePaneWithId(..) => ScreenContext::ResizePaneWithId,
|
||||
ScreenInstruction::EditScrollbackForPaneWithId(..) => {
|
||||
ScreenContext::EditScrollbackForPaneWithId
|
||||
},
|
||||
ScreenInstruction::WriteToPaneId(..) => ScreenContext::WriteToPaneId,
|
||||
ScreenInstruction::MovePaneWithPaneId(..) => ScreenContext::MovePaneWithPaneId,
|
||||
ScreenInstruction::MovePaneWithPaneIdInDirection(..) => {
|
||||
ScreenContext::MovePaneWithPaneIdInDirection
|
||||
},
|
||||
ScreenInstruction::ClearScreenForPaneId(..) => ScreenContext::ClearScreenForPaneId,
|
||||
ScreenInstruction::ScrollUpInPaneId(..) => ScreenContext::ScrollUpInPaneId,
|
||||
ScreenInstruction::ScrollDownInPaneId(..) => ScreenContext::ScrollDownInPaneId,
|
||||
ScreenInstruction::ScrollToTopInPaneId(..) => ScreenContext::ScrollToTopInPaneId,
|
||||
ScreenInstruction::ScrollToBottomInPaneId(..) => ScreenContext::ScrollToBottomInPaneId,
|
||||
ScreenInstruction::PageScrollUpInPaneId(..) => ScreenContext::PageScrollUpInPaneId,
|
||||
ScreenInstruction::PageScrollDownInPaneId(..) => ScreenContext::PageScrollDownInPaneId,
|
||||
ScreenInstruction::TogglePaneIdFullscreen(..) => ScreenContext::TogglePaneIdFullscreen,
|
||||
ScreenInstruction::TogglePaneEmbedOrEjectForPaneId(..) => {
|
||||
ScreenContext::TogglePaneEmbedOrEjectForPaneId
|
||||
},
|
||||
ScreenInstruction::CloseTabWithIndex(..) => ScreenContext::CloseTabWithIndex,
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -2010,6 +2046,19 @@ impl Screen {
|
|||
);
|
||||
}
|
||||
}
|
||||
pub fn resize_pane_with_id(&mut self, resize: ResizeStrategy, pane_id: PaneId) {
|
||||
let mut found = false;
|
||||
for tab in self.tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
tab.resize_pane_with_id(resize, pane_id);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
log::error!("Failed to find pane with id: {:?} to resize", pane_id);
|
||||
}
|
||||
}
|
||||
pub fn break_pane(
|
||||
&mut self,
|
||||
default_shell: Option<TerminalAction>,
|
||||
|
|
@ -2586,11 +2635,35 @@ pub(crate) fn screen_thread_main(
|
|||
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::OpenInPlaceEditor(pid, client_id) => {
|
||||
active_tab!(screen, client_id, |tab: &mut Tab| tab
|
||||
.replace_active_pane_with_editor_pane(pid, client_id), ?);
|
||||
screen.unblock_input()?;
|
||||
screen.log_and_report_session_state()?;
|
||||
ScreenInstruction::OpenInPlaceEditor(pid, client_tab_index_or_pane_id) => {
|
||||
match client_tab_index_or_pane_id {
|
||||
ClientTabIndexOrPaneId::ClientId(client_id) => {
|
||||
active_tab!(screen, client_id, |tab: &mut Tab| tab
|
||||
.replace_active_pane_with_editor_pane(pid, client_id), ?);
|
||||
screen.unblock_input()?;
|
||||
screen.log_and_report_session_state()?;
|
||||
},
|
||||
ClientTabIndexOrPaneId::TabIndex(tab_index) => {
|
||||
log::error!("Cannot OpenInPlaceEditor with a TabIndex");
|
||||
},
|
||||
ClientTabIndexOrPaneId::PaneId(pane_id_to_replace) => {
|
||||
let mut found = false;
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id_to_replace) {
|
||||
tab.replace_pane_with_editor_pane(pid, pane_id_to_replace);
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if !found {
|
||||
log::error!(
|
||||
"Could not find pane with id {:?} to replace",
|
||||
pane_id_to_replace
|
||||
);
|
||||
}
|
||||
},
|
||||
}
|
||||
|
||||
screen.render(None)?;
|
||||
},
|
||||
|
|
@ -4165,6 +4238,195 @@ pub(crate) fn screen_thread_main(
|
|||
ScreenInstruction::RerunCommandPane(terminal_pane_id) => {
|
||||
screen.rerun_command_pane_with_id(terminal_pane_id)
|
||||
},
|
||||
ScreenInstruction::ResizePaneWithId(resize, pane_id) => {
|
||||
screen.resize_pane_with_id(resize, pane_id)
|
||||
},
|
||||
ScreenInstruction::EditScrollbackForPaneWithId(pane_id) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
tab.edit_scrollback_for_pane_with_id(pane_id).non_fatal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::WriteToPaneId(bytes, pane_id) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
tab.write_to_pane_id(&None, bytes, false, pane_id, None)
|
||||
.non_fatal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::MovePaneWithPaneId(pane_id) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
tab.move_pane(pane_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::MovePaneWithPaneIdInDirection(pane_id, direction) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
match direction {
|
||||
Direction::Down => tab.move_pane_down(pane_id),
|
||||
Direction::Up => tab.move_pane_up(pane_id),
|
||||
Direction::Left => tab.move_pane_left(pane_id),
|
||||
Direction::Right => tab.move_pane_right(pane_id),
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::ClearScreenForPaneId(pane_id) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
tab.clear_screen_for_pane_id(pane_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::ScrollUpInPaneId(pane_id) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
if let PaneId::Terminal(terminal_pane_id) = pane_id {
|
||||
tab.scroll_terminal_up(terminal_pane_id);
|
||||
} else {
|
||||
// this is because to do this with plugins, we need the client_id -
|
||||
// which we do not have (yet?) in this context...
|
||||
log::error!(
|
||||
"Currently only terminal panes are supported for scrolling up"
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::ScrollDownInPaneId(pane_id) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
if let PaneId::Terminal(terminal_pane_id) = pane_id {
|
||||
tab.scroll_terminal_down(terminal_pane_id);
|
||||
} else {
|
||||
// this is because to do this with plugins, we need the client_id -
|
||||
// which we do not have (yet?) in this context...
|
||||
log::error!(
|
||||
"Currently only terminal panes are supported for scrolling down"
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::ScrollToTopInPaneId(pane_id) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
if let PaneId::Terminal(terminal_pane_id) = pane_id {
|
||||
tab.scroll_terminal_to_top(terminal_pane_id);
|
||||
} else {
|
||||
// this is because to do this with plugins, we need the client_id -
|
||||
// which we do not have (yet?) in this context...
|
||||
log::error!(
|
||||
"Currently only terminal panes are supported for scrolling to top"
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::ScrollToBottomInPaneId(pane_id) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
if let PaneId::Terminal(terminal_pane_id) = pane_id {
|
||||
tab.scroll_terminal_to_bottom(terminal_pane_id);
|
||||
} else {
|
||||
// this is because to do this with plugins, we need the client_id -
|
||||
// which we do not have (yet?) in this context...
|
||||
log::error!("Currently only terminal panes are supported for scrolling to bottom");
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::PageScrollUpInPaneId(pane_id) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
if let PaneId::Terminal(terminal_pane_id) = pane_id {
|
||||
tab.scroll_terminal_page_up(terminal_pane_id);
|
||||
} else {
|
||||
// this is because to do this with plugins, we need the client_id -
|
||||
// which we do not have (yet?) in this context...
|
||||
log::error!(
|
||||
"Currently only terminal panes are supported for scrolling"
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::PageScrollDownInPaneId(pane_id) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
if let PaneId::Terminal(terminal_pane_id) = pane_id {
|
||||
tab.scroll_terminal_page_down(terminal_pane_id);
|
||||
} else {
|
||||
// this is because to do this with plugins, we need the client_id -
|
||||
// which we do not have (yet?) in this context...
|
||||
log::error!(
|
||||
"Currently only terminal panes are supported for scrolling"
|
||||
);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::TogglePaneIdFullscreen(pane_id) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
tab.toggle_pane_fullscreen(pane_id);
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::TogglePaneEmbedOrEjectForPaneId(pane_id) => {
|
||||
let all_tabs = screen.get_tabs_mut();
|
||||
for tab in all_tabs.values_mut() {
|
||||
if tab.has_pane_with_pid(&pane_id) {
|
||||
tab.toggle_pane_embed_or_floating_for_pane_id(pane_id)
|
||||
.non_fatal();
|
||||
break;
|
||||
}
|
||||
}
|
||||
screen.render(None)?;
|
||||
},
|
||||
ScreenInstruction::CloseTabWithIndex(tab_index) => {
|
||||
screen.close_tab_at_index(tab_index).non_fatal()
|
||||
},
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
|
|
|
|||
|
|
@ -265,7 +265,7 @@ pub trait Pane {
|
|||
fn pull_left(&mut self, count: usize);
|
||||
fn pull_up(&mut self, count: usize);
|
||||
fn clear_screen(&mut self);
|
||||
fn dump_screen(&mut self, _client_id: ClientId, _full: bool) -> String {
|
||||
fn dump_screen(&self, _full: bool) -> String {
|
||||
"".to_owned()
|
||||
}
|
||||
fn scroll_up(&mut self, count: usize, client_id: ClientId);
|
||||
|
|
@ -1024,6 +1024,38 @@ impl Tab {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn toggle_pane_embed_or_floating_for_pane_id(&mut self, pane_id: PaneId) -> Result<()> {
|
||||
let err_context = || {
|
||||
format!(
|
||||
"failed to toggle embedded/floating pane for pane_id {:?}",
|
||||
pane_id
|
||||
)
|
||||
};
|
||||
if self.tiled_panes.fullscreen_is_active() {
|
||||
self.tiled_panes.unset_fullscreen();
|
||||
}
|
||||
if self.floating_panes.panes_contain(&pane_id) {
|
||||
if self.tiled_panes.has_room_for_new_pane() {
|
||||
let floating_pane_to_embed = self
|
||||
.extract_pane(pane_id, true, None)
|
||||
.with_context(|| {
|
||||
format!("failed to find floating pane (ID: {pane_id:?}) to embed",)
|
||||
})
|
||||
.with_context(err_context)?;
|
||||
self.add_tiled_pane(floating_pane_to_embed, pane_id, None)?;
|
||||
}
|
||||
} else if self.tiled_panes.panes_contain(&pane_id) {
|
||||
if self.get_selectable_tiled_panes().count() <= 1 {
|
||||
log::error!("Cannot float the last tiled pane...");
|
||||
// don't close the only pane on screen...
|
||||
return Ok(());
|
||||
}
|
||||
if let Some(embedded_pane_to_float) = self.extract_pane(pane_id, true, None) {
|
||||
self.add_floating_pane(embedded_pane_to_float, pane_id, None, None)?;
|
||||
}
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn toggle_floating_panes(
|
||||
&mut self,
|
||||
client_id: Option<ClientId>,
|
||||
|
|
@ -1181,28 +1213,7 @@ impl Tab {
|
|||
|
||||
match pid {
|
||||
PaneId::Terminal(pid) => {
|
||||
let next_terminal_position = self.get_next_terminal_position(); // TODO: this is not accurate in this case
|
||||
let mut new_pane = TerminalPane::new(
|
||||
pid,
|
||||
PaneGeom::default(), // the initial size will be set later
|
||||
self.style,
|
||||
next_terminal_position,
|
||||
String::new(),
|
||||
self.link_handler.clone(),
|
||||
self.character_cell_size.clone(),
|
||||
self.sixel_image_store.clone(),
|
||||
self.terminal_emulator_colors.clone(),
|
||||
self.terminal_emulator_color_codes.clone(),
|
||||
None,
|
||||
None,
|
||||
self.debug,
|
||||
self.arrow_fonts,
|
||||
self.styled_underlines,
|
||||
self.explicitly_disable_kitty_keyboard_protocol,
|
||||
);
|
||||
new_pane.update_name("EDITING SCROLLBACK"); // we do this here and not in the
|
||||
// constructor so it won't be overrided
|
||||
// by the editor
|
||||
let new_pane = self.new_scrollback_editor_pane(pid);
|
||||
let replaced_pane = if self.floating_panes.panes_are_visible() {
|
||||
self.floating_panes
|
||||
.replace_active_pane(Box::new(new_pane), client_id)
|
||||
|
|
@ -1213,9 +1224,7 @@ impl Tab {
|
|||
};
|
||||
match replaced_pane {
|
||||
Some(replaced_pane) => {
|
||||
let is_scrollback_editor = true;
|
||||
self.suppressed_panes
|
||||
.insert(PaneId::Terminal(pid), (is_scrollback_editor, replaced_pane));
|
||||
self.insert_scrollback_editor_replaced_pane(replaced_pane, pid);
|
||||
self.get_active_pane(client_id)
|
||||
.with_context(|| format!("no active pane found for client {client_id}"))
|
||||
.and_then(|current_active_pane| {
|
||||
|
|
@ -1243,6 +1252,60 @@ impl Tab {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn replace_pane_with_editor_pane(
|
||||
&mut self,
|
||||
pid: PaneId,
|
||||
pane_id_to_replace: PaneId,
|
||||
) -> Result<()> {
|
||||
// this method creates a new pane from pid and replaces it with the pane iwth the given pane_id_to_replace
|
||||
// the pane with the given pane_id_to_replace is then suppressed (hidden and not rendered) until the current
|
||||
// created pane is closed, in which case it will be replaced back by it
|
||||
let err_context = || format!("failed to suppress pane");
|
||||
|
||||
match pid {
|
||||
PaneId::Terminal(pid) => {
|
||||
let new_pane = self.new_scrollback_editor_pane(pid);
|
||||
let replaced_pane = if self.floating_panes.panes_contain(&pane_id_to_replace) {
|
||||
self.floating_panes
|
||||
.replace_pane(pane_id_to_replace, Box::new(new_pane))
|
||||
.ok()
|
||||
} else if self.tiled_panes.panes_contain(&pane_id_to_replace) {
|
||||
self.tiled_panes
|
||||
.replace_pane(pane_id_to_replace, Box::new(new_pane))
|
||||
} else if self
|
||||
.suppressed_panes
|
||||
.values()
|
||||
.any(|s_p| s_p.1.pid() == pane_id_to_replace)
|
||||
{
|
||||
log::error!("Cannot replace suppressed pane");
|
||||
None
|
||||
} else {
|
||||
// not a thing
|
||||
None
|
||||
};
|
||||
match replaced_pane {
|
||||
Some(replaced_pane) => {
|
||||
resize_pty!(
|
||||
replaced_pane,
|
||||
self.os_api,
|
||||
self.senders,
|
||||
self.character_cell_size
|
||||
);
|
||||
self.insert_scrollback_editor_replaced_pane(replaced_pane, pid);
|
||||
},
|
||||
None => {
|
||||
Err::<(), _>(anyhow!("Could not find editor pane to replace"))
|
||||
.with_context(err_context)
|
||||
.non_fatal();
|
||||
},
|
||||
}
|
||||
},
|
||||
PaneId::Plugin(_pid) => {
|
||||
// TBD, currently unsupported
|
||||
},
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn suppress_pane_and_replace_with_pid(
|
||||
&mut self,
|
||||
old_pane_id: PaneId,
|
||||
|
|
@ -1493,6 +1556,23 @@ impl Tab {
|
|||
}
|
||||
})
|
||||
}
|
||||
pub fn get_pane_with_id(&self, pane_id: PaneId) -> Option<&dyn Pane> {
|
||||
self.floating_panes
|
||||
.get_pane(pane_id)
|
||||
.map(Box::as_ref)
|
||||
.or_else(|| self.tiled_panes.get_pane(pane_id).map(Box::as_ref))
|
||||
.or_else(|| self.suppressed_panes.get(&pane_id).map(|p| p.1.as_ref()))
|
||||
}
|
||||
pub fn get_pane_with_id_mut(&mut self, pane_id: PaneId) -> Option<&mut Box<dyn Pane>> {
|
||||
self.floating_panes
|
||||
.get_pane_mut(pane_id)
|
||||
.or_else(|| self.tiled_panes.get_pane_mut(pane_id))
|
||||
.or_else(|| {
|
||||
self.suppressed_panes
|
||||
.get_mut(&pane_id)
|
||||
.map(|(_, pane)| pane)
|
||||
})
|
||||
}
|
||||
pub fn get_active_pane_mut(&mut self, client_id: ClientId) -> Option<&mut Box<dyn Pane>> {
|
||||
self.get_active_pane_id(client_id).and_then(|ap| {
|
||||
if self.floating_panes.panes_are_visible() {
|
||||
|
|
@ -1948,6 +2028,13 @@ impl Tab {
|
|||
}
|
||||
self.tiled_panes.toggle_active_pane_fullscreen(client_id);
|
||||
}
|
||||
pub fn toggle_pane_fullscreen(&mut self, pane_id: PaneId) {
|
||||
if self.tiled_panes.panes_contain(&pane_id) {
|
||||
self.tiled_panes.toggle_pane_fullscreen(pane_id);
|
||||
} else {
|
||||
log::error!("No tiled pane with id: {:?} found", pane_id);
|
||||
}
|
||||
}
|
||||
pub fn is_fullscreen_active(&self) -> bool {
|
||||
self.tiled_panes.fullscreen_is_active()
|
||||
}
|
||||
|
|
@ -2391,6 +2478,20 @@ impl Tab {
|
|||
.move_active_pane(search_backwards, client_id);
|
||||
}
|
||||
}
|
||||
pub fn move_pane(&mut self, pane_id: PaneId) {
|
||||
if !self.has_selectable_panes() {
|
||||
return;
|
||||
}
|
||||
if self.tiled_panes.fullscreen_is_active() {
|
||||
return;
|
||||
}
|
||||
let search_backwards = false;
|
||||
if self.floating_panes.panes_are_visible() {
|
||||
self.floating_panes.move_pane(search_backwards, pane_id);
|
||||
} else {
|
||||
self.tiled_panes.move_pane(search_backwards, pane_id);
|
||||
}
|
||||
}
|
||||
pub fn move_active_pane_backwards(&mut self, client_id: ClientId) {
|
||||
if !self.has_selectable_panes() {
|
||||
return;
|
||||
|
|
@ -2422,6 +2523,21 @@ impl Tab {
|
|||
self.tiled_panes.move_active_pane_down(client_id);
|
||||
}
|
||||
}
|
||||
pub fn move_pane_down(&mut self, pane_id: PaneId) {
|
||||
if self.floating_panes.panes_are_visible() {
|
||||
self.floating_panes.move_pane_down(pane_id);
|
||||
self.swap_layouts.set_is_floating_damaged();
|
||||
self.set_force_render(); // we force render here to make sure the panes under the floating pane render and don't leave "garbage" behind
|
||||
} else {
|
||||
if !self.has_selectable_panes() {
|
||||
return;
|
||||
}
|
||||
if self.tiled_panes.fullscreen_is_active() {
|
||||
return;
|
||||
}
|
||||
self.tiled_panes.move_pane_down(pane_id);
|
||||
}
|
||||
}
|
||||
pub fn move_active_pane_up(&mut self, client_id: ClientId) {
|
||||
if self.floating_panes.panes_are_visible() {
|
||||
self.floating_panes.move_active_pane_up(client_id);
|
||||
|
|
@ -2437,6 +2553,21 @@ impl Tab {
|
|||
self.tiled_panes.move_active_pane_up(client_id);
|
||||
}
|
||||
}
|
||||
pub fn move_pane_up(&mut self, pane_id: PaneId) {
|
||||
if self.floating_panes.panes_are_visible() {
|
||||
self.floating_panes.move_pane_up(pane_id);
|
||||
self.swap_layouts.set_is_floating_damaged();
|
||||
self.set_force_render(); // we force render here to make sure the panes under the floating pane render and don't leave "garbage" behind
|
||||
} else {
|
||||
if !self.has_selectable_panes() {
|
||||
return;
|
||||
}
|
||||
if self.tiled_panes.fullscreen_is_active() {
|
||||
return;
|
||||
}
|
||||
self.tiled_panes.move_pane_up(pane_id);
|
||||
}
|
||||
}
|
||||
pub fn move_active_pane_right(&mut self, client_id: ClientId) {
|
||||
if self.floating_panes.panes_are_visible() {
|
||||
self.floating_panes.move_active_pane_right(client_id);
|
||||
|
|
@ -2452,6 +2583,21 @@ impl Tab {
|
|||
self.tiled_panes.move_active_pane_right(client_id);
|
||||
}
|
||||
}
|
||||
pub fn move_pane_right(&mut self, pane_id: PaneId) {
|
||||
if self.floating_panes.panes_are_visible() {
|
||||
self.floating_panes.move_pane_right(pane_id);
|
||||
self.swap_layouts.set_is_floating_damaged();
|
||||
self.set_force_render(); // we force render here to make sure the panes under the floating pane render and don't leave "garbage" behind
|
||||
} else {
|
||||
if !self.has_selectable_panes() {
|
||||
return;
|
||||
}
|
||||
if self.tiled_panes.fullscreen_is_active() {
|
||||
return;
|
||||
}
|
||||
self.tiled_panes.move_pane_right(pane_id);
|
||||
}
|
||||
}
|
||||
pub fn move_active_pane_left(&mut self, client_id: ClientId) {
|
||||
if self.floating_panes.panes_are_visible() {
|
||||
self.floating_panes.move_active_pane_left(client_id);
|
||||
|
|
@ -2467,6 +2613,21 @@ impl Tab {
|
|||
self.tiled_panes.move_active_pane_left(client_id);
|
||||
}
|
||||
}
|
||||
pub fn move_pane_left(&mut self, pane_id: PaneId) {
|
||||
if self.floating_panes.panes_are_visible() {
|
||||
self.floating_panes.move_pane_left(pane_id);
|
||||
self.swap_layouts.set_is_floating_damaged();
|
||||
self.set_force_render(); // we force render here to make sure the panes under the floating pane render and don't leave "garbage" behind
|
||||
} else {
|
||||
if !self.has_selectable_panes() {
|
||||
return;
|
||||
}
|
||||
if self.tiled_panes.fullscreen_is_active() {
|
||||
return;
|
||||
}
|
||||
self.tiled_panes.move_pane_left(pane_id);
|
||||
}
|
||||
}
|
||||
fn close_down_to_max_terminals(&mut self) -> Result<()> {
|
||||
if let Some(max_panes) = self.max_panes {
|
||||
let terminals = self.get_tiled_pane_ids();
|
||||
|
|
@ -2744,6 +2905,11 @@ impl Tab {
|
|||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn clear_screen_for_pane_id(&mut self, pane_id: PaneId) {
|
||||
if let Some(pane) = self.get_pane_with_id_mut(pane_id) {
|
||||
pane.clear_screen();
|
||||
}
|
||||
}
|
||||
pub fn dump_active_terminal_screen(
|
||||
&mut self,
|
||||
file: Option<String>,
|
||||
|
|
@ -2754,13 +2920,25 @@ impl Tab {
|
|||
|| format!("failed to dump active terminal screen for client {client_id}");
|
||||
|
||||
if let Some(active_pane) = self.get_active_pane_or_floating_pane_mut(client_id) {
|
||||
let dump = active_pane.dump_screen(client_id, full);
|
||||
let dump = active_pane.dump_screen(full);
|
||||
self.os_api
|
||||
.write_to_file(dump, file)
|
||||
.with_context(err_context)?;
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn dump_terminal_screen(
|
||||
&mut self,
|
||||
file: Option<String>,
|
||||
pane_id: PaneId,
|
||||
full: bool,
|
||||
) -> Result<()> {
|
||||
if let Some(pane) = self.get_pane_with_id(pane_id) {
|
||||
let dump = pane.dump_screen(full);
|
||||
self.os_api.write_to_file(dump, file).non_fatal()
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn edit_scrollback(&mut self, client_id: ClientId) -> Result<()> {
|
||||
let err_context = || format!("failed to edit scrollback for client {client_id}");
|
||||
|
||||
|
|
@ -2779,16 +2957,44 @@ impl Tab {
|
|||
.send_to_pty(PtyInstruction::OpenInPlaceEditor(
|
||||
file,
|
||||
line_number,
|
||||
client_id,
|
||||
ClientTabIndexOrPaneId::ClientId(client_id),
|
||||
))
|
||||
.with_context(err_context)
|
||||
}
|
||||
pub fn edit_scrollback_for_pane_with_id(&mut self, pane_id: PaneId) -> Result<()> {
|
||||
if let PaneId::Terminal(_terminal_pane_id) = pane_id {
|
||||
let mut file = temp_dir();
|
||||
file.push(format!("{}.dump", Uuid::new_v4()));
|
||||
self.dump_terminal_screen(Some(String::from(file.to_string_lossy())), pane_id, true)
|
||||
.non_fatal();
|
||||
let line_number = self
|
||||
.get_pane_with_id(pane_id)
|
||||
.and_then(|a_t| a_t.get_line_number());
|
||||
self.senders.send_to_pty(PtyInstruction::OpenInPlaceEditor(
|
||||
file,
|
||||
line_number,
|
||||
ClientTabIndexOrPaneId::PaneId(pane_id),
|
||||
))
|
||||
} else {
|
||||
log::error!("Editing plugin pane scrollback is currently unsupported.");
|
||||
Ok(())
|
||||
}
|
||||
}
|
||||
pub fn scroll_active_terminal_up(&mut self, client_id: ClientId) {
|
||||
if let Some(active_pane) = self.get_active_pane_or_floating_pane_mut(client_id) {
|
||||
active_pane.scroll_up(1, client_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll_terminal_up(&mut self, terminal_pane_id: u32) {
|
||||
if let Some(terminal_pane) = self.get_pane_with_id_mut(PaneId::Terminal(terminal_pane_id)) {
|
||||
let fictitious_client_id = 1; // this is not checked for terminal panes and we
|
||||
// don't have an actual client id here
|
||||
// TODO: traits were a mistake
|
||||
terminal_pane.scroll_up(1, fictitious_client_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll_active_terminal_down(&mut self, client_id: ClientId) -> Result<()> {
|
||||
let err_context = || format!("failed to scroll down active pane for client {client_id}");
|
||||
|
||||
|
|
@ -2804,14 +3010,34 @@ impl Tab {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn scroll_terminal_down(&mut self, terminal_pane_id: u32) {
|
||||
if let Some(terminal_pane) = self.get_pane_with_id_mut(PaneId::Terminal(terminal_pane_id)) {
|
||||
let fictitious_client_id = 1; // this is not checked for terminal panes and we
|
||||
// don't have an actual client id here
|
||||
// TODO: traits were a mistake
|
||||
terminal_pane.scroll_down(1, fictitious_client_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll_active_terminal_up_page(&mut self, client_id: ClientId) {
|
||||
if let Some(active_pane) = self.get_active_pane_or_floating_pane_mut(client_id) {
|
||||
// prevent overflow when row == 0
|
||||
let scroll_rows = active_pane.rows().max(1) - 1;
|
||||
let scroll_rows = active_pane.rows().max(1).saturating_sub(1);
|
||||
active_pane.scroll_up(scroll_rows, client_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll_terminal_page_up(&mut self, terminal_pane_id: u32) {
|
||||
if let Some(terminal_pane) = self.get_pane_with_id_mut(PaneId::Terminal(terminal_pane_id)) {
|
||||
let fictitious_client_id = 1; // this is not checked for terminal panes and we
|
||||
// don't have an actual client id here
|
||||
// TODO: traits were a mistake
|
||||
// prevent overflow when row == 0
|
||||
let scroll_rows = terminal_pane.rows().max(1).saturating_sub(1);
|
||||
terminal_pane.scroll_up(scroll_rows, fictitious_client_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll_active_terminal_down_page(&mut self, client_id: ClientId) -> Result<()> {
|
||||
let err_context =
|
||||
|| format!("failed to scroll down one page in active pane for client {client_id}");
|
||||
|
|
@ -2829,14 +3055,40 @@ impl Tab {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn scroll_terminal_page_down(&mut self, terminal_pane_id: u32) {
|
||||
if let Some(terminal_pane) = self.get_pane_with_id_mut(PaneId::Terminal(terminal_pane_id)) {
|
||||
let fictitious_client_id = 1; // this is not checked for terminal panes and we
|
||||
// don't have an actual client id here
|
||||
// TODO: traits were a mistake
|
||||
let scroll_rows = terminal_pane.get_content_rows();
|
||||
terminal_pane.scroll_down(scroll_rows, fictitious_client_id);
|
||||
if !terminal_pane.is_scrolled() {
|
||||
if let PaneId::Terminal(raw_fd) = terminal_pane.pid() {
|
||||
self.process_pending_vte_events(raw_fd).non_fatal()
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll_active_terminal_up_half_page(&mut self, client_id: ClientId) {
|
||||
if let Some(active_pane) = self.get_active_pane_or_floating_pane_mut(client_id) {
|
||||
// prevent overflow when row == 0
|
||||
let scroll_rows = (active_pane.rows().max(1) - 1) / 2;
|
||||
let scroll_rows = (active_pane.rows().max(1).saturating_sub(1)) / 2;
|
||||
active_pane.scroll_up(scroll_rows, client_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll_terminal_half_page_up(&mut self, terminal_pane_id: u32) {
|
||||
if let Some(terminal_pane) = self.get_pane_with_id_mut(PaneId::Terminal(terminal_pane_id)) {
|
||||
let fictitious_client_id = 1; // this is not checked for terminal panes and we
|
||||
// don't have an actual client id here
|
||||
// TODO: traits were a mistake
|
||||
// prevent overflow when row == 0
|
||||
let scroll_rows = (terminal_pane.rows().max(1).saturating_sub(1)) / 2;
|
||||
terminal_pane.scroll_down(scroll_rows, fictitious_client_id);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll_active_terminal_down_half_page(&mut self, client_id: ClientId) -> Result<()> {
|
||||
let err_context =
|
||||
|| format!("failed to scroll down half a page in active pane for client {client_id}");
|
||||
|
|
@ -2854,6 +3106,21 @@ impl Tab {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn scroll_terminal_half_page_down(&mut self, terminal_pane_id: u32) {
|
||||
if let Some(terminal_pane) = self.get_pane_with_id_mut(PaneId::Terminal(terminal_pane_id)) {
|
||||
let fictitious_client_id = 1; // this is not checked for terminal panes and we
|
||||
// don't have an actual client id here
|
||||
// TODO: traits were a mistake
|
||||
let scroll_rows = (terminal_pane.rows().max(1) - 1) / 2;
|
||||
terminal_pane.scroll_down(scroll_rows, fictitious_client_id);
|
||||
if !terminal_pane.is_scrolled() {
|
||||
if let PaneId::Terminal(raw_fd) = terminal_pane.pid() {
|
||||
self.process_pending_vte_events(raw_fd).non_fatal();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll_active_terminal_to_bottom(&mut self, client_id: ClientId) -> Result<()> {
|
||||
let err_context =
|
||||
|| format!("failed to scroll to bottom in active pane for client {client_id}");
|
||||
|
|
@ -2870,6 +3137,17 @@ impl Tab {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn scroll_terminal_to_bottom(&mut self, terminal_pane_id: u32) {
|
||||
if let Some(terminal_pane) = self.get_pane_with_id_mut(PaneId::Terminal(terminal_pane_id)) {
|
||||
terminal_pane.clear_scroll();
|
||||
if !terminal_pane.is_scrolled() {
|
||||
if let PaneId::Terminal(raw_fd) = terminal_pane.pid() {
|
||||
self.process_pending_vte_events(raw_fd).non_fatal();
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn scroll_active_terminal_to_top(&mut self, client_id: ClientId) -> Result<()> {
|
||||
if let Some(active_pane) = self.get_active_pane_or_floating_pane_mut(client_id) {
|
||||
active_pane.clear_scroll();
|
||||
|
|
@ -2880,6 +3158,18 @@ impl Tab {
|
|||
Ok(())
|
||||
}
|
||||
|
||||
pub fn scroll_terminal_to_top(&mut self, terminal_pane_id: u32) {
|
||||
if let Some(terminal_pane) = self.get_pane_with_id_mut(PaneId::Terminal(terminal_pane_id)) {
|
||||
terminal_pane.clear_scroll();
|
||||
if let Some(size) = terminal_pane.get_line_number() {
|
||||
let fictitious_client_id = 1; // this is not checked for terminal panes and we
|
||||
// don't have an actual client id here
|
||||
// TODO: traits were a mistake
|
||||
terminal_pane.scroll_up(size, fictitious_client_id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
pub fn clear_active_terminal_scroll(&mut self, client_id: ClientId) -> Result<()> {
|
||||
// TODO: is this a thing?
|
||||
let err_context =
|
||||
|
|
@ -3954,6 +4244,50 @@ impl Tab {
|
|||
},
|
||||
}
|
||||
}
|
||||
pub fn resize_pane_with_id(&mut self, strategy: ResizeStrategy, pane_id: PaneId) -> Result<()> {
|
||||
let err_context = || format!("unable to resize pane");
|
||||
if self.floating_panes.panes_contain(&pane_id) {
|
||||
let successfully_resized = self
|
||||
.floating_panes
|
||||
.resize_pane_with_id(strategy, pane_id)
|
||||
.with_context(err_context)?;
|
||||
if successfully_resized {
|
||||
self.swap_layouts.set_is_floating_damaged();
|
||||
self.swap_layouts.set_is_tiled_damaged();
|
||||
self.set_force_render(); // we force render here to make sure the panes under the floating pane render and don't leave "garbage" in case of a decrease
|
||||
}
|
||||
} else if self.tiled_panes.panes_contain(&pane_id) {
|
||||
match self.tiled_panes.resize_pane_with_id(strategy, pane_id) {
|
||||
Ok(_) => {},
|
||||
Err(err) => match err.downcast_ref::<ZellijError>() {
|
||||
Some(ZellijError::CantResizeFixedPanes { pane_ids }) => {
|
||||
let mut pane_ids_to_error = vec![];
|
||||
for (id, is_terminal) in pane_ids {
|
||||
if *is_terminal {
|
||||
pane_ids_to_error.push(PaneId::Terminal(*id));
|
||||
} else {
|
||||
pane_ids_to_error.push(PaneId::Plugin(*id));
|
||||
};
|
||||
}
|
||||
self.senders
|
||||
.send_to_background_jobs(BackgroundJob::DisplayPaneError(
|
||||
pane_ids_to_error,
|
||||
"FIXED!".into(),
|
||||
))
|
||||
.with_context(err_context)?;
|
||||
},
|
||||
_ => Err::<(), _>(err).fatal(),
|
||||
},
|
||||
}
|
||||
} else if self
|
||||
.suppressed_panes
|
||||
.values()
|
||||
.any(|s_p| s_p.1.pid() == pane_id)
|
||||
{
|
||||
log::error!("Cannot resize suppressed panes");
|
||||
}
|
||||
Ok(())
|
||||
}
|
||||
pub fn update_theme(&mut self, theme: Palette) {
|
||||
self.style.colors = theme;
|
||||
self.floating_panes.update_pane_themes(theme);
|
||||
|
|
@ -3995,6 +4329,42 @@ impl Tab {
|
|||
pub fn update_auto_layout(&mut self, auto_layout: bool) {
|
||||
self.auto_layout = auto_layout;
|
||||
}
|
||||
fn new_scrollback_editor_pane(&self, pid: u32) -> TerminalPane {
|
||||
let next_terminal_position = self.get_next_terminal_position();
|
||||
let mut new_pane = TerminalPane::new(
|
||||
pid,
|
||||
PaneGeom::default(), // the initial size will be set later
|
||||
self.style,
|
||||
next_terminal_position,
|
||||
String::new(),
|
||||
self.link_handler.clone(),
|
||||
self.character_cell_size.clone(),
|
||||
self.sixel_image_store.clone(),
|
||||
self.terminal_emulator_colors.clone(),
|
||||
self.terminal_emulator_color_codes.clone(),
|
||||
None,
|
||||
None,
|
||||
self.debug,
|
||||
self.arrow_fonts,
|
||||
self.styled_underlines,
|
||||
self.explicitly_disable_kitty_keyboard_protocol,
|
||||
);
|
||||
new_pane.update_name("EDITING SCROLLBACK"); // we do this here and not in the
|
||||
// constructor so it won't be overrided
|
||||
// by the editor
|
||||
new_pane
|
||||
}
|
||||
fn insert_scrollback_editor_replaced_pane(
|
||||
&mut self,
|
||||
replaced_pane: Box<dyn Pane>,
|
||||
terminal_pane_id: u32,
|
||||
) {
|
||||
let is_scrollback_editor = true;
|
||||
self.suppressed_panes.insert(
|
||||
PaneId::Terminal(terminal_pane_id),
|
||||
(is_scrollback_editor, replaced_pane),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
pub fn pane_info_for_pane(pane_id: &PaneId, pane: &Box<dyn Pane>) -> PaneInfo {
|
||||
|
|
|
|||
|
|
@ -29,7 +29,10 @@ use std::env::set_var;
|
|||
use std::os::unix::io::RawFd;
|
||||
use std::sync::{Arc, Mutex};
|
||||
|
||||
use crate::{plugins::PluginInstruction, pty::PtyInstruction};
|
||||
use crate::{
|
||||
plugins::PluginInstruction,
|
||||
pty::{ClientTabIndexOrPaneId, PtyInstruction},
|
||||
};
|
||||
use zellij_utils::ipc::PixelDimensions;
|
||||
|
||||
use zellij_utils::{
|
||||
|
|
@ -1699,7 +1702,7 @@ pub fn send_cli_edit_scrollback_action() {
|
|||
{
|
||||
assert_eq!(scrollback_contents_file, &PathBuf::from(&dumped_file_name));
|
||||
assert_eq!(terminal_id, &Some(1));
|
||||
assert_eq!(client_id, &1);
|
||||
assert_eq!(client_id, &ClientTabIndexOrPaneId::ClientId(1));
|
||||
found_instruction = true;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -857,6 +857,179 @@ pub fn rerun_command_pane(terminal_pane_id: u32) {
|
|||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Sugar for close_terminal_pane and close_plugin_pane
|
||||
pub fn close_pane_with_id(pane_id: PaneId) {
|
||||
let plugin_command = match pane_id {
|
||||
PaneId::Terminal(terminal_pane_id) => PluginCommand::CloseTerminalPane(terminal_pane_id),
|
||||
PaneId::Plugin(plugin_pane_id) => PluginCommand::ClosePluginPane(plugin_pane_id),
|
||||
};
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Resize the specified pane (increase/decrease) with an optional direction (left/right/up/down)
|
||||
pub fn resize_pane_with_id(resize_strategy: ResizeStrategy, pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::ResizePaneIdWithDirection(resize_strategy, pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Changes the focus to the pane with the specified id, unsuppressing it if it was suppressed and switching to its tab and layer (eg. floating/tiled).
|
||||
pub fn focus_pane_with_id(pane_id: PaneId, should_float_if_hidden: bool) {
|
||||
let plugin_command = match pane_id {
|
||||
PaneId::Terminal(terminal_pane_id) => {
|
||||
PluginCommand::FocusTerminalPane(terminal_pane_id, should_float_if_hidden)
|
||||
},
|
||||
PaneId::Plugin(plugin_pane_id) => {
|
||||
PluginCommand::FocusPluginPane(plugin_pane_id, should_float_if_hidden)
|
||||
},
|
||||
};
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Edit the scrollback of the specified pane in the user's default `$EDITOR` (currently only works
|
||||
/// for terminal panes)
|
||||
pub fn edit_scrollback_for_pane_with_id(pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::EditScrollbackForPaneWithId(pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Write bytes to the `STDIN` of the specified pane
|
||||
pub fn write_to_pane_id(bytes: Vec<u8>, pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::WriteToPaneId(bytes, pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Write characters to the `STDIN` of the specified pane
|
||||
pub fn write_chars_to_pane_id(chars: &str, pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::WriteCharsToPaneId(chars.to_owned(), pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Switch the position of the pane with this id with a different pane
|
||||
pub fn move_pane_with_pane_id(pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::MovePaneWithPaneId(pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Switch the position of the pane with this id with a different pane in the specified direction (eg. `Down`, `Up`, `Left`, `Right`).
|
||||
pub fn move_pane_with_pane_id_in_direction(pane_id: PaneId, direction: Direction) {
|
||||
let plugin_command = PluginCommand::MovePaneWithPaneIdInDirection(pane_id, direction);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Clear the scroll buffer of the specified pane
|
||||
pub fn clear_screen_for_pane_id(pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::ClearScreenForPaneId(pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Scroll the specified pane up 1 line
|
||||
pub fn scroll_up_in_pane_id(pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::ScrollUpInPaneId(pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Scroll the specified pane down 1 line
|
||||
pub fn scroll_down_in_pane_id(pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::ScrollDownInPaneId(pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Scroll the specified pane all the way to the top of the scrollbuffer
|
||||
pub fn scroll_to_top_in_pane_id(pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::ScrollToTopInPaneId(pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Scroll the specified pane all the way to the bottom of the scrollbuffer
|
||||
pub fn scroll_to_bottom_in_pane_id(pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::ScrollToBottomInPaneId(pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Scroll the specified pane up one page
|
||||
pub fn page_scroll_up_in_pane_id(pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::PageScrollUpInPaneId(pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Scroll the specified pane down one page
|
||||
pub fn page_scroll_down_in_pane_id(pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::PageScrollDownInPaneId(pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Toggle the specified pane to be fullscreen or normal sized
|
||||
pub fn toggle_pane_id_fullscreen(pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::TogglePaneIdFullscreen(pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Embed the specified pane (make it stop floating) or turn it to a float pane if it is not
|
||||
pub fn toggle_pane_embed_or_eject_for_pane_id(pane_id: PaneId) {
|
||||
let plugin_command = PluginCommand::TogglePaneEmbedOrEjectForPaneId(pane_id);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Close the focused tab
|
||||
pub fn close_tab_with_index(tab_index: usize) {
|
||||
let plugin_command = PluginCommand::CloseTabWithIndex(tab_index);
|
||||
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
|
||||
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
|
||||
unsafe { host_run_plugin_command() };
|
||||
}
|
||||
|
||||
/// Rename the specified pane
|
||||
pub fn rename_pane_with_id<S: AsRef<str>>(pane_id: PaneId, new_name: S)
|
||||
where
|
||||
S: ToString,
|
||||
{
|
||||
let plugin_command = match pane_id {
|
||||
PaneId::Terminal(terminal_pane_id) => {
|
||||
PluginCommand::RenameTerminalPane(terminal_pane_id, new_name.to_string())
|
||||
},
|
||||
PaneId::Plugin(plugin_pane_id) => {
|
||||
PluginCommand::RenamePluginPane(plugin_pane_id, new_name.to_string())
|
||||
},
|
||||
};
|
||||
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
|
||||
|
||||
#[allow(unused)]
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@ pub struct PluginCommand {
|
|||
pub name: i32,
|
||||
#[prost(
|
||||
oneof = "plugin_command::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, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 60, 61, 62, 63, 64, 65, 66, 67"
|
||||
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, 28, 29, 30, 31, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83"
|
||||
)]
|
||||
pub payload: ::core::option::Option<plugin_command::Payload>,
|
||||
}
|
||||
|
|
@ -128,10 +128,150 @@ pub mod plugin_command {
|
|||
OpenCommandPaneBackgroundPayload(super::OpenCommandPanePayload),
|
||||
#[prost(message, tag = "67")]
|
||||
RerunCommandPanePayload(super::RerunCommandPanePayload),
|
||||
#[prost(message, tag = "68")]
|
||||
ResizePaneIdWithDirectionPayload(super::ResizePaneIdWithDirectionPayload),
|
||||
#[prost(message, tag = "69")]
|
||||
EditScrollbackForPaneWithIdPayload(super::EditScrollbackForPaneWithIdPayload),
|
||||
#[prost(message, tag = "70")]
|
||||
WriteToPaneIdPayload(super::WriteToPaneIdPayload),
|
||||
#[prost(message, tag = "71")]
|
||||
WriteCharsToPaneIdPayload(super::WriteCharsToPaneIdPayload),
|
||||
#[prost(message, tag = "72")]
|
||||
MovePaneWithPaneIdPayload(super::MovePaneWithPaneIdPayload),
|
||||
#[prost(message, tag = "73")]
|
||||
MovePaneWithPaneIdInDirectionPayload(
|
||||
super::MovePaneWithPaneIdInDirectionPayload,
|
||||
),
|
||||
#[prost(message, tag = "74")]
|
||||
ClearScreenForPaneIdPayload(super::ClearScreenForPaneIdPayload),
|
||||
#[prost(message, tag = "75")]
|
||||
ScrollUpInPaneIdPayload(super::ScrollUpInPaneIdPayload),
|
||||
#[prost(message, tag = "76")]
|
||||
ScrollDownInPaneIdPayload(super::ScrollDownInPaneIdPayload),
|
||||
#[prost(message, tag = "77")]
|
||||
ScrollToTopInPaneIdPayload(super::ScrollToTopInPaneIdPayload),
|
||||
#[prost(message, tag = "78")]
|
||||
ScrollToBottomInPaneIdPayload(super::ScrollToBottomInPaneIdPayload),
|
||||
#[prost(message, tag = "79")]
|
||||
PageScrollUpInPaneIdPayload(super::PageScrollUpInPaneIdPayload),
|
||||
#[prost(message, tag = "80")]
|
||||
PageScrollDownInPaneIdPayload(super::PageScrollDownInPaneIdPayload),
|
||||
#[prost(message, tag = "81")]
|
||||
TogglePaneIdFullscreenPayload(super::TogglePaneIdFullscreenPayload),
|
||||
#[prost(message, tag = "82")]
|
||||
TogglePaneEmbedOrEjectForPaneIdPayload(
|
||||
super::TogglePaneEmbedOrEjectForPaneIdPayload,
|
||||
),
|
||||
#[prost(message, tag = "83")]
|
||||
CloseTabWithIndexPayload(super::CloseTabWithIndexPayload),
|
||||
}
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct MovePaneWithPaneIdPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct MovePaneWithPaneIdInDirectionPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
#[prost(message, optional, tag = "2")]
|
||||
pub direction: ::core::option::Option<super::resize::MoveDirection>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ClearScreenForPaneIdPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ScrollUpInPaneIdPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ScrollDownInPaneIdPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ScrollToTopInPaneIdPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ScrollToBottomInPaneIdPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct PageScrollUpInPaneIdPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct PageScrollDownInPaneIdPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct TogglePaneIdFullscreenPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct TogglePaneEmbedOrEjectForPaneIdPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct CloseTabWithIndexPayload {
|
||||
#[prost(uint32, tag = "1")]
|
||||
pub tab_index: u32,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct WriteCharsToPaneIdPayload {
|
||||
#[prost(string, tag = "1")]
|
||||
pub chars_to_write: ::prost::alloc::string::String,
|
||||
#[prost(message, optional, tag = "2")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct WriteToPaneIdPayload {
|
||||
#[prost(bytes = "vec", tag = "1")]
|
||||
pub bytes_to_write: ::prost::alloc::vec::Vec<u8>,
|
||||
#[prost(message, optional, tag = "2")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct EditScrollbackForPaneWithIdPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ResizePaneIdWithDirectionPayload {
|
||||
#[prost(message, optional, tag = "1")]
|
||||
pub resize: ::core::option::Option<super::resize::Resize>,
|
||||
#[prost(message, optional, tag = "2")]
|
||||
pub pane_id: ::core::option::Option<PaneId>,
|
||||
}
|
||||
#[allow(clippy::derive_partial_eq_without_eq)]
|
||||
#[derive(Clone, PartialEq, ::prost::Message)]
|
||||
pub struct ReconfigurePayload {
|
||||
#[prost(string, tag = "1")]
|
||||
pub config: ::prost::alloc::string::String,
|
||||
|
|
@ -478,6 +618,22 @@ pub enum CommandName {
|
|||
ShowPaneWithId = 89,
|
||||
OpenCommandPaneBackground = 90,
|
||||
RerunCommandPane = 91,
|
||||
ResizePaneIdWithDirection = 92,
|
||||
EditScrollbackForPaneWithId = 93,
|
||||
WriteToPaneId = 94,
|
||||
WriteCharsToPaneId = 95,
|
||||
MovePaneWithPaneId = 96,
|
||||
MovePaneWithPaneIdInDirection = 97,
|
||||
ClearScreenForPaneId = 98,
|
||||
ScrollUpInPaneId = 99,
|
||||
ScrollDownInPaneId = 100,
|
||||
ScrollToTopInPaneId = 101,
|
||||
ScrollToBottomInPaneId = 102,
|
||||
PageScrollUpInPaneId = 103,
|
||||
PageScrollDownInPaneId = 104,
|
||||
TogglePaneIdFullscreen = 105,
|
||||
TogglePaneEmbedOrEjectForPaneId = 106,
|
||||
CloseTabWithIndex = 107,
|
||||
}
|
||||
impl CommandName {
|
||||
/// String value of the enum field names used in the ProtoBuf definition.
|
||||
|
|
@ -578,6 +734,24 @@ impl CommandName {
|
|||
CommandName::ShowPaneWithId => "ShowPaneWithId",
|
||||
CommandName::OpenCommandPaneBackground => "OpenCommandPaneBackground",
|
||||
CommandName::RerunCommandPane => "RerunCommandPane",
|
||||
CommandName::ResizePaneIdWithDirection => "ResizePaneIdWithDirection",
|
||||
CommandName::EditScrollbackForPaneWithId => "EditScrollbackForPaneWithId",
|
||||
CommandName::WriteToPaneId => "WriteToPaneId",
|
||||
CommandName::WriteCharsToPaneId => "WriteCharsToPaneId",
|
||||
CommandName::MovePaneWithPaneId => "MovePaneWithPaneId",
|
||||
CommandName::MovePaneWithPaneIdInDirection => "MovePaneWithPaneIdInDirection",
|
||||
CommandName::ClearScreenForPaneId => "ClearScreenForPaneId",
|
||||
CommandName::ScrollUpInPaneId => "ScrollUpInPaneId",
|
||||
CommandName::ScrollDownInPaneId => "ScrollDownInPaneId",
|
||||
CommandName::ScrollToTopInPaneId => "ScrollToTopInPaneId",
|
||||
CommandName::ScrollToBottomInPaneId => "ScrollToBottomInPaneId",
|
||||
CommandName::PageScrollUpInPaneId => "PageScrollUpInPaneId",
|
||||
CommandName::PageScrollDownInPaneId => "PageScrollDownInPaneId",
|
||||
CommandName::TogglePaneIdFullscreen => "TogglePaneIdFullscreen",
|
||||
CommandName::TogglePaneEmbedOrEjectForPaneId => {
|
||||
"TogglePaneEmbedOrEjectForPaneId"
|
||||
}
|
||||
CommandName::CloseTabWithIndex => "CloseTabWithIndex",
|
||||
}
|
||||
}
|
||||
/// Creates an enum from field names used in the ProtoBuf definition.
|
||||
|
|
@ -675,6 +849,24 @@ impl CommandName {
|
|||
"ShowPaneWithId" => Some(Self::ShowPaneWithId),
|
||||
"OpenCommandPaneBackground" => Some(Self::OpenCommandPaneBackground),
|
||||
"RerunCommandPane" => Some(Self::RerunCommandPane),
|
||||
"ResizePaneIdWithDirection" => Some(Self::ResizePaneIdWithDirection),
|
||||
"EditScrollbackForPaneWithId" => Some(Self::EditScrollbackForPaneWithId),
|
||||
"WriteToPaneId" => Some(Self::WriteToPaneId),
|
||||
"WriteCharsToPaneId" => Some(Self::WriteCharsToPaneId),
|
||||
"MovePaneWithPaneId" => Some(Self::MovePaneWithPaneId),
|
||||
"MovePaneWithPaneIdInDirection" => Some(Self::MovePaneWithPaneIdInDirection),
|
||||
"ClearScreenForPaneId" => Some(Self::ClearScreenForPaneId),
|
||||
"ScrollUpInPaneId" => Some(Self::ScrollUpInPaneId),
|
||||
"ScrollDownInPaneId" => Some(Self::ScrollDownInPaneId),
|
||||
"ScrollToTopInPaneId" => Some(Self::ScrollToTopInPaneId),
|
||||
"ScrollToBottomInPaneId" => Some(Self::ScrollToBottomInPaneId),
|
||||
"PageScrollUpInPaneId" => Some(Self::PageScrollUpInPaneId),
|
||||
"PageScrollDownInPaneId" => Some(Self::PageScrollDownInPaneId),
|
||||
"TogglePaneIdFullscreen" => Some(Self::TogglePaneIdFullscreen),
|
||||
"TogglePaneEmbedOrEjectForPaneId" => {
|
||||
Some(Self::TogglePaneEmbedOrEjectForPaneId)
|
||||
}
|
||||
"CloseTabWithIndex" => Some(Self::CloseTabWithIndex),
|
||||
_ => None,
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1820,4 +1820,20 @@ pub enum PluginCommand {
|
|||
ShowPaneWithId(PaneId, bool), // bool -> should_float_if_hidden
|
||||
OpenCommandPaneBackground(CommandToRun, Context),
|
||||
RerunCommandPane(u32), // u32 - terminal pane id
|
||||
ResizePaneIdWithDirection(ResizeStrategy, PaneId),
|
||||
EditScrollbackForPaneWithId(PaneId),
|
||||
WriteToPaneId(Vec<u8>, PaneId),
|
||||
WriteCharsToPaneId(String, PaneId),
|
||||
MovePaneWithPaneId(PaneId),
|
||||
MovePaneWithPaneIdInDirection(PaneId, Direction),
|
||||
ClearScreenForPaneId(PaneId),
|
||||
ScrollUpInPaneId(PaneId),
|
||||
ScrollDownInPaneId(PaneId),
|
||||
ScrollToTopInPaneId(PaneId),
|
||||
ScrollToBottomInPaneId(PaneId),
|
||||
PageScrollUpInPaneId(PaneId),
|
||||
PageScrollDownInPaneId(PaneId),
|
||||
TogglePaneIdFullscreen(PaneId),
|
||||
TogglePaneEmbedOrEjectForPaneId(PaneId),
|
||||
CloseTabWithIndex(usize), // usize - tab_index
|
||||
}
|
||||
|
|
|
|||
|
|
@ -355,6 +355,21 @@ pub enum ScreenContext {
|
|||
ListClientsMetadata,
|
||||
Reconfigure,
|
||||
RerunCommandPane,
|
||||
ResizePaneWithId,
|
||||
EditScrollbackForPaneWithId,
|
||||
WriteToPaneId,
|
||||
MovePaneWithPaneId,
|
||||
MovePaneWithPaneIdInDirection,
|
||||
ClearScreenForPaneId,
|
||||
ScrollUpInPaneId,
|
||||
ScrollDownInPaneId,
|
||||
ScrollToTopInPaneId,
|
||||
ScrollToBottomInPaneId,
|
||||
PageScrollUpInPaneId,
|
||||
PageScrollDownInPaneId,
|
||||
TogglePaneIdFullscreen,
|
||||
TogglePaneEmbedOrEjectForPaneId,
|
||||
CloseTabWithIndex,
|
||||
}
|
||||
|
||||
/// Stack call representations corresponding to the different types of [`PtyInstruction`]s.
|
||||
|
|
|
|||
|
|
@ -103,6 +103,22 @@ enum CommandName {
|
|||
ShowPaneWithId = 89;
|
||||
OpenCommandPaneBackground = 90;
|
||||
RerunCommandPane = 91;
|
||||
ResizePaneIdWithDirection = 92;
|
||||
EditScrollbackForPaneWithId = 93;
|
||||
WriteToPaneId = 94;
|
||||
WriteCharsToPaneId = 95;
|
||||
MovePaneWithPaneId = 96;
|
||||
MovePaneWithPaneIdInDirection = 97;
|
||||
ClearScreenForPaneId = 98;
|
||||
ScrollUpInPaneId = 99;
|
||||
ScrollDownInPaneId = 100;
|
||||
ScrollToTopInPaneId = 101;
|
||||
ScrollToBottomInPaneId = 102;
|
||||
PageScrollUpInPaneId = 103;
|
||||
PageScrollDownInPaneId = 104;
|
||||
TogglePaneIdFullscreen = 105;
|
||||
TogglePaneEmbedOrEjectForPaneId = 106;
|
||||
CloseTabWithIndex = 107;
|
||||
}
|
||||
|
||||
message PluginCommand {
|
||||
|
|
@ -165,9 +181,93 @@ message PluginCommand {
|
|||
ShowPaneWithIdPayload show_pane_with_id_payload = 65;
|
||||
OpenCommandPanePayload open_command_pane_background_payload = 66;
|
||||
RerunCommandPanePayload rerun_command_pane_payload = 67;
|
||||
ResizePaneIdWithDirectionPayload resize_pane_id_with_direction_payload = 68;
|
||||
EditScrollbackForPaneWithIdPayload edit_scrollback_for_pane_with_id_payload = 69;
|
||||
WriteToPaneIdPayload write_to_pane_id_payload = 70;
|
||||
WriteCharsToPaneIdPayload write_chars_to_pane_id_payload = 71;
|
||||
MovePaneWithPaneIdPayload move_pane_with_pane_id_payload = 72;
|
||||
MovePaneWithPaneIdInDirectionPayload move_pane_with_pane_id_in_direction_payload = 73;
|
||||
ClearScreenForPaneIdPayload clear_screen_for_pane_id_payload = 74;
|
||||
ScrollUpInPaneIdPayload scroll_up_in_pane_id_payload = 75;
|
||||
ScrollDownInPaneIdPayload scroll_down_in_pane_id_payload = 76;
|
||||
ScrollToTopInPaneIdPayload scroll_to_top_in_pane_id_payload = 77;
|
||||
ScrollToBottomInPaneIdPayload scroll_to_bottom_in_pane_id_payload = 78;
|
||||
PageScrollUpInPaneIdPayload page_scroll_up_in_pane_id_payload = 79;
|
||||
PageScrollDownInPaneIdPayload page_scroll_down_in_pane_id_payload = 80;
|
||||
TogglePaneIdFullscreenPayload toggle_pane_id_fullscreen_payload = 81;
|
||||
TogglePaneEmbedOrEjectForPaneIdPayload toggle_pane_embed_or_eject_for_pane_id_payload = 82;
|
||||
CloseTabWithIndexPayload close_tab_with_index_payload = 83;
|
||||
}
|
||||
}
|
||||
|
||||
message MovePaneWithPaneIdPayload {
|
||||
PaneId pane_id = 1;
|
||||
}
|
||||
|
||||
message MovePaneWithPaneIdInDirectionPayload {
|
||||
PaneId pane_id = 1;
|
||||
resize.MoveDirection direction = 2;
|
||||
}
|
||||
|
||||
message ClearScreenForPaneIdPayload {
|
||||
PaneId pane_id = 1;
|
||||
}
|
||||
|
||||
message ScrollUpInPaneIdPayload {
|
||||
PaneId pane_id = 1;
|
||||
}
|
||||
|
||||
message ScrollDownInPaneIdPayload {
|
||||
PaneId pane_id = 1;
|
||||
}
|
||||
|
||||
message ScrollToTopInPaneIdPayload {
|
||||
PaneId pane_id = 1;
|
||||
}
|
||||
|
||||
message ScrollToBottomInPaneIdPayload {
|
||||
PaneId pane_id = 1;
|
||||
}
|
||||
|
||||
message PageScrollUpInPaneIdPayload {
|
||||
PaneId pane_id = 1;
|
||||
}
|
||||
|
||||
message PageScrollDownInPaneIdPayload {
|
||||
PaneId pane_id = 1;
|
||||
}
|
||||
|
||||
message TogglePaneIdFullscreenPayload {
|
||||
PaneId pane_id = 1;
|
||||
}
|
||||
|
||||
message TogglePaneEmbedOrEjectForPaneIdPayload {
|
||||
PaneId pane_id = 1;
|
||||
}
|
||||
|
||||
message CloseTabWithIndexPayload {
|
||||
uint32 tab_index = 1;
|
||||
}
|
||||
|
||||
message WriteCharsToPaneIdPayload {
|
||||
string chars_to_write = 1;
|
||||
PaneId pane_id = 2;
|
||||
}
|
||||
|
||||
message WriteToPaneIdPayload {
|
||||
bytes bytes_to_write = 1;
|
||||
PaneId pane_id = 2;
|
||||
}
|
||||
|
||||
message EditScrollbackForPaneWithIdPayload {
|
||||
PaneId pane_id = 1;
|
||||
}
|
||||
|
||||
message ResizePaneIdWithDirectionPayload {
|
||||
resize.Resize resize = 1;
|
||||
PaneId pane_id = 2;
|
||||
}
|
||||
|
||||
message ReconfigurePayload {
|
||||
string config = 1;
|
||||
bool write_to_disk = 2;
|
||||
|
|
|
|||
|
|
@ -3,17 +3,23 @@ pub use super::generated_api::api::{
|
|||
event::{EventNameList as ProtobufEventNameList, Header},
|
||||
input_mode::InputMode as ProtobufInputMode,
|
||||
plugin_command::{
|
||||
plugin_command::Payload, CliPipeOutputPayload, CommandName, ContextItem, EnvVariable,
|
||||
ExecCmdPayload, FixedOrPercent as ProtobufFixedOrPercent,
|
||||
plugin_command::Payload, ClearScreenForPaneIdPayload, CliPipeOutputPayload,
|
||||
CloseTabWithIndexPayload, CommandName, ContextItem, EditScrollbackForPaneWithIdPayload,
|
||||
EnvVariable, ExecCmdPayload, FixedOrPercent as ProtobufFixedOrPercent,
|
||||
FixedOrPercentValue as ProtobufFixedOrPercentValue,
|
||||
FloatingPaneCoordinates as ProtobufFloatingPaneCoordinates, HidePaneWithIdPayload,
|
||||
HttpVerb as ProtobufHttpVerb, IdAndNewName, KillSessionsPayload, MessageToPluginPayload,
|
||||
MovePayload, NewPluginArgs as ProtobufNewPluginArgs, NewTabsWithLayoutInfoPayload,
|
||||
OpenCommandPanePayload, OpenFilePayload, PaneId as ProtobufPaneId,
|
||||
PaneType as ProtobufPaneType, PluginCommand as ProtobufPluginCommand, PluginMessagePayload,
|
||||
ReconfigurePayload, RequestPluginPermissionPayload, RerunCommandPanePayload, ResizePayload,
|
||||
RunCommandPayload, SetTimeoutPayload, ShowPaneWithIdPayload, SubscribePayload,
|
||||
SwitchSessionPayload, SwitchTabToPayload, UnsubscribePayload, WebRequestPayload,
|
||||
MovePaneWithPaneIdInDirectionPayload, MovePaneWithPaneIdPayload, MovePayload,
|
||||
NewPluginArgs as ProtobufNewPluginArgs, NewTabsWithLayoutInfoPayload,
|
||||
OpenCommandPanePayload, OpenFilePayload, PageScrollDownInPaneIdPayload,
|
||||
PageScrollUpInPaneIdPayload, PaneId as ProtobufPaneId, PaneType as ProtobufPaneType,
|
||||
PluginCommand as ProtobufPluginCommand, PluginMessagePayload, ReconfigurePayload,
|
||||
RequestPluginPermissionPayload, RerunCommandPanePayload, ResizePaneIdWithDirectionPayload,
|
||||
ResizePayload, RunCommandPayload, ScrollDownInPaneIdPayload, ScrollToBottomInPaneIdPayload,
|
||||
ScrollToTopInPaneIdPayload, ScrollUpInPaneIdPayload, SetTimeoutPayload,
|
||||
ShowPaneWithIdPayload, SubscribePayload, SwitchSessionPayload, SwitchTabToPayload,
|
||||
TogglePaneEmbedOrEjectForPaneIdPayload, TogglePaneIdFullscreenPayload, UnsubscribePayload,
|
||||
WebRequestPayload, WriteCharsToPaneIdPayload, WriteToPaneIdPayload,
|
||||
},
|
||||
plugin_permission::PermissionType as ProtobufPermissionType,
|
||||
resize::ResizeAction as ProtobufResizeAction,
|
||||
|
|
@ -991,6 +997,183 @@ impl TryFrom<ProtobufPluginCommand> for PluginCommand {
|
|||
),
|
||||
_ => Err("Mismatched payload for RerunCommandPane"),
|
||||
},
|
||||
Some(CommandName::ResizePaneIdWithDirection) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::ResizePaneIdWithDirectionPayload(resize_with_direction_payload)) => {
|
||||
match (
|
||||
resize_with_direction_payload.resize,
|
||||
resize_with_direction_payload.pane_id,
|
||||
) {
|
||||
(Some(resize), Some(pane_id)) => {
|
||||
Ok(PluginCommand::ResizePaneIdWithDirection(
|
||||
resize.try_into()?,
|
||||
pane_id.try_into()?,
|
||||
))
|
||||
},
|
||||
_ => Err("Malformed resize_pane_with_id payload"),
|
||||
}
|
||||
},
|
||||
_ => Err("Mismatched payload for Resize"),
|
||||
},
|
||||
Some(CommandName::EditScrollbackForPaneWithId) => match protobuf_plugin_command.payload
|
||||
{
|
||||
Some(Payload::EditScrollbackForPaneWithIdPayload(
|
||||
edit_scrollback_for_pane_with_id_payload,
|
||||
)) => match edit_scrollback_for_pane_with_id_payload.pane_id {
|
||||
Some(pane_id) => Ok(PluginCommand::EditScrollbackForPaneWithId(
|
||||
pane_id.try_into()?,
|
||||
)),
|
||||
_ => Err("Malformed edit_scrollback_for_pane_with_id payload"),
|
||||
},
|
||||
_ => Err("Mismatched payload for EditScrollback"),
|
||||
},
|
||||
Some(CommandName::WriteToPaneId) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::WriteToPaneIdPayload(write_to_pane_id_payload)) => {
|
||||
match write_to_pane_id_payload.pane_id {
|
||||
Some(pane_id) => Ok(PluginCommand::WriteToPaneId(
|
||||
write_to_pane_id_payload.bytes_to_write,
|
||||
pane_id.try_into()?,
|
||||
)),
|
||||
_ => Err("Malformed write_to_pane_id payload"),
|
||||
}
|
||||
},
|
||||
_ => Err("Mismatched payload for WriteToPaneId"),
|
||||
},
|
||||
Some(CommandName::WriteCharsToPaneId) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::WriteCharsToPaneIdPayload(write_chars_to_pane_id_payload)) => {
|
||||
match write_chars_to_pane_id_payload.pane_id {
|
||||
Some(pane_id) => Ok(PluginCommand::WriteCharsToPaneId(
|
||||
write_chars_to_pane_id_payload.chars_to_write,
|
||||
pane_id.try_into()?,
|
||||
)),
|
||||
_ => Err("Malformed write_chars_to_pane_id payload"),
|
||||
}
|
||||
},
|
||||
_ => Err("Mismatched payload for WriteCharsCharsToPaneId"),
|
||||
},
|
||||
Some(CommandName::MovePaneWithPaneId) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::MovePaneWithPaneIdPayload(move_pane_with_pane_id_payload)) => {
|
||||
match move_pane_with_pane_id_payload.pane_id {
|
||||
Some(pane_id) => Ok(PluginCommand::MovePaneWithPaneId(pane_id.try_into()?)),
|
||||
_ => Err("Malformed move_pane_with_pane_id payload"),
|
||||
}
|
||||
},
|
||||
_ => Err("Mismatched payload for MovePaneWithPaneId"),
|
||||
},
|
||||
Some(CommandName::MovePaneWithPaneIdInDirection) => {
|
||||
match protobuf_plugin_command.payload {
|
||||
Some(Payload::MovePaneWithPaneIdInDirectionPayload(move_payload)) => {
|
||||
match (move_payload.direction, move_payload.pane_id) {
|
||||
(Some(direction), Some(pane_id)) => {
|
||||
Ok(PluginCommand::MovePaneWithPaneIdInDirection(
|
||||
pane_id.try_into()?,
|
||||
direction.try_into()?,
|
||||
))
|
||||
},
|
||||
_ => Err("Malformed MovePaneWithPaneIdInDirection payload"),
|
||||
}
|
||||
},
|
||||
_ => Err("Mismatched payload for MovePaneWithDirection"),
|
||||
}
|
||||
},
|
||||
Some(CommandName::ClearScreenForPaneId) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::ClearScreenForPaneIdPayload(clear_screen_for_pane_id_payload)) => {
|
||||
match clear_screen_for_pane_id_payload.pane_id {
|
||||
Some(pane_id) => {
|
||||
Ok(PluginCommand::ClearScreenForPaneId(pane_id.try_into()?))
|
||||
},
|
||||
_ => Err("Malformed clear_screen_for_pane_id_payload payload"),
|
||||
}
|
||||
},
|
||||
_ => Err("Mismatched payload for ClearScreenForPaneId"),
|
||||
},
|
||||
Some(CommandName::ScrollUpInPaneId) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::ScrollUpInPaneIdPayload(scroll_up_in_pane_id_payload)) => {
|
||||
match scroll_up_in_pane_id_payload.pane_id {
|
||||
Some(pane_id) => Ok(PluginCommand::ScrollUpInPaneId(pane_id.try_into()?)),
|
||||
_ => Err("Malformed scroll_up_in_pane_id_payload payload"),
|
||||
}
|
||||
},
|
||||
_ => Err("Mismatched payload for ScrollUpInPaneId"),
|
||||
},
|
||||
Some(CommandName::ScrollDownInPaneId) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::ScrollDownInPaneIdPayload(scroll_down_in_pane_id_payload)) => {
|
||||
match scroll_down_in_pane_id_payload.pane_id {
|
||||
Some(pane_id) => Ok(PluginCommand::ScrollDownInPaneId(pane_id.try_into()?)),
|
||||
_ => Err("Malformed scroll_down_in_pane_id_payload payload"),
|
||||
}
|
||||
},
|
||||
_ => Err("Mismatched payload for ScrollDownInPaneId"),
|
||||
},
|
||||
Some(CommandName::ScrollToTopInPaneId) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::ScrollToTopInPaneIdPayload(scroll_to_top_in_pane_id_payload)) => {
|
||||
match scroll_to_top_in_pane_id_payload.pane_id {
|
||||
Some(pane_id) => {
|
||||
Ok(PluginCommand::ScrollToTopInPaneId(pane_id.try_into()?))
|
||||
},
|
||||
_ => Err("Malformed scroll_to_top_in_pane_id_payload payload"),
|
||||
}
|
||||
},
|
||||
_ => Err("Mismatched payload for ScrollToTopInPaneId"),
|
||||
},
|
||||
Some(CommandName::ScrollToBottomInPaneId) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::ScrollToBottomInPaneIdPayload(
|
||||
scroll_to_bottom_in_pane_id_payload,
|
||||
)) => match scroll_to_bottom_in_pane_id_payload.pane_id {
|
||||
Some(pane_id) => Ok(PluginCommand::ScrollToBottomInPaneId(pane_id.try_into()?)),
|
||||
_ => Err("Malformed scroll_to_bottom_in_pane_id_payload payload"),
|
||||
},
|
||||
_ => Err("Mismatched payload for ScrollToBottomInPaneId"),
|
||||
},
|
||||
Some(CommandName::PageScrollUpInPaneId) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::PageScrollUpInPaneIdPayload(page_scroll_up_in_pane_id_payload)) => {
|
||||
match page_scroll_up_in_pane_id_payload.pane_id {
|
||||
Some(pane_id) => {
|
||||
Ok(PluginCommand::PageScrollUpInPaneId(pane_id.try_into()?))
|
||||
},
|
||||
_ => Err("Malformed page_scroll_up_in_pane_id_payload payload"),
|
||||
}
|
||||
},
|
||||
_ => Err("Mismatched payload for PageScrollUpInPaneId"),
|
||||
},
|
||||
Some(CommandName::PageScrollDownInPaneId) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::PageScrollDownInPaneIdPayload(
|
||||
page_scroll_down_in_pane_id_payload,
|
||||
)) => match page_scroll_down_in_pane_id_payload.pane_id {
|
||||
Some(pane_id) => Ok(PluginCommand::PageScrollDownInPaneId(pane_id.try_into()?)),
|
||||
_ => Err("Malformed page_scroll_down_in_pane_id_payload payload"),
|
||||
},
|
||||
_ => Err("Mismatched payload for PageScrollDownInPaneId"),
|
||||
},
|
||||
Some(CommandName::TogglePaneIdFullscreen) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::TogglePaneIdFullscreenPayload(toggle_pane_id_fullscreen_payload)) => {
|
||||
match toggle_pane_id_fullscreen_payload.pane_id {
|
||||
Some(pane_id) => {
|
||||
Ok(PluginCommand::TogglePaneIdFullscreen(pane_id.try_into()?))
|
||||
},
|
||||
_ => Err("Malformed toggle_pane_id_fullscreen_payload payload"),
|
||||
}
|
||||
},
|
||||
_ => Err("Mismatched payload for TogglePaneIdFullscreen"),
|
||||
},
|
||||
Some(CommandName::TogglePaneEmbedOrEjectForPaneId) => {
|
||||
match protobuf_plugin_command.payload {
|
||||
Some(Payload::TogglePaneEmbedOrEjectForPaneIdPayload(
|
||||
toggle_pane_embed_or_eject_payload,
|
||||
)) => match toggle_pane_embed_or_eject_payload.pane_id {
|
||||
Some(pane_id) => Ok(PluginCommand::TogglePaneEmbedOrEjectForPaneId(
|
||||
pane_id.try_into()?,
|
||||
)),
|
||||
_ => Err("Malformed toggle_pane_embed_or_eject_payload payload"),
|
||||
},
|
||||
_ => Err("Mismatched payload for TogglePaneEmbedOrEjectForPaneId"),
|
||||
}
|
||||
},
|
||||
Some(CommandName::CloseTabWithIndex) => match protobuf_plugin_command.payload {
|
||||
Some(Payload::CloseTabWithIndexPayload(close_tab_index_payload)) => Ok(
|
||||
PluginCommand::CloseTabWithIndex(close_tab_index_payload.tab_index as usize),
|
||||
),
|
||||
_ => Err("Mismatched payload for CloseTabWithIndex"),
|
||||
},
|
||||
None => Err("Unrecognized plugin command"),
|
||||
}
|
||||
}
|
||||
|
|
@ -1605,6 +1788,140 @@ impl TryFrom<PluginCommand> for ProtobufPluginCommand {
|
|||
terminal_pane_id,
|
||||
})),
|
||||
}),
|
||||
PluginCommand::ResizePaneIdWithDirection(resize, pane_id) => {
|
||||
Ok(ProtobufPluginCommand {
|
||||
name: CommandName::ResizePaneIdWithDirection as i32,
|
||||
payload: Some(Payload::ResizePaneIdWithDirectionPayload(
|
||||
ResizePaneIdWithDirectionPayload {
|
||||
resize: Some(resize.try_into()?),
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
},
|
||||
)),
|
||||
})
|
||||
},
|
||||
PluginCommand::EditScrollbackForPaneWithId(pane_id) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::EditScrollbackForPaneWithId as i32,
|
||||
payload: Some(Payload::EditScrollbackForPaneWithIdPayload(
|
||||
EditScrollbackForPaneWithIdPayload {
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
PluginCommand::WriteToPaneId(bytes_to_write, pane_id) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::WriteToPaneId as i32,
|
||||
payload: Some(Payload::WriteToPaneIdPayload(WriteToPaneIdPayload {
|
||||
bytes_to_write,
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
})),
|
||||
}),
|
||||
PluginCommand::WriteCharsToPaneId(chars_to_write, pane_id) => {
|
||||
Ok(ProtobufPluginCommand {
|
||||
name: CommandName::WriteCharsToPaneId as i32,
|
||||
payload: Some(Payload::WriteCharsToPaneIdPayload(
|
||||
WriteCharsToPaneIdPayload {
|
||||
chars_to_write,
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
},
|
||||
)),
|
||||
})
|
||||
},
|
||||
PluginCommand::MovePaneWithPaneId(pane_id) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::MovePaneWithPaneId as i32,
|
||||
payload: Some(Payload::MovePaneWithPaneIdPayload(
|
||||
MovePaneWithPaneIdPayload {
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
PluginCommand::MovePaneWithPaneIdInDirection(pane_id, direction) => {
|
||||
Ok(ProtobufPluginCommand {
|
||||
name: CommandName::MovePaneWithPaneIdInDirection as i32,
|
||||
payload: Some(Payload::MovePaneWithPaneIdInDirectionPayload(
|
||||
MovePaneWithPaneIdInDirectionPayload {
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
direction: Some(direction.try_into()?),
|
||||
},
|
||||
)),
|
||||
})
|
||||
},
|
||||
PluginCommand::ClearScreenForPaneId(pane_id) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::ClearScreenForPaneId as i32,
|
||||
payload: Some(Payload::ClearScreenForPaneIdPayload(
|
||||
ClearScreenForPaneIdPayload {
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
PluginCommand::ScrollUpInPaneId(pane_id) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::ScrollUpInPaneId as i32,
|
||||
payload: Some(Payload::ScrollUpInPaneIdPayload(ScrollUpInPaneIdPayload {
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
})),
|
||||
}),
|
||||
PluginCommand::ScrollDownInPaneId(pane_id) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::ScrollDownInPaneId as i32,
|
||||
payload: Some(Payload::ScrollDownInPaneIdPayload(
|
||||
ScrollDownInPaneIdPayload {
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
PluginCommand::ScrollToTopInPaneId(pane_id) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::ScrollToTopInPaneId as i32,
|
||||
payload: Some(Payload::ScrollToTopInPaneIdPayload(
|
||||
ScrollToTopInPaneIdPayload {
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
PluginCommand::ScrollToBottomInPaneId(pane_id) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::ScrollToBottomInPaneId as i32,
|
||||
payload: Some(Payload::ScrollToBottomInPaneIdPayload(
|
||||
ScrollToBottomInPaneIdPayload {
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
PluginCommand::PageScrollUpInPaneId(pane_id) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::PageScrollUpInPaneId as i32,
|
||||
payload: Some(Payload::PageScrollUpInPaneIdPayload(
|
||||
PageScrollUpInPaneIdPayload {
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
PluginCommand::PageScrollDownInPaneId(pane_id) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::PageScrollDownInPaneId as i32,
|
||||
payload: Some(Payload::PageScrollDownInPaneIdPayload(
|
||||
PageScrollDownInPaneIdPayload {
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
PluginCommand::TogglePaneIdFullscreen(pane_id) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::TogglePaneIdFullscreen as i32,
|
||||
payload: Some(Payload::TogglePaneIdFullscreenPayload(
|
||||
TogglePaneIdFullscreenPayload {
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
PluginCommand::TogglePaneEmbedOrEjectForPaneId(pane_id) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::TogglePaneEmbedOrEjectForPaneId as i32,
|
||||
payload: Some(Payload::TogglePaneEmbedOrEjectForPaneIdPayload(
|
||||
TogglePaneEmbedOrEjectForPaneIdPayload {
|
||||
pane_id: Some(pane_id.try_into()?),
|
||||
},
|
||||
)),
|
||||
}),
|
||||
PluginCommand::CloseTabWithIndex(tab_index) => Ok(ProtobufPluginCommand {
|
||||
name: CommandName::CloseTabWithIndex as i32,
|
||||
payload: Some(Payload::CloseTabWithIndexPayload(
|
||||
CloseTabWithIndexPayload {
|
||||
tab_index: tab_index as u32,
|
||||
},
|
||||
)),
|
||||
}),
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue