Feature: Add pane names (#928)
* Read pane name from layout * Update pane name at runtime * Fix tests * prefer and render pane name over pane title * fix clippy errors * fix after rebase
This commit is contained in:
parent
368c852e57
commit
c75bcbd937
21 changed files with 233 additions and 22 deletions
|
|
@ -279,7 +279,7 @@ pub fn ctrl_keys(help: &ModeInfo, max_len: usize, separator: &str) -> LinePart {
|
||||||
colored_elements,
|
colored_elements,
|
||||||
separator,
|
separator,
|
||||||
),
|
),
|
||||||
InputMode::Pane => key_indicators(
|
InputMode::Pane | InputMode::RenamePane => key_indicators(
|
||||||
max_len,
|
max_len,
|
||||||
&[
|
&[
|
||||||
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock),
|
CtrlKeyShortcut::new(CtrlKeyMode::Unselected, CtrlKeyAction::Lock),
|
||||||
|
|
|
||||||
|
|
@ -131,7 +131,8 @@ fn read_from_channel(
|
||||||
let last_snapshot = last_snapshot.clone();
|
let last_snapshot = last_snapshot.clone();
|
||||||
let cursor_coordinates = cursor_coordinates.clone();
|
let cursor_coordinates = cursor_coordinates.clone();
|
||||||
let mut vte_parser = vte::Parser::new();
|
let mut vte_parser = vte::Parser::new();
|
||||||
let mut terminal_output = TerminalPane::new(0, *pane_geom, Palette::default(), 0); // 0 is the pane index
|
let mut terminal_output =
|
||||||
|
TerminalPane::new(0, *pane_geom, Palette::default(), 0, String::new()); // 0 is the pane index
|
||||||
let mut retries_left = 3;
|
let mut retries_left = 3;
|
||||||
move || {
|
move || {
|
||||||
let mut should_sleep = false;
|
let mut should_sleep = false;
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ pub fn start_client(
|
||||||
client_attributes,
|
client_attributes,
|
||||||
Box::new(opts),
|
Box::new(opts),
|
||||||
Box::new(config_options.clone()),
|
Box::new(config_options.clone()),
|
||||||
layout.unwrap(),
|
Box::new(layout.unwrap()),
|
||||||
Some(config.plugins.clone()),
|
Some(config.plugins.clone()),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ pub enum ServerInstruction {
|
||||||
ClientAttributes,
|
ClientAttributes,
|
||||||
Box<CliArgs>,
|
Box<CliArgs>,
|
||||||
Box<Options>,
|
Box<Options>,
|
||||||
LayoutFromYaml,
|
Box<LayoutFromYaml>,
|
||||||
ClientId,
|
ClientId,
|
||||||
Option<PluginsConfig>,
|
Option<PluginsConfig>,
|
||||||
),
|
),
|
||||||
|
|
@ -531,7 +531,7 @@ pub fn start_server(mut os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
|
||||||
pub struct SessionOptions {
|
pub struct SessionOptions {
|
||||||
pub opts: Box<CliArgs>,
|
pub opts: Box<CliArgs>,
|
||||||
pub config_options: Box<Options>,
|
pub config_options: Box<Options>,
|
||||||
pub layout: LayoutFromYaml,
|
pub layout: Box<LayoutFromYaml>,
|
||||||
pub plugins: Option<PluginsConfig>,
|
pub plugins: Option<PluginsConfig>,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -12,7 +12,7 @@ use crate::ClientId;
|
||||||
use zellij_utils::pane_size::Offset;
|
use zellij_utils::pane_size::Offset;
|
||||||
use zellij_utils::position::Position;
|
use zellij_utils::position::Position;
|
||||||
use zellij_utils::shared::ansi_len;
|
use zellij_utils::shared::ansi_len;
|
||||||
use zellij_utils::zellij_tile::prelude::{Event, Mouse, PaletteColor};
|
use zellij_utils::zellij_tile::prelude::{Event, InputMode, Mouse, PaletteColor};
|
||||||
use zellij_utils::{
|
use zellij_utils::{
|
||||||
channels::SenderWithContext,
|
channels::SenderWithContext,
|
||||||
pane_size::{Dimension, PaneGeom},
|
pane_size::{Dimension, PaneGeom},
|
||||||
|
|
@ -28,6 +28,7 @@ pub(crate) struct PluginPane {
|
||||||
pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
pub send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
||||||
pub active_at: Instant,
|
pub active_at: Instant,
|
||||||
pub pane_title: String,
|
pub pane_title: String,
|
||||||
|
pub pane_name: String,
|
||||||
frame: bool,
|
frame: bool,
|
||||||
borderless: bool,
|
borderless: bool,
|
||||||
}
|
}
|
||||||
|
|
@ -38,6 +39,7 @@ impl PluginPane {
|
||||||
position_and_size: PaneGeom,
|
position_and_size: PaneGeom,
|
||||||
send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
send_plugin_instructions: SenderWithContext<PluginInstruction>,
|
||||||
title: String,
|
title: String,
|
||||||
|
pane_name: String,
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
pid,
|
pid,
|
||||||
|
|
@ -51,6 +53,7 @@ impl PluginPane {
|
||||||
content_offset: Offset::default(),
|
content_offset: Offset::default(),
|
||||||
pane_title: title,
|
pane_title: title,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -209,14 +212,29 @@ impl Pane for PluginPane {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn render_frame(&mut self, _client_id: ClientId, frame_params: FrameParams) -> Option<String> {
|
fn render_frame(
|
||||||
|
&mut self,
|
||||||
|
_client_id: ClientId,
|
||||||
|
frame_params: FrameParams,
|
||||||
|
input_mode: InputMode,
|
||||||
|
) -> Option<String> {
|
||||||
// FIXME: This is a hack that assumes all fixed-size panes are borderless. This
|
// FIXME: This is a hack that assumes all fixed-size panes are borderless. This
|
||||||
// will eventually need fixing!
|
// will eventually need fixing!
|
||||||
if self.frame && !(self.geom.rows.is_fixed() || self.geom.cols.is_fixed()) {
|
if self.frame && !(self.geom.rows.is_fixed() || self.geom.cols.is_fixed()) {
|
||||||
|
let pane_title = if self.pane_name.is_empty()
|
||||||
|
&& input_mode == InputMode::RenamePane
|
||||||
|
&& frame_params.is_main_client
|
||||||
|
{
|
||||||
|
String::from("Enter name...")
|
||||||
|
} else if self.pane_name.is_empty() {
|
||||||
|
self.pane_title.clone()
|
||||||
|
} else {
|
||||||
|
self.pane_name.clone()
|
||||||
|
};
|
||||||
let frame = PaneFrame::new(
|
let frame = PaneFrame::new(
|
||||||
self.current_geom().into(),
|
self.current_geom().into(),
|
||||||
(0, 0), // scroll position
|
(0, 0), // scroll position
|
||||||
self.pane_title.clone(),
|
pane_title,
|
||||||
frame_params,
|
frame_params,
|
||||||
);
|
);
|
||||||
Some(frame.render())
|
Some(frame.render())
|
||||||
|
|
@ -231,6 +249,20 @@ impl Pane for PluginPane {
|
||||||
) -> Option<String> {
|
) -> Option<String> {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
|
fn update_name(&mut self, name: &str) {
|
||||||
|
match name {
|
||||||
|
"\0" => {
|
||||||
|
self.pane_name = String::new();
|
||||||
|
}
|
||||||
|
"\u{007F}" | "\u{0008}" => {
|
||||||
|
//delete and backspace keys
|
||||||
|
self.pane_name.pop();
|
||||||
|
}
|
||||||
|
c => {
|
||||||
|
self.pane_name.push_str(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
fn pid(&self) -> PaneId {
|
fn pid(&self) -> PaneId {
|
||||||
PaneId::Plugin(self.pid)
|
PaneId::Plugin(self.pid)
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ use zellij_utils::{
|
||||||
pane_size::{Dimension, PaneGeom},
|
pane_size::{Dimension, PaneGeom},
|
||||||
position::Position,
|
position::Position,
|
||||||
vte,
|
vte,
|
||||||
zellij_tile::data::{Palette, PaletteColor},
|
zellij_tile::data::{InputMode, Palette, PaletteColor},
|
||||||
};
|
};
|
||||||
|
|
||||||
pub const SELECTION_SCROLL_INTERVAL_MS: u64 = 10;
|
pub const SELECTION_SCROLL_INTERVAL_MS: u64 = 10;
|
||||||
|
|
@ -44,6 +44,7 @@ pub struct TerminalPane {
|
||||||
selection_scrolled_at: time::Instant,
|
selection_scrolled_at: time::Instant,
|
||||||
content_offset: Offset,
|
content_offset: Offset,
|
||||||
pane_title: String,
|
pane_title: String,
|
||||||
|
pane_name: String,
|
||||||
frame: HashMap<ClientId, PaneFrame>,
|
frame: HashMap<ClientId, PaneFrame>,
|
||||||
borderless: bool,
|
borderless: bool,
|
||||||
fake_cursor_locations: HashSet<(usize, usize)>, // (x, y) - these hold a record of previous fake cursors which we need to clear on render
|
fake_cursor_locations: HashSet<(usize, usize)>, // (x, y) - these hold a record of previous fake cursors which we need to clear on render
|
||||||
|
|
@ -278,16 +279,31 @@ impl Pane for TerminalPane {
|
||||||
None
|
None
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
fn render_frame(&mut self, client_id: ClientId, frame_params: FrameParams) -> Option<String> {
|
fn render_frame(
|
||||||
|
&mut self,
|
||||||
|
client_id: ClientId,
|
||||||
|
frame_params: FrameParams,
|
||||||
|
input_mode: InputMode,
|
||||||
|
) -> Option<String> {
|
||||||
// TODO: remove the cursor stuff from here
|
// TODO: remove the cursor stuff from here
|
||||||
let mut vte_output = None;
|
let mut vte_output = None;
|
||||||
let frame = PaneFrame::new(
|
let pane_title = if self.pane_name.is_empty()
|
||||||
self.current_geom().into(),
|
&& input_mode == InputMode::RenamePane
|
||||||
self.grid.scrollback_position_and_length(),
|
&& frame_params.is_main_client
|
||||||
|
{
|
||||||
|
String::from("Enter name...")
|
||||||
|
} else if self.pane_name.is_empty() {
|
||||||
self.grid
|
self.grid
|
||||||
.title
|
.title
|
||||||
.clone()
|
.clone()
|
||||||
.unwrap_or_else(|| self.pane_title.clone()),
|
.unwrap_or_else(|| self.pane_title.clone())
|
||||||
|
} else {
|
||||||
|
self.pane_name.clone()
|
||||||
|
};
|
||||||
|
let frame = PaneFrame::new(
|
||||||
|
self.current_geom().into(),
|
||||||
|
self.grid.scrollback_position_and_length(),
|
||||||
|
pane_title,
|
||||||
frame_params,
|
frame_params,
|
||||||
);
|
);
|
||||||
match self.frame.get(&client_id) {
|
match self.frame.get(&client_id) {
|
||||||
|
|
@ -336,6 +352,20 @@ impl Pane for TerminalPane {
|
||||||
}
|
}
|
||||||
vte_output
|
vte_output
|
||||||
}
|
}
|
||||||
|
fn update_name(&mut self, name: &str) {
|
||||||
|
match name {
|
||||||
|
"\0" => {
|
||||||
|
self.pane_name = String::new();
|
||||||
|
}
|
||||||
|
"\u{007F}" | "\u{0008}" => {
|
||||||
|
//delete and backspace keys
|
||||||
|
self.pane_name.pop();
|
||||||
|
}
|
||||||
|
c => {
|
||||||
|
self.pane_name.push_str(c);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
fn pid(&self) -> PaneId {
|
fn pid(&self) -> PaneId {
|
||||||
PaneId::Terminal(self.pid)
|
PaneId::Terminal(self.pid)
|
||||||
}
|
}
|
||||||
|
|
@ -475,6 +505,7 @@ impl TerminalPane {
|
||||||
position_and_size: PaneGeom,
|
position_and_size: PaneGeom,
|
||||||
palette: Palette,
|
palette: Palette,
|
||||||
pane_index: usize,
|
pane_index: usize,
|
||||||
|
pane_name: String,
|
||||||
) -> TerminalPane {
|
) -> TerminalPane {
|
||||||
let initial_pane_title = format!("Pane #{}", pane_index);
|
let initial_pane_title = format!("Pane #{}", pane_index);
|
||||||
let grid = Grid::new(
|
let grid = Grid::new(
|
||||||
|
|
@ -495,6 +526,7 @@ impl TerminalPane {
|
||||||
colors: palette,
|
colors: palette,
|
||||||
selection_scrolled_at: time::Instant::now(),
|
selection_scrolled_at: time::Instant::now(),
|
||||||
pane_title: initial_pane_title,
|
pane_title: initial_pane_title,
|
||||||
|
pane_name,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
fake_cursor_locations: HashSet::new(),
|
fake_cursor_locations: HashSet::new(),
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@ pub fn scrolling_inside_a_pane() {
|
||||||
|
|
||||||
let pid = 1;
|
let pid = 1;
|
||||||
let palette = Palette::default();
|
let palette = Palette::default();
|
||||||
let mut terminal_pane = TerminalPane::new(pid, fake_win_size, palette, 0); // 0 is the pane index
|
let mut terminal_pane = TerminalPane::new(pid, fake_win_size, palette, 0, String::new()); // 0 is the pane index
|
||||||
let mut text_to_fill_pane = String::new();
|
let mut text_to_fill_pane = String::new();
|
||||||
for i in 0..30 {
|
for i in 0..30 {
|
||||||
writeln!(&mut text_to_fill_pane, "\rline {}", i + 1).unwrap();
|
writeln!(&mut text_to_fill_pane, "\rline {}", i + 1).unwrap();
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ pub(crate) struct Pty {
|
||||||
|
|
||||||
use std::convert::TryFrom;
|
use std::convert::TryFrom;
|
||||||
|
|
||||||
pub(crate) fn pty_thread_main(mut pty: Pty, layout: LayoutFromYaml) {
|
pub(crate) fn pty_thread_main(mut pty: Pty, layout: Box<LayoutFromYaml>) {
|
||||||
loop {
|
loop {
|
||||||
let (event, mut err_ctx) = pty.bus.recv().expect("failed to receive event on channel");
|
let (event, mut err_ctx) = pty.bus.recv().expect("failed to receive event on channel");
|
||||||
err_ctx.add_call(ContextType::Pty((&event).into()));
|
err_ctx.add_call(ContextType::Pty((&event).into()));
|
||||||
|
|
|
||||||
|
|
@ -226,6 +226,12 @@ fn route_action(
|
||||||
};
|
};
|
||||||
session.senders.send_to_pty(pty_instr).unwrap();
|
session.senders.send_to_pty(pty_instr).unwrap();
|
||||||
}
|
}
|
||||||
|
Action::PaneNameInput(c) => {
|
||||||
|
session
|
||||||
|
.senders
|
||||||
|
.send_to_screen(ScreenInstruction::UpdatePaneName(c, client_id))
|
||||||
|
.unwrap();
|
||||||
|
}
|
||||||
Action::Run(command) => {
|
Action::Run(command) => {
|
||||||
let run_cmd = Some(TerminalAction::RunCommand(command.clone().into()));
|
let run_cmd = Some(TerminalAction::RunCommand(command.clone().into()));
|
||||||
let pty_instr = match command.direction {
|
let pty_instr = match command.direction {
|
||||||
|
|
|
||||||
|
|
@ -68,6 +68,7 @@ pub enum ScreenInstruction {
|
||||||
TogglePaneFrames,
|
TogglePaneFrames,
|
||||||
SetSelectable(PaneId, bool, usize),
|
SetSelectable(PaneId, bool, usize),
|
||||||
ClosePane(PaneId, Option<ClientId>),
|
ClosePane(PaneId, Option<ClientId>),
|
||||||
|
UpdatePaneName(Vec<u8>, ClientId),
|
||||||
NewTab(Layout, Vec<RawFd>, ClientId),
|
NewTab(Layout, Vec<RawFd>, ClientId),
|
||||||
SwitchTabNext(ClientId),
|
SwitchTabNext(ClientId),
|
||||||
SwitchTabPrev(ClientId),
|
SwitchTabPrev(ClientId),
|
||||||
|
|
@ -140,6 +141,7 @@ impl From<&ScreenInstruction> for ScreenContext {
|
||||||
ScreenInstruction::TogglePaneFrames => ScreenContext::TogglePaneFrames,
|
ScreenInstruction::TogglePaneFrames => ScreenContext::TogglePaneFrames,
|
||||||
ScreenInstruction::SetSelectable(..) => ScreenContext::SetSelectable,
|
ScreenInstruction::SetSelectable(..) => ScreenContext::SetSelectable,
|
||||||
ScreenInstruction::ClosePane(..) => ScreenContext::ClosePane,
|
ScreenInstruction::ClosePane(..) => ScreenContext::ClosePane,
|
||||||
|
ScreenInstruction::UpdatePaneName(..) => ScreenContext::UpdatePaneName,
|
||||||
ScreenInstruction::NewTab(..) => ScreenContext::NewTab,
|
ScreenInstruction::NewTab(..) => ScreenContext::NewTab,
|
||||||
ScreenInstruction::SwitchTabNext(..) => ScreenContext::SwitchTabNext,
|
ScreenInstruction::SwitchTabNext(..) => ScreenContext::SwitchTabNext,
|
||||||
ScreenInstruction::SwitchTabPrev(..) => ScreenContext::SwitchTabPrev,
|
ScreenInstruction::SwitchTabPrev(..) => ScreenContext::SwitchTabPrev,
|
||||||
|
|
@ -975,6 +977,14 @@ pub(crate) fn screen_thread_main(
|
||||||
}
|
}
|
||||||
screen.update_tabs();
|
screen.update_tabs();
|
||||||
}
|
}
|
||||||
|
ScreenInstruction::UpdatePaneName(c, client_id) => {
|
||||||
|
screen
|
||||||
|
.get_active_tab_mut(client_id)
|
||||||
|
.unwrap()
|
||||||
|
.update_active_pane_name(c, client_id);
|
||||||
|
|
||||||
|
screen.render();
|
||||||
|
}
|
||||||
ScreenInstruction::ToggleActiveTerminalFullscreen(client_id) => {
|
ScreenInstruction::ToggleActiveTerminalFullscreen(client_id) => {
|
||||||
screen
|
screen
|
||||||
.get_active_tab_mut(client_id)
|
.get_active_tab_mut(client_id)
|
||||||
|
|
|
||||||
|
|
@ -23,8 +23,9 @@ use std::time::Instant;
|
||||||
use std::{
|
use std::{
|
||||||
cmp::Reverse,
|
cmp::Reverse,
|
||||||
collections::{BTreeMap, HashMap, HashSet},
|
collections::{BTreeMap, HashMap, HashSet},
|
||||||
|
str,
|
||||||
};
|
};
|
||||||
use zellij_tile::data::{Event, ModeInfo, Palette, PaletteColor};
|
use zellij_tile::data::{Event, InputMode, ModeInfo, Palette, PaletteColor};
|
||||||
use zellij_utils::{
|
use zellij_utils::{
|
||||||
input::{
|
input::{
|
||||||
layout::{Direction, Layout, Run},
|
layout::{Direction, Layout, Run},
|
||||||
|
|
@ -181,12 +182,18 @@ pub trait Pane {
|
||||||
fn selectable(&self) -> bool;
|
fn selectable(&self) -> bool;
|
||||||
fn set_selectable(&mut self, selectable: bool);
|
fn set_selectable(&mut self, selectable: bool);
|
||||||
fn render(&mut self, client_id: Option<ClientId>) -> Option<String>;
|
fn render(&mut self, client_id: Option<ClientId>) -> Option<String>;
|
||||||
fn render_frame(&mut self, client_id: ClientId, frame_params: FrameParams) -> Option<String>;
|
fn render_frame(
|
||||||
|
&mut self,
|
||||||
|
client_id: ClientId,
|
||||||
|
frame_params: FrameParams,
|
||||||
|
input_mode: InputMode,
|
||||||
|
) -> Option<String>;
|
||||||
fn render_fake_cursor(
|
fn render_fake_cursor(
|
||||||
&mut self,
|
&mut self,
|
||||||
cursor_color: PaletteColor,
|
cursor_color: PaletteColor,
|
||||||
text_color: PaletteColor,
|
text_color: PaletteColor,
|
||||||
) -> Option<String>;
|
) -> Option<String>;
|
||||||
|
fn update_name(&mut self, name: &str);
|
||||||
fn pid(&self) -> PaneId;
|
fn pid(&self) -> PaneId;
|
||||||
fn reduce_height(&mut self, percent: f64);
|
fn reduce_height(&mut self, percent: f64);
|
||||||
fn increase_height(&mut self, percent: f64);
|
fn increase_height(&mut self, percent: f64);
|
||||||
|
|
@ -400,6 +407,7 @@ impl Tab {
|
||||||
*position_and_size,
|
*position_and_size,
|
||||||
self.senders.to_plugin.as_ref().unwrap().clone(),
|
self.senders.to_plugin.as_ref().unwrap().clone(),
|
||||||
pane_title,
|
pane_title,
|
||||||
|
layout.pane_name.clone().unwrap_or_default(),
|
||||||
);
|
);
|
||||||
new_plugin.set_borderless(layout.borderless);
|
new_plugin.set_borderless(layout.borderless);
|
||||||
self.panes.insert(PaneId::Plugin(pid), Box::new(new_plugin));
|
self.panes.insert(PaneId::Plugin(pid), Box::new(new_plugin));
|
||||||
|
|
@ -412,6 +420,7 @@ impl Tab {
|
||||||
*position_and_size,
|
*position_and_size,
|
||||||
self.colors,
|
self.colors,
|
||||||
next_terminal_position,
|
next_terminal_position,
|
||||||
|
layout.pane_name.clone().unwrap_or_default(),
|
||||||
);
|
);
|
||||||
new_pane.set_borderless(layout.borderless);
|
new_pane.set_borderless(layout.borderless);
|
||||||
self.panes
|
self.panes
|
||||||
|
|
@ -588,6 +597,7 @@ impl Tab {
|
||||||
bottom_winsize,
|
bottom_winsize,
|
||||||
self.colors,
|
self.colors,
|
||||||
next_terminal_position,
|
next_terminal_position,
|
||||||
|
String::new(),
|
||||||
);
|
);
|
||||||
terminal_to_split.set_geom(top_winsize);
|
terminal_to_split.set_geom(top_winsize);
|
||||||
self.panes.insert(pid, Box::new(new_terminal));
|
self.panes.insert(pid, Box::new(new_terminal));
|
||||||
|
|
@ -604,6 +614,7 @@ impl Tab {
|
||||||
right_winsize,
|
right_winsize,
|
||||||
self.colors,
|
self.colors,
|
||||||
next_terminal_position,
|
next_terminal_position,
|
||||||
|
String::new(),
|
||||||
);
|
);
|
||||||
terminal_to_split.set_geom(left_winsize);
|
terminal_to_split.set_geom(left_winsize);
|
||||||
self.panes.insert(pid, Box::new(new_terminal));
|
self.panes.insert(pid, Box::new(new_terminal));
|
||||||
|
|
@ -647,6 +658,7 @@ impl Tab {
|
||||||
bottom_winsize,
|
bottom_winsize,
|
||||||
self.colors,
|
self.colors,
|
||||||
next_terminal_position,
|
next_terminal_position,
|
||||||
|
String::new(),
|
||||||
);
|
);
|
||||||
active_pane.set_geom(top_winsize);
|
active_pane.set_geom(top_winsize);
|
||||||
self.panes.insert(pid, Box::new(new_terminal));
|
self.panes.insert(pid, Box::new(new_terminal));
|
||||||
|
|
@ -684,8 +696,13 @@ impl Tab {
|
||||||
}
|
}
|
||||||
let terminal_ws = active_pane.position_and_size();
|
let terminal_ws = active_pane.position_and_size();
|
||||||
if let Some((left_winsize, right_winsize)) = split(Direction::Vertical, &terminal_ws) {
|
if let Some((left_winsize, right_winsize)) = split(Direction::Vertical, &terminal_ws) {
|
||||||
let new_terminal =
|
let new_terminal = TerminalPane::new(
|
||||||
TerminalPane::new(term_pid, right_winsize, self.colors, next_terminal_position);
|
term_pid,
|
||||||
|
right_winsize,
|
||||||
|
self.colors,
|
||||||
|
next_terminal_position,
|
||||||
|
String::new(),
|
||||||
|
);
|
||||||
active_pane.set_geom(left_winsize);
|
active_pane.set_geom(left_winsize);
|
||||||
self.panes.insert(pid, Box::new(new_terminal));
|
self.panes.insert(pid, Box::new(new_terminal));
|
||||||
}
|
}
|
||||||
|
|
@ -3451,6 +3468,17 @@ impl Tab {
|
||||||
.unwrap();
|
.unwrap();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
pub fn update_active_pane_name(&mut self, buf: Vec<u8>, client_id: ClientId) {
|
||||||
|
if let Some(active_terminal_id) = self.get_active_terminal_id(client_id) {
|
||||||
|
let s = str::from_utf8(&buf).unwrap();
|
||||||
|
let active_terminal = self
|
||||||
|
.panes
|
||||||
|
.get_mut(&PaneId::Terminal(active_terminal_id))
|
||||||
|
.unwrap();
|
||||||
|
active_terminal.update_name(s);
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(clippy::borrowed_box)]
|
#[allow(clippy::borrowed_box)]
|
||||||
|
|
|
||||||
|
|
@ -132,7 +132,7 @@ impl<'a> PaneContentsAndUi<'a> {
|
||||||
other_cursors_exist_in_session: self.multiple_users_exist_in_session,
|
other_cursors_exist_in_session: self.multiple_users_exist_in_session,
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
if let Some(vte_output) = self.pane.render_frame(client_id, frame_params) {
|
if let Some(vte_output) = self.pane.render_frame(client_id, frame_params, client_mode) {
|
||||||
// FIXME: Use Termion for cursor and style clearing?
|
// FIXME: Use Termion for cursor and style clearing?
|
||||||
self.output.push_to_client(
|
self.output.push_to_client(
|
||||||
client_id,
|
client_id,
|
||||||
|
|
|
||||||
|
|
@ -77,8 +77,12 @@ pub enum InputMode {
|
||||||
/// `Scroll` mode allows scrolling up and down within a pane.
|
/// `Scroll` mode allows scrolling up and down within a pane.
|
||||||
#[serde(alias = "scroll")]
|
#[serde(alias = "scroll")]
|
||||||
Scroll,
|
Scroll,
|
||||||
|
/// `RenameTab` mode allows assigning a new name to a tab.
|
||||||
#[serde(alias = "renametab")]
|
#[serde(alias = "renametab")]
|
||||||
RenameTab,
|
RenameTab,
|
||||||
|
/// `RenamePane` mode allows assigning a new name to a pane.
|
||||||
|
#[serde(alias = "renamepane")]
|
||||||
|
RenamePane,
|
||||||
/// `Session` mode allows detaching sessions
|
/// `Session` mode allows detaching sessions
|
||||||
#[serde(alias = "session")]
|
#[serde(alias = "session")]
|
||||||
Session,
|
Session,
|
||||||
|
|
@ -133,6 +137,7 @@ impl FromStr for InputMode {
|
||||||
"session" => Ok(InputMode::Session),
|
"session" => Ok(InputMode::Session),
|
||||||
"move" => Ok(InputMode::Move),
|
"move" => Ok(InputMode::Move),
|
||||||
"prompt" => Ok(InputMode::Prompt),
|
"prompt" => Ok(InputMode::Prompt),
|
||||||
|
"renamepane" => Ok(InputMode::RenamePane),
|
||||||
e => Err(e.to_string().into()),
|
e => Err(e.to_string().into()),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,6 +135,8 @@ keybinds:
|
||||||
key: [ Alt: '[',]
|
key: [ Alt: '[',]
|
||||||
- action: [FocusNextPane,]
|
- action: [FocusNextPane,]
|
||||||
key: [ Alt: ']',]
|
key: [ Alt: ']',]
|
||||||
|
- action: [SwitchToMode: RenamePane, PaneNameInput: [0],]
|
||||||
|
key: [Char: 'c']
|
||||||
move:
|
move:
|
||||||
- action: [SwitchToMode: Locked,]
|
- action: [SwitchToMode: Locked,]
|
||||||
key: [Ctrl: 'g']
|
key: [Ctrl: 'g']
|
||||||
|
|
@ -304,6 +306,27 @@ keybinds:
|
||||||
key: [ Alt: '[',]
|
key: [ Alt: '[',]
|
||||||
- action: [FocusNextPane,]
|
- action: [FocusNextPane,]
|
||||||
key: [ Alt: ']',]
|
key: [ Alt: ']',]
|
||||||
|
renamepane:
|
||||||
|
- action: [SwitchToMode: Normal,]
|
||||||
|
key: [Ctrl: 'c', Ctrl: 's', Char: ' ',]
|
||||||
|
- action: [SwitchToMode: Pane,]
|
||||||
|
key: [Char: "\n",]
|
||||||
|
- action: [PaneNameInput: [27] , SwitchToMode: Pane,]
|
||||||
|
key: [Esc,]
|
||||||
|
- action: [NewPane: ,]
|
||||||
|
key: [ Alt: 'n',]
|
||||||
|
- action: [MoveFocus: Left,]
|
||||||
|
key: [ Alt: 'h',]
|
||||||
|
- action: [MoveFocus: Right,]
|
||||||
|
key: [ Alt: 'l',]
|
||||||
|
- action: [MoveFocus: Down,]
|
||||||
|
key: [ Alt: 'j',]
|
||||||
|
- action: [MoveFocus: Up,]
|
||||||
|
key: [ Alt: 'k',]
|
||||||
|
- action: [FocusPreviousPane,]
|
||||||
|
key: [ Alt: '[',]
|
||||||
|
- action: [FocusNextPane,]
|
||||||
|
key: [ Alt: ']',]
|
||||||
session:
|
session:
|
||||||
- action: [SwitchToMode: Locked,]
|
- action: [SwitchToMode: Locked,]
|
||||||
key: [Ctrl: 'g']
|
key: [Ctrl: 'g']
|
||||||
|
|
|
||||||
|
|
@ -251,6 +251,7 @@ pub enum ScreenContext {
|
||||||
SetFixedHeight,
|
SetFixedHeight,
|
||||||
SetFixedWidth,
|
SetFixedWidth,
|
||||||
ClosePane,
|
ClosePane,
|
||||||
|
UpdatePaneName,
|
||||||
NewTab,
|
NewTab,
|
||||||
SwitchTabNext,
|
SwitchTabNext,
|
||||||
SwitchTabPrev,
|
SwitchTabPrev,
|
||||||
|
|
|
||||||
|
|
@ -83,6 +83,7 @@ pub enum Action {
|
||||||
NewPane(Option<Direction>),
|
NewPane(Option<Direction>),
|
||||||
/// Close the focus pane.
|
/// Close the focus pane.
|
||||||
CloseFocus,
|
CloseFocus,
|
||||||
|
PaneNameInput(Vec<u8>),
|
||||||
/// Create a new tab, optionally with a specified tab layout.
|
/// Create a new tab, optionally with a specified tab layout.
|
||||||
NewTab(Option<TabLayout>),
|
NewTab(Option<TabLayout>),
|
||||||
/// Do nothing.
|
/// Do nothing.
|
||||||
|
|
|
||||||
|
|
@ -209,6 +209,7 @@ impl Keybinds {
|
||||||
mode_keybind_or_action(Action::Write(raw_bytes))
|
mode_keybind_or_action(Action::Write(raw_bytes))
|
||||||
}
|
}
|
||||||
InputMode::RenameTab => mode_keybind_or_action(Action::TabNameInput(raw_bytes)),
|
InputMode::RenameTab => mode_keybind_or_action(Action::TabNameInput(raw_bytes)),
|
||||||
|
InputMode::RenamePane => mode_keybind_or_action(Action::PaneNameInput(raw_bytes)),
|
||||||
_ => mode_keybind_or_action(Action::NoOp),
|
_ => mode_keybind_or_action(Action::NoOp),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -133,6 +133,8 @@ impl fmt::Display for RunPluginLocation {
|
||||||
pub struct Layout {
|
pub struct Layout {
|
||||||
pub direction: Direction,
|
pub direction: Direction,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
pub pane_name: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
pub parts: Vec<Layout>,
|
pub parts: Vec<Layout>,
|
||||||
pub split_size: Option<SplitSize>,
|
pub split_size: Option<SplitSize>,
|
||||||
pub run: Option<Run>,
|
pub run: Option<Run>,
|
||||||
|
|
@ -411,6 +413,8 @@ fn default_as_some_true() -> Option<bool> {
|
||||||
pub struct LayoutTemplate {
|
pub struct LayoutTemplate {
|
||||||
pub direction: Direction,
|
pub direction: Direction,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
pub pane_name: Option<String>,
|
||||||
|
#[serde(default)]
|
||||||
pub borderless: bool,
|
pub borderless: bool,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub parts: Vec<LayoutTemplate>,
|
pub parts: Vec<LayoutTemplate>,
|
||||||
|
|
@ -454,6 +458,7 @@ impl LayoutTemplate {
|
||||||
pub struct TabLayout {
|
pub struct TabLayout {
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub direction: Direction,
|
pub direction: Direction,
|
||||||
|
pub pane_name: Option<String>,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
pub borderless: bool,
|
pub borderless: bool,
|
||||||
#[serde(default)]
|
#[serde(default)]
|
||||||
|
|
@ -703,6 +708,7 @@ impl TryFrom<TabLayout> for Layout {
|
||||||
fn try_from(tab: TabLayout) -> Result<Self, Self::Error> {
|
fn try_from(tab: TabLayout) -> Result<Self, Self::Error> {
|
||||||
Ok(Layout {
|
Ok(Layout {
|
||||||
direction: tab.direction,
|
direction: tab.direction,
|
||||||
|
pane_name: tab.pane_name,
|
||||||
borderless: tab.borderless,
|
borderless: tab.borderless,
|
||||||
parts: Self::from_vec_tab_layout(tab.parts)?,
|
parts: Self::from_vec_tab_layout(tab.parts)?,
|
||||||
split_size: tab.split_size,
|
split_size: tab.split_size,
|
||||||
|
|
@ -715,6 +721,7 @@ impl From<TabLayout> for LayoutTemplate {
|
||||||
fn from(tab: TabLayout) -> Self {
|
fn from(tab: TabLayout) -> Self {
|
||||||
Self {
|
Self {
|
||||||
direction: tab.direction,
|
direction: tab.direction,
|
||||||
|
pane_name: tab.pane_name,
|
||||||
borderless: tab.borderless,
|
borderless: tab.borderless,
|
||||||
parts: Self::from_vec_tab_layout(tab.parts),
|
parts: Self::from_vec_tab_layout(tab.parts),
|
||||||
body: false,
|
body: false,
|
||||||
|
|
@ -730,6 +737,7 @@ impl TryFrom<LayoutTemplate> for Layout {
|
||||||
fn try_from(template: LayoutTemplate) -> Result<Self, Self::Error> {
|
fn try_from(template: LayoutTemplate) -> Result<Self, Self::Error> {
|
||||||
Ok(Layout {
|
Ok(Layout {
|
||||||
direction: template.direction,
|
direction: template.direction,
|
||||||
|
pane_name: template.pane_name,
|
||||||
borderless: template.borderless,
|
borderless: template.borderless,
|
||||||
parts: Self::from_vec_template_layout(template.parts)?,
|
parts: Self::from_vec_template_layout(template.parts)?,
|
||||||
split_size: template.split_size,
|
split_size: template.split_size,
|
||||||
|
|
@ -752,6 +760,7 @@ impl Default for TabLayout {
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
name: String::new(),
|
name: String::new(),
|
||||||
|
pane_name: None,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -760,10 +769,12 @@ impl Default for LayoutTemplate {
|
||||||
fn default() -> Self {
|
fn default() -> Self {
|
||||||
Self {
|
Self {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
|
pane_name: None,
|
||||||
body: false,
|
body: false,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
parts: vec![LayoutTemplate {
|
parts: vec![LayoutTemplate {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
|
pane_name: None,
|
||||||
body: true,
|
body: true,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
split_size: None,
|
split_size: None,
|
||||||
|
|
|
||||||
|
|
@ -40,6 +40,7 @@ pub fn get_mode_info(
|
||||||
("x".to_string(), "Close".to_string()),
|
("x".to_string(), "Close".to_string()),
|
||||||
("f".to_string(), "Fullscreen".to_string()),
|
("f".to_string(), "Fullscreen".to_string()),
|
||||||
("z".to_string(), "Frames".to_string()),
|
("z".to_string(), "Frames".to_string()),
|
||||||
|
("c".to_string(), "Rename".to_string()),
|
||||||
],
|
],
|
||||||
InputMode::Tab => vec![
|
InputMode::Tab => vec![
|
||||||
("←↓↑→".to_string(), "Move focus".to_string()),
|
("←↓↑→".to_string(), "Move focus".to_string()),
|
||||||
|
|
@ -55,6 +56,7 @@ pub fn get_mode_info(
|
||||||
("u/d".to_string(), "Scroll Half Page".to_string()),
|
("u/d".to_string(), "Scroll Half Page".to_string()),
|
||||||
],
|
],
|
||||||
InputMode::RenameTab => vec![("Enter".to_string(), "when done".to_string())],
|
InputMode::RenameTab => vec![("Enter".to_string(), "when done".to_string())],
|
||||||
|
InputMode::RenamePane => vec![("Enter".to_string(), "when done".to_string())],
|
||||||
InputMode::Session => vec![("d".to_string(), "Detach".to_string())],
|
InputMode::Session => vec![("d".to_string(), "Detach".to_string())],
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -40,10 +40,12 @@ fn default_layout_merged_correctly() {
|
||||||
let merged_layout = Layout {
|
let merged_layout = Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: true,
|
borderless: true,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Fixed(1)),
|
split_size: Some(SplitSize::Fixed(1)),
|
||||||
run: Some(Run::Plugin(RunPlugin {
|
run: Some(Run::Plugin(RunPlugin {
|
||||||
|
|
@ -54,6 +56,7 @@ fn default_layout_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -61,6 +64,7 @@ fn default_layout_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: true,
|
borderless: true,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Fixed(2)),
|
split_size: Some(SplitSize::Fixed(2)),
|
||||||
run: Some(Run::Plugin(RunPlugin {
|
run: Some(Run::Plugin(RunPlugin {
|
||||||
|
|
@ -84,10 +88,12 @@ fn default_layout_new_tab_correct() {
|
||||||
let merged_layout = Layout {
|
let merged_layout = Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: true,
|
borderless: true,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Fixed(1)),
|
split_size: Some(SplitSize::Fixed(1)),
|
||||||
run: Some(Run::Plugin(RunPlugin {
|
run: Some(Run::Plugin(RunPlugin {
|
||||||
|
|
@ -98,6 +104,7 @@ fn default_layout_new_tab_correct() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -105,6 +112,7 @@ fn default_layout_new_tab_correct() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: true,
|
borderless: true,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Fixed(2)),
|
split_size: Some(SplitSize::Fixed(2)),
|
||||||
run: Some(Run::Plugin(RunPlugin {
|
run: Some(Run::Plugin(RunPlugin {
|
||||||
|
|
@ -168,13 +176,16 @@ fn three_panes_with_tab_merged_correctly() {
|
||||||
let merged_layout = Layout {
|
let merged_layout = Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![Layout {
|
parts: vec![Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(50.0)),
|
split_size: Some(SplitSize::Percent(50.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -182,10 +193,12 @@ fn three_panes_with_tab_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(50.0)),
|
split_size: Some(SplitSize::Percent(50.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -193,6 +206,7 @@ fn three_panes_with_tab_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(50.0)),
|
split_size: Some(SplitSize::Percent(50.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -220,9 +234,11 @@ fn three_panes_with_tab_new_tab_is_correct() {
|
||||||
let merged_layout = Layout {
|
let merged_layout = Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![Layout {
|
parts: vec![Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -260,10 +276,12 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() {
|
||||||
let merged_layout = Layout {
|
let merged_layout = Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Fixed(1)),
|
split_size: Some(SplitSize::Fixed(1)),
|
||||||
run: Some(Run::Plugin(RunPlugin {
|
run: Some(Run::Plugin(RunPlugin {
|
||||||
|
|
@ -274,10 +292,12 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(50.0)),
|
split_size: Some(SplitSize::Percent(50.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -285,10 +305,12 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(50.0)),
|
split_size: Some(SplitSize::Percent(50.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -296,6 +318,7 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(50.0)),
|
split_size: Some(SplitSize::Percent(50.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -311,6 +334,7 @@ fn three_panes_with_tab_and_default_plugins_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Fixed(2)),
|
split_size: Some(SplitSize::Fixed(2)),
|
||||||
run: Some(Run::Plugin(RunPlugin {
|
run: Some(Run::Plugin(RunPlugin {
|
||||||
|
|
@ -334,10 +358,12 @@ fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() {
|
||||||
let merged_layout = Layout {
|
let merged_layout = Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Fixed(1)),
|
split_size: Some(SplitSize::Fixed(1)),
|
||||||
run: Some(Run::Plugin(RunPlugin {
|
run: Some(Run::Plugin(RunPlugin {
|
||||||
|
|
@ -348,6 +374,7 @@ fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -355,6 +382,7 @@ fn three_panes_with_tab_and_default_plugins_new_tab_is_correct() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Fixed(2)),
|
split_size: Some(SplitSize::Fixed(2)),
|
||||||
run: Some(Run::Plugin(RunPlugin {
|
run: Some(Run::Plugin(RunPlugin {
|
||||||
|
|
@ -396,14 +424,17 @@ fn deeply_nested_tab_merged_correctly() {
|
||||||
let merged_layout = Layout {
|
let merged_layout = Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(21.0)),
|
split_size: Some(SplitSize::Percent(21.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -411,10 +442,12 @@ fn deeply_nested_tab_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(22.0)),
|
split_size: Some(SplitSize::Percent(22.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -422,10 +455,12 @@ fn deeply_nested_tab_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(23.0)),
|
split_size: Some(SplitSize::Percent(23.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -433,6 +468,7 @@ fn deeply_nested_tab_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(24.0)),
|
split_size: Some(SplitSize::Percent(24.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -452,6 +488,7 @@ fn deeply_nested_tab_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(15.0)),
|
split_size: Some(SplitSize::Percent(15.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -459,6 +496,7 @@ fn deeply_nested_tab_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(15.0)),
|
split_size: Some(SplitSize::Percent(15.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -466,6 +504,7 @@ fn deeply_nested_tab_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(15.0)),
|
split_size: Some(SplitSize::Percent(15.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -504,10 +543,12 @@ fn three_tabs_tab_one_merged_correctly() {
|
||||||
let merged_layout = Layout {
|
let merged_layout = Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(50.0)),
|
split_size: Some(SplitSize::Percent(50.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -515,6 +556,7 @@ fn three_tabs_tab_one_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -539,14 +581,17 @@ fn three_tabs_tab_two_merged_correctly() {
|
||||||
let merged_layout = Layout {
|
let merged_layout = Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(50.0)),
|
split_size: Some(SplitSize::Percent(50.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -554,6 +599,7 @@ fn three_tabs_tab_two_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -565,6 +611,7 @@ fn three_tabs_tab_two_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -589,14 +636,17 @@ fn three_tabs_tab_three_merged_correctly() {
|
||||||
let merged_layout = Layout {
|
let merged_layout = Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![
|
parts: vec![
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Vertical,
|
direction: Direction::Vertical,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: Some(SplitSize::Percent(50.0)),
|
split_size: Some(SplitSize::Percent(50.0)),
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -604,6 +654,7 @@ fn three_tabs_tab_three_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -615,6 +666,7 @@ fn three_tabs_tab_three_merged_correctly() {
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -650,9 +702,11 @@ fn no_tabs_merged_correctly() {
|
||||||
let merged_layout = Layout {
|
let merged_layout = Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![Layout {
|
parts: vec![Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
parts: vec![],
|
parts: vec![],
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
|
|
@ -699,6 +753,7 @@ fn no_layout_template_merged_correctly() {
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
},
|
},
|
||||||
Layout {
|
Layout {
|
||||||
direction: Direction::Horizontal,
|
direction: Direction::Horizontal,
|
||||||
|
|
@ -706,15 +761,18 @@ fn no_layout_template_merged_correctly() {
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
},
|
},
|
||||||
],
|
],
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
}],
|
}],
|
||||||
split_size: None,
|
split_size: None,
|
||||||
run: None,
|
run: None,
|
||||||
borderless: false,
|
borderless: false,
|
||||||
|
pane_name: None,
|
||||||
};
|
};
|
||||||
|
|
||||||
assert_eq!(merged_layout, tab_layout.try_into().unwrap());
|
assert_eq!(merged_layout, tab_layout.try_into().unwrap());
|
||||||
|
|
|
||||||
|
|
@ -62,7 +62,7 @@ pub enum ClientToServerMsg {
|
||||||
ClientAttributes,
|
ClientAttributes,
|
||||||
Box<CliArgs>,
|
Box<CliArgs>,
|
||||||
Box<Options>,
|
Box<Options>,
|
||||||
LayoutFromYaml,
|
Box<LayoutFromYaml>,
|
||||||
Option<PluginsConfig>,
|
Option<PluginsConfig>,
|
||||||
),
|
),
|
||||||
AttachClient(ClientAttributes, Options),
|
AttachClient(ClientAttributes, Options),
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue