summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorAram Drevekenin <aram@poor.dev>2021-08-24 10:58:36 +0200
committerAram Drevekenin <aram@poor.dev>2021-08-24 10:58:36 +0200
commit618c2c376bb4edca8693ea4b871279bc04501559 (patch)
treeb4d4426b353955e8af1ed8ad6531f95860eda5f6
parent7a2f86db1b34b027ca03be73ec7bc4681f33fbdf (diff)
parent88b4063879845cf53397f60201473ce386280cfe (diff)
Merge branch 'tab-layout' of https://github.com/a-kenji/zellij into a-kenji-tab-layout
-rw-r--r--example/multiple_tabs_layout.yaml82
-rw-r--r--example/multiple_tabs_layout_htop_command.yaml85
-rw-r--r--src/main.rs24
-rw-r--r--src/tests/fixtures/layouts/parts-total-less-than-100-percent.yaml2
-rw-r--r--src/tests/fixtures/layouts/parts-total-more-than-100-percent.yaml3
-rw-r--r--src/tests/fixtures/layouts/three-panes-with-nesting.yaml24
-rw-r--r--zellij-client/src/input_handler.rs2
-rw-r--r--zellij-client/src/lib.rs4
-rw-r--r--zellij-server/src/lib.rs57
-rw-r--r--zellij-server/src/pty.rs15
-rw-r--r--zellij-server/src/route.rs4
-rw-r--r--zellij-utils/assets/config/default.yaml2
-rw-r--r--zellij-utils/assets/layouts/default.yaml32
-rw-r--r--zellij-utils/assets/layouts/disable-status-bar.yaml20
-rw-r--r--zellij-utils/assets/layouts/strider.yaml32
-rw-r--r--zellij-utils/src/input/actions.rs7
-rw-r--r--zellij-utils/src/input/config.rs92
-rw-r--r--zellij-utils/src/input/layout.rs300
-rw-r--r--zellij-utils/src/input/unit/fixtures/layouts/deeply-nested-tab-layout.yaml43
-rw-r--r--zellij-utils/src/input/unit/fixtures/layouts/multiple-tabs-should-not-error.yaml18
-rw-r--r--zellij-utils/src/input/unit/fixtures/layouts/three-panes-with-tab-and-command.yaml35
-rw-r--r--zellij-utils/src/input/unit/fixtures/layouts/three-panes-with-tab-and-default-plugins.yaml31
-rw-r--r--zellij-utils/src/input/unit/fixtures/layouts/three-panes-with-tab.yaml21
-rw-r--r--zellij-utils/src/input/unit/fixtures/layouts/three-tabs-merged-correctly.yaml29
-rw-r--r--zellij-utils/src/input/unit/keybinds_test.rs6
-rw-r--r--zellij-utils/src/input/unit/layout_test.rs685
-rw-r--r--zellij-utils/src/ipc.rs23
-rw-r--r--zellij-utils/src/setup.rs22
28 files changed, 1572 insertions, 128 deletions
diff --git a/example/multiple_tabs_layout.yaml b/example/multiple_tabs_layout.yaml
new file mode 100644
index 000000000..6c4d15980
--- /dev/null
+++ b/example/multiple_tabs_layout.yaml
@@ -0,0 +1,82 @@
+---
+direction: Horizontal
+parts:
+ - direction: Vertical
+ split_size:
+ Fixed: 1
+ run:
+ plugin: tab-bar
+ - direction: Vertical
+ tabs:
+ - direction: Vertical
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ - direction: Vertical
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Horizontal
+ split_size:
+ Percent: 50
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ - direction: Vertical
+ - direction: Vertical
+ - direction: Vertical
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 20
+ run:
+ plugin: strider
+ - direction: Horizontal
+ split_size:
+ Percent: 80
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 40
+ - direction: Horizontal
+ split_size:
+ Percent: 60
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ split_size:
+ Fixed: 2
+ run:
+ plugin: status-bar
diff --git a/example/multiple_tabs_layout_htop_command.yaml b/example/multiple_tabs_layout_htop_command.yaml
new file mode 100644
index 000000000..6739eba8f
--- /dev/null
+++ b/example/multiple_tabs_layout_htop_command.yaml
@@ -0,0 +1,85 @@
+---
+direction: Horizontal
+parts:
+ - direction: Vertical
+ split_size:
+ Fixed: 1
+ run:
+ plugin: tab-bar
+ - direction: Vertical
+ tabs:
+ - direction: Vertical
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ run:
+ command: {cmd: htop}
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Horizontal
+ split_size:
+ Percent: 50
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ - direction: Vertical
+ run:
+ command: {cmd: htop, args: ["-C"]}
+ - direction: Vertical
+ - direction: Vertical
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 20
+ run:
+ plugin: strider
+ - direction: Horizontal
+ split_size:
+ Percent: 80
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 40
+ - direction: Horizontal
+ split_size:
+ Percent: 60
+ parts:
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ split_size:
+ Percent: 50
+ - direction: Vertical
+ split_size:
+ Fixed: 2
+ run:
+ plugin: status-bar
diff --git a/src/main.rs b/src/main.rs
index 1a3a16ed6..f0d00f77a 100644
--- a/src/main.rs
+++ b/src/main.rs
@@ -24,14 +24,6 @@ pub fn main() {
list_sessions();
}
- let (config, layout, config_options) = match Setup::from_options(&opts) {
- Ok(results) => results,
- Err(e) => {
- eprintln!("{}", e);
- process::exit(1);
- }
- };
-
atomic_create_dir(&*ZELLIJ_TMP_DIR).unwrap();
atomic_create_dir(&*ZELLIJ_TMP_LOG_DIR).unwrap();
if let Some(path) = opts.server {
@@ -62,6 +54,14 @@ pub fn main() {
session_name = Some(get_active_session());
}
+ let (config, _, config_options) = match Setup::from_options(&opts) {
+ Ok(results) => results,
+ Err(e) => {
+ eprintln!("{}", e);
+ process::exit(1);
+ }
+ };
+
start_client(
Box::new(os_input),
opts,
@@ -70,6 +70,14 @@ pub fn main() {
None,
);
} else {
+ let (config, layout, _) = match Setup::from_options(&opts) {
+ Ok(results) => results,
+ Err(e) => {
+ eprintln!("{}", e);
+ process::exit(1);
+ }
+ };
+
let session_name = opts
.session
.clone()
diff --git a/src/tests/fixtures/layouts/parts-total-less-than-100-percent.yaml b/src/tests/fixtures/layouts/parts-total-less-than-100-percent.yaml
index e1a1a6071..f0f66a323 100644
--- a/src/tests/fixtures/layouts/parts-total-less-than-100-percent.yaml
+++ b/src/tests/fixtures/layouts/parts-total-less-than-100-percent.yaml
@@ -9,6 +9,8 @@
- direction: Horizontal
split_size:
Percent: 50
+ tabs:
+ - direction: Horizontal
split_size:
Percent: 80
- direction: Vertical
diff --git a/src/tests/fixtures/layouts/parts-total-more-than-100-percent.yaml b/src/tests/fixtures/layouts/parts-total-more-than-100-percent.yaml
index 33d942253..2b55547d4 100644
--- a/src/tests/fixtures/layouts/parts-total-more-than-100-percent.yaml
+++ b/src/tests/fixtures/layouts/parts-total-more-than-100-percent.yaml
@@ -9,6 +9,9 @@
- direction: Horizontal
split_size:
Percent: 90
+ - direction: Horizontal
+ tabs:
+ - direction: Horizontal
split_size:
Percent: 80
- direction: Vertical
diff --git a/src/tests/fixtures/layouts/three-panes-with-nesting.yaml b/src/tests/fixtures/layouts/three-panes-with-nesting.yaml
index f1e0dd7e5..20a647f3d 100644
--- a/src/tests/fixtures/layouts/three-panes-with-nesting.yaml
+++ b/src/tests/fixtures/layouts/three-panes-with-nesting.yaml
@@ -1,16 +1,18 @@
---
direction: Horizontal
-parts:
- - direction: Vertical
+tabs:
+ - direction: Horizontal
parts:
- - direction: Horizontal
- split_size:
- Percent: 20
- - direction: Horizontal
+ - direction: Vertical
+ parts:
+ - direction: Horizontal
+ split_size:
+ Percent: 20
+ - direction: Horizontal
+ split_size:
+ Percent: 80
split_size:
Percent: 80
- split_size:
- Percent: 80
- - direction: Vertical
- split_size:
- Percent: 20
+ - direction: Vertical
+ split_size:
+ Percent: 20
diff --git a/zellij-client/src/input_handler.rs b/zellij-client/src/input_handler.rs
index 03d223b2e..217b10f97 100644
--- a/zellij-client/src/input_handler.rs
+++ b/zellij-client/src/input_handler.rs
@@ -185,7 +185,7 @@ impl InputHandler {
}
Action::CloseFocus
| Action::NewPane(_)
- | Action::NewTab
+ | Action::NewTab(_)
| Action::GoToNextTab
| Action::GoToPreviousTab
| Action::CloseTab
diff --git a/zellij-client/src/lib.rs b/zellij-client/src/lib.rs
index 5c832e860..f74a74ddf 100644
--- a/zellij-client/src/lib.rs
+++ b/zellij-client/src/lib.rs
@@ -19,7 +19,7 @@ use zellij_utils::{
channels::{self, ChannelWithContext, SenderWithContext},
consts::{SESSION_NAME, ZELLIJ_IPC_PIPE},
errors::{ClientContext, ContextType, ErrorInstruction},
- input::{actions::Action, config::Config, layout::Layout, options::Options},
+ input::{actions::Action, config::Config, layout::LayoutTemplate, options::Options},
ipc::{ClientAttributes, ClientToServerMsg, ExitReason, ServerToClientMsg},
};
@@ -87,7 +87,7 @@ pub fn start_client(
opts: CliArgs,
config: Config,
info: ClientInfo,
- layout: Option<Layout>,
+ layout: Option<LayoutTemplate>,
) {
info!("Starting Zellij client!");
let clear_client_terminal_attributes = "\u{1b}[?1l\u{1b}=\u{1b}[r\u{1b}12l\u{1b}[?1000l\u{1b}[?1002l\u{1b}[?1003l\u{1b}[?1005l\u{1b}[?1006l\u{1b}[?12l";
diff --git a/zellij-server/src/lib.rs b/zellij-server/src/lib.rs
index 690304bb5..d0b3b5d27 100644
--- a/zellij-server/src/lib.rs
+++ b/zellij-server/src/lib.rs
@@ -11,11 +11,13 @@ mod ui;
mod wasm_vm;
use log::info;
+use std::{
+ path::PathBuf,
+ sync::{Arc, Mutex, RwLock},
+ thread,
+};
use zellij_utils::zellij_tile;
-use std::path::PathBuf;
-use std::sync::{Arc, Mutex, RwLock};
-use std::thread;
use wasmer::Store;
use zellij_tile::data::{Event, Palette, PluginCapabilities};
@@ -34,7 +36,7 @@ use zellij_utils::{
input::{
command::{RunCommand, TerminalAction},
get_mode_info,
- layout::Layout,
+ layout::LayoutTemplate,
options::Options,
},
ipc::{ClientAttributes, ClientToServerMsg, ExitReason, ServerToClientMsg},
@@ -44,7 +46,12 @@ use zellij_utils::{
/// Instructions related to server-side application
#[derive(Debug, Clone)]
pub(crate) enum ServerInstruction {
- NewClient(ClientAttributes, Box<CliArgs>, Box<Options>, Option<Layout>),
+ NewClient(
+ ClientAttributes,
+ Box<CliArgs>,
+ Box<Options>,
+ Option<LayoutTemplate>,
+ ),
Render(Option<String>),
UnblockInputThread,
ClientExit,
@@ -207,7 +214,7 @@ pub fn start_server(os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
to_server.clone(),
client_attributes,
session_state.clone(),
- layout,
+ layout.clone(),
);
*session_data.write().unwrap() = Some(session);
*session_state.write().unwrap() = SessionState::Attached;
@@ -219,14 +226,34 @@ pub fn start_server(os_input: Box<dyn ServerOsApi>, socket_path: PathBuf) {
})
});
- session_data
- .read()
- .unwrap()
- .as_ref()
- .unwrap()
- .senders
- .send_to_pty(PtyInstruction::NewTab(default_shell.clone()))
- .unwrap();
+ let spawn_tabs = |tab_layout| {
+ session_data
+ .read()
+ .unwrap()
+ .as_ref()
+ .unwrap()
+ .senders
+ .send_to_pty(PtyInstruction::NewTab(default_shell.clone(), tab_layout))
+ .unwrap()
+ };
+
+ match layout {
+ None => {
+ spawn_tabs(None);
+ }
+ Some(layout) => {
+ if !&layout.tabs.is_empty() {
+ for tab_layout in layout.tabs {
+ spawn_tabs(Some(tab_layout.clone()));
+ // Spawning tabs in too quick succession might mess up the layout
+ // TODO: investigate why
+ thread::sleep(std::time::Duration::from_millis(250));
+ }
+ } else {
+ spawn_tabs(None);
+ }
+ }
+ }
}
ServerInstruction::AttachClient(attrs, _, options) => {
*session_state.write().unwrap() = SessionState::Attached;
@@ -302,7 +329,7 @@ fn init_session(
to_server: SenderWithContext<ServerInstruction>,
client_attributes: ClientAttributes,
session_state: Arc<RwLock<SessionState>>,
- layout: Option<Layout>,
+ layout: Option<LayoutTemplate>,
) -> SessionMetaData {
let (to_screen, screen_receiver): ChannelWithContext<ScreenInstruction> = channels::unbounded();
let to_screen = SenderWithContext::new(to_screen);
diff --git a/zellij-server/src/pty.rs b/zellij-server/src/pty.rs
index 5ef3b3217..5c0e4a269 100644
--- a/zellij-server/src/pty.rs
+++ b/zellij-server/src/pty.rs
@@ -20,7 +20,7 @@ use zellij_utils::{
errors::{get_current_ctx, ContextType, PtyContext},
input::{
command::TerminalAction,
- layout::{Layout, Run},
+ layout::{Layout, LayoutTemplate, Run, TabLayout},
},
logging::debug_to_file,
};
@@ -33,7 +33,7 @@ pub(crate) enum PtyInstruction {
SpawnTerminal(Option<TerminalAction>),
SpawnTerminalVertically(Option<TerminalAction>),
SpawnTerminalHorizontally(Option<TerminalAction>),
- NewTab(Option<TerminalAction>),
+ NewTab(Option<TerminalAction>, Option<TabLayout>),
ClosePane(PaneId),
CloseTab(Vec<PaneId>),
Exit,
@@ -47,7 +47,7 @@ impl From<&PtyInstruction> for PtyContext {
PtyInstruction::SpawnTerminalHorizontally(_) => PtyContext::SpawnTerminalHorizontally,
PtyInstruction::ClosePane(_) => PtyContext::ClosePane,
PtyInstruction::CloseTab(_) => PtyContext::CloseTab,
- PtyInstruction::NewTab(_) => PtyContext::NewTab,
+ PtyInstruction::NewTab(..) => PtyContext::NewTab,
PtyInstruction::Exit => PtyContext::Exit,
}
}
@@ -60,7 +60,7 @@ pub(crate) struct Pty {
task_handles: HashMap<RawFd, JoinHandle<()>>,
}
-pub(crate) fn pty_thread_main(mut pty: Pty, maybe_layout: Option<Layout>) {
+pub(crate) fn pty_thread_main(mut pty: Pty, maybe_layout: Option<LayoutTemplate>) {
loop {
let (event, mut err_ctx) = pty.bus.recv().expect("failed to receive event on channel");
err_ctx.add_call(ContextType::Pty((&event).into()));
@@ -86,11 +86,12 @@ pub(crate) fn pty_thread_main(mut pty: Pty, maybe_layout: Option<Layout>) {
.send_to_screen(ScreenInstruction::HorizontalSplit(PaneId::Terminal(pid)))
.unwrap();
}
- PtyInstruction::NewTab(terminal_action) => {
+ PtyInstruction::NewTab(terminal_action, tab_layout) => {
if let Some(layout) = maybe_layout.clone() {
- pty.spawn_terminals_for_layout(layout, terminal_action);
+ let merged_layout = layout.construct_tab_layout(tab_layout);
+ pty.spawn_terminals_for_layout(merged_layout, terminal_action.clone());
} else {
- let pid = pty.spawn_terminal(terminal_action);
+ let pid = pty.spawn_terminal(terminal_action.clone());
pty.bus
.senders
.send_to_screen(ScreenInstruction::NewTab(pid))
diff --git a/zellij-server/src/route.rs b/zellij-server/src/route.rs
index 54ddfe1b1..a88d04b09 100644
--- a/zellij-server/src/route.rs
+++ b/zellij-server/src/route.rs
@@ -197,11 +197,11 @@ fn route_action(
.send_to_screen(ScreenInstruction::CloseFocusedPane)
.unwrap();
}
- Action::NewTab => {
+ Action::NewTab(tab_layout) => {
let shell = session.default_shell.clone();
session
.senders
- .send_to_pty(PtyInstruction::NewTab(shell))
+ .send_to_pty(PtyInstruction::NewTab(shell, tab_layout))
.unwrap();
}
Action::GoToNextTab => {
diff --git a/zellij-utils/assets/config/default.yaml b/zellij-utils/assets/config/default.yaml
index 94f12f33c..42f2287b7 100644
--- a/zellij-utils/assets/config/default.yaml
+++ b/zellij-utils/assets/config/default.yaml
@@ -136,7 +136,7 @@ keybinds: