border styling

This commit is contained in:
Aram Drevekenin
2026-09-18 16:11:54 +02:00
parent 8fb05cb464
commit 9e4e28bbc6
125 changed files with 4200 additions and 302 deletions
+3
View File
@@ -11,3 +11,6 @@ linker = "x86_64-w64-mingw32-gcc"
[build]
target-dir = "target"
[env]
RUST_MIN_STACK = "16777216"
+29
View File
@@ -293,6 +293,35 @@ load_plugins {
//
// pane_frames true
// pane_frame_style "titles"
// Configure the look of the pane frame borders
//
// ui {
// pane_frames {
// // round the corners of single-line borders
// rounded_corners true
// // line style for all four sides of tiled pane frames
// // one of: single, double, heavy, dashed, heavy_dashed
// border_style "single"
// // per-side overrides, eg. a double top border with single sides
// border_top "double"
// border_right "single"
// border_bottom "single"
// border_left "single"
// // when two neighbouring panes disagree about a shared grid line
// // (pane frames off), that line falls back to border_style above
// // the same keys prefixed with "floating_" apply to floating panes,
// // they default to the values above
// floating_border_style "double"
// floating_border_top "double"
// floating_border_right "double"
// floating_border_bottom "double"
// floating_border_left "double"
// floating_border_rounded_corners false
// }
// }
// Toggle between having Zellij lay out panes according to a predefined set of layouts whenever possible
// Options:
// - true (default)
+6
View File
@@ -52,6 +52,7 @@ fn main() {
near_current_pane,
no_focus,
borderless,
border_style,
tab_id,
})) = opts.command
{
@@ -97,6 +98,7 @@ fn main() {
near_current_pane,
no_focus,
borderless,
border_style,
tab_id,
};
commands::send_action_to_session(command_cli_action, opts.session, config);
@@ -116,6 +118,7 @@ fn main() {
pinned,
no_focus,
borderless,
border_style,
tab_id,
})) = opts.command
{
@@ -151,6 +154,7 @@ fn main() {
near_current_pane: false,
no_focus,
borderless,
border_style,
tab_id,
};
commands::send_action_to_session(command_cli_action, opts.session, config);
@@ -172,6 +176,7 @@ fn main() {
near_current_pane,
no_focus,
borderless,
border_style,
tab_id,
})) = opts.command
{
@@ -198,6 +203,7 @@ fn main() {
near_current_pane,
no_focus,
borderless,
border_style,
tab_id,
};
commands::send_action_to_session(command_cli_action, opts.session, config);
@@ -97,6 +97,11 @@ pub fn zellij_server_listener(
colors: palette,
rounded_corners: config.ui.pane_frames.rounded_corners,
hide_session_name: config.ui.pane_frames.hide_session_name,
border_style: config.ui.pane_frames.resolved_border_style(),
floating_border_style: config
.ui
.pane_frames
.resolved_floating_border_style(),
},
};
@@ -368,6 +368,7 @@ fn control_payload_to_server_msg(
no_focus: false,
borderless: None,
tab_id: None,
border_style: None,
},
terminal_id: None,
client_id: None,
+1
View File
@@ -320,6 +320,7 @@ fn new_pane_cli_action(
no_focus: false,
borderless: None,
tab_id: None,
border_style: None,
}
}
@@ -36,6 +36,7 @@ fn no_focus_new_pane_action(command: &[&str]) -> CliAction {
no_focus: true,
borderless: None,
tab_id: None,
border_style: None,
}
}
@@ -40,6 +40,7 @@ fn replace_pane_in_place_with_held_command(
no_focus: false,
borderless: None,
tab_id: None,
border_style: None,
});
zellij.expect_pty_spawn()
}
+15
View File
@@ -464,6 +464,11 @@ impl SessionMetaData {
auto_layout: new_config.options.auto_layout.unwrap_or(true),
rounded_corners: new_config.ui.pane_frames.rounded_corners,
hide_session_name: new_config.ui.pane_frames.hide_session_name,
border_style: new_config.ui.pane_frames.resolved_border_style(),
floating_border_style: new_config
.ui
.pane_frames
.resolved_floating_border_style(),
stacked_resize: new_config.options.stacked_resize.unwrap_or(true),
stacked_pane_list: new_config.options.stacked_pane_list.unwrap_or(true),
default_editor: new_config.options.scrollback_editor.clone(),
@@ -1026,6 +1031,11 @@ pub fn start_server_impl(
.unwrap_or_else(|| default_palette().into()),
rounded_corners: config.ui.pane_frames.rounded_corners,
hide_session_name: config.ui.pane_frames.hide_session_name,
border_style: config.ui.pane_frames.resolved_border_style(),
floating_border_style: config
.ui
.pane_frames
.resolved_floating_border_style(),
},
};
@@ -1207,6 +1217,11 @@ pub fn start_server_impl(
.unwrap_or_else(|| default_palette().into()),
rounded_corners: config.ui.pane_frames.rounded_corners,
hide_session_name: config.ui.pane_frames.hide_session_name,
border_style: config.ui.pane_frames.resolved_border_style(),
floating_border_style: config
.ui
.pane_frames
.resolved_floating_border_style(),
},
};
+1
View File
@@ -169,6 +169,7 @@ impl PaneGroups {
height: Some(PercentOrFixed::Fixed(height)),
pinned: Some(true),
borderless: Some(false),
border_style: None,
};
let _ = self.senders.send_to_pty(PtyInstruction::FillPluginCwd(
should_float,
+12 -1
View File
@@ -1,6 +1,6 @@
pub mod floating_pane_grid;
use zellij_utils::{
data::{Direction, FloatingPaneCoordinates, PaneInfo, ResizeStrategy},
data::{BorderStyle, Direction, FloatingPaneCoordinates, PaneInfo, ResizeStrategy},
position::Position,
};
@@ -1710,6 +1710,17 @@ impl FloatingPanes {
pane.update_rounded_corners(rounded_corners);
}
}
pub fn update_border_styles(
&mut self,
border_style: BorderStyle,
floating_border_style: BorderStyle,
) {
self.style.border_style = border_style;
self.style.floating_border_style = floating_border_style;
for pane in self.panes.values_mut() {
pane.invalidate_frame_cache();
}
}
pub fn next_selectable_pane_id_above(&mut self, pane_id: &PaneId) -> Option<PaneId> {
let display_area = *self.display_area.borrow();
let viewport = *self.viewport.borrow();
+16 -1
View File
@@ -22,7 +22,8 @@ use std::rc::Rc;
use vte;
use zellij_utils::data::PaneContents;
use zellij_utils::data::{
BareKey, KeyWithModifier, PermissionStatus, PermissionType, PluginPermission,
BareKey, BorderStyleOverride, KeyWithModifier, PermissionStatus, PermissionType,
PluginPermission,
};
use zellij_utils::pane_size::{Offset, SizeInPixels};
use zellij_utils::position::Position;
@@ -99,6 +100,7 @@ pub(crate) struct PluginPane {
prev_pane_name: String,
frame: HashMap<ClientId, PaneFrame>,
borderless: bool,
border_style_override: BorderStyleOverride,
exclude_from_sync: bool,
pane_frame_color_override: Option<(PaletteColor, Option<String>)>,
invoked_with: Option<Run>,
@@ -146,6 +148,7 @@ impl PluginPane {
content_offset: Offset::default(),
pane_title: title,
borderless: false,
border_style_override: BorderStyleOverride::default(),
pane_name: pane_name.clone(),
prev_pane_name: pane_name,
terminal_emulator_colors,
@@ -747,6 +750,14 @@ impl Pane for PluginPane {
fn borderless(&self) -> bool {
self.borderless
}
fn set_border_style_override(&mut self, border_style_override: BorderStyleOverride) {
self.border_style_override = border_style_override;
self.frame.clear();
self.set_should_render(true);
}
fn border_style_override(&self) -> BorderStyleOverride {
self.border_style_override
}
fn set_exclude_from_sync(&mut self, exclude_from_sync: bool) {
self.exclude_from_sync = exclude_from_sync;
}
@@ -847,6 +858,10 @@ impl Pane for PluginPane {
self.style.rounded_corners = rounded_corners;
self.frame.clear();
}
fn invalidate_frame_cache(&mut self) {
self.frame.clear();
self.set_should_render(true);
}
fn set_should_be_suppressed(&mut self, should_be_suppressed: bool) {
self.should_be_suppressed = should_be_suppressed;
}
+16 -2
View File
@@ -25,8 +25,8 @@ use zellij_utils::input::mouse::{MouseEvent, MouseEventType};
use zellij_utils::pane_size::Offset;
use zellij_utils::{
data::{
BareKey, InputMode, KeyWithModifier, Palette, PaletteColor, PaneId as ZellijUtilsPaneId,
RegexHighlight, Style, Styling,
BareKey, BorderStyleOverride, InputMode, KeyWithModifier, Palette, PaletteColor,
PaneId as ZellijUtilsPaneId, RegexHighlight, Style, Styling,
},
errors::prelude::*,
input::layout::Run,
@@ -145,6 +145,7 @@ pub struct TerminalPane {
prev_pane_name: String,
frame: HashMap<ClientId, PaneFrame>,
borderless: bool,
border_style_override: BorderStyleOverride,
exclude_from_sync: bool,
fake_cursor_locations: HashSet<(usize, usize)>, // (x, y) - these hold a record of previous fake cursors which we need to clear on render
search_term: String,
@@ -990,6 +991,14 @@ impl Pane for TerminalPane {
self.set_content_offset(Offset::frame(1));
}
}
fn set_border_style_override(&mut self, border_style_override: BorderStyleOverride) {
self.border_style_override = border_style_override;
self.frame.clear();
self.set_should_render(true);
}
fn border_style_override(&self) -> BorderStyleOverride {
self.border_style_override
}
fn set_exclude_from_sync(&mut self, exclude_from_sync: bool) {
self.exclude_from_sync = exclude_from_sync;
@@ -1232,6 +1241,10 @@ impl Pane for TerminalPane {
self.style.rounded_corners = rounded_corners;
self.frame.clear();
}
fn invalidate_frame_cache(&mut self) {
self.frame.clear();
self.set_should_render(true);
}
fn drain_fake_cursors(&mut self) -> Option<HashSet<(usize, usize)>> {
if !self.fake_cursor_locations.is_empty() {
for (y, _x) in &self.fake_cursor_locations {
@@ -1418,6 +1431,7 @@ impl TerminalPane {
pane_name: pane_name.clone(),
prev_pane_name: pane_name,
borderless: false,
border_style_override: BorderStyleOverride::default(),
exclude_from_sync: false,
fake_cursor_locations: HashSet::new(),
search_term: String::new(),
+36 -7
View File
@@ -28,7 +28,10 @@ use crate::{
};
use stacked_panes::StackedPanes;
use zellij_utils::{
data::{Direction, ModeInfo, PaneInfo, Resize, ResizeStrategy, Style, Styling},
data::{
BorderStyle, BorderStyleOverride, Direction, LineStyle, ModeInfo, PaneInfo, Resize,
ResizeStrategy, Style, Styling,
},
errors::prelude::*,
input::{
command::RunCommand,
@@ -1161,6 +1164,11 @@ impl TiledPanes {
let connected_clients: Vec<ClientId> = connected_clients.into_iter().collect();
let multiple_users_exist_in_session = { self.connected_clients_in_app.borrow().len() > 1 };
let mut client_id_to_boundaries: HashMap<ClientId, Boundaries> = HashMap::new();
let fallback_line_style = self
.style
.border_style
.uniform_style()
.unwrap_or(LineStyle::Single);
let active_panes = if floating_panes_are_visible {
HashMap::new()
} else {
@@ -1317,9 +1325,12 @@ impl TiledPanes {
pane_is_selectable,
)
.with_context(err_context)?;
let boundaries = client_id_to_boundaries
.entry(*client_id)
.or_insert_with(|| Boundaries::new(*self.viewport.borrow()));
let boundaries =
client_id_to_boundaries
.entry(*client_id)
.or_insert_with(|| {
Boundaries::new(*self.viewport.borrow(), fallback_line_style)
});
pane_contents_and_ui.render_pane_boundaries(
*client_id,
client_mode,
@@ -1329,9 +1340,12 @@ impl TiledPanes {
pane_is_on_bottom_of_stack,
);
} else {
let boundaries = client_id_to_boundaries
.entry(*client_id)
.or_insert_with(|| Boundaries::new(*self.viewport.borrow()));
let boundaries =
client_id_to_boundaries
.entry(*client_id)
.or_insert_with(|| {
Boundaries::new(*self.viewport.borrow(), fallback_line_style)
});
pane_contents_and_ui.render_pane_boundaries(
*client_id,
client_mode,
@@ -1415,6 +1429,7 @@ impl TiledPanes {
run: Option<Run>,
geom: PaneGeom,
should_be_borderless: Option<bool>,
border_style: Option<BorderStyleOverride>,
) {
match self
.panes
@@ -1423,6 +1438,9 @@ impl TiledPanes {
{
Some((_, pane)) => {
pane.set_geom(geom);
if let Some(border_style) = border_style {
pane.set_border_style_override(border_style);
}
if let Some(should_be_borderless) = should_be_borderless {
pane.set_borderless(should_be_borderless);
@@ -3130,6 +3148,17 @@ impl TiledPanes {
pane.update_rounded_corners(rounded_corners);
}
}
pub fn update_border_styles(
&mut self,
border_style: BorderStyle,
floating_border_style: BorderStyle,
) {
self.style.border_style = border_style;
self.style.floating_border_style = floating_border_style;
for pane in self.panes.values_mut() {
pane.invalidate_frame_cache();
}
}
pub fn stack_panes(
&mut self,
root_pane_id: PaneId,
+84 -21
View File
@@ -21,13 +21,14 @@ use tokio::sync::oneshot;
use wasmi::{Caller, Linker};
use zellij_utils::consts::ipc_connect;
use zellij_utils::data::{
BreakPanesToNewTabResponse, BreakPanesToTabWithIdResponse, BreakPanesToTabWithIndexResponse,
CommandType, ConnectToSession, DeleteAllDeadSessionsResponse, DeleteDeadSessionResponse,
DeleteLayoutResponse, EditLayoutResponse, Event, FloatingPaneCoordinates,
FocusOrCreateTabResponse, GetFocusedPaneInfoResponse, GetPaneCwdResponse, GetPanePidResponse,
GetPaneRunningCommandResponse, HttpVerb, KeyWithModifier, KillSessionsResponse, LayoutInfo,
LayoutMetadata, LayoutParsingError, MessageToPlugin, NewPanePlacement, NewTabResponse,
NewTabUnfocusedResponse, NewTiledPaneInTabResponse, OpenCommandPaneBackgroundResponse,
BorderStyleOverride, BreakPanesToNewTabResponse, BreakPanesToTabWithIdResponse,
BreakPanesToTabWithIndexResponse, CommandType, ConnectToSession, DeleteAllDeadSessionsResponse,
DeleteDeadSessionResponse, DeleteLayoutResponse, EditLayoutResponse, Event,
FloatingPaneCoordinates, FocusOrCreateTabResponse, GetFocusedPaneInfoResponse,
GetPaneCwdResponse, GetPanePidResponse, GetPaneRunningCommandResponse, HttpVerb,
KeyWithModifier, KillSessionsResponse, LayoutInfo, LayoutMetadata, LayoutParsingError,
MessageToPlugin, NewPanePlacement, NewTabResponse, NewTabUnfocusedResponse,
NewTiledPaneInTabResponse, OpenCommandPaneBackgroundResponse,
OpenCommandPaneFloatingNearPluginResponse, OpenCommandPaneFloatingResponse,
OpenCommandPaneInPlaceOfPaneIdResponse, OpenCommandPaneInPlaceOfPluginResponse,
OpenCommandPaneInPlaceResponse, OpenCommandPaneNearPluginResponse, OpenCommandPaneResponse,
@@ -199,21 +200,35 @@ fn host_run_plugin_command(mut caller: Caller<'_, PluginEnv>) {
floating_pane_coordinates,
context,
) => open_file_floating(env, file_to_open, floating_pane_coordinates, context),
PluginCommand::OpenTerminal(cwd) => open_terminal(env, cwd.path.try_into()?),
PluginCommand::OpenTerminal(cwd) => {
let border_style = cwd.border_style;
open_terminal(env, cwd.path.try_into()?, border_style)
},
PluginCommand::OpenTerminalNearPlugin(cwd) => {
open_terminal_near_plugin(env, cwd.path.try_into()?)
let border_style = cwd.border_style;
open_terminal_near_plugin(env, cwd.path.try_into()?, border_style)
},
PluginCommand::OpenTerminalFloating(cwd, floating_pane_coordinates) => {
let floating_pane_coordinates = FloatingPaneCoordinates::merge_border_style(
floating_pane_coordinates,
cwd.border_style,
);
open_terminal_floating(env, cwd.path.try_into()?, floating_pane_coordinates)
},
PluginCommand::OpenTerminalFloatingNearPlugin(
cwd,
floating_pane_coordinates,
) => open_terminal_floating_near_plugin(
env,
cwd.path.try_into()?,
floating_pane_coordinates,
),
) => {
let floating_pane_coordinates = FloatingPaneCoordinates::merge_border_style(
floating_pane_coordinates,
cwd.border_style,
);
open_terminal_floating_near_plugin(
env,
cwd.path.try_into()?,
floating_pane_coordinates,
)
},
PluginCommand::OpenCommandPane(command_to_run, context) => {
open_command_pane(env, command_to_run, context)
},
@@ -628,6 +643,9 @@ fn host_run_plugin_command(mut caller: Caller<'_, PluginEnv>) {
PluginCommand::TogglePaneBorderless(pane_id) => {
toggle_pane_borderless(env, pane_id.into())
},
PluginCommand::SetPaneBorderStyle(pane_id, border_style) => {
set_pane_border_style(env, pane_id.into(), border_style)
},
PluginCommand::SetPaneBorderless(pane_id, borderless) => {
set_pane_borderless(env, pane_id.into(), borderless)
},
@@ -1214,6 +1232,7 @@ fn open_editor_pane_in_new_tab(
.map(|cwd| translate_plugin_path(env, cwd))
.or_else(|| Some(env.plugin_cwd.clone()));
let file_to_open = FileToOpen {
border_style: None,
path,
cwd,
..file_to_open
@@ -1413,6 +1432,7 @@ fn open_file(env: &PluginEnv, file_to_open: FileToOpen, context: BTreeMap<String
let floating = false;
let in_place = false;
let start_suppressed = false;
let border_style = file_to_open.border_style;
let path = translate_plugin_path(env, file_to_open.path);
let cwd = file_to_open
.cwd
@@ -1427,7 +1447,7 @@ fn open_file(env: &PluginEnv, file_to_open: FileToOpen, context: BTreeMap<String
in_place,
close_replaced_pane: false,
start_suppressed,
coordinates: None,
coordinates: FloatingPaneCoordinates::merge_border_style(None, border_style),
near_current_pane: false,
no_focus: false,
tab_id: None,
@@ -1509,6 +1529,7 @@ fn open_file_floating(
let floating = true;
let in_place = false;
let start_suppressed = false;
let border_style = file_to_open.border_style;
let path = translate_plugin_path(env, file_to_open.path);
let cwd = file_to_open
.cwd
@@ -1523,7 +1544,10 @@ fn open_file_floating(
in_place,
close_replaced_pane: false,
start_suppressed,
coordinates: floating_pane_coordinates,
coordinates: FloatingPaneCoordinates::merge_border_style(
floating_pane_coordinates,
border_style,
),
near_current_pane: false,
no_focus: false,
tab_id: None,
@@ -1588,6 +1612,7 @@ fn open_file_near_plugin(
file_to_open: FileToOpen,
context: BTreeMap<String, String>,
) {
let border_style = file_to_open.border_style;
let cwd = file_to_open
.cwd
.map(|cwd| translate_plugin_path(env, cwd))
@@ -1606,7 +1631,7 @@ fn open_file_near_plugin(
let pty_instr = PtyInstruction::SpawnTerminal(
Some(open_file),
Some(title),
NewPanePlacement::default(),
NewPanePlacement::default().with_border_style(border_style),
start_suppressed,
ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)),
Some(NotificationEnd::new(completion_tx)),
@@ -1631,6 +1656,10 @@ fn open_file_floating_near_plugin(
floating_pane_coordinates: Option<FloatingPaneCoordinates>,
context: BTreeMap<String, String>,
) {
let floating_pane_coordinates = FloatingPaneCoordinates::merge_border_style(
floating_pane_coordinates,
file_to_open.border_style,
);
let cwd = file_to_open
.cwd
.map(|cwd| translate_plugin_path(env, cwd))
@@ -1708,7 +1737,7 @@ fn open_file_in_place_of_plugin(
.non_fatal();
}
fn open_terminal(env: &PluginEnv, cwd: PathBuf) {
fn open_terminal(env: &PluginEnv, cwd: PathBuf, border_style: Option<BorderStyleOverride>) {
let error_msg = || format!("failed to open file in plugin {}", env.name());
let cwd = translate_plugin_path(env, cwd);
let mut default_shell = env.default_shell.clone().unwrap_or_else(|| {
@@ -1730,6 +1759,7 @@ fn open_terminal(env: &PluginEnv, cwd: PathBuf) {
near_current_pane: false,
no_focus: false,
borderless: None,
border_style,
tab_id: None,
};
let result = apply_action!(action, error_msg, env);
@@ -1744,7 +1774,11 @@ fn open_terminal(env: &PluginEnv, cwd: PathBuf) {
.non_fatal();
}
fn open_terminal_near_plugin(env: &PluginEnv, cwd: PathBuf) {
fn open_terminal_near_plugin(
env: &PluginEnv,
cwd: PathBuf,
border_style: Option<BorderStyleOverride>,
) {
let cwd = translate_plugin_path(env, cwd);
let mut default_shell = env.default_shell.clone().unwrap_or_else(|| {
TerminalAction::RunCommand(RunCommand {
@@ -1764,6 +1798,7 @@ fn open_terminal_near_plugin(env: &PluginEnv, cwd: PathBuf) {
NewPanePlacement::Tiled {
direction: None,
borderless: None,
border_style,
},
false,
ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)),
@@ -1946,6 +1981,7 @@ fn open_command_pane_in_place_of_plugin(
context: BTreeMap<String, String>,
) {
let command = command_to_run.path;
let _border_style = command_to_run.border_style;
let cwd = command_to_run
.cwd
.map(|cwd| translate_plugin_path(env, cwd));
@@ -2045,6 +2081,7 @@ fn open_command_pane_in_place_of_pane_id(
context: BTreeMap<String, String>,
) {
let command = command_to_run.path;
let _border_style = command_to_run.border_style;
let cwd = command_to_run
.cwd
.map(|cwd| translate_plugin_path(env, cwd));
@@ -2140,6 +2177,7 @@ fn open_command_pane(
) {
let error_msg = || format!("failed to open command in plugin {}", env.name());
let command = command_to_run.path;
let border_style = command_to_run.border_style;
let cwd = command_to_run
.cwd
.map(|cwd| translate_plugin_path(env, cwd));
@@ -2170,6 +2208,7 @@ fn open_command_pane(
near_current_pane: false,
no_focus: false,
borderless: None,
border_style,
tab_id: None,
};
let result = apply_action!(action, error_msg, env);
@@ -2191,6 +2230,7 @@ fn open_command_pane_near_plugin(
context: BTreeMap<String, String>,
) {
let command = command_to_run.path;
let border_style = command_to_run.border_style;
let cwd = command_to_run
.cwd
.map(|cwd| translate_plugin_path(env, cwd));
@@ -2224,6 +2264,7 @@ fn open_command_pane_near_plugin(
NewPanePlacement::Tiled {
direction: None,
borderless: None,
border_style,
},
false,
ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)),
@@ -2250,6 +2291,7 @@ fn open_command_pane_floating(
) {
let error_msg = || format!("failed to open command in plugin {}", env.name());
let command = command_to_run.path;
let border_style = command_to_run.border_style;
let cwd = command_to_run
.cwd
.map(|cwd| translate_plugin_path(env, cwd));
@@ -2276,7 +2318,10 @@ fn open_command_pane_floating(
let action = Action::NewFloatingPane {
command: Some(run_command_action),
pane_name: name,
coordinates: floating_pane_coordinates,
coordinates: FloatingPaneCoordinates::merge_border_style(
floating_pane_coordinates,
border_style,
),
near_current_pane: false,
no_focus: false,
tab_id: None,
@@ -2301,6 +2346,7 @@ fn open_command_pane_floating_near_plugin(
context: BTreeMap<String, String>,
) {
let command = command_to_run.path;
let border_style = command_to_run.border_style;
let cwd = command_to_run
.cwd
.map(|cwd| translate_plugin_path(env, cwd));
@@ -2331,7 +2377,10 @@ fn open_command_pane_floating_near_plugin(
let _ = env.senders.send_to_pty(PtyInstruction::SpawnTerminal(
Some(run_cmd),
name,
NewPanePlacement::Floating(floating_pane_coordinates),
NewPanePlacement::Floating(FloatingPaneCoordinates::merge_border_style(
floating_pane_coordinates,
border_style,
)),
false,
ClientTabIndexOrPaneId::PaneId(PaneId::Plugin(env.plugin_id)),
Some(NotificationEnd::new(completion_tx)),
@@ -2361,6 +2410,7 @@ fn open_command_pane_in_place(
) {
let error_msg = || format!("failed to open command in plugin {}", env.name());
let command = command_to_run.path;
let _border_style = command_to_run.border_style;
let cwd = command_to_run
.cwd
.map(|cwd| translate_plugin_path(env, cwd));
@@ -2875,6 +2925,7 @@ fn new_tiled_pane_in_tab(env: &PluginEnv, tab_position: usize) {
near_current_pane: false,
no_focus: false,
borderless: None,
border_style: None,
tab_id: Some(tab_position),
};
let result = apply_action!(action, error_msg, env);
@@ -3968,6 +4019,16 @@ fn set_pane_borderless(env: &PluginEnv, pane_id: PaneId, borderless: bool) {
));
}
fn set_pane_border_style(env: &PluginEnv, pane_id: PaneId, border_style: BorderStyleOverride) {
let _ = env
.senders
.send_to_screen(ScreenInstruction::SetPaneBorderStyle(
pane_id,
border_style,
None,
));
}
fn set_pane_color(env: &PluginEnv, pane_id: PaneId, fg: Option<String>, bg: Option<String>) {
let _ = env
.senders
@@ -4708,6 +4769,7 @@ fn try_edit_layout(
// Create FileToOpen for the layout file
let file_to_open = FileToOpen {
border_style: None,
path: file_path,
line_number: None,
cwd: Some(layout_dir.clone()),
@@ -5579,6 +5641,7 @@ fn check_command_permission(
| PluginCommand::ChangeFloatingPanesCoordinates(..)
| PluginCommand::TogglePaneBorderless(..)
| PluginCommand::SetPaneBorderless(..)
| PluginCommand::SetPaneBorderStyle(..)
| PluginCommand::SetPaneColor(..)
| PluginCommand::GroupAndUngroupPanes(..)
| PluginCommand::HighlightAndUnhighlightPanes(..)
+29 -2
View File
@@ -678,8 +678,12 @@ pub(crate) fn route_action(
Some(direction) => NewPanePlacement::Tiled {
direction: Some(direction),
borderless: None,
border_style: None,
},
None => NewPanePlacement::NoPreference {
borderless: None,
border_style: None,
},
None => NewPanePlacement::NoPreference { borderless: None },
};
senders
.send_to_pty(PtyInstruction::SpawnTerminal(
@@ -782,7 +786,12 @@ pub(crate) fn route_action(
} else {
NewPanePlacement::Tiled {
direction: split_direction,
borderless: None,
borderless: floating_pane_coordinates
.as_ref()
.and_then(|c| c.borderless),
border_style: floating_pane_coordinates
.as_ref()
.and_then(|c| c.border_style),
}
},
start_suppressed,
@@ -889,6 +898,7 @@ pub(crate) fn route_action(
NewPanePlacement::Stacked {
pane_id_to_stack_under: None,
borderless: None,
border_style: None,
},
if no_focus {
ClientTabIndexOrPaneId::TabIndexNoFocus(tab_id)
@@ -902,6 +912,7 @@ pub(crate) fn route_action(
NewPanePlacement::Stacked {
pane_id_to_stack_under: Some(pane_id.into()),
borderless: None,
border_style: None,
},
ClientTabIndexOrPaneId::PaneId(pane_id),
)
@@ -910,6 +921,7 @@ pub(crate) fn route_action(
NewPanePlacement::Stacked {
pane_id_to_stack_under: None,
borderless: None,
border_style: None,
},
if no_focus {
ClientTabIndexOrPaneId::ClientIdNoFocus(client_id)
@@ -937,6 +949,7 @@ pub(crate) fn route_action(
near_current_pane,
no_focus,
borderless,
border_style,
tab_id,
} => {
let run_cmd = run_command
@@ -951,6 +964,7 @@ pub(crate) fn route_action(
NewPanePlacement::Tiled {
direction,
borderless,
border_style,
},
false,
client_tab_index_or_paneid,
@@ -1008,6 +1022,7 @@ pub(crate) fn route_action(
NewPanePlacement::Tiled {
direction: command.direction,
borderless: None,
border_style: None,
},
false,
client_tab_index_or_paneid,
@@ -1915,6 +1930,18 @@ pub(crate) fn route_action(
))
.with_context(err_context)?;
},
Action::SetPaneBorderStyle {
pane_id,
border_style,
} => {
senders
.send_to_screen(ScreenInstruction::SetPaneBorderStyle(
pane_id.into(),
border_style,
Some(NotificationEnd::new(completion_tx)),
))
.with_context(err_context)?;
},
Action::TogglePaneInGroup => {
senders
.send_to_screen(ScreenInstruction::TogglePaneInGroup(
+42 -7
View File
@@ -40,11 +40,12 @@ use crate::route::NotificationEnd;
use log::{debug, warn};
use zellij_utils::data::{
CommandOrPlugin, Direction, EventType, FloatingPaneCoordinates, GetFocusedPaneInfoResponse,
HostTerminalThemeMode, KeyWithModifier, LayoutInfo, LayoutWithError, ListPanesResponse,
ListTabsResponse, NewPanePlacement, PaneContents, PaneInfo, PaneListEntry, PaneManifest,
PaneRenderReport, PaneScrollbackResponse, PluginPermission, RegexHighlight, Resize,
ResizeStrategy, SessionInfo, Styling, TabInfo, ThemeHue, WebSharing,
BorderStyle, BorderStyleOverride, CommandOrPlugin, Direction, EventType,
FloatingPaneCoordinates, GetFocusedPaneInfoResponse, HostTerminalThemeMode, KeyWithModifier,
LayoutInfo, LayoutWithError, ListPanesResponse, ListTabsResponse, NewPanePlacement,
PaneContents, PaneInfo, PaneListEntry, PaneManifest, PaneRenderReport, PaneScrollbackResponse,
PluginPermission, RegexHighlight, Resize, ResizeStrategy, SessionInfo, Styling, TabInfo,
ThemeHue, WebSharing,
};
use zellij_utils::errors::prelude::*;
use zellij_utils::input::actions::Action;
@@ -814,6 +815,8 @@ pub enum ScreenInstruction {
auto_layout: bool,
rounded_corners: bool,
hide_session_name: bool,
border_style: BorderStyle,
floating_border_style: BorderStyle,
stacked_resize: bool,
stacked_pane_list: bool,
default_editor: Option<PathBuf>,
@@ -892,6 +895,7 @@ pub enum ScreenInstruction {
),
TogglePaneBorderless(PaneId, Option<NotificationEnd>),
SetPaneBorderless(PaneId, bool, Option<NotificationEnd>),
SetPaneBorderStyle(PaneId, BorderStyleOverride, Option<NotificationEnd>),
AddHighlightPaneFrameColorOverride(Vec<PaneId>, Option<String>), // Option<String> => optional
// message
GroupAndUngroupPanes(Vec<PaneId>, Vec<PaneId>, bool, ClientId), // panes_to_group, panes_to_ungroup, bool -> for all clients
@@ -1263,6 +1267,7 @@ impl From<&ScreenInstruction> for ScreenContext {
},
ScreenInstruction::TogglePaneBorderless(..) => ScreenContext::TogglePaneBorderless,
ScreenInstruction::SetPaneBorderless(..) => ScreenContext::SetPaneBorderless,
ScreenInstruction::SetPaneBorderStyle(..) => ScreenContext::SetPaneBorderStyle,
ScreenInstruction::AddHighlightPaneFrameColorOverride(..) => {
ScreenContext::AddHighlightPaneFrameColorOverride
},
@@ -6726,6 +6731,7 @@ impl Screen {
height: Some(PercentOrFixed::Fixed(pane.rows())),
pinned: Some(pane.current_geom().is_pinned),
borderless: Some(pane.borderless()),
border_style: None,
};
new_active_tab.add_floating_pane(
pane,
@@ -6894,6 +6900,8 @@ impl Screen {
auto_layout: bool,
rounded_corners: bool,
hide_session_name: bool,
border_style: BorderStyle,
floating_border_style: BorderStyle,
stacked_resize: bool,
stacked_pane_list: bool,
default_editor: Option<PathBuf>,
@@ -6920,6 +6928,10 @@ impl Screen {
self.default_mode_info.update_theme(theme);
self.default_mode_info
.update_rounded_corners(rounded_corners);
self.default_mode_info
.update_border_styles(border_style, floating_border_style);
self.style.border_style = border_style;
self.style.floating_border_style = floating_border_style;
// `default_mode_info` is the fallback used by `change_mode` for
// clients that don't yet have a per-client `mode_info` entry, so its
// keybinds and base mode must be kept in sync with reconfigures.
@@ -6960,6 +6972,7 @@ impl Screen {
for tab in self.tabs.values_mut() {
tab.update_theme(theme);
tab.update_rounded_corners(rounded_corners);
tab.update_border_styles(border_style, floating_border_style);
tab.update_default_shell(default_shell.clone());
tab.update_default_editor(self.default_editor.clone());
tab.update_auto_layout(auto_layout);
@@ -7308,6 +7321,14 @@ impl Screen {
}
}
}
pub fn set_pane_border_style(&mut self, pane_id: PaneId, border_style: BorderStyleOverride) {
for (_tab_id, tab) in self.tabs.iter_mut() {
if tab.has_pane_with_pid(&pane_id) {
tab.set_pane_border_style(pane_id, border_style);
break;
}
}
}
pub fn handle_mouse_event(&mut self, event: MouseEvent, client_id: ClientId) {
let is_bare_motion = event.event_type == MouseEventType::Motion
&& !event.left
@@ -7524,6 +7545,7 @@ impl Screen {
focused_clients,
default_fg,
default_bg,
p.border_style_override(),
)
})
.collect();
@@ -7553,7 +7575,7 @@ impl Screen {
PaneLayoutMetadata::new(
pane_id,
p.position_and_size(),
false, // floating panes are never borderless
p.borderless(),
p.invoked_with().clone(),
p.custom_title(),
!focused_clients.is_empty(),
@@ -7565,6 +7587,7 @@ impl Screen {
focused_clients,
default_fg,
default_bg,
p.border_style_override(),
)
})
.collect();
@@ -8429,6 +8452,7 @@ pub(crate) fn screen_thread_main(
NewPanePlacement::Tiled {
direction: Some(direction),
borderless,
border_style: None,
} => {
if direction == Direction::Left
|| direction == Direction::Right
@@ -10894,6 +10918,7 @@ pub(crate) fn screen_thread_main(
new_pane_placement = NewPanePlacement::Tiled {
direction: None,
borderless: None,
border_style: None,
};
}
if should_be_in_place {
@@ -11669,6 +11694,8 @@ pub(crate) fn screen_thread_main(
auto_layout,
rounded_corners,
hide_session_name,
border_style,
floating_border_style,
stacked_resize,
stacked_pane_list,
default_editor,
@@ -11702,6 +11729,8 @@ pub(crate) fn screen_thread_main(
auto_layout,
rounded_corners,
hide_session_name,
border_style,
floating_border_style,
stacked_resize,
stacked_pane_list,
default_editor,
@@ -12128,6 +12157,10 @@ pub(crate) fn screen_thread_main(
screen.set_pane_borderless(pane_id, borderless);
let _ = screen.render(None);
},
ScreenInstruction::SetPaneBorderStyle(pane_id, border_style, _completion_tx) => {
screen.set_pane_border_style(pane_id, border_style);
let _ = screen.render(None);
},
ScreenInstruction::GroupAndUngroupPanes(
pane_ids_to_group,
pane_ids_to_ungroup,
@@ -12904,7 +12937,9 @@ pub(crate) fn screen_thread_main(
mut _completion_tx,
) => {
if let Some(tab) = screen.tabs.get_mut(&tab_id) {
let applied = tab.apply_floating_swap_layout(&layout_name).unwrap_or(false);
let applied = tab
.apply_floating_swap_layout(&layout_name)
.unwrap_or(false);
if !applied {
log::error!(
"Floating swap layout not found or incompatible: {layout_name}"
+7 -1
View File
@@ -6,7 +6,7 @@ use std::time::{SystemTime, UNIX_EPOCH};
use zellij_utils::common_path::common_path_all;
use zellij_utils::pane_size::PaneGeom;
use zellij_utils::{
data::{LayoutMetadata, PaneMetadata, TabMetadata},
data::{BorderStyleOverride, LayoutMetadata, PaneMetadata, TabMetadata},
input::command::RunCommand,
input::layout::{Layout, Run, RunPlugin, RunPluginOrAlias},
input::plugins::PluginAliases,
@@ -535,6 +535,7 @@ impl Into<PaneLayoutManifest> for PaneLayoutMetadata {
pane_contents: self.pane_contents,
default_fg: self.default_fg,
default_bg: self.default_bg,
border_style: self.border_style.none_if_empty(),
}
}
}
@@ -561,6 +562,7 @@ pub struct PaneLayoutMetadata {
focused_clients: Vec<ClientId>,
default_fg: Option<String>,
default_bg: Option<String>,
border_style: BorderStyleOverride,
}
impl PaneLayoutMetadata {
@@ -575,6 +577,7 @@ impl PaneLayoutMetadata {
focused_clients: Vec<ClientId>,
default_fg: Option<String>,
default_bg: Option<String>,
border_style: BorderStyleOverride,
) -> Self {
PaneLayoutMetadata {
id,
@@ -588,6 +591,7 @@ impl PaneLayoutMetadata {
focused_clients,
default_fg,
default_bg,
border_style,
}
}
fn to_pane_metadata(&self) -> PaneMetadata {
@@ -701,6 +705,7 @@ mod tests {
vec![],
None,
None,
Default::default(),
)
}
@@ -720,6 +725,7 @@ mod tests {
vec![],
None,
None,
Default::default(),
)
}
+12
View File
@@ -552,6 +552,7 @@ impl<'a> LayoutApplier<'a> {
}
new_plugin.set_borderless(layout.borderless.unwrap_or(false));
new_plugin.set_border_style_override(layout.border_style.unwrap_or_default());
if let Some(exclude_from_sync) = layout.exclude_from_sync {
new_plugin.set_exclude_from_sync(exclude_from_sync);
}
@@ -605,6 +606,7 @@ impl<'a> LayoutApplier<'a> {
} else {
new_pane.set_borderless(false);
}
new_pane.set_border_style_override(floating_pane_layout.border_style.unwrap_or_default());
resize_pty!(
new_pane,
self.os_api,
@@ -662,6 +664,7 @@ impl<'a> LayoutApplier<'a> {
} else {
new_pane.set_borderless(false);
}
new_pane.set_border_style_override(floating_pane_layout.border_style.unwrap_or_default());
if floating_pane_layout.default_fg.is_some() || floating_pane_layout.default_bg.is_some() {
new_pane.set_pane_default_colors(
floating_pane_layout.default_fg.clone(),
@@ -735,6 +738,7 @@ impl<'a> LayoutApplier<'a> {
new_pane.handle_pty_bytes("\n\r".as_bytes().into());
}
new_pane.set_borderless(layout.borderless.unwrap_or(false));
new_pane.set_border_style_override(layout.border_style.unwrap_or_default());
if let Some(exclude_from_sync) = layout.exclude_from_sync {
new_pane.set_exclude_from_sync(exclude_from_sync);
}
@@ -764,6 +768,7 @@ impl<'a> LayoutApplier<'a> {
layout.run,
position_and_size,
layout.borderless,
layout.border_style,
);
found_exact_match = true;
}
@@ -784,6 +789,7 @@ impl<'a> LayoutApplier<'a> {
run_instruction.clone(),
position_and_size,
layout.borderless,
layout.border_style,
);
found_empty_location = true;
}
@@ -1331,6 +1337,9 @@ impl<'a> PaneApplier<'a> {
if let Some(should_be_borderless) = floating_panes_layout.borderless {
pane.set_borderless(should_be_borderless);
}
if let Some(border_style) = floating_panes_layout.border_style {
pane.set_border_style_override(border_style);
}
self.apply_position_and_size_to_floating_pane(pane, position_and_size);
Ok(())
}
@@ -1410,6 +1419,9 @@ impl<'a> PaneApplier<'a> {
if let Some(should_be_borderless) = layout.borderless {
pane.set_borderless(should_be_borderless);
}
if let Some(border_style) = layout.border_style {
pane.set_border_style_override(border_style);
}
if let Some(pane_title) = layout.name.as_ref() {
pane.set_title(pane_title.into());
}
+62 -8
View File
@@ -17,8 +17,9 @@ use unicode_width::UnicodeWidthStr;
use uuid::Uuid;
use zellij_utils::data::PaneContents;
use zellij_utils::data::{
Direction, KeyWithModifier, NewPanePlacement, PaneInfo, PermissionStatus, PermissionType,
PluginPermission, RegexHighlight, ResizeStrategy, Style, StyledText, WebSharing,
BorderStyle, BorderStyleOverride, Direction, KeyWithModifier, NewPanePlacement, PaneInfo,
PermissionStatus, PermissionType, PluginPermission, RegexHighlight, ResizeStrategy, Style,
StyledText, WebSharing,
};
use zellij_utils::errors::prelude::*;
use zellij_utils::input::command::RunCommand;
@@ -627,6 +628,10 @@ pub trait Pane {
fn load_pane_name(&mut self);
fn set_borderless(&mut self, borderless: bool);
fn borderless(&self) -> bool;
fn set_border_style_override(&mut self, _border_style: BorderStyleOverride) {}
fn border_style_override(&self) -> BorderStyleOverride {
BorderStyleOverride::default()
}
fn set_exclude_from_sync(&mut self, exclude_from_sync: bool);
fn exclude_from_sync(&self) -> bool;
@@ -754,6 +759,7 @@ pub trait Pane {
fn update_kitty_host_support(&mut self, _supported: KittyHostSupport) {}
fn update_sixel_host_support(&mut self, _supported: bool) {}
fn update_rounded_corners(&mut self, _rounded_corners: bool) {}
fn invalidate_frame_cache(&mut self) {}
fn set_should_be_suppressed(&mut self, _should_be_suppressed: bool) {}
fn query_should_be_suppressed(&self) -> bool {
false
@@ -2028,14 +2034,17 @@ impl Tab {
self.tiled_panes.unset_fullscreen();
}
self.dissolve_stack_lists_for_classic_mutation();
self.swap_layouts.set_current_tiled_layout_position(position);
self.swap_layouts
.set_current_tiled_layout_position(position);
self.apply_tiled_layout_candidate(Some(layout_candidate))?;
Ok(true)
}
pub fn apply_floating_swap_layout(&mut self, layout_name: &str) -> Result<bool> {
let Some((position, layout_candidate)) = self
.swap_layouts
.floating_layout_candidate_by_name(layout_name, self.floating_panes.visible_panes_count())
let Some((position, layout_candidate)) =
self.swap_layouts.floating_layout_candidate_by_name(
layout_name,
self.floating_panes.visible_panes_count(),
)
else {
return Ok(false);
};
@@ -2532,8 +2541,9 @@ impl Tab {
blocking_notification: Option<NotificationEnd>,
) -> Result<()> {
let invoked_with = self.normalize_invoked_with_for_default_shell(invoked_with);
match new_pane_placement {
NewPanePlacement::NoPreference { borderless } => self.new_no_preference_pane(
let border_style = new_pane_placement.get_border_style();
let result = match new_pane_placement {
NewPanePlacement::NoPreference { borderless, .. } => self.new_no_preference_pane(
pid,
initial_pane_title,
invoked_with,
@@ -2546,6 +2556,7 @@ impl Tab {
NewPanePlacement::Tiled {
direction: None,
borderless,
..
} => self.new_tiled_pane(
pid,
initial_pane_title,
@@ -2559,6 +2570,7 @@ impl Tab {
NewPanePlacement::Tiled {
direction: Some(direction),
borderless,
..
} => {
let is_vertical = direction == Direction::Left || direction == Direction::Right;
let focused_client_id = client_id.filter(|_| should_focus_pane);
@@ -2637,6 +2649,7 @@ impl Tab {
pane_id_to_replace,
close_replaced_pane,
borderless,
..
} => self.new_in_place_pane(
pid,
initial_pane_title,
@@ -2650,6 +2663,7 @@ impl Tab {
NewPanePlacement::Stacked {
pane_id_to_stack_under,
borderless,
..
} => self.new_stacked_pane(
pid,
initial_pane_title,
@@ -2661,7 +2675,11 @@ impl Tab {
blocking_notification,
borderless,
),
};
if let Some(border_style) = border_style {
self.set_pane_border_style(pid, border_style);
}
result
}
pub fn new_no_preference_pane(
&mut self,
@@ -7607,6 +7625,21 @@ impl Tab {
pane.update_rounded_corners(rounded_corners);
}
}
pub fn update_border_styles(
&mut self,
border_style: BorderStyle,
floating_border_style: BorderStyle,
) {
self.style.border_style = border_style;
self.style.floating_border_style = floating_border_style;
self.floating_panes
.update_border_styles(border_style, floating_border_style);
self.tiled_panes
.update_border_styles(border_style, floating_border_style);
for (_, pane) in self.suppressed_panes.values_mut() {
pane.invalidate_frame_cache();
}
}
pub fn update_arrow_fonts(&mut self, should_support_arrow_fonts: bool) {
self.arrow_fonts = should_support_arrow_fonts;
self.floating_panes
@@ -7882,6 +7915,27 @@ impl Tab {
log::error!("Pane with id {:?} not found", pane_id);
Ok(())
}
pub fn set_pane_border_style(
&mut self,
pane_id: PaneId,
border_style: BorderStyleOverride,
) -> bool {
if let Some(pane) = self.floating_panes.get_pane_mut(pane_id) {
pane.set_border_style_override(border_style);
self.set_force_render();
return true;
}
if let Some(pane) = self.tiled_panes.get_pane_mut(pane_id) {
pane.set_border_style_override(border_style);
self.set_force_render();
return true;
}
if let Some(pane) = self.suppressed_panes.get_mut(&pane_id) {
pane.1.set_border_style_override(border_style);
return true;
}
false
}
pub fn get_viewport(&self) -> Viewport {
self.viewport.borrow().clone()
}
@@ -14,10 +14,10 @@ use std::path::PathBuf;
use std::sync::Mutex;
use zellij_utils::channels::Receiver;
use zellij_utils::data::Direction;
use zellij_utils::data::Resize;
use zellij_utils::data::ResizeStrategy;
use zellij_utils::data::WebSharing;
use zellij_utils::data::{BorderStyle, BorderStyleOverride, Direction, LineStyle};
use zellij_utils::envs::set_session_name;
use zellij_utils::errors::{prelude::*, ErrorContext};
use zellij_utils::input::layout::{
@@ -1558,6 +1558,7 @@ fn new_stacked_pane() {
NewPanePlacement::Stacked {
pane_id_to_stack_under: None,
borderless: None,
border_style: None,
},
Some(client_id),
None,
@@ -1597,6 +1598,7 @@ fn kitty_visible_panes_exclude_collapsed_stack_members() {
NewPanePlacement::Stacked {
pane_id_to_stack_under: None,
borderless: None,
border_style: None,
},
Some(client_id),
None,
@@ -10843,6 +10845,7 @@ fn borderless_floating_pane() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(true),
border_style: None,
};
tab.new_floating_pane(
@@ -10890,6 +10893,7 @@ fn borderless_pane_content_fills_edges() {
height: Some(PercentOrFixed::Fixed(5)),
pinned: None,
borderless: Some(true),
border_style: None,
};
tab.new_floating_pane(
@@ -10938,6 +10942,7 @@ fn borderless_pinned_floating_pane() {
height: Some(PercentOrFixed::Fixed(8)),
pinned: Some(true),
borderless: Some(true),
border_style: None,
};
tab.new_floating_pane(
@@ -10990,6 +10995,7 @@ fn cursor_hidden_when_floating_pane_is_under_pinned_pane() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: Some(false),
borderless: Some(false),
border_style: None,
};
tab.new_floating_pane(
@@ -11011,6 +11017,7 @@ fn cursor_hidden_when_floating_pane_is_under_pinned_pane() {
height: Some(PercentOrFixed::Fixed(8)),
pinned: Some(true),
borderless: Some(false),
border_style: None,
};
tab.new_floating_pane(
@@ -11070,6 +11077,7 @@ fn cursor_visible_when_pinned_pane_is_focused() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: Some(false),
borderless: Some(false),
border_style: None,
};
tab.new_floating_pane(
@@ -11091,6 +11099,7 @@ fn cursor_visible_when_pinned_pane_is_focused() {
height: Some(PercentOrFixed::Fixed(8)),
pinned: Some(true),
borderless: Some(false),
border_style: None,
};
tab.new_floating_pane(
@@ -11532,6 +11541,7 @@ fn test_ctrl_drag_resizes_floating_pane_from_edge() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
};
tab.toggle_floating_panes(Some(client_id), None, None)
@@ -11613,6 +11623,7 @@ fn test_ctrl_drag_resizes_floating_pane_from_corner() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
};
tab.toggle_floating_panes(Some(client_id), None, None)
@@ -11694,6 +11705,7 @@ fn test_ctrl_drag_resizes_pinned_floating_pane_when_floating_panes_not_shown() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: Some(true),
borderless: Some(false),
border_style: None,
};
tab.new_pane(
@@ -11957,6 +11969,7 @@ fn test_left_click_on_floating_pane_changes_focus() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
};
let coordinates_2 = FloatingPaneCoordinates {
@@ -11966,6 +11979,7 @@ fn test_left_click_on_floating_pane_changes_focus() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
};
tab.toggle_floating_panes(Some(client_id), None, None)
@@ -12028,6 +12042,7 @@ fn test_left_click_on_pinned_floating_pane() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
};
let coordinates_2 = FloatingPaneCoordinates {
@@ -12037,6 +12052,7 @@ fn test_left_click_on_pinned_floating_pane() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
};
tab.toggle_floating_panes(Some(client_id), None, None)
@@ -13366,6 +13382,7 @@ fn test_ctrl_scroll_up_increases_pinned_floating_pane_size_when_floating_panes_h
height: Some(PercentOrFixed::Fixed(10)),
pinned: Some(true),
borderless: Some(false),
border_style: None,
};
tab.new_pane(
@@ -13434,6 +13451,7 @@ fn test_ctrl_scroll_down_decreases_pinned_floating_pane_size_when_floating_panes
height: Some(PercentOrFixed::Fixed(10)),
pinned: Some(true),
borderless: Some(false),
border_style: None,
};
tab.new_pane(
@@ -13706,6 +13724,7 @@ fn adding_stacked_pane_in_stack_list_mode_moves_existing_pane_to_suppressed_imme
NewPanePlacement::Stacked {
pane_id_to_stack_under: None,
borderless: None,
border_style: None,
},
Some(client_id),
None,
@@ -13933,6 +13952,7 @@ fn in_place_pane_with_close_replaced_pane_false_restores_original() {
NewPanePlacement::Tiled {
direction: None,
borderless: None,
border_style: None,
},
Some(client_id),
None,
@@ -13996,6 +14016,7 @@ fn in_place_pane_with_close_replaced_pane_true_closes_original() {
NewPanePlacement::Tiled {
direction: None,
borderless: None,
border_style: None,
},
Some(client_id),
None,
@@ -15060,6 +15081,7 @@ fn focus_follows_mouse_focuses_floating_pane_on_hover() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
};
let coordinates_2 = FloatingPaneCoordinates {
@@ -15069,6 +15091,7 @@ fn focus_follows_mouse_focuses_floating_pane_on_hover() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
};
tab.toggle_floating_panes(Some(client_id), None, None)
@@ -15284,6 +15307,7 @@ fn focus_follows_mouse_ignores_tiled_pane_when_floating_visible() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
})),
Some(client_id),
None,
@@ -15334,6 +15358,7 @@ fn focus_follows_mouse_focuses_floating_pane_when_floating_visible() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
})),
Some(client_id),
None,
@@ -15352,6 +15377,7 @@ fn focus_follows_mouse_focuses_floating_pane_when_floating_visible() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
})),
Some(client_id),
None,
@@ -16545,3 +16571,202 @@ fn host_focus_events_only_reach_panes_that_asked_for_them() {
.map(|bytes| String::from_utf8_lossy(bytes).to_string());
assert_eq!(written, Some("\u{1b}[O\u{1b}[I".to_owned()));
}
fn border_style_override(all: LineStyle) -> BorderStyleOverride {
BorderStyleOverride {
all: Some(all),
..Default::default()
}
}
fn uniform_border_style(line_style: LineStyle) -> BorderStyle {
BorderStyle {
top: line_style,
right: line_style,
bottom: line_style,
left: line_style,
rounded_corners: false,
}
}
fn render_tab(tab: &mut Tab, size: Size, client_id: ClientId) -> String {
let mut output = Output::default();
tab.render(&mut output, None).unwrap();
take_snapshot(
output.serialize().unwrap().get(&client_id).unwrap(),
size.rows,
size.cols,
Palette::default(),
)
}
#[test]
fn a_per_pane_border_style_is_drawn_on_the_pane_frame() {
let size = Size { cols: 40, rows: 10 };
let client_id = 1;
let mut tab = create_new_tab(size, ModeInfo::default());
tab.set_pane_border_style(
PaneId::Terminal(1),
border_style_override(LineStyle::Double),
);
let snapshot = render_tab(&mut tab, size, client_id);
assert!(snapshot.contains('╔'), "{}", snapshot);
assert!(snapshot.contains('║'), "{}", snapshot);
assert!(snapshot.contains('╝'), "{}", snapshot);
}
#[test]
fn a_per_pane_border_style_reaches_a_floating_pane() {
let size = Size { cols: 60, rows: 20 };
let client_id = 1;
let mut tab = create_new_tab(size, ModeInfo::default());
tab.toggle_floating_panes(Some(client_id), None, None)
.unwrap();
tab.new_pane(
PaneId::Terminal(2),
None,
None,
false,
true,
NewPanePlacement::default(),
Some(client_id),
None,
)
.unwrap();
tab.set_pane_border_style(PaneId::Terminal(2), border_style_override(LineStyle::Heavy));
let snapshot = render_tab(&mut tab, size, client_id);
assert!(snapshot.contains('┏'), "{}", snapshot);
assert!(snapshot.contains('┃'), "{}", snapshot);
}
#[test]
fn setting_a_border_style_on_an_unknown_pane_reports_failure() {
let size = Size { cols: 40, rows: 10 };
let mut tab = create_new_tab(size, ModeInfo::default());
assert!(tab.set_pane_border_style(
PaneId::Terminal(1),
border_style_override(LineStyle::Double)
));
assert!(!tab.set_pane_border_style(
PaneId::Terminal(99),
border_style_override(LineStyle::Double)
));
}
#[test]
fn an_empty_border_style_override_restores_the_configured_default() {
let size = Size { cols: 40, rows: 10 };
let client_id = 1;
let mut tab = create_new_tab(size, ModeInfo::default());
tab.set_pane_border_style(
PaneId::Terminal(1),
border_style_override(LineStyle::Double),
);
assert!(render_tab(&mut tab, size, client_id).contains('╔'));
tab.set_pane_border_style(PaneId::Terminal(1), BorderStyleOverride::default());
let snapshot = render_tab(&mut tab, size, client_id);
assert!(!snapshot.contains('╔'), "{}", snapshot);
assert!(snapshot.contains('┌'), "{}", snapshot);
}
#[test]
fn reconfiguring_the_global_border_style_repaints_open_panes() {
let size = Size { cols: 40, rows: 10 };
let client_id = 1;
let mut tab = create_new_tab(size, ModeInfo::default());
assert!(render_tab(&mut tab, size, client_id).contains('┌'));
let heavy = uniform_border_style(LineStyle::Heavy);
tab.update_border_styles(heavy, heavy);
let snapshot = render_tab(&mut tab, size, client_id);
assert!(snapshot.contains('┏'), "{}", snapshot);
assert!(snapshot.contains('┛'), "{}", snapshot);
}
#[test]
fn a_per_pane_border_style_wins_over_the_global_one() {
let size = Size { cols: 40, rows: 10 };
let client_id = 1;
let mut tab = create_new_tab(size, ModeInfo::default());
let heavy = uniform_border_style(LineStyle::Heavy);
tab.update_border_styles(heavy, heavy);
tab.set_pane_border_style(
PaneId::Terminal(1),
border_style_override(LineStyle::Double),
);
let snapshot = render_tab(&mut tab, size, client_id);
assert!(snapshot.contains('╔'), "{}", snapshot);
assert!(!snapshot.contains('┏'), "{}", snapshot);
}
#[test]
fn border_styles_from_a_layout_reach_the_panes() {
let size = Size { cols: 60, rows: 20 };
let client_id = 1;
let layout = r#"
layout {
pane border_style="double"
floating_panes {
pane x=2 y=2 width=20 height=6 border_style="heavy"
}
}
"#;
let mut tab = create_new_tab_with_layout(size, ModeInfo::default(), layout);
let snapshot = render_tab(&mut tab, size, client_id);
assert!(snapshot.contains('╔'), "{}", snapshot);
assert!(snapshot.contains('┏'), "{}", snapshot);
}
#[test]
fn matching_neighbours_share_a_styled_grid_line() {
let size = Size { cols: 60, rows: 10 };
let client_id = 1;
let mut tab = create_new_tab(size, ModeInfo::default());
tab.set_pane_frames(PaneFrameStyle::None);
tab.vertical_split(PaneId::Terminal(2), None, client_id, None, None)
.unwrap();
tab.set_pane_border_style(
PaneId::Terminal(1),
border_style_override(LineStyle::Double),
);
tab.set_pane_border_style(
PaneId::Terminal(2),
border_style_override(LineStyle::Double),
);
let snapshot = render_tab(&mut tab, size, client_id);
assert!(snapshot.contains('║'), "{}", snapshot);
}
#[test]
fn mismatched_neighbours_fall_back_to_the_ambient_grid_line() {
let size = Size { cols: 60, rows: 10 };
let client_id = 1;
let mut tab = create_new_tab(size, ModeInfo::default());
tab.set_pane_frames(PaneFrameStyle::None);
tab.vertical_split(PaneId::Terminal(2), None, client_id, None, None)
.unwrap();
let double = uniform_border_style(LineStyle::Double);
tab.update_border_styles(double, double);
tab.set_pane_border_style(PaneId::Terminal(2), border_style_override(LineStyle::Heavy));
let snapshot = render_tab(&mut tab, size, client_id);
assert!(snapshot.contains('║'), "{}", snapshot);
assert!(!snapshot.contains('┃'), "{}", snapshot);
assert!(!snapshot.contains('│'), "{}", snapshot);
}
#[test]
fn mismatched_neighbours_fall_back_to_single_when_the_ambient_style_is_mixed() {
let size = Size { cols: 60, rows: 10 };
let client_id = 1;
let mut tab = create_new_tab(size, ModeInfo::default());
tab.set_pane_frames(PaneFrameStyle::None);
tab.vertical_split(PaneId::Terminal(2), None, client_id, None, None)
.unwrap();
let mixed = BorderStyle {
top: LineStyle::Double,
..Default::default()
};
tab.update_border_styles(mixed, mixed);
tab.set_pane_border_style(PaneId::Terminal(2), border_style_override(LineStyle::Heavy));
let snapshot = render_tab(&mut tab, size, client_id);
assert!(snapshot.contains('│'), "{}", snapshot);
}
+2
View File
@@ -910,6 +910,7 @@ pub fn split_in_direction_without_a_connected_client_still_creates_the_pane() {
NewPanePlacement::Tiled {
direction: Some(Direction::Down),
borderless: None,
border_style: None,
},
None,
None,
@@ -940,6 +941,7 @@ pub fn split_in_direction_without_a_connected_client_splits_the_existing_pane()
NewPanePlacement::Tiled {
direction: Some(Direction::Right),
borderless: None,
border_style: None,
},
None,
None,
+379
View File
@@ -0,0 +1,379 @@
use crate::ui::boundaries::boundary_type;
use zellij_utils::data::LineStyle;
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
pub enum Corner {
TopLeft,
TopRight,
BottomLeft,
BottomRight,
}
pub fn horizontal(line_style: LineStyle) -> &'static str {
match line_style {
LineStyle::Single => "─",
LineStyle::Double => "═",
LineStyle::Heavy => "━",
LineStyle::Dashed => "┄",
LineStyle::HeavyDashed => "┅",
}
}
pub fn vertical(line_style: LineStyle) -> &'static str {
match line_style {
LineStyle::Single => "│",
LineStyle::Double => "║",
LineStyle::Heavy => "┃",
LineStyle::Dashed => "┆",
LineStyle::HeavyDashed => "┇",
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum Weight {
Light,
Double,
Heavy,
}
fn weight(line_style: LineStyle) -> Weight {
match line_style {
LineStyle::Single | LineStyle::Dashed => Weight::Light,
LineStyle::Double => Weight::Double,
LineStyle::Heavy | LineStyle::HeavyDashed => Weight::Heavy,
}
}
pub fn corner(
corner: Corner,
horizontal_style: LineStyle,
vertical_style: LineStyle,
rounded: bool,
) -> &'static str {
let horizontal_weight = weight(horizontal_style);
let mut vertical_weight = weight(vertical_style);
// there are no glyphs mixing a double arm with a heavy arm, in this case we render both arms
// in the weight of the horizontal arm
if (horizontal_weight == Weight::Double && vertical_weight == Weight::Heavy)
|| (horizontal_weight == Weight::Heavy && vertical_weight == Weight::Double)
{
vertical_weight = horizontal_weight;
}
if rounded && horizontal_weight == Weight::Light && vertical_weight == Weight::Light {
return match corner {
Corner::TopLeft => boundary_type::TOP_LEFT_ROUND,
Corner::TopRight => boundary_type::TOP_RIGHT_ROUND,
Corner::BottomLeft => boundary_type::BOTTOM_LEFT_ROUND,
Corner::BottomRight => boundary_type::BOTTOM_RIGHT_ROUND,
};
}
match (corner, horizontal_weight, vertical_weight) {
(Corner::TopLeft, Weight::Light, Weight::Light) => "┌",
(Corner::TopLeft, Weight::Double, Weight::Light) => "╒",
(Corner::TopLeft, Weight::Light, Weight::Double) => "╓",
(Corner::TopLeft, Weight::Double, Weight::Double) => "╔",
(Corner::TopLeft, Weight::Heavy, Weight::Light) => "┍",
(Corner::TopLeft, Weight::Light, Weight::Heavy) => "┎",
(Corner::TopLeft, Weight::Heavy, Weight::Heavy) => "┏",
(Corner::TopRight, Weight::Light, Weight::Light) => "┐",
(Corner::TopRight, Weight::Double, Weight::Light) => "╕",
(Corner::TopRight, Weight::Light, Weight::Double) => "╖",
(Corner::TopRight, Weight::Double, Weight::Double) => "╗",
(Corner::TopRight, Weight::Heavy, Weight::Light) => "┑",
(Corner::TopRight, Weight::Light, Weight::Heavy) => "┒",
(Corner::TopRight, Weight::Heavy, Weight::Heavy) => "┓",
(Corner::BottomLeft, Weight::Light, Weight::Light) => "└",
(Corner::BottomLeft, Weight::Double, Weight::Light) => "╘",
(Corner::BottomLeft, Weight::Light, Weight::Double) => "╙",
(Corner::BottomLeft, Weight::Double, Weight::Double) => "╚",
(Corner::BottomLeft, Weight::Heavy, Weight::Light) => "┕",
(Corner::BottomLeft, Weight::Light, Weight::Heavy) => "┖",
(Corner::BottomLeft, Weight::Heavy, Weight::Heavy) => "┗",
(Corner::BottomRight, Weight::Light, Weight::Light) => "┘",
(Corner::BottomRight, Weight::Double, Weight::Light) => "╛",
(Corner::BottomRight, Weight::Light, Weight::Double) => "╜",
(Corner::BottomRight, Weight::Double, Weight::Double) => "╝",
(Corner::BottomRight, Weight::Heavy, Weight::Light) => "┙",
(Corner::BottomRight, Weight::Light, Weight::Heavy) => "┚",
(Corner::BottomRight, Weight::Heavy, Weight::Heavy) => "┛",
(_, Weight::Double, Weight::Heavy) | (_, Weight::Heavy, Weight::Double) => {
unreachable!("double/heavy mixes are normalized above")
},
}
}
pub fn title_separator_left(horizontal_style: LineStyle) -> &'static str {
match weight(horizontal_style) {
Weight::Light => boundary_type::VERTICAL_LEFT,
Weight::Double => "╡",
Weight::Heavy => "┥",
}
}
pub fn title_separator_right(horizontal_style: LineStyle) -> &'static str {
match weight(horizontal_style) {
Weight::Light => boundary_type::VERTICAL_RIGHT,
Weight::Double => "╞",
Weight::Heavy => "┝",
}
}
pub fn remap_light_glyph(glyph: &'static str, line_style: LineStyle) -> &'static str {
match line_style {
LineStyle::Single => glyph,
LineStyle::Dashed => match glyph {
boundary_type::HORIZONTAL => "┄",
boundary_type::VERTICAL => "┆",
_ => glyph,
},
LineStyle::Double => match glyph {
boundary_type::HORIZONTAL => "═",
boundary_type::VERTICAL => "║",
boundary_type::TOP_LEFT => "╔",
boundary_type::TOP_LEFT_ROUND => "╔",
boundary_type::TOP_RIGHT => "╗",
boundary_type::TOP_RIGHT_ROUND => "╗",
boundary_type::BOTTOM_LEFT => "╚",
boundary_type::BOTTOM_LEFT_ROUND => "╚",
boundary_type::BOTTOM_RIGHT => "╝",
boundary_type::BOTTOM_RIGHT_ROUND => "╝",
boundary_type::VERTICAL_LEFT => "╣",
boundary_type::VERTICAL_RIGHT => "╠",
boundary_type::HORIZONTAL_DOWN => "╦",
boundary_type::HORIZONTAL_UP => "╩",
boundary_type::CROSS => "╬",
_ => glyph,
},
LineStyle::Heavy | LineStyle::HeavyDashed => {
let heavy_dashed = line_style == LineStyle::HeavyDashed;
match glyph {
boundary_type::HORIZONTAL => {
if heavy_dashed {
"┅"
} else {
"━"
}
},
boundary_type::VERTICAL => {
if heavy_dashed {
"┇"
} else {
"┃"
}
},
boundary_type::TOP_LEFT => "┏",
boundary_type::TOP_LEFT_ROUND => "┏",
boundary_type::TOP_RIGHT => "┓",
boundary_type::TOP_RIGHT_ROUND => "┓",
boundary_type::BOTTOM_LEFT => "┗",
boundary_type::BOTTOM_LEFT_ROUND => "┗",
boundary_type::BOTTOM_RIGHT => "┛",
boundary_type::BOTTOM_RIGHT_ROUND => "┛",
boundary_type::VERTICAL_LEFT => "┫",
boundary_type::VERTICAL_RIGHT => "┣",
boundary_type::HORIZONTAL_DOWN => "┳",
boundary_type::HORIZONTAL_UP => "┻",
boundary_type::CROSS => "╋",
_ => glyph,
}
},
}
}
#[cfg(test)]
mod tests {
use super::*;
const ALL: [LineStyle; 5] = [
LineStyle::Single,
LineStyle::Double,
LineStyle::Heavy,
LineStyle::Dashed,
LineStyle::HeavyDashed,
];
const CORNERS: [Corner; 4] = [
Corner::TopLeft,
Corner::TopRight,
Corner::BottomLeft,
Corner::BottomRight,
];
#[test]
fn every_edge_style_has_its_own_glyph() {
let horizontals: Vec<&str> = ALL.iter().map(|s| horizontal(*s)).collect();
let verticals: Vec<&str> = ALL.iter().map(|s| vertical(*s)).collect();
assert_eq!(horizontals, vec!["─", "═", "━", "┄", "┅"]);
assert_eq!(verticals, vec!["│", "║", "┃", "┆", "┇"]);
}
#[test]
fn every_corner_combination_resolves_to_a_single_width_glyph() {
for corner in CORNERS {
for horizontal_style in ALL {
for vertical_style in ALL {
for rounded in [false, true] {
let glyph =
super::corner(corner, horizontal_style, vertical_style, rounded);
assert_eq!(
glyph.chars().count(),
1,
"{:?} {:?}/{:?} rounded={} produced {:?}",
corner,
horizontal_style,
vertical_style,
rounded,
glyph
);
}
}
}
}
}
#[test]
fn corners_only_round_when_both_arms_are_single_width() {
assert_eq!(
corner(Corner::TopLeft, LineStyle::Single, LineStyle::Single, true),
"╭"
);
assert_eq!(
corner(Corner::TopLeft, LineStyle::Dashed, LineStyle::Dashed, true),
"╭"
);
assert_eq!(
corner(Corner::TopLeft, LineStyle::Double, LineStyle::Single, true),
"╒"
);
assert_eq!(
corner(Corner::TopLeft, LineStyle::Single, LineStyle::Heavy, true),
"┎"
);
}
#[test]
fn mixed_weight_corners_use_the_dedicated_glyphs() {
assert_eq!(
corner(
Corner::BottomRight,
LineStyle::Double,
LineStyle::Single,
false
),
"╛"
);
assert_eq!(
corner(
Corner::BottomRight,
LineStyle::Single,
LineStyle::Double,
false
),
"╜"
);
assert_eq!(
corner(
Corner::BottomRight,
LineStyle::Heavy,
LineStyle::Single,
false
),
"┙"
);
assert_eq!(
corner(
Corner::BottomRight,
LineStyle::Single,
LineStyle::Heavy,
false
),
"┚"
);
}
#[test]
fn a_double_and_heavy_corner_uses_the_horizontal_arm_for_both() {
assert_eq!(
corner(Corner::TopLeft, LineStyle::Double, LineStyle::Heavy, false),
"╔"
);
assert_eq!(
corner(Corner::TopLeft, LineStyle::Heavy, LineStyle::Double, false),
"┏"
);
}
#[test]
fn title_separators_follow_the_horizontal_weight() {
assert_eq!(title_separator_left(LineStyle::Single), "┤");
assert_eq!(title_separator_right(LineStyle::Single), "├");
assert_eq!(title_separator_left(LineStyle::Double), "╡");
assert_eq!(title_separator_right(LineStyle::Double), "╞");
assert_eq!(title_separator_left(LineStyle::HeavyDashed), "┥");
assert_eq!(title_separator_right(LineStyle::HeavyDashed), "┝");
}
#[test]
fn remapping_covers_every_light_glyph_for_double_and_heavy() {
let light = [
boundary_type::HORIZONTAL,
boundary_type::VERTICAL,
boundary_type::TOP_LEFT,
boundary_type::TOP_RIGHT,
boundary_type::BOTTOM_LEFT,
boundary_type::BOTTOM_RIGHT,
boundary_type::VERTICAL_LEFT,
boundary_type::VERTICAL_RIGHT,
boundary_type::HORIZONTAL_DOWN,
boundary_type::HORIZONTAL_UP,
boundary_type::CROSS,
];
for glyph in light {
for line_style in [LineStyle::Double, LineStyle::Heavy] {
assert_ne!(
remap_light_glyph(glyph, line_style),
glyph,
"{:?} left {} unmapped",
line_style,
glyph
);
}
}
}
#[test]
fn dashed_remapping_only_touches_the_straight_runs() {
assert_eq!(
remap_light_glyph(boundary_type::HORIZONTAL, LineStyle::Dashed),
"┄"
);
assert_eq!(
remap_light_glyph(boundary_type::VERTICAL, LineStyle::Dashed),
"┆"
);
assert_eq!(
remap_light_glyph(boundary_type::CROSS, LineStyle::Dashed),
boundary_type::CROSS
);
assert_eq!(
remap_light_glyph(boundary_type::HORIZONTAL, LineStyle::HeavyDashed),
"┅"
);
assert_eq!(
remap_light_glyph(boundary_type::CROSS, LineStyle::HeavyDashed),
"╋"
);
}
#[test]
fn a_single_style_remap_is_the_identity() {
assert_eq!(
remap_light_glyph(boundary_type::CROSS, LineStyle::Single),
boundary_type::CROSS
);
}
}
+187 -31
View File
@@ -3,10 +3,14 @@ use zellij_utils::pane_size::{Offset, Viewport};
use crate::output::CharacterChunk;
use crate::panes::terminal_character::{TerminalCharacter, EMPTY_TERMINAL_CHARACTER, RESET_STYLES};
use crate::tab::Pane;
use crate::ui::border_glyphs::remap_light_glyph;
use ansi_term::Colour::{Fixed, RGB};
use std::collections::HashMap;
use zellij_utils::errors::prelude::*;
use zellij_utils::{data::PaletteColor, shared::colors};
use zellij_utils::{
data::{BorderStyle, LineStyle, PaletteColor},
shared::colors,
};
use std::fmt::{Display, Error, Formatter};
pub mod boundary_type {
@@ -34,6 +38,7 @@ pub struct BoundarySymbol {
boundary_type: BoundaryType,
invisible: bool,
color: Option<(PaletteColor, usize)>, // (color, color_precedence)
line_style: Option<LineStyle>,
}
impl BoundarySymbol {
@@ -42,25 +47,39 @@ impl BoundarySymbol {
boundary_type,
invisible: false,
color: Some((PaletteColor::EightBit(colors::GRAY), 0)),
line_style: Some(LineStyle::Single),
}
}
pub fn color(&mut self, color: Option<(PaletteColor, usize)>) -> Self {
self.color = color;
*self
}
pub fn as_terminal_character(&self) -> Result<TerminalCharacter> {
pub fn line_style(&mut self, line_style: LineStyle) -> Self {
self.line_style = Some(line_style);
*self
}
pub fn glyph(&self, fallback_line_style: LineStyle) -> BoundaryType {
remap_light_glyph(
self.boundary_type,
self.line_style.unwrap_or(fallback_line_style),
)
}
pub fn as_terminal_character(
&self,
fallback_line_style: LineStyle,
) -> Result<TerminalCharacter> {
let tc = if self.invisible {
EMPTY_TERMINAL_CHARACTER
} else {
let character = self
.boundary_type
let glyph = self.glyph(fallback_line_style);
let character = glyph
.chars()
.next()
.context("no boundary symbols defined")
.with_context(|| {
format!(
"failed to convert boundary symbol {} into terminal character",
self.boundary_type
glyph
)
})?;
TerminalCharacter::new_singlewidth_styled(
@@ -76,18 +95,15 @@ impl BoundarySymbol {
impl Display for BoundarySymbol {
fn fmt(&self, f: &mut Formatter) -> Result<(), Error> {
let glyph = self.glyph(LineStyle::Single);
match self.invisible {
true => write!(f, " "),
false => match self.color {
Some(color) => match color.0 {
PaletteColor::Rgb((r, g, b)) => {
write!(f, "{}", RGB(r, g, b).paint(self.boundary_type))
},
PaletteColor::EightBit(color) => {
write!(f, "{}", Fixed(color).paint(self.boundary_type))
},
PaletteColor::Rgb((r, g, b)) => write!(f, "{}", RGB(r, g, b).paint(glyph)),
PaletteColor::EightBit(color) => write!(f, "{}", Fixed(color).paint(glyph)),
},
None => write!(f, "{}", self.boundary_type),
None => write!(f, "{}", glyph),
},
}
}
@@ -110,6 +126,16 @@ fn combine_symbols(
},
_ => current_symbol.color.or(next_symbol.color),
};
let line_style = match (current_symbol.line_style, next_symbol.line_style) {
(Some(current_line_style), Some(next_line_style)) => {
if current_line_style == next_line_style {
Some(current_line_style)
} else {
None
}
},
_ => None,
};
match (current_symbol.boundary_type, next_symbol.boundary_type) {
(CROSS, _) | (_, CROSS) => {
// (┼, *) or (*, ┼) => Some(┼)
@@ -118,6 +144,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(TOP_RIGHT, TOP_RIGHT) => {
@@ -127,6 +154,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(TOP_RIGHT, VERTICAL) | (TOP_RIGHT, BOTTOM_RIGHT) | (TOP_RIGHT, VERTICAL_LEFT) => {
@@ -138,6 +166,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(TOP_RIGHT, HORIZONTAL) | (TOP_RIGHT, TOP_LEFT) | (TOP_RIGHT, HORIZONTAL_DOWN) => {
@@ -149,6 +178,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(TOP_RIGHT, BOTTOM_LEFT) | (TOP_RIGHT, VERTICAL_RIGHT) | (TOP_RIGHT, HORIZONTAL_UP) => {
@@ -160,6 +190,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(HORIZONTAL, HORIZONTAL) => {
@@ -169,6 +200,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(HORIZONTAL, VERTICAL) | (HORIZONTAL, VERTICAL_LEFT) | (HORIZONTAL, VERTICAL_RIGHT) => {
@@ -180,6 +212,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(HORIZONTAL, TOP_LEFT) | (HORIZONTAL, HORIZONTAL_DOWN) => {
@@ -190,6 +223,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(HORIZONTAL, BOTTOM_RIGHT) | (HORIZONTAL, BOTTOM_LEFT) | (HORIZONTAL, HORIZONTAL_UP) => {
@@ -201,6 +235,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(VERTICAL, VERTICAL) => {
@@ -210,6 +245,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(VERTICAL, TOP_LEFT) | (VERTICAL, BOTTOM_LEFT) | (VERTICAL, VERTICAL_RIGHT) => {
@@ -221,6 +257,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(VERTICAL, BOTTOM_RIGHT) | (VERTICAL, VERTICAL_LEFT) => {
@@ -231,6 +268,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(VERTICAL, HORIZONTAL_DOWN) | (VERTICAL, HORIZONTAL_UP) => {
@@ -241,6 +279,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(TOP_LEFT, TOP_LEFT) => {
@@ -250,6 +289,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(TOP_LEFT, BOTTOM_RIGHT) | (TOP_LEFT, VERTICAL_LEFT) | (TOP_LEFT, HORIZONTAL_UP) => {
@@ -261,6 +301,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(TOP_LEFT, BOTTOM_LEFT) | (TOP_LEFT, VERTICAL_RIGHT) => {
@@ -271,6 +312,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(TOP_LEFT, HORIZONTAL_DOWN) => {
@@ -280,6 +322,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(BOTTOM_RIGHT, BOTTOM_RIGHT) => {
@@ -289,6 +332,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(BOTTOM_RIGHT, BOTTOM_LEFT) | (BOTTOM_RIGHT, HORIZONTAL_UP) => {
@@ -299,6 +343,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(BOTTOM_RIGHT, VERTICAL_LEFT) => {
@@ -308,6 +353,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(BOTTOM_RIGHT, VERTICAL_RIGHT) | (BOTTOM_RIGHT, HORIZONTAL_DOWN) => {
@@ -318,6 +364,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(BOTTOM_LEFT, BOTTOM_LEFT) => {
@@ -327,6 +374,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(BOTTOM_LEFT, VERTICAL_LEFT) | (BOTTOM_LEFT, HORIZONTAL_DOWN) => {
@@ -337,6 +385,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(BOTTOM_LEFT, VERTICAL_RIGHT) => {
@@ -346,6 +395,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(BOTTOM_LEFT, HORIZONTAL_UP) => {
@@ -355,6 +405,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(VERTICAL_LEFT, VERTICAL_LEFT) => {
@@ -364,6 +415,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(VERTICAL_LEFT, VERTICAL_RIGHT)
@@ -377,6 +429,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(VERTICAL_RIGHT, VERTICAL_RIGHT) => {
@@ -386,6 +439,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(VERTICAL_RIGHT, HORIZONTAL_DOWN) | (VERTICAL_RIGHT, HORIZONTAL_UP) => {
@@ -396,6 +450,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(HORIZONTAL_DOWN, HORIZONTAL_DOWN) => {
@@ -405,6 +460,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(HORIZONTAL_DOWN, HORIZONTAL_UP) => {
@@ -414,6 +470,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(HORIZONTAL_UP, HORIZONTAL_UP) => {
@@ -423,6 +480,7 @@ fn combine_symbols(
boundary_type,
invisible,
color,
line_style,
})
},
(_, _) => combine_symbols(next_symbol, current_symbol),
@@ -443,14 +501,16 @@ impl Coordinates {
pub struct Boundaries {
viewport: Viewport,
fallback_line_style: LineStyle,
pub boundary_characters: HashMap<Coordinates, BoundarySymbol>,
}
#[allow(clippy::if_same_then_else)]
impl Boundaries {
pub fn new(viewport: Viewport) -> Self {
pub fn new(viewport: Viewport, fallback_line_style: LineStyle) -> Self {
Boundaries {
viewport,
fallback_line_style,
boundary_characters: HashMap::new(),
}
}
@@ -458,6 +518,7 @@ impl Boundaries {
&mut self,
rect: &dyn Pane,
color: Option<(PaletteColor, usize)>, // (color, color_precedence)
border_style: BorderStyle,
pane_is_on_top_of_stack: bool,
pane_is_on_bottom_of_stack: bool,
pane_is_stacked_under: bool,
@@ -479,19 +540,29 @@ impl Boundaries {
let coordinates = Coordinates::new(boundary_x_coords, row);
let symbol_to_add = if row == first_row_coordinates && row != self.viewport.y {
if pane_is_stacked {
BoundarySymbol::new(boundary_type::VERTICAL_RIGHT).color(color)
BoundarySymbol::new(boundary_type::VERTICAL_RIGHT)
.color(color)
.line_style(border_style.left)
} else {
BoundarySymbol::new(boundary_type::TOP_LEFT).color(color)
BoundarySymbol::new(boundary_type::TOP_LEFT)
.color(color)
.line_style(border_style.left)
}
} else if row == first_row_coordinates && pane_is_stacked {
BoundarySymbol::new(boundary_type::TOP_LEFT).color(color)
BoundarySymbol::new(boundary_type::TOP_LEFT)
.color(color)
.line_style(border_style.left)
} else if row == last_row_coordinates - 1
&& row != self.viewport.y + self.viewport.rows - 1
&& content_offset.bottom > 0
{
BoundarySymbol::new(boundary_type::BOTTOM_LEFT).color(color)
BoundarySymbol::new(boundary_type::BOTTOM_LEFT)
.color(color)
.line_style(border_style.left)
} else {
BoundarySymbol::new(boundary_type::VERTICAL).color(color)
BoundarySymbol::new(boundary_type::VERTICAL)
.color(color)
.line_style(border_style.left)
};
let next_symbol = self
.boundary_characters
@@ -509,11 +580,17 @@ impl Boundaries {
for col in first_col_coordinates..last_col_coordinates {
let coordinates = Coordinates::new(col, boundary_y_coords);
let symbol_to_add = if col == first_col_coordinates && col != self.viewport.x {
BoundarySymbol::new(boundary_type::TOP_LEFT).color(color)
BoundarySymbol::new(boundary_type::TOP_LEFT)
.color(color)
.line_style(border_style.top)
} else if col == last_col_coordinates - 1 && col != self.viewport.cols - 1 {
BoundarySymbol::new(boundary_type::TOP_RIGHT).color(color)
BoundarySymbol::new(boundary_type::TOP_RIGHT)
.color(color)
.line_style(border_style.top)
} else {
BoundarySymbol::new(boundary_type::HORIZONTAL).color(color)
BoundarySymbol::new(boundary_type::HORIZONTAL)
.color(color)
.line_style(border_style.top)
};
let next_symbol = self
.boundary_characters
@@ -532,20 +609,30 @@ impl Boundaries {
for row in first_row_coordinates..last_row_coordinates {
let coordinates = Coordinates::new(boundary_x_coords, row);
let symbol_to_add = if row == first_row_coordinates && pane_is_stacked {
BoundarySymbol::new(boundary_type::VERTICAL_LEFT).color(color)
BoundarySymbol::new(boundary_type::VERTICAL_LEFT)
.color(color)
.line_style(border_style.right)
} else if row == first_row_coordinates && row != self.viewport.y {
if pane_is_stacked {
BoundarySymbol::new(boundary_type::VERTICAL_LEFT).color(color)
BoundarySymbol::new(boundary_type::VERTICAL_LEFT)
.color(color)
.line_style(border_style.right)
} else {
BoundarySymbol::new(boundary_type::TOP_RIGHT).color(color)
BoundarySymbol::new(boundary_type::TOP_RIGHT)
.color(color)
.line_style(border_style.right)
}
} else if row == last_row_coordinates - 1
&& row != self.viewport.y + self.viewport.rows - 1
&& content_offset.bottom > 0
{
BoundarySymbol::new(boundary_type::BOTTOM_RIGHT).color(color)
BoundarySymbol::new(boundary_type::BOTTOM_RIGHT)
.color(color)
.line_style(border_style.right)
} else {
BoundarySymbol::new(boundary_type::VERTICAL).color(color)
BoundarySymbol::new(boundary_type::VERTICAL)
.color(color)
.line_style(border_style.right)
};
let next_symbol = self
.boundary_characters
@@ -563,11 +650,17 @@ impl Boundaries {
for col in first_col_coordinates..last_col_coordinates {
let coordinates = Coordinates::new(col, boundary_y_coords);
let symbol_to_add = if col == first_col_coordinates && col != self.viewport.x {
BoundarySymbol::new(boundary_type::BOTTOM_LEFT).color(color)
BoundarySymbol::new(boundary_type::BOTTOM_LEFT)
.color(color)
.line_style(border_style.bottom)
} else if col == last_col_coordinates - 1 && col != self.viewport.cols - 1 {
BoundarySymbol::new(boundary_type::BOTTOM_RIGHT).color(color)
BoundarySymbol::new(boundary_type::BOTTOM_RIGHT)
.color(color)
.line_style(border_style.bottom)
} else {
BoundarySymbol::new(boundary_type::HORIZONTAL).color(color)
BoundarySymbol::new(boundary_type::HORIZONTAL)
.color(color)
.line_style(border_style.bottom)
};
let next_symbol = self
.boundary_characters
@@ -584,16 +677,25 @@ impl Boundaries {
) -> Result<Vec<CharacterChunk>> {
let mut character_chunks = vec![];
for (coordinates, boundary_character) in &self.boundary_characters {
let glyph = boundary_character.glyph(self.fallback_line_style);
let already_on_screen = existing_boundaries_on_screen
.and_then(|e| e.boundary_characters.get(coordinates))
.map(|e| e == boundary_character)
.map(|e| {
e.color == boundary_character.color
&& e.invisible == boundary_character.invisible
&& e.glyph(
existing_boundaries_on_screen
.map(|b| b.fallback_line_style)
.unwrap_or(LineStyle::Single),
) == glyph
})
.unwrap_or(false);
if already_on_screen {
continue;
}
character_chunks.push(CharacterChunk::new(
vec![boundary_character
.as_terminal_character()
.as_terminal_character(self.fallback_line_style)
.context("failed to render as terminal character")?],
coordinates.x,
coordinates.y,
@@ -653,3 +755,57 @@ impl Boundaries {
&& rect.y() + rect.rows() <= self.viewport.y + self.viewport.rows
}
}
#[cfg(test)]
mod tests {
use super::*;
fn symbol(boundary_type: BoundaryType, line_style: LineStyle) -> BoundarySymbol {
BoundarySymbol::new(boundary_type).line_style(line_style)
}
#[test]
fn matching_line_styles_are_kept_through_a_junction() {
let combined = combine_symbols(
symbol(boundary_type::HORIZONTAL, LineStyle::Double),
symbol(boundary_type::VERTICAL, LineStyle::Double),
)
.unwrap();
assert_eq!(combined.glyph(LineStyle::Single), "╬");
}
#[test]
fn conflicting_line_styles_fall_back_to_the_ambient_style() {
let combined = combine_symbols(
symbol(boundary_type::HORIZONTAL, LineStyle::Double),
symbol(boundary_type::VERTICAL, LineStyle::Heavy),
)
.unwrap();
assert_eq!(combined.glyph(LineStyle::Single), "┼");
assert_eq!(combined.glyph(LineStyle::Double), "╬");
}
#[test]
fn a_style_without_a_glyph_for_the_junction_falls_back_to_single() {
let combined = combine_symbols(
symbol(boundary_type::HORIZONTAL, LineStyle::Dashed),
symbol(boundary_type::VERTICAL, LineStyle::Dashed),
)
.unwrap();
assert_eq!(combined.glyph(LineStyle::Single), "┼");
assert_eq!(
symbol(boundary_type::HORIZONTAL, LineStyle::Dashed).glyph(LineStyle::Single),
"┄"
);
}
#[test]
fn heavy_junctions_are_kept() {
let combined = combine_symbols(
symbol(boundary_type::HORIZONTAL, LineStyle::Heavy),
symbol(boundary_type::TOP_LEFT, LineStyle::Heavy),
)
.unwrap();
assert_eq!(combined.glyph(LineStyle::Single), "┳");
}
}
+1
View File
@@ -1,3 +1,4 @@
pub mod border_glyphs;
pub mod boundaries;
pub mod components;
pub mod hint_text;
+171 -44
View File
@@ -3,13 +3,14 @@ use crate::panes::{
AnsiCode, CharacterStyles, RcCharacterStyles, TerminalCharacter, EMPTY_TERMINAL_CHARACTER,
};
use crate::tab::GuestChoiceIndicator;
use crate::ui::border_glyphs::{self, Corner};
use crate::ui::boundaries::boundary_type;
use crate::ui::hint_text::{
exit_code_segments, hover_segments, rerun_segments, resize_segments, HintExitStatus, HintLevel,
HintSegment, HintTier,
};
use crate::ClientId;
use zellij_utils::data::{client_id_to_colors, PaletteColor, Style};
use zellij_utils::data::{client_id_to_colors, BorderStyle, LineStyle, PaletteColor, Style};
use zellij_utils::errors::prelude::*;
use zellij_utils::pane_size::{Offset, PaneGeom, Viewport};
use zellij_utils::position::Position;
@@ -80,6 +81,7 @@ pub struct FrameParams {
pub is_main_client: bool, // more accurately: is_focused_for_main_client
pub other_focused_clients: Vec<ClientId>,
pub style: Style,
pub border_style: BorderStyle,
pub color: Option<PaletteColor>,
pub other_cursors_exist_in_session: bool,
pub pane_is_stacked_under: bool,
@@ -108,6 +110,7 @@ pub struct PaneFrame {
pub title: String,
pub scroll_position: (usize, usize), // (position, length)
pub style: Style,
pub border_style: BorderStyle,
pub color: Option<PaletteColor>,
pub focused_client: Option<ClientId>,
pub is_main_client: bool,
@@ -147,6 +150,7 @@ impl PaneFrame {
title: main_title,
scroll_position,
style: frame_params.style,
border_style: frame_params.border_style,
color: frame_params.color,
focused_client: frame_params.focused_client,
is_main_client: frame_params.is_main_client,
@@ -195,29 +199,63 @@ impl PaneFrame {
let color = client_id_to_colors(client_id, self.style.colors.multiplayer_user_colors);
background_color(" ", color.map(|c| c.0))
}
fn top_horizontal(&self) -> &'static str {
border_glyphs::horizontal(self.border_style.top)
}
fn bottom_horizontal(&self) -> &'static str {
border_glyphs::horizontal(self.border_style.bottom)
}
fn left_vertical(&self) -> &'static str {
border_glyphs::vertical(self.border_style.left)
}
fn right_vertical(&self) -> &'static str {
border_glyphs::vertical(self.border_style.right)
}
fn title_separator_left(&self) -> &'static str {
border_glyphs::title_separator_left(self.border_style.top)
}
fn title_separator_right(&self) -> &'static str {
border_glyphs::title_separator_right(self.border_style.top)
}
fn horizontal_style_of_corner(&self, corner: Corner) -> LineStyle {
match corner {
Corner::TopLeft | Corner::TopRight => self.border_style.top,
Corner::BottomLeft | Corner::BottomRight => self.border_style.bottom,
}
}
fn vertical_style_of_corner(&self, corner: Corner) -> LineStyle {
match corner {
Corner::TopLeft | Corner::BottomLeft => self.border_style.left,
Corner::TopRight | Corner::BottomRight => self.border_style.right,
}
}
fn get_corner(&self, corner: &'static str) -> &'static str {
let corner = if !self.should_draw_pane_frames
if !self.should_draw_pane_frames
&& (corner == boundary_type::TOP_LEFT || corner == boundary_type::TOP_RIGHT)
{
boundary_type::HORIZONTAL
} else if self.pane_is_stacked_under && corner == boundary_type::TOP_RIGHT {
boundary_type::BOTTOM_RIGHT
} else if self.pane_is_stacked_under && corner == boundary_type::TOP_LEFT {
boundary_type::BOTTOM_LEFT
} else {
corner
return self.top_horizontal();
}
let style_corner = match corner {
boundary_type::TOP_LEFT => Corner::TopLeft,
boundary_type::TOP_RIGHT => Corner::TopRight,
boundary_type::BOTTOM_LEFT => Corner::BottomLeft,
_ => Corner::BottomRight,
};
if self.style.rounded_corners {
match corner {
boundary_type::TOP_RIGHT => boundary_type::TOP_RIGHT_ROUND,
boundary_type::TOP_LEFT => boundary_type::TOP_LEFT_ROUND,
boundary_type::BOTTOM_RIGHT => boundary_type::BOTTOM_RIGHT_ROUND,
boundary_type::BOTTOM_LEFT => boundary_type::BOTTOM_LEFT_ROUND,
_ => corner,
let shape_corner = if self.pane_is_stacked_under {
match style_corner {
Corner::TopRight => Corner::BottomRight,
Corner::TopLeft => Corner::BottomLeft,
other => other,
}
} else {
corner
}
style_corner
};
border_glyphs::corner(
shape_corner,
self.horizontal_style_of_corner(style_corner),
self.vertical_style_of_corner(style_corner),
self.border_style.rounded_corners,
)
}
fn render_title_right_side(
&self,
@@ -310,8 +348,8 @@ impl PaneFrame {
}
}
fn render_my_focus(&self, max_length: usize) -> Option<(Vec<TerminalCharacter>, usize)> {
let mut left_separator = foreground_color(boundary_type::VERTICAL_LEFT, self.color);
let mut right_separator = foreground_color(boundary_type::VERTICAL_RIGHT, self.color);
let mut left_separator = foreground_color(self.title_separator_left(), self.color);
let mut right_separator = foreground_color(self.title_separator_right(), self.color);
let full_indication_text = "MY FOCUS";
let mut full_indication = vec![];
full_indication.append(&mut left_separator);
@@ -340,8 +378,8 @@ impl PaneFrame {
&self,
max_length: usize,
) -> Option<(Vec<TerminalCharacter>, usize)> {
let mut left_separator = foreground_color(boundary_type::VERTICAL_LEFT, self.color);
let mut right_separator = foreground_color(boundary_type::VERTICAL_RIGHT, self.color);
let mut left_separator = foreground_color(self.title_separator_left(), self.color);
let mut right_separator = foreground_color(self.title_separator_right(), self.color);
let full_indication_text = "MY FOCUS AND:";
let short_indication_text = "+";
let mut full_indication = foreground_color(full_indication_text, self.color);
@@ -383,8 +421,8 @@ impl PaneFrame {
&self,
max_length: usize,
) -> Option<(Vec<TerminalCharacter>, usize)> {
let mut left_separator = foreground_color(boundary_type::VERTICAL_LEFT, self.color);
let mut right_separator = foreground_color(boundary_type::VERTICAL_RIGHT, self.color);
let mut left_separator = foreground_color(self.title_separator_left(), self.color);
let mut right_separator = foreground_color(self.title_separator_right(), self.color);
let full_indication_text = if self.other_focused_clients.len() == 1 {
"FOCUSED USER:"
} else {
@@ -563,7 +601,7 @@ impl PaneFrame {
col += right_side_len;
continue;
} else {
title_line.append(&mut foreground_color(boundary_type::HORIZONTAL, self.color));
title_line.append(&mut foreground_color(self.top_horizontal(), self.color));
}
if col == self.geom.x + self.geom.cols - 1 {
break;
@@ -605,7 +643,7 @@ impl PaneFrame {
col += *middle_len;
continue;
} else {
title_line.append(&mut foreground_color(boundary_type::HORIZONTAL, self.color));
title_line.append(&mut foreground_color(self.top_horizontal(), self.color));
}
if col == self.geom.x + self.geom.cols - 1 {
break;
@@ -640,7 +678,7 @@ impl PaneFrame {
col += *middle_len;
continue;
} else {
title_line.append(&mut foreground_color(boundary_type::HORIZONTAL, self.color));
title_line.append(&mut foreground_color(self.top_horizontal(), self.color));
}
if col == self.geom.x + self.geom.cols - 1 {
break;
@@ -663,7 +701,7 @@ impl PaneFrame {
let total_title_length = self.geom.cols.saturating_sub(2); // 2 for the left and right corners
let mut middle = String::new();
for _ in (left_side_len + right_side_len)..total_title_length {
middle.push_str(boundary_type::HORIZONTAL);
middle.push_str(self.top_horizontal());
}
let mut ret = vec![];
ret.append(&mut left_boundary);
@@ -685,7 +723,7 @@ impl PaneFrame {
let total_title_length = self.geom.cols.saturating_sub(2); // 2 for the left and right corners
let mut middle_padding = String::new();
for _ in *left_side_len..total_title_length {
middle_padding.push_str(boundary_type::HORIZONTAL);
middle_padding.push_str(self.top_horizontal());
}
let mut ret = vec![];
ret.append(&mut left_boundary);
@@ -702,7 +740,7 @@ impl PaneFrame {
let total_title_length = self.geom.cols.saturating_sub(2); // 2 for the left and right corners
let mut middle_padding = String::new();
for _ in 0..total_title_length {
middle_padding.push_str(boundary_type::HORIZONTAL);
middle_padding.push_str(self.top_horizontal());
}
let mut ret = vec![];
ret.append(&mut left_boundary);
@@ -812,7 +850,7 @@ impl PaneFrame {
line.push(EMPTY_TERMINAL_CHARACTER);
}
}
line.append(&mut foreground_color(boundary_type::VERTICAL, None));
line.append(&mut foreground_color(self.left_vertical(), None));
for _ in 0..corner_padding {
line.push(EMPTY_TERMINAL_CHARACTER);
}
@@ -824,7 +862,7 @@ impl PaneFrame {
for _ in 0..corner_padding {
line.push(EMPTY_TERMINAL_CHARACTER);
}
line.append(&mut foreground_color(boundary_type::VERTICAL, None));
line.append(&mut foreground_color(self.right_vertical(), None));
let mut occupied_columns = entry_start + full_width_entry_length;
let (mut scroll_part, scroll_length) = self
.bracketed_scroll_indicator(usable_cols.saturating_sub(occupied_columns))
@@ -1045,7 +1083,7 @@ impl PaneFrame {
};
let right_start = width.saturating_sub(right_length).max(middle_end);
let fill_character = if self.pane_is_stacked {
foreground_color(boundary_type::HORIZONTAL, self.color)
foreground_color(self.bottom_horizontal(), self.color)
.into_iter()
.next()
.unwrap_or(EMPTY_TERMINAL_CHARACTER)
@@ -1096,7 +1134,7 @@ impl PaneFrame {
let padding_len = max_undertitle_length.saturating_sub(text_len);
let mut padding = String::new();
for _ in 0..padding_len {
padding.push_str(boundary_type::HORIZONTAL);
padding.push_str(self.bottom_horizontal());
}
let mut ret = vec![];
@@ -1130,7 +1168,7 @@ impl PaneFrame {
let padding_len = max_undertitle_length.saturating_sub(help_text_len);
let mut padding = String::new();
for _ in 0..padding_len {
padding.push_str(boundary_type::HORIZONTAL);
padding.push_str(self.bottom_horizontal());
}
let mut ret = vec![];
@@ -1183,7 +1221,7 @@ impl PaneFrame {
// render exit status and tips
let mut padding = String::new();
for _ in full_text_len..max_undertitle_length {
padding.push_str(boundary_type::HORIZONTAL);
padding.push_str(self.bottom_horizontal());
}
let mut ret = vec![];
ret.append(&mut left_boundary);
@@ -1196,7 +1234,7 @@ impl PaneFrame {
// render only exit status
let mut padding = String::new();
for _ in first_part_len..max_undertitle_length {
padding.push_str(boundary_type::HORIZONTAL);
padding.push_str(self.bottom_horizontal());
}
let mut ret = vec![];
ret.append(&mut left_boundary);
@@ -1213,7 +1251,7 @@ impl PaneFrame {
let full_text_len = first_part_len;
let mut padding = String::new();
for _ in full_text_len..max_undertitle_length {
padding.push_str(boundary_type::HORIZONTAL);
padding.push_str(self.bottom_horizontal());
}
let mut ret = vec![];
ret.append(&mut left_boundary);
@@ -1241,7 +1279,7 @@ impl PaneFrame {
// render exit status and tips
let mut padding = String::new();
for _ in hover_shortcuts_len..max_undertitle_length {
padding.push_str(boundary_type::HORIZONTAL);
padding.push_str(self.bottom_horizontal());
}
let mut ret = vec![];
ret.append(&mut left_boundary);
@@ -1369,7 +1407,7 @@ impl PaneFrame {
// bottom right corner
self.get_corner(boundary_type::BOTTOM_RIGHT)
} else {
boundary_type::HORIZONTAL
self.bottom_horizontal()
};
let mut boundary_character = foreground_color(boundary, self.color);
@@ -1381,9 +1419,9 @@ impl PaneFrame {
}
} else {
let boundary_character_left =
foreground_color(boundary_type::VERTICAL, self.color);
foreground_color(self.left_vertical(), self.color);
let boundary_character_right =
foreground_color(boundary_type::VERTICAL, self.color);
foreground_color(self.right_vertical(), self.color);
let x = self.geom.x;
let y = self.geom.y + row;
@@ -1421,7 +1459,7 @@ impl PaneFrame {
Some(ExitStatus::Exited) => {
self.render_hint_segments(&exit_code_segments(HintExitStatus::Exited))
},
None => (foreground_color(boundary_type::HORIZONTAL, self.color), 1),
None => (foreground_color(self.bottom_horizontal(), self.color), 1),
}
}
fn second_held_title_part_full(&self) -> (Vec<TerminalCharacter>, usize) {
@@ -1438,7 +1476,7 @@ impl PaneFrame {
let mut ret = vec![];
let mut padding = String::new();
for _ in 0..max_undertitle_length {
padding.push_str(boundary_type::HORIZONTAL);
padding.push_str(self.bottom_horizontal());
}
ret.append(&mut left_boundary);
ret.append(&mut foreground_color(&padding, self.color));
@@ -1468,6 +1506,7 @@ mod tests {
is_main_client: true,
other_focused_clients: vec![],
style: Style::default(),
border_style: BorderStyle::default(),
color: None,
other_cursors_exist_in_session: false,
pane_is_stacked_over: false,
@@ -1496,6 +1535,94 @@ mod tests {
chars.iter().map(|c| c.character).collect()
}
fn frame_rows(border_style: BorderStyle) -> Vec<String> {
let mut frame = pane_frame_with(false, false, 10);
frame.border_style = border_style;
frame.geom.rows = 3;
frame.mouse_hover_tips = false;
frame.show_help_text = false;
let (chunks, _) = frame.render().unwrap();
let mut rows: Vec<(usize, usize, String)> = chunks
.iter()
.map(|c| (c.y, c.x, characters_to_string(&c.terminal_characters)))
.collect();
rows.sort();
let mut by_row: Vec<String> = vec![String::new(); 3];
for (y, _x, text) in rows {
by_row[y].push_str(&text);
}
by_row
}
#[test]
fn single_line_frame_with_rounded_corners() {
let rows = frame_rows(BorderStyle {
rounded_corners: true,
..Default::default()
});
assert!(rows[0].starts_with('╭'), "{}", rows[0]);
assert!(rows[0].ends_with('╮'), "{}", rows[0]);
assert_eq!(rows[1], "││");
assert_eq!(rows[2], "╰────────╯");
}
#[test]
fn double_top_border_with_single_sides() {
let rows = frame_rows(BorderStyle {
top: LineStyle::Double,
rounded_corners: true,
..Default::default()
});
assert!(rows[0].starts_with('╒'), "{}", rows[0]);
assert!(rows[0].ends_with('╕'), "{}", rows[0]);
assert_eq!(rows[1], "││");
assert_eq!(rows[2], "╰────────╯");
}
#[test]
fn all_double_border() {
let rows = frame_rows(BorderStyle {
top: LineStyle::Double,
right: LineStyle::Double,
bottom: LineStyle::Double,
left: LineStyle::Double,
rounded_corners: true,
});
assert!(rows[0].starts_with('╔'), "{}", rows[0]);
assert!(rows[0].ends_with('╗'), "{}", rows[0]);
assert_eq!(rows[1], "║║");
assert_eq!(rows[2], "╚════════╝");
}
#[test]
fn heavy_and_double_corner_falls_back_to_the_horizontal_arm() {
let rows = frame_rows(BorderStyle {
top: LineStyle::Double,
right: LineStyle::Heavy,
bottom: LineStyle::Heavy,
left: LineStyle::Heavy,
rounded_corners: false,
});
assert!(rows[0].starts_with('╔'), "{}", rows[0]);
assert!(rows[0].ends_with('╗'), "{}", rows[0]);
assert_eq!(rows[1], "┃┃");
assert_eq!(rows[2], "┗━━━━━━━━┛");
}
#[test]
fn dashed_border_uses_light_corners() {
let rows = frame_rows(BorderStyle {
top: LineStyle::Dashed,
right: LineStyle::Dashed,
bottom: LineStyle::Dashed,
left: LineStyle::Dashed,
rounded_corners: false,
});
assert!(rows[0].starts_with('┌'), "{}", rows[0]);
assert_eq!(rows[1], "┆┆");
assert_eq!(rows[2], "└┄┄┄┄┄┄┄┄┘");
}
#[test]
fn help_text_full_includes_ctrl_scroll_when_enabled_for_tiled_pane() {
let frame = pane_frame_with(true, false, 80);
+14 -1
View File
@@ -6,7 +6,7 @@ use crate::ui::boundaries::Boundaries;
use crate::ui::pane_boundaries_frame::{FrameParams, StackListEntry};
use crate::ClientId;
use std::collections::{HashMap, HashSet};
use zellij_utils::data::{client_id_to_colors, InputMode, PaletteColor, Style};
use zellij_utils::data::{client_id_to_colors, BorderStyle, InputMode, PaletteColor, Style};
use zellij_utils::errors::prelude::*;
use zellij_utils::pane_size::PaneGeom;
@@ -358,12 +358,14 @@ impl<'a> PaneContentsAndUi<'a> {
});
let frame_is_dimmed = self.frame_is_dimmed_for_client(client_id);
let guest_choice_indicator = self.pane.guest_choice_indicator(client_id);
let border_style = self.border_style(pane_is_floating);
let frame_params = if session_is_mirrored {
FrameParams {
focused_client,
is_main_client: pane_focused_for_client_id,
other_focused_clients: vec![],
style: self.style,
border_style,
color: frame_color.map(|c| c.0),
other_cursors_exist_in_session: false,
pane_is_stacked_over: self.pane_is_stacked_over,
@@ -393,6 +395,7 @@ impl<'a> PaneContentsAndUi<'a> {
is_main_client: pane_focused_for_client_id,
other_focused_clients,
style: self.style,
border_style,
color: frame_color.map(|c| c.0),
other_cursors_exist_in_session: self.multiple_users_exist_in_session,
pane_is_stacked_over: self.pane_is_stacked_over,
@@ -437,6 +440,14 @@ impl<'a> PaneContentsAndUi<'a> {
Ok(())
}
pub fn border_style(&self, pane_is_floating: bool) -> BorderStyle {
let base = if pane_is_floating {
self.style.floating_border_style
} else {
self.style.border_style
};
self.pane.border_style_override().apply_to(base)
}
pub fn render_pane_boundaries(
&self,
client_id: ClientId,
@@ -447,9 +458,11 @@ impl<'a> PaneContentsAndUi<'a> {
pane_is_on_bottom_of_stack: bool,
) {
let color = self.frame_color(client_id, client_mode, session_is_mirrored);
let pane_is_floating = false;
boundaries.add_rect(
self.pane.as_ref(),
color,
self.border_style(pane_is_floating),
pane_is_on_top_of_stack,
pane_is_on_bottom_of_stack,
self.pane_is_stacked_under,
+59
View File
@@ -1744,6 +1744,7 @@ fn open_new_floating_pane_with_custom_coordinates() {
height: Some(PercentOrFixed::Fixed(2)),
pinned: None,
borderless: Some(false),
border_style: None,
})),
Some(1),
None,
@@ -1780,6 +1781,7 @@ fn open_new_floating_pane_with_custom_coordinates_exceeding_viewport() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
})),
Some(1),
None,
@@ -1816,6 +1818,7 @@ fn floating_pane_auto_centers_horizontally_with_only_width() {
height: Some(PercentOrFixed::Fixed(10)),
pinned: None,
borderless: Some(false),
border_style: None,
})),
Some(1),
None,
@@ -1852,6 +1855,7 @@ fn floating_pane_auto_centers_vertically_with_only_height() {
height: Some(PercentOrFixed::Fixed(20)),
pinned: None,
borderless: Some(false),
border_style: None,
})),
Some(1),
None,
@@ -1888,6 +1892,7 @@ fn floating_pane_auto_centers_both_axes_with_only_size() {
height: Some(PercentOrFixed::Fixed(30)),
pinned: None,
borderless: Some(false),
border_style: None,
})),
Some(1),
None,
@@ -1924,6 +1929,7 @@ fn floating_pane_respects_explicit_coordinates_with_size() {
height: Some(PercentOrFixed::Fixed(30)),
pinned: None,
borderless: Some(false),
border_style: None,
})),
Some(1),
None,
@@ -1960,6 +1966,7 @@ fn floating_pane_centers_with_percentage_width() {
height: Some(PercentOrFixed::Fixed(20)),
pinned: None,
borderless: Some(false),
border_style: None,
})),
Some(1),
None,
@@ -2001,6 +2008,7 @@ fn floating_pane_centers_large_pane_safely() {
height: Some(PercentOrFixed::Fixed(50)),
pinned: None,
borderless: Some(false),
border_style: None,
})),
Some(1),
None,
@@ -2413,6 +2421,7 @@ fn group_panes_following_focus() {
NewPanePlacement::Tiled {
direction: None,
borderless: None,
border_style: None,
},
Some(client_id),
None,
@@ -2474,6 +2483,7 @@ fn break_group_with_mouse() {
NewPanePlacement::Tiled {
direction: None,
borderless: None,
border_style: None,
},
Some(client_id),
None,
@@ -3572,6 +3582,7 @@ pub fn send_cli_new_pane_action_with_default_parameters() {
no_focus: false,
borderless: Some(false),
tab_id: None,
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -3607,6 +3618,7 @@ pub fn web_new_pane_in_tab_action_targets_requested_tab() {
no_focus: false,
borderless: None,
tab_id: Some(0),
border_style: None,
};
route_arbitrary_action_to_server(&session_metadata, action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
@@ -3682,6 +3694,7 @@ pub fn send_cli_new_pane_action_with_split_direction() {
no_focus: false,
borderless: Some(false),
tab_id: None,
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -3738,6 +3751,7 @@ pub fn send_cli_new_pane_action_with_command_and_cwd() {
no_focus: false,
borderless: Some(false),
tab_id: None,
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -3805,6 +3819,7 @@ pub fn send_cli_new_pane_action_with_floating_pane_and_coordinates() {
no_focus: false,
borderless: Some(false),
tab_id: None,
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -3849,6 +3864,7 @@ pub fn send_cli_edit_action_with_default_parameters() {
near_current_pane: false,
no_focus: false,
tab_id: None,
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_edit_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -3893,6 +3909,7 @@ pub fn send_cli_edit_action_with_line_number() {
near_current_pane: false,
no_focus: false,
tab_id: None,
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_edit_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -3937,6 +3954,7 @@ pub fn send_cli_edit_action_with_split_direction() {
near_current_pane: false,
no_focus: false,
tab_id: None,
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_edit_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100)); // give time for actions to be
@@ -5310,6 +5328,7 @@ pub fn send_cli_change_floating_pane_coordinates_action() {
height: Some("10".to_owned()),
pinned: None,
borderless: Some(false),
border_style: None,
};
send_cli_action_to_server(
&session_metadata,
@@ -5329,6 +5348,39 @@ pub fn send_cli_change_floating_pane_coordinates_action() {
assert_snapshot!(format!("{}", snapshot_count));
}
#[test]
pub fn send_cli_set_pane_border_style_action() {
let size = Size { cols: 80, rows: 10 };
let client_id = 10;
let mut mock_screen = MockScreen::new(size);
let session_metadata = mock_screen.clone_session_metadata();
let screen_thread = mock_screen.run(Some(TiledPaneLayout::default()), vec![]);
let received_server_instructions = Arc::new(Mutex::new(vec![]));
let server_receiver = mock_screen.server_receiver.take().unwrap();
let server_thread = log_actions_in_thread!(
received_server_instructions,
ServerInstruction::KillSession,
server_receiver
);
let set_pane_border_style_action = CliAction::SetPaneBorderStyle {
pane_id: "0".to_owned(),
border_style: Some("double,rounded:false".to_owned()),
};
send_cli_action_to_server(&session_metadata, set_pane_border_style_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
mock_screen.teardown(vec![server_thread, screen_thread]);
let snapshots = take_snapshots_and_cursor_coordinates_from_render_events(
received_server_instructions.lock().unwrap().iter(),
size,
);
let snapshot_count = snapshots.len();
for (_cursor_coordinates, snapshot) in snapshots {
assert_snapshot!(format!("{}", snapshot));
}
assert_snapshot!(format!("{}", snapshot_count));
}
#[test]
pub fn go_to_tab_by_id_verifies_screen_state() {
let size = Size {
@@ -5633,6 +5685,7 @@ pub fn send_cli_new_pane_in_place_with_close_replaced_pane() {
no_focus: false,
borderless: None,
tab_id: None,
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
@@ -5685,6 +5738,7 @@ pub fn send_cli_edit_in_place_with_close_replaced_pane() {
no_focus: false,
borderless: None,
tab_id: None,
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
@@ -8424,6 +8478,7 @@ pub fn send_cli_new_pane_action_with_tab_id() {
no_focus: false,
borderless: Some(false),
tab_id: Some(0),
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
@@ -8487,6 +8542,7 @@ pub fn send_cli_new_floating_pane_action_with_tab_id() {
no_focus: false,
borderless: None,
tab_id: Some(0),
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
@@ -8537,6 +8593,7 @@ pub fn send_cli_edit_action_with_tab_id() {
no_focus: false,
borderless: None,
tab_id: Some(0),
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_edit_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
@@ -8599,6 +8656,7 @@ pub fn send_cli_new_pane_action_with_tab_id_and_direction() {
no_focus: false,
borderless: Some(false),
tab_id: Some(0),
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
@@ -8661,6 +8719,7 @@ pub fn send_cli_new_pane_action_with_tab_id_and_stacked() {
no_focus: false,
borderless: None,
tab_id: Some(0),
border_style: None,
};
send_cli_action_to_server(&session_metadata, cli_new_pane_action, client_id);
std::thread::sleep(std::time::Duration::from_millis(100));
@@ -2,4 +2,4 @@
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())"
---
[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: None, cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), Tiled { direction: None, borderless: None }, false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false), Exit]
[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: None, cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), Tiled { direction: None, borderless: Some(false), border_style: None }, false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false), Exit]
@@ -2,4 +2,4 @@
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())"
---
[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: Some(100), cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), Tiled { direction: None, borderless: None }, false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false), Exit]
[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: Some(100), cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), Tiled { direction: None, borderless: Some(false), border_style: None }, false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false), Exit]
@@ -2,4 +2,4 @@
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())"
---
[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: None, cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), Tiled { direction: Some(Down), borderless: None }, false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false), Exit]
[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(OpenFile(OpenFilePayload { path: "/file/to/edit", line_number: None, cwd: Some("."), originating_plugin: None })), Some("Editing: /file/to/edit"), Tiled { direction: Some(Down), borderless: Some(false), border_style: None }, false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false), Exit]
@@ -2,4 +2,4 @@
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{:?}\", new_pane_instruction)"
---
Some(SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None, use_terminal_title: false })), None, Tiled { direction: Some(Right), borderless: Some(false) }, false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false))
Some(SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None, use_terminal_title: false })), None, Tiled { direction: Some(Right), borderless: Some(false), border_style: None }, false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false))
@@ -2,4 +2,4 @@
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())"
---
[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(None, None, Tiled { direction: None, borderless: Some(false) }, false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false), Exit]
[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(None, None, Tiled { direction: None, borderless: Some(false), border_style: None }, false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false), Exit]
@@ -2,4 +2,4 @@
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())"
---
[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None, use_terminal_title: false })), None, Floating(Some(FloatingPaneCoordinates { x: Some(Fixed(10)), y: None, width: Some(Percent(20)), height: None, pinned: None, borderless: Some(false) })), false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false), Exit]
[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(Some(RunCommand(RunCommand { command: "htop", args: [], cwd: Some("/some/folder"), hold_on_close: true, hold_on_start: false, originating_plugin: None, use_terminal_title: false })), None, Floating(Some(FloatingPaneCoordinates { x: Some(Fixed(10)), y: None, width: Some(Percent(20)), height: None, pinned: None, borderless: Some(false), border_style: None })), false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false), Exit]
@@ -2,4 +2,4 @@
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{:?}\", *received_pty_instructions.lock().unwrap())"
---
[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(None, None, Tiled { direction: Some(Right), borderless: Some(false) }, false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false), Exit]
[UpdateActivePane(Some(Terminal(0)), 1), UpdateActivePane(Some(Terminal(0)), 1), SpawnTerminal(None, None, Tiled { direction: Some(Right), borderless: Some(false), border_style: None }, false, ClientId(10), Some(NotificationEnd { channel: None, exit_status: None, unblock_condition: None, affected_pane_id: None, affected_tab_id: None, error_message: None, stdout_message: None }), false), Exit]
@@ -1,6 +1,5 @@
---
source: zellij-server/src/./unit/screen_tests.rs
assertion_line: 3515
expression: "format!(\"{:#?}\", new_tab_action)"
---
Some(
@@ -19,6 +18,7 @@ Some(
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -37,6 +37,7 @@ Some(
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -52,6 +53,7 @@ Some(
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,6 +1,6 @@
---
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{:#?}\", new_tab_instruction)"
expression: output
---
NewTab(
None,
@@ -21,6 +21,7 @@ NewTab(
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -43,6 +44,7 @@ NewTab(
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -65,6 +67,7 @@ NewTab(
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -84,6 +87,7 @@ NewTab(
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,6 +1,6 @@
---
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{:#?}\", new_tab_instruction)"
expression: output
---
NewTab(
None,
@@ -21,6 +21,7 @@ NewTab(
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -43,6 +44,7 @@ NewTab(
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -65,6 +67,7 @@ NewTab(
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -84,6 +87,7 @@ NewTab(
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -21,6 +21,7 @@ NewTab(
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -43,6 +44,7 @@ NewTab(
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -65,6 +67,7 @@ NewTab(
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -84,6 +87,7 @@ NewTab(
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -0,0 +1,14 @@
---
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{}\", snapshot)"
---
00 (C): ╔ Pane #1 ═════════════════════════════════════════════════════════════════════╗
01 (C): ║ ║
02 (C): ║ ║
03 (C): ║ ║
04 (C): ║ ║
05 (C): ║ ║
06 (C): ║ ║
07 (C): ║ ║
08 (C): ║ ║
09 (C): ╚══════════════════════════════════════════════════════════════════════════════╝
@@ -0,0 +1,5 @@
---
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{}\", snapshot_count)"
---
2
@@ -0,0 +1,14 @@
---
source: zellij-server/src/./unit/screen_tests.rs
expression: "format!(\"{}\", snapshot)"
---
00 (C): ┌ Pane #1 ─────────────────────────────────────────────────────────────────────┐
01 (C): │ │
02 (C): │ │
03 (C): │ │
04 (C): │ │
05 (C): │ │
06 (C): │ │
07 (C): │ │
08 (C): │ │
09 (C): └──────────────────────────────────────────────────────────────────────────────┘
+7
View File
@@ -2603,6 +2603,13 @@ pub fn set_pane_borderless(pane_id: PaneId, borderless: bool) {
unsafe { host_run_plugin_command() };
}
pub fn set_pane_border_style(pane_id: PaneId, border_style: BorderStyleOverride) {
let plugin_command = PluginCommand::SetPaneBorderStyle(pane_id, border_style);
let protobuf_plugin_command: ProtobufPluginCommand = plugin_command.try_into().unwrap();
object_to_stdout(&protobuf_plugin_command.encode_to_vec());
unsafe { host_run_plugin_command() };
}
/// Set the default foreground and/or background color of a pane
///
/// # Arguments
+27
View File
@@ -312,6 +312,33 @@ load_plugins {
//
// pane_frame_style "titles"
// Configure the look of the pane frame borders
//
// ui {
// pane_frames {
// // round the corners of single-line borders
// rounded_corners true
// // line style for all four sides of tiled pane frames
// // one of: single, double, heavy, dashed, heavy_dashed
// border_style "single"
// // per-side overrides, eg. a double top border with single sides
// border_top "double"
// border_right "single"
// border_bottom "single"
// border_left "single"
// // when two neighbouring panes disagree about a shared grid line
// // (pane frames off), that line falls back to border_style above
// // the same keys prefixed with "floating_" apply to floating panes,
// // they default to the values above
// floating_border_style "double"
// floating_border_top "double"
// floating_border_right "double"
// floating_border_bottom "double"
// floating_border_left "double"
// floating_border_rounded_corners false
// }
// }
// Toggle between having Zellij lay out panes according to a predefined set of layouts whenever possible
// Options:
// - true (default)
+30 -1
View File
@@ -158,6 +158,8 @@ pub struct TiledPaneLayout {
pub hide_floating_panes: bool,
#[prost(string, optional, tag="13")]
pub pane_initial_contents: ::core::option::Option<::prost::alloc::string::String>,
#[prost(message, optional, tag="14")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -186,6 +188,8 @@ pub struct FloatingPaneLayout {
pub logical_position: ::core::option::Option<u32>,
#[prost(bool, optional, tag="12")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="13")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -303,7 +307,7 @@ pub struct OverrideLayoutPayload {
pub struct Action {
#[prost(enumeration="ActionName", tag="1")]
pub name: i32,
#[prost(oneof="action::OptionalPayload", 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63")]
#[prost(oneof="action::OptionalPayload", 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, 32, 33, 34, 35, 36, 37, 38, 39, 40, 41, 42, 43, 44, 45, 46, 47, 48, 49, 50, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64")]
pub optional_payload: ::core::option::Option<action::OptionalPayload>,
}
/// Nested message and enum types in `Action`.
@@ -429,10 +433,20 @@ pub mod action {
ApplyTiledSwapLayoutPayload(::prost::alloc::string::String),
#[prost(string, tag="63")]
ApplyFloatingSwapLayoutPayload(::prost::alloc::string::String),
#[prost(message, tag="64")]
SetPaneBorderStylePayload(super::SetPaneBorderStylePayload),
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SetPaneBorderStylePayload {
#[prost(message, optional, tag="1")]
pub pane_id: ::core::option::Option<PaneId>,
#[prost(message, optional, tag="2")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SetPaneFrameStylePayload {
#[prost(enumeration="super::pane_frame_style::PaneFrameStyle", tag="1")]
pub pane_frame_style: i32,
@@ -546,6 +560,8 @@ pub struct NewTiledPanePayload {
pub near_current_pane: bool,
#[prost(bool, optional, tag="4")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="5")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -709,6 +725,8 @@ pub struct FloatingPaneCoordinates {
pub pinned: ::core::option::Option<bool>,
#[prost(bool, optional, tag="6")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="7")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
/// SetPaneBorderlessPayload specifies the pane and borderless state
#[allow(clippy::derive_partial_eq_without_eq)]
@@ -748,6 +766,8 @@ pub mod new_pane_placement {
pub struct NoPreferenceOptions {
#[prost(bool, optional, tag="1")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="2")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -756,6 +776,8 @@ pub struct TiledPlacement {
pub direction: ::core::option::Option<i32>,
#[prost(bool, optional, tag="2")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="3")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -772,6 +794,8 @@ pub struct InPlaceConfig {
pub close_replaced_pane: bool,
#[prost(bool, optional, tag="3")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="4")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -780,6 +804,8 @@ pub struct StackedPlacement {
pub pane_id: ::core::option::Option<PaneId>,
#[prost(bool, optional, tag="2")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="3")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -1149,6 +1175,7 @@ pub enum ActionName {
CopyLastCommandOutput = 113,
ApplyTiledSwapLayout = 114,
ApplyFloatingSwapLayout = 115,
SetPaneBorderStyle = 116,
}
impl ActionName {
/// String value of the enum field names used in the ProtoBuf definition.
@@ -1270,6 +1297,7 @@ impl ActionName {
ActionName::CopyLastCommandOutput => "CopyLastCommandOutput",
ActionName::ApplyTiledSwapLayout => "ApplyTiledSwapLayout",
ActionName::ApplyFloatingSwapLayout => "ApplyFloatingSwapLayout",
ActionName::SetPaneBorderStyle => "SetPaneBorderStyle",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
@@ -1388,6 +1416,7 @@ impl ActionName {
"CopyLastCommandOutput" => Some(Self::CopyLastCommandOutput),
"ApplyTiledSwapLayout" => Some(Self::ApplyTiledSwapLayout),
"ApplyFloatingSwapLayout" => Some(Self::ApplyFloatingSwapLayout),
"SetPaneBorderStyle" => Some(Self::SetPaneBorderStyle),
_ => None,
}
}
+2
View File
@@ -8,4 +8,6 @@ pub struct Command {
pub args: ::prost::alloc::vec::Vec<::prost::alloc::string::String>,
#[prost(string, optional, tag="3")]
pub cwd: ::core::option::Option<::prost::alloc::string::String>,
#[prost(message, optional, tag="4")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
+2
View File
@@ -8,4 +8,6 @@ pub struct File {
pub line_number: ::core::option::Option<i32>,
#[prost(string, optional, tag="3")]
pub cwd: ::core::option::Option<::prost::alloc::string::String>,
#[prost(message, optional, tag="4")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
@@ -4,7 +4,7 @@
pub struct PluginCommand {
#[prost(enumeration="CommandName", tag="1")]
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, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 168, 169, 170, 171, 172, 173")]
#[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, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 140, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155, 156, 157, 158, 159, 160, 161, 162, 163, 164, 168, 169, 170, 171, 172, 173, 174")]
pub payload: ::core::option::Option<plugin_command::Payload>,
}
/// Nested message and enum types in `PluginCommand`.
@@ -324,6 +324,8 @@ pub mod plugin_command {
ApplyTiledSwapLayoutPayload(::prost::alloc::string::String),
#[prost(string, tag="173")]
ApplyFloatingSwapLayoutPayload(::prost::alloc::string::String),
#[prost(message, tag="174")]
SetPaneBorderStylePayload(super::SetPaneBorderStylePayload),
}
}
#[allow(clippy::derive_partial_eq_without_eq)]
@@ -574,6 +576,14 @@ pub struct SetPaneBorderlessPayload {
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SetPaneBorderStylePayload {
#[prost(message, optional, tag="1")]
pub pane_id: ::core::option::Option<PaneId>,
#[prost(message, optional, tag="2")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct ChangeHostFolderPayload {
#[prost(string, tag="1")]
pub new_host_folder: ::prost::alloc::string::String,
@@ -1006,6 +1016,8 @@ pub struct FloatingPaneCoordinates {
pub pinned: ::core::option::Option<bool>,
#[prost(bool, optional, tag="6")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="7")]
pub border_style: ::core::option::Option<super::style::BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -2233,6 +2245,7 @@ pub enum CommandName {
FocusHostSession = 228,
ApplyTiledSwapLayout = 229,
ApplyFloatingSwapLayout = 230,
SetPaneBorderStyle = 231,
}
impl CommandName {
/// String value of the enum field names used in the ProtoBuf definition.
@@ -2446,6 +2459,7 @@ impl CommandName {
CommandName::FocusHostSession => "FocusHostSession",
CommandName::ApplyTiledSwapLayout => "ApplyTiledSwapLayout",
CommandName::ApplyFloatingSwapLayout => "ApplyFloatingSwapLayout",
CommandName::SetPaneBorderStyle => "SetPaneBorderStyle",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
@@ -2656,6 +2670,7 @@ impl CommandName {
"FocusHostSession" => Some(Self::FocusHostSession),
"ApplyTiledSwapLayout" => Some(Self::ApplyTiledSwapLayout),
"ApplyFloatingSwapLayout" => Some(Self::ApplyFloatingSwapLayout),
"SetPaneBorderStyle" => Some(Self::SetPaneBorderStyle),
_ => None,
}
}
+69
View File
@@ -11,6 +11,40 @@ pub struct Style {
pub hide_session_name: bool,
#[prost(message, optional, tag="4")]
pub styling: ::core::option::Option<Styling>,
#[prost(message, optional, tag="5")]
pub border_style: ::core::option::Option<BorderStyle>,
#[prost(message, optional, tag="6")]
pub floating_border_style: ::core::option::Option<BorderStyle>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BorderStyle {
#[prost(enumeration="LineStyle", tag="1")]
pub top: i32,
#[prost(enumeration="LineStyle", tag="2")]
pub right: i32,
#[prost(enumeration="LineStyle", tag="3")]
pub bottom: i32,
#[prost(enumeration="LineStyle", tag="4")]
pub left: i32,
#[prost(bool, tag="5")]
pub rounded_corners: bool,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BorderStyleOverride {
#[prost(enumeration="LineStyle", optional, tag="1")]
pub all: ::core::option::Option<i32>,
#[prost(enumeration="LineStyle", optional, tag="2")]
pub top: ::core::option::Option<i32>,
#[prost(enumeration="LineStyle", optional, tag="3")]
pub right: ::core::option::Option<i32>,
#[prost(enumeration="LineStyle", optional, tag="4")]
pub bottom: ::core::option::Option<i32>,
#[prost(enumeration="LineStyle", optional, tag="5")]
pub left: ::core::option::Option<i32>,
#[prost(bool, optional, tag="6")]
pub rounded_corners: ::core::option::Option<bool>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -117,6 +151,41 @@ pub struct Styling {
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum LineStyle {
Single = 0,
Double = 1,
Heavy = 2,
Dashed = 3,
HeavyDashed = 4,
}
impl LineStyle {
/// String value of the enum field names used in the ProtoBuf definition.
///
/// The values are not transformed in any way and thus are considered stable
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
pub fn as_str_name(&self) -> &'static str {
match self {
LineStyle::Single => "Single",
LineStyle::Double => "Double",
LineStyle::Heavy => "Heavy",
LineStyle::Dashed => "Dashed",
LineStyle::HeavyDashed => "HeavyDashed",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
match value {
"Single" => Some(Self::Single),
"Double" => Some(Self::Double),
"Heavy" => Some(Self::Heavy),
"Dashed" => Some(Self::Dashed),
"HeavyDashed" => Some(Self::HeavyDashed),
_ => None,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum ColorType {
Rgb = 0,
EightBit = 1,
@@ -71,6 +71,40 @@ pub struct Style {
pub rounded_corners: bool,
#[prost(bool, tag="3")]
pub hide_session_name: bool,
#[prost(message, optional, tag="4")]
pub border_style: ::core::option::Option<BorderStyle>,
#[prost(message, optional, tag="5")]
pub floating_border_style: ::core::option::Option<BorderStyle>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BorderStyle {
#[prost(enumeration="LineStyle", tag="1")]
pub top: i32,
#[prost(enumeration="LineStyle", tag="2")]
pub right: i32,
#[prost(enumeration="LineStyle", tag="3")]
pub bottom: i32,
#[prost(enumeration="LineStyle", tag="4")]
pub left: i32,
#[prost(bool, tag="5")]
pub rounded_corners: bool,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct BorderStyleOverride {
#[prost(enumeration="LineStyle", optional, tag="1")]
pub all: ::core::option::Option<i32>,
#[prost(enumeration="LineStyle", optional, tag="2")]
pub top: ::core::option::Option<i32>,
#[prost(enumeration="LineStyle", optional, tag="3")]
pub right: ::core::option::Option<i32>,
#[prost(enumeration="LineStyle", optional, tag="4")]
pub bottom: ::core::option::Option<i32>,
#[prost(enumeration="LineStyle", optional, tag="5")]
pub left: ::core::option::Option<i32>,
#[prost(bool, optional, tag="6")]
pub rounded_corners: ::core::option::Option<bool>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -120,7 +154,7 @@ pub struct RgbColor {
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Action {
#[prost(oneof="action::ActionType", tags="1, 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, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155")]
#[prost(oneof="action::ActionType", tags="1, 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, 51, 52, 53, 54, 55, 56, 57, 58, 59, 60, 61, 62, 63, 64, 65, 66, 67, 68, 69, 70, 71, 72, 73, 74, 75, 76, 77, 78, 79, 80, 81, 82, 83, 84, 85, 86, 87, 88, 89, 90, 91, 92, 93, 94, 95, 96, 156, 97, 98, 99, 100, 101, 102, 103, 104, 105, 106, 107, 108, 109, 110, 111, 112, 113, 114, 115, 116, 117, 118, 119, 120, 121, 122, 123, 124, 125, 126, 127, 128, 129, 130, 131, 132, 133, 134, 135, 136, 137, 138, 139, 141, 142, 143, 144, 145, 146, 147, 148, 149, 150, 151, 152, 153, 154, 155")]
pub action_type: ::core::option::Option<action::ActionType>,
}
/// Nested message and enum types in `Action`.
@@ -320,6 +354,8 @@ pub mod action {
TogglePaneBorderless(super::TogglePaneBorderlessAction),
#[prost(message, tag="96")]
SetPaneBorderless(super::SetPaneBorderlessAction),
#[prost(message, tag="156")]
SetPaneBorderStyle(super::SetPaneBorderStyleAction),
#[prost(message, tag="97")]
SaveSession(super::SaveSessionAction),
#[prost(message, tag="98")]
@@ -949,6 +985,8 @@ pub struct NewTiledPaneAction {
pub tab_id: ::core::option::Option<u32>,
#[prost(bool, tag="10")]
pub no_focus: bool,
#[prost(message, optional, tag="11")]
pub border_style: ::core::option::Option<BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -1366,6 +1404,14 @@ pub struct SetPaneColorAction {
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct SetPaneBorderStyleAction {
#[prost(message, optional, tag="1")]
pub pane_id: ::core::option::Option<PaneId>,
#[prost(message, optional, tag="2")]
pub border_style: ::core::option::Option<BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
pub struct Position {
/// Changed from uint32 to int32 to support negative line numbers
#[prost(int32, tag="1")]
@@ -1518,6 +1564,8 @@ pub mod new_pane_placement {
pub struct NoPreferencePlacement {
#[prost(bool, optional, tag="1")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="2")]
pub border_style: ::core::option::Option<BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -1526,6 +1574,8 @@ pub struct TiledPlacement {
pub direction: ::core::option::Option<i32>,
#[prost(bool, optional, tag="2")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="3")]
pub border_style: ::core::option::Option<BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -1534,6 +1584,8 @@ pub struct StackedPlacement {
pub pane_id_to_stack_under: ::core::option::Option<PaneId>,
#[prost(bool, optional, tag="2")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="3")]
pub border_style: ::core::option::Option<BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -1544,6 +1596,8 @@ pub struct NewPanePlacementInPlace {
pub close_replaced_pane: bool,
#[prost(bool, optional, tag="3")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="4")]
pub border_style: ::core::option::Option<BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -1582,6 +1636,8 @@ pub struct FloatingPaneCoordinates {
pub pinned: ::core::option::Option<bool>,
#[prost(bool, optional, tag="6")]
pub borderless: ::core::option::Option<bool>,
#[prost(message, optional, tag="7")]
pub border_style: ::core::option::Option<BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -1656,9 +1712,11 @@ pub struct TiledPaneLayout {
pub pane_initial_contents: ::core::option::Option<::prost::alloc::string::String>,
#[prost(string, optional, tag="14")]
pub default_fg: ::core::option::Option<::prost::alloc::string::String>,
/// NOTE: run_instructions_to_ignore is not represented here because it's a field used only inside the server itself and not part of the server/client contract
#[prost(string, optional, tag="15")]
pub default_bg: ::core::option::Option<::prost::alloc::string::String>,
/// NOTE: run_instructions_to_ignore is not represented here because it's a field used only inside the server itself and not part of the server/client contract
#[prost(message, optional, tag="16")]
pub border_style: ::core::option::Option<BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -1691,6 +1749,8 @@ pub struct FloatingPaneLayout {
pub default_fg: ::core::option::Option<::prost::alloc::string::String>,
#[prost(string, optional, tag="14")]
pub default_bg: ::core::option::Option<::prost::alloc::string::String>,
#[prost(message, optional, tag="15")]
pub border_style: ::core::option::Option<BorderStyleOverride>,
}
#[allow(clippy::derive_partial_eq_without_eq)]
#[derive(Clone, PartialEq, ::prost::Message)]
@@ -2438,6 +2498,41 @@ impl KeyModifier {
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum LineStyle {
Single = 0,
Double = 1,
Heavy = 2,
Dashed = 3,
HeavyDashed = 4,
}
impl LineStyle {
/// String value of the enum field names used in the ProtoBuf definition.
///
/// The values are not transformed in any way and thus are considered stable
/// (if the ProtoBuf definition does not change) and safe for programmatic use.
pub fn as_str_name(&self) -> &'static str {
match self {
LineStyle::Single => "LINE_STYLE_SINGLE",
LineStyle::Double => "LINE_STYLE_DOUBLE",
LineStyle::Heavy => "LINE_STYLE_HEAVY",
LineStyle::Dashed => "LINE_STYLE_DASHED",
LineStyle::HeavyDashed => "LINE_STYLE_HEAVY_DASHED",
}
}
/// Creates an enum from field names used in the ProtoBuf definition.
pub fn from_str_name(value: &str) -> ::core::option::Option<Self> {
match value {
"LINE_STYLE_SINGLE" => Some(Self::Single),
"LINE_STYLE_DOUBLE" => Some(Self::Double),
"LINE_STYLE_HEAVY" => Some(Self::Heavy),
"LINE_STYLE_DASHED" => Some(Self::Dashed),
"LINE_STYLE_HEAVY_DASHED" => Some(Self::HeavyDashed),
_ => None,
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, PartialOrd, Ord, ::prost::Enumeration)]
#[repr(i32)]
pub enum AnsiCode {
Unspecified = 0,
Black = 1,
+27
View File
@@ -537,6 +537,9 @@ pub enum Sessions {
conflicts_with("in_place")
)]
tab_id: Option<usize>,
/// Border line style, eg. "double" or "top:double,left:single,rounded"
#[clap(long, value_parser)]
border_style: Option<String>,
},
/// Load a plugin
/// Returns: Created pane ID (format: plugin_<id>)
@@ -592,6 +595,9 @@ pub enum Sessions {
/// Target a specific tab by ID
#[clap(long, value_parser, conflicts_with("in_place"))]
tab_id: Option<usize>,
/// Border line style, eg. "double" or "top:double,left:single,rounded"
#[clap(long, value_parser)]
border_style: Option<String>,
},
/// Edit file with default $EDITOR / $VISUAL
/// Returns: Created pane ID (format: terminal_<id>)
@@ -657,6 +663,9 @@ pub enum Sessions {
conflicts_with("in_place")
)]
tab_id: Option<usize>,
/// Border line style, eg. "double" or "top:double,left:single,rounded"
#[clap(long, value_parser)]
border_style: Option<String>,
},
/// Send data to one or more plugins, launch them if they are not running.
#[clap(override_usage(
@@ -1014,6 +1023,9 @@ pub enum CliAction {
conflicts_with("in_place")
)]
tab_id: Option<usize>,
/// Border line style, eg. "double" or "top:double,left:single,rounded"
#[clap(long, value_parser)]
border_style: Option<String>,
},
/// Open the specified file in a new zellij pane with your default EDITOR
/// Returns: Created pane ID (format: terminal_<id>)
@@ -1078,6 +1090,9 @@ pub enum CliAction {
conflicts_with("in_place")
)]
tab_id: Option<usize>,
/// Border line style, eg. "double" or "top:double,left:single,rounded"
#[clap(long, value_parser)]
border_style: Option<String>,
},
/// Switch input mode of all connected clients [locked|pane|tab|resize|move|search|session]
SwitchMode {
@@ -1549,6 +1564,9 @@ tail -f /tmp/my-live-logfile | zellij action pipe --name logs --plugin https://e
/// mouse if without a border)
#[clap(short, long, value_parser)]
borderless: Option<bool>,
/// Border line style, eg. "double" or "top:double,left:single,rounded"
#[clap(long, value_parser)]
border_style: Option<String>,
},
TogglePaneBorderless {
/// The pane_id of the pane, eg. terminal_1, plugin_2 or 3 (equivalent to terminal_3)
@@ -1563,6 +1581,15 @@ tail -f /tmp/my-live-logfile | zellij action pipe --name logs --plugin https://e
#[clap(short, long, value_parser)]
borderless: bool,
},
/// Change the border line style of an existing pane
SetPaneBorderStyle {
/// The pane_id of the pane, eg. terminal_1, plugin_2 or 3 (equivalent to terminal_3)
#[clap(short, long, value_parser)]
pane_id: String,
/// Border line style, eg. "double" or "top:double,left:single,rounded"
#[clap(long, value_parser)]
border_style: Option<String>,
},
/// Detach from the current session
Detach,
/// Switch the theme to dark (uses configured `theme_dark`).
@@ -89,6 +89,33 @@ message Style {
Styling colors = 1;
bool rounded_corners = 2;
bool hide_session_name = 3;
BorderStyle border_style = 4;
BorderStyle floating_border_style = 5;
}
enum LineStyle {
LINE_STYLE_SINGLE = 0;
LINE_STYLE_DOUBLE = 1;
LINE_STYLE_HEAVY = 2;
LINE_STYLE_DASHED = 3;
LINE_STYLE_HEAVY_DASHED = 4;
}
message BorderStyle {
LineStyle top = 1;
LineStyle right = 2;
LineStyle bottom = 3;
LineStyle left = 4;
bool rounded_corners = 5;
}
message BorderStyleOverride {
optional LineStyle all = 1;
optional LineStyle top = 2;
optional LineStyle right = 3;
optional LineStyle bottom = 4;
optional LineStyle left = 5;
optional bool rounded_corners = 6;
}
message Styling {
@@ -233,6 +260,7 @@ message Action {
OverrideLayoutAction override_layout = 94;
TogglePaneBorderlessAction toggle_pane_borderless = 95;
SetPaneBorderlessAction set_pane_borderless = 96;
SetPaneBorderStyleAction set_pane_border_style = 156;
SaveSessionAction save_session = 97;
ListPanesAction list_panes = 98;
WriteCharsToPaneIdAction write_chars_to_pane_id = 99;
@@ -511,6 +539,7 @@ message NewTiledPaneAction {
optional bool borderless = 8;
optional uint32 tab_id = 9;
bool no_focus = 10;
optional BorderStyleOverride border_style = 11;
}
message NewInPlacePaneAction {
@@ -759,6 +788,11 @@ message SetPaneColorAction {
optional string bg = 3;
}
message SetPaneBorderStyleAction {
PaneId pane_id = 1;
BorderStyleOverride border_style = 2;
}
// Supporting enums and messages
enum InputMode {
INPUT_MODE_UNSPECIFIED = 0;
@@ -880,22 +914,26 @@ message NewPanePlacement {
message NoPreferencePlacement {
optional bool borderless = 1;
optional BorderStyleOverride border_style = 2;
}
message TiledPlacement {
optional Direction direction = 1;
optional bool borderless = 2;
optional BorderStyleOverride border_style = 3;
}
message StackedPlacement {
optional PaneId pane_id_to_stack_under = 1;
optional bool borderless = 2;
optional BorderStyleOverride border_style = 3;
}
message NewPanePlacementInPlace {
optional PaneId pane_id_to_replace = 1;
bool close_replaced_pane = 2;
optional bool borderless = 3;
optional BorderStyleOverride border_style = 4;
}
message PaneIdWithPlugin {
@@ -932,6 +970,7 @@ message FloatingPaneCoordinates {
optional FloatingCoordinate height = 4;
optional bool pinned = 5;
optional bool borderless = 6;
optional BorderStyleOverride border_style = 7;
}
message FloatingCoordinate {
@@ -968,6 +1007,7 @@ message TiledPaneLayout {
optional string pane_initial_contents = 13;
optional string default_fg = 14;
optional string default_bg = 15;
optional BorderStyleOverride border_style = 16;
// NOTE: run_instructions_to_ignore is not represented here because it's a field used only inside the server itself and not part of the server/client contract
}
@@ -986,6 +1026,7 @@ message FloatingPaneLayout {
optional bool borderless = 12;
optional string default_fg = 13;
optional string default_bg = 14;
optional BorderStyleOverride border_style = 15;
}
message SwapTiledLayout {
+487 -2
View File
@@ -1426,11 +1426,210 @@ pub struct Palette {
pub brown: PaletteColor,
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
pub enum LineStyle {
#[default]
Single,
Double,
Heavy,
Dashed,
HeavyDashed,
}
impl LineStyle {
pub fn is_heavy(&self) -> bool {
matches!(self, LineStyle::Heavy | LineStyle::HeavyDashed)
}
pub fn is_double(&self) -> bool {
matches!(self, LineStyle::Double)
}
pub fn is_single(&self) -> bool {
matches!(self, LineStyle::Single | LineStyle::Dashed)
}
}
impl FromStr for LineStyle {
type Err = String;
fn from_str(s: &str) -> Result<Self, Self::Err> {
match s.trim().to_lowercase().as_str() {
"single" | "light" | "normal" => Ok(LineStyle::Single),
"double" => Ok(LineStyle::Double),
"heavy" | "bold" | "thick" => Ok(LineStyle::Heavy),
"dashed" => Ok(LineStyle::Dashed),
"heavy_dashed" | "heavy-dashed" | "heavydashed" => Ok(LineStyle::HeavyDashed),
_ => Err(format!(
"Unknown line style: '{}', expected one of: single, double, heavy, dashed, heavy_dashed",
s
)),
}
}
}
impl fmt::Display for LineStyle {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> fmt::Result {
let name = match self {
LineStyle::Single => "single",
LineStyle::Double => "double",
LineStyle::Heavy => "heavy",
LineStyle::Dashed => "dashed",
LineStyle::HeavyDashed => "heavy_dashed",
};
write!(f, "{}", name)
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
pub struct BorderStyle {
pub top: LineStyle,
pub right: LineStyle,
pub bottom: LineStyle,
pub left: LineStyle,
pub rounded_corners: bool,
}
impl BorderStyle {
pub fn with_rounded_corners(rounded_corners: bool) -> Self {
BorderStyle {
rounded_corners,
..Default::default()
}
}
pub fn uniform_style(&self) -> Option<LineStyle> {
if self.top == self.right && self.right == self.bottom && self.bottom == self.left {
Some(self.top)
} else {
None
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
pub struct BorderStyleOverride {
pub all: Option<LineStyle>,
pub top: Option<LineStyle>,
pub right: Option<LineStyle>,
pub bottom: Option<LineStyle>,
pub left: Option<LineStyle>,
pub rounded_corners: Option<bool>,
}
impl BorderStyleOverride {
pub fn is_empty(&self) -> bool {
self.all.is_none()
&& self.top.is_none()
&& self.right.is_none()
&& self.bottom.is_none()
&& self.left.is_none()
&& self.rounded_corners.is_none()
}
pub fn none_if_empty(self) -> Option<Self> {
if self.is_empty() {
None
} else {
Some(self)
}
}
pub fn from_cli_string(value: &str) -> Result<Self, String> {
let mut border_style_override = BorderStyleOverride::default();
for token in value.split(',') {
let token = token.trim();
if token.is_empty() {
continue;
}
let (key, value) = match token.split_once(|c| c == ':' || c == '=') {
Some((key, value)) => (key.trim().to_lowercase(), Some(value.trim())),
None => (token.to_lowercase(), None),
};
match (key.as_str(), value) {
("rounded" | "rounded_corners" | "rounded-corners", value) => {
let rounded = match value {
None => true,
Some(value) => value.parse::<bool>().map_err(|_| {
format!("Expected true or false for rounded corners, got '{}'", value)
})?,
};
border_style_override.rounded_corners = Some(rounded);
},
("all", Some(value)) => border_style_override.all = Some(LineStyle::from_str(value)?),
("top", Some(value)) => border_style_override.top = Some(LineStyle::from_str(value)?),
("right", Some(value)) => {
border_style_override.right = Some(LineStyle::from_str(value)?)
},
("bottom", Some(value)) => {
border_style_override.bottom = Some(LineStyle::from_str(value)?)
},
("left", Some(value)) => {
border_style_override.left = Some(LineStyle::from_str(value)?)
},
(_, Some(_)) => {
return Err(format!(
"Unknown border side: '{}', expected one of: all, top, right, bottom, left, rounded",
key
))
},
(line_style, None) => border_style_override.all = Some(LineStyle::from_str(line_style)?),
}
}
Ok(border_style_override)
}
pub fn from_optional_cli_string(value: Option<&str>) -> Result<Option<Self>, String> {
match value {
Some(value) => Self::from_cli_string(value).map(|b| b.none_if_empty()),
None => Ok(None),
}
}
pub fn from_strings(
all: Option<String>,
top: Option<String>,
right: Option<String>,
bottom: Option<String>,
left: Option<String>,
rounded_corners: Option<bool>,
) -> Result<Self, String> {
let parse = |value: Option<String>| -> Result<Option<LineStyle>, String> {
match value {
Some(value) => LineStyle::from_str(&value).map(Some),
None => Ok(None),
}
};
Ok(BorderStyleOverride {
all: parse(all)?,
top: parse(top)?,
right: parse(right)?,
bottom: parse(bottom)?,
left: parse(left)?,
rounded_corners,
})
}
pub fn apply_to(&self, base: BorderStyle) -> BorderStyle {
let all = self.all;
BorderStyle {
top: self.top.or(all).unwrap_or(base.top),
right: self.right.or(all).unwrap_or(base.right),
bottom: self.bottom.or(all).unwrap_or(base.bottom),
left: self.left.or(all).unwrap_or(base.left),
rounded_corners: self.rounded_corners.unwrap_or(base.rounded_corners),
}
}
pub fn merge(&self, other: &BorderStyleOverride) -> BorderStyleOverride {
BorderStyleOverride {
all: other.all.or(self.all),
top: other.top.or(self.top),
right: other.right.or(self.right),
bottom: other.bottom.or(self.bottom),
left: other.left.or(self.left),
rounded_corners: other.rounded_corners.or(self.rounded_corners),
}
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq, Hash, Default, Serialize, Deserialize)]
pub struct Style {
pub colors: Styling,
pub rounded_corners: bool,
pub hide_session_name: bool,
pub border_style: BorderStyle,
pub floating_border_style: BorderStyle,
}
#[derive(Debug, Copy, Clone, PartialEq, Eq, Hash, Deserialize, Serialize)]
@@ -1827,6 +2026,14 @@ impl ModeInfo {
pub fn update_rounded_corners(&mut self, rounded_corners: bool) {
self.style.rounded_corners = rounded_corners;
}
pub fn update_border_styles(
&mut self,
border_style: BorderStyle,
floating_border_style: BorderStyle,
) {
self.style.border_style = border_style;
self.style.floating_border_style = floating_border_style;
}
pub fn update_arrow_fonts(&mut self, should_support_arrow_fonts: bool) {
// it is honestly quite baffling to me how "arrow_fonts: false" can mean "I support arrow
// fonts", but since this is a public API... ¯\_(ツ)_/¯
@@ -2821,6 +3028,8 @@ pub struct FileToOpen {
pub path: PathBuf,
pub line_number: Option<usize>,
pub cwd: Option<PathBuf>,
#[serde(default)]
pub border_style: Option<BorderStyleOverride>,
}
impl FileToOpen {
@@ -2838,6 +3047,10 @@ impl FileToOpen {
self.cwd = Some(cwd);
self
}
pub fn with_border_style(mut self, border_style: BorderStyleOverride) -> Self {
self.border_style = Some(border_style);
self
}
}
#[derive(Debug, Default, Clone)]
@@ -2845,6 +3058,7 @@ pub struct CommandToRun {
pub path: PathBuf,
pub args: Vec<String>,
pub cwd: Option<PathBuf>,
pub border_style: Option<BorderStyleOverride>,
}
impl CommandToRun {
@@ -2861,6 +3075,10 @@ impl CommandToRun {
..Default::default()
}
}
pub fn with_border_style(mut self, border_style: BorderStyleOverride) -> Self {
self.border_style = Some(border_style);
self
}
}
#[derive(Debug, Default, Clone)]
@@ -3095,6 +3313,8 @@ pub struct FloatingPaneCoordinates {
pub height: Option<PercentOrFixed>,
pub pinned: Option<bool>,
pub borderless: Option<bool>,
#[serde(default)]
pub border_style: Option<BorderStyleOverride>,
}
impl FloatingPaneCoordinates {
@@ -3146,9 +3366,27 @@ impl FloatingPaneCoordinates {
height,
pinned,
borderless,
border_style: None,
})
}
}
pub fn with_border_style(mut self, border_style: Option<BorderStyleOverride>) -> Self {
self.border_style = border_style;
self
}
pub fn merge_border_style(
coordinates: Option<Self>,
border_style: Option<BorderStyleOverride>,
) -> Option<Self> {
match border_style {
Some(border_style) => Some(
coordinates
.unwrap_or_default()
.with_border_style(Some(border_style)),
),
None => coordinates,
}
}
pub fn with_x_fixed(mut self, x: usize) -> Self {
self.x = Some(PercentOrFixed::Fixed(x));
self
@@ -3208,6 +3446,7 @@ impl From<PaneGeom> for FloatingPaneCoordinates {
height: Some(PercentOrFixed::Fixed(pane_geom.rows.as_usize())),
pinned: Some(pane_geom.is_pinned),
borderless: None,
border_style: None,
}
}
}
@@ -3304,26 +3543,33 @@ impl FromStr for WebSharing {
pub enum NewPanePlacement {
NoPreference {
borderless: Option<bool>,
border_style: Option<BorderStyleOverride>,
},
Tiled {
direction: Option<Direction>,
borderless: Option<bool>,
border_style: Option<BorderStyleOverride>,
},
Floating(Option<FloatingPaneCoordinates>),
InPlace {
pane_id_to_replace: Option<PaneId>,
close_replaced_pane: bool,
borderless: Option<bool>,
border_style: Option<BorderStyleOverride>,
},
Stacked {
pane_id_to_stack_under: Option<PaneId>,
borderless: Option<bool>,
border_style: Option<BorderStyleOverride>,
},
}
impl Default for NewPanePlacement {
fn default() -> Self {
NewPanePlacement::NoPreference { borderless: None }
NewPanePlacement::NoPreference {
borderless: None,
border_style: None,
}
}
}
@@ -3343,6 +3589,7 @@ impl NewPanePlacement {
pane_id_to_replace: None,
close_replaced_pane,
borderless: None,
border_style: None,
}
} else {
self
@@ -3356,6 +3603,7 @@ impl NewPanePlacement {
pane_id_to_replace,
close_replaced_pane,
borderless: None,
border_style: None,
}
}
pub fn should_float(&self) -> Option<bool> {
@@ -3390,13 +3638,67 @@ impl NewPanePlacement {
}
pub fn get_borderless(&self) -> Option<bool> {
match self {
NewPanePlacement::NoPreference { borderless } => *borderless,
NewPanePlacement::NoPreference { borderless, .. } => *borderless,
NewPanePlacement::Tiled { borderless, .. } => *borderless,
NewPanePlacement::Floating(coords) => coords.as_ref().and_then(|c| c.borderless),
NewPanePlacement::InPlace { borderless, .. } => *borderless,
NewPanePlacement::Stacked { borderless, .. } => *borderless,
}
}
pub fn get_border_style(&self) -> Option<BorderStyleOverride> {
match self {
NewPanePlacement::NoPreference { border_style, .. } => *border_style,
NewPanePlacement::Tiled { border_style, .. } => *border_style,
NewPanePlacement::Floating(coords) => {
coords.as_ref().and_then(|c| c.border_style.clone())
},
NewPanePlacement::InPlace { border_style, .. } => *border_style,
NewPanePlacement::Stacked { border_style, .. } => *border_style,
}
}
pub fn with_border_style(self, border_style: Option<BorderStyleOverride>) -> Self {
if border_style.is_none() {
return self;
}
match self {
NewPanePlacement::NoPreference { borderless, .. } => NewPanePlacement::NoPreference {
borderless,
border_style,
},
NewPanePlacement::Tiled {
direction,
borderless,
..
} => NewPanePlacement::Tiled {
direction,
borderless,
border_style,
},
NewPanePlacement::Floating(coords) => NewPanePlacement::Floating(Some(
coords.unwrap_or_default().with_border_style(border_style),
)),
NewPanePlacement::InPlace {
pane_id_to_replace,
close_replaced_pane,
borderless,
..
} => NewPanePlacement::InPlace {
pane_id_to_replace,
close_replaced_pane,
borderless,
border_style,
},
NewPanePlacement::Stacked {
pane_id_to_stack_under,
borderless,
..
} => NewPanePlacement::Stacked {
pane_id_to_stack_under,
borderless,
border_style,
},
}
}
}
type Context = BTreeMap<String, String>;
@@ -3593,6 +3895,7 @@ pub enum PluginCommand {
ChangeFloatingPanesCoordinates(Vec<(PaneId, FloatingPaneCoordinates)>),
TogglePaneBorderless(PaneId),
SetPaneBorderless(PaneId, bool),
SetPaneBorderStyle(PaneId, BorderStyleOverride),
OpenCommandPaneNearPlugin(CommandToRun, Context),
OpenTerminalNearPlugin(FileToOpen),
OpenTerminalFloatingNearPlugin(FileToOpen, Option<FloatingPaneCoordinates>),
@@ -3759,3 +4062,185 @@ pub fn can_parse_unicode_bare_keys() {
"Can parse a bare 'ъ' keypress"
);
}
#[test]
fn line_style_names_round_trip() {
for line_style in [
LineStyle::Single,
LineStyle::Double,
LineStyle::Heavy,
LineStyle::Dashed,
LineStyle::HeavyDashed,
] {
assert_eq!(LineStyle::from_str(&line_style.to_string()), Ok(line_style));
}
assert!(LineStyle::from_str("squiggly").is_err());
}
#[test]
fn border_style_override_from_a_bare_cli_style() {
assert_eq!(
BorderStyleOverride::from_cli_string("double"),
Ok(BorderStyleOverride {
all: Some(LineStyle::Double),
..Default::default()
})
);
}
#[test]
fn border_style_override_from_a_compound_cli_string() {
assert_eq!(
BorderStyleOverride::from_cli_string("top:double, left=heavy ,rounded"),
Ok(BorderStyleOverride {
top: Some(LineStyle::Double),
left: Some(LineStyle::Heavy),
rounded_corners: Some(true),
..Default::default()
})
);
assert_eq!(
BorderStyleOverride::from_cli_string("all:dashed,rounded:false"),
Ok(BorderStyleOverride {
all: Some(LineStyle::Dashed),
rounded_corners: Some(false),
..Default::default()
})
);
}
#[test]
fn border_style_override_rejects_unknown_cli_input() {
assert!(BorderStyleOverride::from_cli_string("diagonal:double").is_err());
assert!(BorderStyleOverride::from_cli_string("top:squiggly").is_err());
assert!(BorderStyleOverride::from_cli_string("rounded:maybe").is_err());
}
#[test]
fn empty_cli_border_style_is_treated_as_no_override() {
assert_eq!(
BorderStyleOverride::from_optional_cli_string(Some("")),
Ok(None)
);
assert_eq!(
BorderStyleOverride::from_optional_cli_string(None),
Ok(None)
);
}
#[test]
fn border_style_override_applies_per_side_over_the_shorthand() {
let base = BorderStyle::with_rounded_corners(true);
let applied = BorderStyleOverride {
all: Some(LineStyle::Double),
top: Some(LineStyle::Heavy),
..Default::default()
}
.apply_to(base);
assert_eq!(
applied,
BorderStyle {
top: LineStyle::Heavy,
right: LineStyle::Double,
bottom: LineStyle::Double,
left: LineStyle::Double,
rounded_corners: true,
}
);
}
#[test]
fn an_empty_border_style_override_leaves_the_base_untouched() {
let base = BorderStyle {
top: LineStyle::Double,
right: LineStyle::Heavy,
bottom: LineStyle::Dashed,
left: LineStyle::Single,
rounded_corners: true,
};
assert!(BorderStyleOverride::default().is_empty());
assert_eq!(BorderStyleOverride::default().apply_to(base), base);
}
#[test]
fn border_style_overrides_merge_with_the_later_one_winning() {
let merged = BorderStyleOverride {
all: Some(LineStyle::Single),
top: Some(LineStyle::Single),
..Default::default()
}
.merge(&BorderStyleOverride {
top: Some(LineStyle::Double),
rounded_corners: Some(true),
..Default::default()
});
assert_eq!(
merged,
BorderStyleOverride {
all: Some(LineStyle::Single),
top: Some(LineStyle::Double),
rounded_corners: Some(true),
..Default::default()
}
);
}
#[test]
fn a_uniform_border_style_reports_its_line_style() {
assert_eq!(
BorderStyle {
top: LineStyle::Double,
right: LineStyle::Double,
bottom: LineStyle::Double,
left: LineStyle::Double,
rounded_corners: false,
}
.uniform_style(),
Some(LineStyle::Double)
);
assert_eq!(
BorderStyle {
top: LineStyle::Double,
..Default::default()
}
.uniform_style(),
None
);
}
#[test]
fn new_pane_placement_carries_a_border_style() {
let placement = NewPanePlacement::Tiled {
direction: None,
borderless: None,
border_style: None,
}
.with_border_style(Some(BorderStyleOverride {
all: Some(LineStyle::Heavy),
..Default::default()
}));
assert_eq!(
placement.get_border_style(),
Some(BorderStyleOverride {
all: Some(LineStyle::Heavy),
..Default::default()
})
);
}
#[test]
fn a_floating_placement_carries_its_border_style_in_the_coordinates() {
let placement = NewPanePlacement::Floating(None).with_border_style(Some(BorderStyleOverride {
all: Some(LineStyle::Double),
..Default::default()
}));
let coordinates = placement.floating_pane_coordinates().unwrap();
assert_eq!(
coordinates.border_style,
Some(BorderStyleOverride {
all: Some(LineStyle::Double),
..Default::default()
})
);
assert_eq!(placement.get_border_style(), coordinates.border_style);
}
+1
View File
@@ -429,6 +429,7 @@ pub enum ScreenContext {
ChangeFloatingPanesCoordinates,
TogglePaneBorderless,
SetPaneBorderless,
SetPaneBorderStyle,
AddHighlightPaneFrameColorOverride,
GroupAndUngroupPanes,
HighlightAndUnhighlightPanes,
+268 -15
View File
@@ -7,8 +7,8 @@ use super::layout::{
};
use crate::cli::CliAction;
use crate::data::{
CommandOrPlugin, Direction, KeyWithModifier, LayoutInfo, NewPanePlacement, OriginatingPlugin,
PaneId, Resize, UnblockCondition,
BorderStyleOverride, CommandOrPlugin, Direction, KeyWithModifier, LayoutInfo, NewPanePlacement,
OriginatingPlugin, PaneId, Resize, UnblockCondition,
};
use crate::data::{FloatingPaneCoordinates, InputMode};
use crate::home::{find_default_config_dir, get_layout_dir};
@@ -320,6 +320,7 @@ pub enum Action {
near_current_pane: bool,
no_focus: bool,
borderless: Option<bool>,
border_style: Option<BorderStyleOverride>,
tab_id: Option<usize>,
},
/// Open a new pane in place of the focused one, suppressing it instead
@@ -631,6 +632,10 @@ pub enum Action {
pane_id: PaneId,
borderless: bool,
},
SetPaneBorderStyle {
pane_id: PaneId,
border_style: BorderStyleOverride,
},
TogglePaneInGroup,
ToggleGroupMarking,
// Pane-targeting CLI-only variants
@@ -1130,8 +1135,11 @@ impl Action {
near_current_pane,
no_focus,
borderless,
border_style,
tab_id,
} => {
let border_style =
BorderStyleOverride::from_optional_cli_string(border_style.as_deref())?;
let pane_id_to_replace = match pane_id {
Some(pane_id_str) => match PaneId::from_str(&pane_id_str) {
Ok(parsed_pane_id) => Some(parsed_pane_id),
@@ -1187,24 +1195,28 @@ impl Action {
};
let placement = if floating {
NewPanePlacement::Floating(FloatingPaneCoordinates::new(
x, y, width, height, pinned, borderless,
NewPanePlacement::Floating(FloatingPaneCoordinates::merge_border_style(
FloatingPaneCoordinates::new(x, y, width, height, pinned, borderless),
border_style,
))
} else if in_place {
NewPanePlacement::InPlace {
pane_id_to_replace,
close_replaced_pane,
borderless,
border_style,
}
} else if stacked {
NewPanePlacement::Stacked {
pane_id_to_stack_under: None,
borderless,
border_style,
}
} else {
NewPanePlacement::Tiled {
direction,
borderless,
border_style,
}
};
@@ -1244,8 +1256,11 @@ impl Action {
pane_name: name,
skip_cache: skip_plugin_cache,
cwd,
coordinates: FloatingPaneCoordinates::new(
x, y, width, height, pinned, borderless,
coordinates: FloatingPaneCoordinates::merge_border_style(
FloatingPaneCoordinates::new(
x, y, width, height, pinned, borderless,
),
border_style,
),
no_focus,
tab_id,
@@ -1295,8 +1310,11 @@ impl Action {
Ok(vec![Action::NewFloatingPane {
command: Some(run_command_action),
pane_name: name,
coordinates: FloatingPaneCoordinates::new(
x, y, width, height, pinned, borderless,
coordinates: FloatingPaneCoordinates::merge_border_style(
FloatingPaneCoordinates::new(
x, y, width, height, pinned, borderless,
),
border_style,
),
near_current_pane,
no_focus,
@@ -1328,6 +1346,7 @@ impl Action {
near_current_pane,
no_focus,
borderless,
border_style,
tab_id,
}])
}
@@ -1336,8 +1355,11 @@ impl Action {
Ok(vec![Action::NewFloatingPane {
command: None,
pane_name: name,
coordinates: FloatingPaneCoordinates::new(
x, y, width, height, pinned, borderless,
coordinates: FloatingPaneCoordinates::merge_border_style(
FloatingPaneCoordinates::new(
x, y, width, height, pinned, borderless,
),
border_style,
),
near_current_pane,
no_focus,
@@ -1369,6 +1391,7 @@ impl Action {
near_current_pane,
no_focus,
borderless,
border_style,
tab_id,
}])
}
@@ -1390,8 +1413,11 @@ impl Action {
near_current_pane,
no_focus,
borderless,
border_style,
tab_id,
} => {
let border_style =
BorderStyleOverride::from_optional_cli_string(border_style.as_deref())?;
let mut file = file;
let current_dir = get_current_dir();
let cwd = cwd
@@ -1410,8 +1436,9 @@ impl Action {
in_place,
close_replaced_pane,
start_suppressed,
coordinates: FloatingPaneCoordinates::new(
x, y, width, height, pinned, borderless,
coordinates: FloatingPaneCoordinates::merge_border_style(
FloatingPaneCoordinates::new(x, y, width, height, pinned, borderless),
border_style,
),
near_current_pane,
no_focus,
@@ -2077,10 +2104,14 @@ impl Action {
height,
pinned,
borderless,
border_style,
} => {
let Some(coordinates) =
FloatingPaneCoordinates::new(x, y, width, height, pinned, borderless)
else {
let border_style =
BorderStyleOverride::from_optional_cli_string(border_style.as_deref())?;
let Some(coordinates) = FloatingPaneCoordinates::merge_border_style(
FloatingPaneCoordinates::new(x, y, width, height, pinned, borderless),
border_style,
) else {
return Err(format!("Failed to parse floating pane coordinates"));
};
let parsed_pane_id = PaneId::from_str(&pane_id);
@@ -2099,6 +2130,29 @@ impl Action {
}
}
},
CliAction::SetPaneBorderStyle {
pane_id,
border_style,
} => {
let border_style =
BorderStyleOverride::from_optional_cli_string(border_style.as_deref())?
.unwrap_or_default();
let parsed_pane_id = PaneId::from_str(&pane_id);
match parsed_pane_id {
Ok(parsed_pane_id) => {
Ok(vec![Action::SetPaneBorderStyle {
pane_id: parsed_pane_id,
border_style,
}])
},
Err(_e) => {
Err(format!(
"Malformed pane id: {}, expecting either a bare integer (eg. 1), a terminal pane id (eg. terminal_1) or a plugin pane id (eg. plugin_1)",
pane_id
))
}
}
},
CliAction::TogglePaneBorderless { pane_id } => {
let parsed_pane_id = PaneId::from_str(&pane_id);
match parsed_pane_id {
@@ -3698,6 +3752,194 @@ mod tests {
assert!(result.is_err());
}
fn new_pane_cli_action(floating: bool, border_style: Option<&str>) -> CliAction {
CliAction::NewPane {
direction: None,
command: vec![],
plugin: None,
cwd: None,
floating,
in_place: false,
close_replaced_pane: false,
pane_id: None,
name: None,
close_on_exit: false,
start_suspended: false,
configuration: None,
skip_plugin_cache: false,
x: None,
y: None,
width: None,
height: None,
pinned: None,
stacked: false,
blocking: false,
block_until_exit_success: false,
block_until_exit_failure: false,
block_until_exit: false,
unblock_condition: None,
near_current_pane: false,
no_focus: false,
borderless: None,
tab_id: None,
border_style: border_style.map(|s| s.to_string()),
}
}
#[test]
fn test_new_tiled_pane_with_border_style() {
let result = Action::actions_from_cli(
new_pane_cli_action(false, Some("top:double,rounded")),
Box::new(|| PathBuf::from("/tmp")),
None,
);
let actions = result.unwrap();
match &actions[0] {
Action::NewTiledPane { border_style, .. } => {
assert_eq!(
*border_style,
Some(BorderStyleOverride {
top: Some(crate::data::LineStyle::Double),
rounded_corners: Some(true),
..Default::default()
})
);
},
other => panic!("Expected NewTiledPane action, got {:?}", other),
}
}
#[test]
fn test_new_floating_pane_with_border_style() {
let result = Action::actions_from_cli(
new_pane_cli_action(true, Some("heavy")),
Box::new(|| PathBuf::from("/tmp")),
None,
);
let actions = result.unwrap();
match &actions[0] {
Action::NewFloatingPane { coordinates, .. } => {
assert_eq!(
coordinates.as_ref().unwrap().border_style,
Some(BorderStyleOverride {
all: Some(crate::data::LineStyle::Heavy),
..Default::default()
})
);
},
other => panic!("Expected NewFloatingPane action, got {:?}", other),
}
}
#[test]
fn test_new_pane_without_border_style() {
let result = Action::actions_from_cli(
new_pane_cli_action(false, None),
Box::new(|| PathBuf::from("/tmp")),
None,
);
let actions = result.unwrap();
match &actions[0] {
Action::NewTiledPane { border_style, .. } => assert_eq!(*border_style, None),
other => panic!("Expected NewTiledPane action, got {:?}", other),
}
}
#[test]
fn test_new_pane_with_malformed_border_style_is_an_error() {
let result = Action::actions_from_cli(
new_pane_cli_action(false, Some("squiggly")),
Box::new(|| PathBuf::from("/tmp")),
None,
);
assert!(result.is_err());
}
#[test]
fn test_set_pane_border_style() {
let cli_action = CliAction::SetPaneBorderStyle {
pane_id: "plugin_4".to_string(),
border_style: Some("bottom:heavy".to_string()),
};
let result = Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None);
let actions = result.unwrap();
assert_eq!(actions.len(), 1);
match &actions[0] {
Action::SetPaneBorderStyle {
pane_id,
border_style,
} => {
assert_eq!(*pane_id, PaneId::Plugin(4));
assert_eq!(
*border_style,
BorderStyleOverride {
bottom: Some(crate::data::LineStyle::Heavy),
..Default::default()
}
);
},
other => panic!("Expected SetPaneBorderStyle action, got {:?}", other),
}
}
#[test]
fn test_set_pane_border_style_without_a_style_clears_the_override() {
let cli_action = CliAction::SetPaneBorderStyle {
pane_id: "3".to_string(),
border_style: None,
};
let actions =
Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None).unwrap();
match &actions[0] {
Action::SetPaneBorderStyle { border_style, .. } => {
assert!(border_style.is_empty());
},
other => panic!("Expected SetPaneBorderStyle action, got {:?}", other),
}
}
#[test]
fn test_set_pane_border_style_with_a_malformed_pane_id_is_an_error() {
let cli_action = CliAction::SetPaneBorderStyle {
pane_id: "not_a_pane".to_string(),
border_style: None,
};
assert!(
Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None).is_err()
);
}
#[test]
fn test_change_floating_pane_coordinates_with_border_style() {
let cli_action = CliAction::ChangeFloatingPaneCoordinates {
pane_id: "terminal_2".to_string(),
x: Some("10".to_string()),
y: None,
width: None,
height: None,
pinned: None,
borderless: None,
border_style: Some("double".to_string()),
};
let actions =
Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None).unwrap();
match &actions[0] {
Action::ChangeFloatingPaneCoordinates { coordinates, .. } => {
assert_eq!(
coordinates.border_style,
Some(BorderStyleOverride {
all: Some(crate::data::LineStyle::Double),
..Default::default()
})
);
},
other => panic!(
"Expected ChangeFloatingPaneCoordinates action, got {:?}",
other
),
}
}
// Tab-targeting for pane creation commands
#[test]
@@ -3731,6 +3973,7 @@ mod tests {
no_focus: false,
borderless: None,
tab_id: Some(3),
border_style: None,
};
let result = Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None);
assert!(result.is_ok());
@@ -3775,6 +4018,7 @@ mod tests {
no_focus: false,
borderless: None,
tab_id: None,
border_style: None,
};
let result = Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None);
assert!(result.is_ok());
@@ -3819,6 +4063,7 @@ mod tests {
no_focus: false,
borderless: None,
tab_id: None,
border_style: None,
};
let result = Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None);
assert!(result.is_ok());
@@ -3865,6 +4110,7 @@ mod tests {
no_focus: false,
borderless: None,
tab_id: None,
border_style: None,
};
let result = Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None);
assert!(result.is_err());
@@ -3902,6 +4148,7 @@ mod tests {
no_focus: false,
borderless: None,
tab_id: Some(5),
border_style: None,
};
let result = Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None);
assert!(result.is_ok());
@@ -3946,6 +4193,7 @@ mod tests {
no_focus: false,
borderless: None,
tab_id: Some(1),
border_style: None,
};
let result = Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None);
assert!(result.is_ok());
@@ -3990,6 +4238,7 @@ mod tests {
no_focus: false,
borderless: None,
tab_id: Some(2),
border_style: None,
};
let result = Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None);
assert!(result.is_ok());
@@ -4022,6 +4271,7 @@ mod tests {
no_focus: false,
borderless: None,
tab_id: Some(4),
border_style: None,
};
let result = Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None);
assert!(result.is_ok());
@@ -4054,6 +4304,7 @@ mod tests {
no_focus: false,
borderless: None,
tab_id: None,
border_style: None,
};
let result = Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None);
assert!(result.is_ok());
@@ -4098,6 +4349,7 @@ mod tests {
no_focus: false,
borderless: None,
tab_id: Some(2),
border_style: None,
};
let result = Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None);
assert!(result.is_ok());
@@ -4142,6 +4394,7 @@ mod tests {
no_focus: false,
borderless: None,
tab_id: Some(1),
border_style: None,
};
let result = Action::actions_from_cli(cli_action, Box::new(|| PathBuf::from("/tmp")), None);
assert!(result.is_ok());
+1
View File
@@ -1409,6 +1409,7 @@ mod config_test {
pane_frames: FrameConfig {
rounded_corners: true,
hide_session_name: true,
..Default::default()
},
};
assert_eq!(config.ui, expected_ui_config, "Ui config defined in config");
+10 -1
View File
@@ -11,7 +11,10 @@
#[cfg(not(target_family = "wasm"))]
use crate::downloader::Downloader;
use crate::{
data::{Direction, LayoutInfo, LayoutMetadata, LayoutParsingError, LayoutWithError},
data::{
BorderStyleOverride, Direction, LayoutInfo, LayoutMetadata, LayoutParsingError,
LayoutWithError,
},
home::{default_layout_dir, find_default_config_dir},
input::{
command::RunCommand,
@@ -789,6 +792,8 @@ pub struct FloatingPaneLayout {
pub y: Option<PercentOrFixed>,
pub pinned: Option<bool>,
pub borderless: Option<bool>,
#[serde(default)]
pub border_style: Option<BorderStyleOverride>,
pub run: Option<Run>,
pub focus: Option<bool>,
pub already_running: bool,
@@ -808,6 +813,7 @@ impl FloatingPaneLayout {
y: None,
pinned: None,
borderless: None,
border_style: None,
run: None,
focus: None,
already_running: false,
@@ -838,6 +844,7 @@ impl From<&TiledPaneLayout> for FloatingPaneLayout {
name: pane_layout.name.clone(),
run: pane_layout.run.clone(),
focus: pane_layout.focus,
border_style: pane_layout.border_style,
..Default::default()
}
}
@@ -851,6 +858,8 @@ pub struct TiledPaneLayout {
pub split_size: Option<SplitSize>,
pub run: Option<Run>,
pub borderless: Option<bool>,
#[serde(default)]
pub border_style: Option<BorderStyleOverride>,
pub focus: Option<bool>,
pub external_children_index: Option<usize>,
pub children_are_stacked: bool,
+17 -1
View File
@@ -7,7 +7,7 @@ use std::{
fmt,
};
use crate::data::Styling;
use crate::data::{BorderStyle, BorderStyleOverride, Styling};
#[derive(Debug, Default, Clone, Copy, PartialEq, Deserialize, Serialize)]
pub struct UiConfig {
@@ -26,6 +26,10 @@ impl UiConfig {
pub struct FrameConfig {
pub rounded_corners: bool,
pub hide_session_name: bool,
#[serde(default)]
pub border_style: BorderStyleOverride,
#[serde(default)]
pub floating_border_style: BorderStyleOverride,
}
impl FrameConfig {
@@ -33,8 +37,20 @@ impl FrameConfig {
let mut merged = self.clone();
merged.rounded_corners = other.rounded_corners;
merged.hide_session_name = other.hide_session_name;
merged.border_style = merged.border_style.merge(&other.border_style);
merged.floating_border_style = merged
.floating_border_style
.merge(&other.floating_border_style);
merged
}
pub fn resolved_border_style(&self) -> BorderStyle {
self.border_style
.apply_to(BorderStyle::with_rounded_corners(self.rounded_corners))
}
pub fn resolved_floating_border_style(&self) -> BorderStyle {
self.floating_border_style
.apply_to(self.resolved_border_style())
}
}
#[derive(Clone, PartialEq, Default, Serialize, Deserialize)]
@@ -46,6 +46,47 @@ fn layout_with_one_pane() {
assert_eq!(layout, expected_layout);
}
#[test]
fn layout_with_border_styles() {
use crate::data::{BorderStyleOverride, LineStyle};
let kdl_layout = r#"
layout {
pane border_style="double" border_top="heavy" rounded_corners=true
floating_panes {
pane border_style="dashed"
}
}
"#;
let layout = Layout::from_kdl(kdl_layout, Some("layout_file_name".into()), None, None).unwrap();
let (tiled, floating) = layout.template.clone().unwrap();
assert_eq!(
tiled.children[0].border_style,
Some(BorderStyleOverride {
all: Some(LineStyle::Double),
top: Some(LineStyle::Heavy),
rounded_corners: Some(true),
..Default::default()
})
);
assert_eq!(
floating[0].border_style,
Some(BorderStyleOverride {
all: Some(LineStyle::Dashed),
..Default::default()
})
);
}
#[test]
fn layout_with_invalid_border_style() {
let kdl_layout = r#"
layout {
pane border_style="squiggly"
}
"#;
assert!(Layout::from_kdl(kdl_layout, Some("layout_file_name".into()), None, None).is_err());
}
#[test]
fn layout_with_multiple_panes() {
let kdl_layout = r#"
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1410
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -31,6 +30,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -64,6 +64,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -79,6 +80,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1375
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -34,6 +33,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -67,6 +67,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -82,6 +83,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1984
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -23,6 +22,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -41,6 +41,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -59,6 +60,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -74,6 +76,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: true,
@@ -89,6 +92,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1952
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -23,6 +22,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -41,6 +41,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -56,6 +57,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: true,
@@ -71,6 +73,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1969
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -27,6 +26,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -45,6 +45,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -60,6 +61,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: true,
@@ -75,6 +77,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: true,
@@ -90,6 +93,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1938
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -19,6 +18,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -34,6 +34,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -88,6 +89,7 @@ Layout {
borderless: Some(
true,
),
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -114,6 +116,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -132,6 +135,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: Some(
0,
@@ -149,6 +153,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -164,6 +169,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -205,6 +211,7 @@ Layout {
borderless: Some(
true,
),
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -220,6 +227,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -267,6 +275,7 @@ Layout {
borderless: Some(
true,
),
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -293,6 +302,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: Some(
0,
@@ -317,6 +327,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -335,6 +346,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -353,6 +365,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -371,6 +384,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -386,6 +400,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -401,6 +416,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -416,6 +432,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -457,6 +474,7 @@ Layout {
borderless: Some(
true,
),
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -472,6 +490,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -519,6 +538,7 @@ Layout {
borderless: Some(
true,
),
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -545,6 +565,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: Some(
0,
@@ -569,6 +590,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -587,6 +609,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -605,6 +628,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -623,6 +647,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -638,6 +663,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -660,6 +686,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -678,6 +705,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -696,6 +724,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -714,6 +743,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -729,6 +759,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -744,6 +775,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -759,6 +791,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -800,6 +833,7 @@ Layout {
borderless: Some(
true,
),
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -815,6 +849,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1033
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -29,6 +28,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -51,6 +51,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -69,6 +70,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -84,6 +86,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -99,6 +102,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -117,6 +121,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -132,6 +137,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -158,6 +164,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -173,6 +180,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: Some(
1,
@@ -193,6 +201,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -208,6 +217,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -223,6 +233,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 985
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -24,6 +23,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -46,6 +46,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -64,6 +65,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -79,6 +81,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -94,6 +97,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -112,6 +116,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -127,6 +132,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -157,6 +163,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -172,6 +179,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: Some(
1,
@@ -192,6 +200,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -207,6 +216,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -231,6 +241,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1427
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -31,6 +30,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -61,6 +61,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -76,6 +77,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1393
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -31,6 +30,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -61,6 +61,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -76,6 +77,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1085
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -24,6 +23,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -48,6 +48,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -63,6 +64,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -81,6 +83,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -96,6 +99,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -118,6 +122,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -136,6 +141,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -151,6 +157,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -166,6 +173,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -196,6 +204,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -220,6 +229,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -235,6 +245,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -253,6 +264,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -268,6 +280,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -286,6 +299,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -301,6 +315,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -325,6 +340,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1462
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -31,6 +30,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -63,6 +63,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -78,6 +79,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1445
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -33,6 +32,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -65,6 +65,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -80,6 +81,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 2230
expression: "format!(\"{layout:#?}\")"
expression: "normalize_layout_debug(format!(\"{layout:#?}\"))"
---
Layout {
tabs: [
@@ -22,6 +21,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -44,6 +44,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -66,6 +67,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -88,6 +90,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -120,6 +123,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -146,6 +150,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -172,6 +177,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -204,6 +210,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -230,6 +237,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -249,6 +257,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -281,6 +290,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -303,6 +313,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -325,6 +336,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -347,6 +359,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -379,6 +392,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -405,6 +419,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -431,6 +446,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -463,6 +479,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -489,6 +506,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -508,6 +526,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1847
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -22,6 +21,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -54,6 +54,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -73,6 +74,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -97,6 +99,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1868
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -26,6 +25,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -58,6 +58,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -84,6 +85,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -103,6 +105,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -122,6 +125,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -141,6 +145,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -165,6 +170,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1887
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -22,6 +21,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -54,6 +54,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -80,6 +81,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -99,6 +101,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -118,6 +121,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -142,6 +146,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1732
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -22,6 +21,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -54,6 +54,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -73,6 +74,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -105,6 +107,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -137,6 +140,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -156,6 +160,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1765
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -23,6 +22,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -55,6 +55,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -74,6 +75,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1786
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -22,6 +21,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -54,6 +54,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -73,6 +74,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -105,6 +107,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -137,6 +140,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -156,6 +160,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1745
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -22,6 +21,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -54,6 +54,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -73,6 +74,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -105,6 +107,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -137,6 +140,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -156,6 +160,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1802
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -22,6 +21,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -54,6 +54,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -73,6 +74,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -97,6 +99,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 511
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -31,6 +30,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -46,6 +46,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 524
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -31,6 +30,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -46,6 +46,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 819
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -20,6 +19,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -42,6 +42,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -60,6 +61,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -75,6 +77,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -93,6 +96,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -108,6 +112,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -136,6 +141,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -158,6 +164,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -176,6 +183,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -191,6 +199,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -209,6 +218,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -224,6 +234,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -250,6 +261,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -268,6 +280,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -286,6 +299,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -301,6 +315,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -329,6 +344,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -347,6 +363,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -365,6 +382,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -380,6 +398,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 939
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -23,6 +22,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -41,6 +41,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -63,6 +64,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -81,6 +83,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -96,6 +99,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -118,6 +122,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -136,6 +141,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -154,6 +160,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -169,6 +176,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -184,6 +192,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -199,6 +208,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 913
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -23,6 +22,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -41,6 +41,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -63,6 +64,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -81,6 +83,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -96,6 +99,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -114,6 +118,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -129,6 +134,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -144,6 +150,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 844
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -20,6 +19,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -38,6 +38,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -53,6 +54,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -81,6 +83,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -99,6 +102,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -114,6 +118,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -136,6 +141,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -168,6 +174,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -186,6 +193,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -201,6 +209,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -216,6 +225,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1096
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -19,6 +18,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -36,6 +36,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 871
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [],
@@ -23,6 +22,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -45,6 +45,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -60,6 +61,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -78,6 +80,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -93,6 +96,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -115,6 +119,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -137,6 +142,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -155,6 +161,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -170,6 +177,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -188,6 +196,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -203,6 +212,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -225,6 +235,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -247,6 +258,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -265,6 +277,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -280,6 +293,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -298,6 +312,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -313,6 +328,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -335,6 +351,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -353,6 +370,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -371,6 +389,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -386,6 +405,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -401,6 +421,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 892
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -22,6 +21,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -56,6 +56,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -71,6 +72,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -89,6 +91,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -104,6 +107,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -119,6 +123,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -143,6 +148,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 305
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -18,6 +17,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -33,6 +33,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -53,6 +54,7 @@ Layout {
y: None,
pinned: None,
borderless: None,
border_style: None,
run: None,
focus: None,
already_running: false,
@@ -76,6 +78,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -91,6 +94,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -111,6 +115,7 @@ Layout {
y: None,
pinned: None,
borderless: None,
border_style: None,
run: None,
focus: None,
already_running: false,
@@ -127,6 +132,7 @@ Layout {
y: None,
pinned: None,
borderless: None,
border_style: None,
run: None,
focus: None,
already_running: false,
@@ -148,6 +154,7 @@ Layout {
split_size: None,
run: None,
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1616
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -32,6 +31,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -51,6 +51,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -93,6 +94,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -112,6 +114,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1562
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -32,6 +31,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -51,6 +51,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -93,6 +94,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -112,6 +114,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1579
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -32,6 +31,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -51,6 +51,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -93,6 +94,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -112,6 +114,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1597
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -32,6 +31,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -51,6 +51,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -93,6 +94,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -112,6 +114,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1634
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -32,6 +31,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -51,6 +51,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -93,6 +94,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -112,6 +114,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1652
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -22,6 +21,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -41,6 +41,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -73,6 +74,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -92,6 +94,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1686
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -32,6 +31,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -51,6 +51,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -93,6 +94,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -112,6 +114,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1668
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -32,6 +31,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -51,6 +51,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -93,6 +94,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -112,6 +114,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -1,7 +1,6 @@
---
source: zellij-utils/src/input/./unit/layout_test.rs
assertion_line: 1702
expression: "format!(\"{:#?}\", layout)"
expression: "normalize_layout_debug(format!(\"{:#?}\", layout))"
---
Layout {
tabs: [
@@ -26,6 +25,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -45,6 +45,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -81,6 +82,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,
@@ -100,6 +102,7 @@ Layout {
),
),
borderless: None,
border_style: None,
focus: None,
external_children_index: None,
children_are_stacked: false,

Some files were not shown because too many files have changed in this diff Show More