Merge pull request #600 from a-kenji/layout-command

Add commands to layout
This commit is contained in:
a-kenji 2021-07-09 16:58:29 +02:00 committed by GitHub
commit 0ab00e2c6c
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
9 changed files with 142 additions and 32 deletions

View File

@ -0,0 +1,20 @@
---
direction: Vertical
parts:
- direction: Horizontal
split_size:
Percent: 50
parts:
- direction: Vertical
split_size:
Percent: 50
- direction: Vertical
split_size:
Percent: 50
run:
command: {cmd: htop}
- direction: Horizontal
split_size:
Percent: 50
run:
command: {cmd: htop}

View File

@ -0,0 +1,30 @@
---
direction: Horizontal
parts:
- direction: Vertical
split_size:
Fixed: 1
run:
plugin: tab-bar
- direction: Vertical
parts:
- direction: Vertical
parts:
- direction: Vertical
split_size:
Percent: 50
run:
command: {cmd: htop}
- direction: Vertical
split_size:
Percent: 50
run:
command: {cmd: htop, args: ["-C"]}
- direction: Vertical
split_size:
Fixed: 5
- direction: Vertical
split_size:
Fixed: 2
run:
plugin: status-bar

View File

@ -1,11 +1,3 @@
use zellij_utils::async_std;
use async_std::future::timeout as async_timeout;
use async_std::task::{self, JoinHandle};
use std::collections::HashMap;
use std::os::unix::io::RawFd;
use std::time::{Duration, Instant};
use crate::{ use crate::{
os_input_output::{AsyncReader, Pid, ServerOsApi}, os_input_output::{AsyncReader, Pid, ServerOsApi},
panes::PaneId, panes::PaneId,
@ -14,9 +6,22 @@ use crate::{
wasm_vm::PluginInstruction, wasm_vm::PluginInstruction,
ServerInstruction, ServerInstruction,
}; };
use async_std::{
future::timeout as async_timeout,
task::{self, JoinHandle},
};
use std::{
collections::HashMap,
os::unix::io::RawFd,
time::{Duration, Instant},
};
use zellij_utils::{ use zellij_utils::{
async_std,
errors::{get_current_ctx, ContextType, PtyContext}, errors::{get_current_ctx, ContextType, PtyContext},
input::{command::TerminalAction, layout::Layout}, input::{
command::TerminalAction,
layout::{Layout, Run},
},
logging::debug_to_file, logging::debug_to_file,
}; };
@ -236,19 +241,36 @@ impl Pty {
pub fn spawn_terminals_for_layout( pub fn spawn_terminals_for_layout(
&mut self, &mut self,
layout: Layout, layout: Layout,
terminal_action: Option<TerminalAction>, default_shell: Option<TerminalAction>,
) { ) {
let total_panes = layout.total_terminal_panes(); let extracted_run_instructions = layout.extract_run_instructions();
let mut new_pane_pids = vec![]; let mut new_pane_pids = vec![];
for _ in 0..total_panes { for run_instruction in extracted_run_instructions {
let (pid_primary, pid_secondary): (RawFd, Pid) = self match run_instruction {
.bus Some(Run::Command(command)) => {
.os_input let cmd = TerminalAction::RunCommand(command);
.as_mut() let (pid_primary, pid_secondary): (RawFd, Pid) = self
.unwrap() .bus
.spawn_terminal(terminal_action.clone()); .os_input
self.id_to_child_pid.insert(pid_primary, pid_secondary); .as_mut()
new_pane_pids.push(pid_primary); .unwrap()
.spawn_terminal(Some(cmd));
self.id_to_child_pid.insert(pid_primary, pid_secondary);
new_pane_pids.push(pid_primary);
}
None => {
let (pid_primary, pid_secondary): (RawFd, Pid) = self
.bus
.os_input
.as_mut()
.unwrap()
.spawn_terminal(default_shell.clone());
self.id_to_child_pid.insert(pid_primary, pid_secondary);
new_pane_pids.push(pid_primary);
}
// Investigate moving plugin loading to here.
Some(Run::Plugin(_)) => {}
}
} }
self.bus self.bus
.senders .senders

View File

@ -26,7 +26,10 @@ use std::{
}; };
use zellij_tile::data::{Event, InputMode, ModeInfo, Palette}; use zellij_tile::data::{Event, InputMode, ModeInfo, Palette};
use zellij_utils::{ use zellij_utils::{
input::{layout::Layout, parse_keys}, input::{
layout::{Layout, Run},
parse_keys,
},
pane_size::PositionAndSize, pane_size::PositionAndSize,
shared::adjust_to_size, shared::adjust_to_size,
}; };
@ -338,7 +341,7 @@ impl Tab {
let mut new_pids = new_pids.iter(); let mut new_pids = new_pids.iter();
for (layout, position_and_size) in positions_and_size { for (layout, position_and_size) in positions_and_size {
// A plugin pane // A plugin pane
if let Some(plugin) = &layout.plugin { if let Some(Run::Plugin(Some(plugin))) = &layout.run {
let (pid_tx, pid_rx) = channel(); let (pid_tx, pid_rx) = channel();
self.senders self.senders
.send_to_plugin(PluginInstruction::Load(pid_tx, plugin.clone())) .send_to_plugin(PluginInstruction::Load(pid_tx, plugin.clone()))

View File

@ -4,9 +4,11 @@ parts:
- direction: Vertical - direction: Vertical
split_size: split_size:
Fixed: 1 Fixed: 1
plugin: tab-bar run:
plugin: tab-bar
- direction: Vertical - direction: Vertical
- direction: Vertical - direction: Vertical
split_size: split_size:
Fixed: 2 Fixed: 2
plugin: status-bar run:
plugin: status-bar

View File

@ -4,5 +4,6 @@ parts:
- direction: Vertical - direction: Vertical
split_size: split_size:
Fixed: 1 Fixed: 1
plugin: tab-bar run:
plugin: tab-bar
- direction: Vertical - direction: Vertical

View File

@ -4,15 +4,18 @@ parts:
- direction: Vertical - direction: Vertical
split_size: split_size:
Fixed: 1 Fixed: 1
plugin: tab-bar run:
plugin: tab-bar
- direction: Vertical - direction: Vertical
parts: parts:
- direction: Horizontal - direction: Horizontal
split_size: split_size:
Percent: 20 Percent: 20
plugin: strider run:
plugin: strider
- direction: Horizontal - direction: Horizontal
- direction: Vertical - direction: Vertical
split_size: split_size:
Fixed: 2 Fixed: 2
plugin: status-bar run:
plugin: status-bar

View File

@ -11,6 +11,7 @@ pub enum TerminalAction {
#[derive(Clone, Debug, Deserialize, Default, Serialize, PartialEq, Eq)] #[derive(Clone, Debug, Deserialize, Default, Serialize, PartialEq, Eq)]
pub struct RunCommand { pub struct RunCommand {
#[serde(alias = "cmd")]
pub command: PathBuf, pub command: PathBuf,
#[serde(default)] #[serde(default)]
pub args: Vec<String>, pub args: Vec<String>,

View File

@ -8,7 +8,11 @@
// place. // place.
// If plugins should be able to depend on the layout system // If plugins should be able to depend on the layout system
// then [`zellij-utils`] could be a proper place. // then [`zellij-utils`] could be a proper place.
use crate::{input::config::ConfigError, pane_size::PositionAndSize, setup}; use crate::{
input::{command::RunCommand, config::ConfigError},
pane_size::PositionAndSize,
setup,
};
use crate::{serde, serde_yaml}; use crate::{serde, serde_yaml};
use serde::{Deserialize, Serialize}; use serde::{Deserialize, Serialize};
@ -29,6 +33,15 @@ pub enum SplitSize {
Fixed(u16), // An absolute number of columns or rows Fixed(u16), // An absolute number of columns or rows
} }
#[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(crate = "self::serde")]
pub enum Run {
#[serde(rename = "plugin")]
Plugin(Option<PathBuf>),
#[serde(rename = "command")]
Command(RunCommand),
}
#[derive(Debug, Serialize, Deserialize, Clone)] #[derive(Debug, Serialize, Deserialize, Clone)]
#[serde(crate = "self::serde")] #[serde(crate = "self::serde")]
pub struct Layout { pub struct Layout {
@ -36,7 +49,7 @@ pub struct Layout {
#[serde(default)] #[serde(default)]
pub parts: Vec<Layout>, pub parts: Vec<Layout>,
pub split_size: Option<SplitSize>, pub split_size: Option<SplitSize>,
pub plugin: Option<PathBuf>, pub run: Option<Run>,
} }
type LayoutResult = Result<Layout, ConfigError>; type LayoutResult = Result<Layout, ConfigError>;
@ -127,13 +140,28 @@ impl Layout {
let mut total_panes = 0; let mut total_panes = 0;
total_panes += self.parts.len(); total_panes += self.parts.len();
for part in self.parts.iter() { for part in self.parts.iter() {
if part.plugin.is_none() { match part.run {
total_panes += part.total_terminal_panes(); Some(Run::Command(_)) | None => {
total_panes += part.total_terminal_panes();
}
Some(Run::Plugin(_)) => {}
} }
} }
total_panes total_panes
} }
pub fn extract_run_instructions(&self) -> Vec<Option<Run>> {
let mut run_instructions = vec![];
if self.parts.is_empty() {
run_instructions.push(self.run.clone());
}
for part in self.parts.iter() {
let mut current_runnables = part.extract_run_instructions();
run_instructions.append(&mut current_runnables);
}
run_instructions
}
pub fn position_panes_in_space( pub fn position_panes_in_space(
&self, &self,
space: &PositionAndSize, space: &PositionAndSize,