//! The layout system.
// Layouts have been moved from [`zellij-server`] to
// [`zellij-utils`] in order to provide more helpful
// error messages to the user until a more general
// logging system is in place.
// In case there is a logging system in place evaluate,
// if [`zellij-utils`], or [`zellij-server`] is a proper
// place.
// If plugins should be able to depend on the layout system
// then [`zellij-utils`] could be a proper place.
use crate::{
input::{
command::RunCommand,
config::{ConfigError, LayoutNameInTabError},
},
pane_size::{Dimension, PaneGeom},
setup,
};
use crate::{serde, serde_yaml};
use super::{
config::ConfigFromYaml,
plugins::{PluginTag, PluginsConfigError},
};
use serde::{Deserialize, Serialize};
use std::convert::{TryFrom, TryInto};
use std::vec::Vec;
use std::{
cmp::max,
fmt, fs,
ops::Not,
path::{Path, PathBuf},
};
use std::{fs::File, io::prelude::*};
use url::Url;
#[derive(Debug, PartialEq, Eq, Serialize, Deserialize, Clone, Copy)]
#[serde(crate = "self::serde")]
pub enum Direction {
Horizontal,
Vertical,
}
impl Not for Direction {
type Output = Self;
fn not(self) -> Self::Output {
match self {
Direction::Horizontal => Direction::Vertical,
Direction::Vertical => Direction::Horizontal,
}
}
}
#[derive(Debug, Serialize, Deserialize, Clone, Copy, PartialEq)]
#[serde(crate = "self::serde")]
pub enum SplitSize {
Percent(f64), // 1 to 100
Fixed(usize), // An absolute number of columns or rows
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(crate = "self::serde")]
pub enum Run {
#[serde(rename = "plugin")]
Plugin(RunPlugin),
#[serde(rename = "command")]
Command(RunCommand),
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(crate = "self::serde")]
pub enum RunFromYaml {
#[serde(rename = "plugin")]
Plugin(RunPluginFromYaml),
#[serde(rename = "command")]
Command(RunCommand),
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(crate = "self::serde")]
pub struct RunPluginFromYaml {
#[serde(default)]
pub _allow_exec_host_cmd: bool,
pub location: Url,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(crate = "self::serde")]
pub struct RunPlugin {
#[serde(default)]
pub _allow_exec_host_cmd: bool,
pub location: RunPluginLocation,
}
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq, Eq)]
#[serde(crate = "self::serde")]
pub enum RunPluginLocation {
File(PathBuf),
Zellij(PluginTag),
}
impl From<&RunPluginLocation> for Url {
fn from(location: &RunPluginLocation) -> Self {
let url = match location {
RunPluginLocation::File(path) => format!(
"file:{}",
path.clone().into_os_string().into_string().unwrap()
),
RunPluginLocation::Zellij(tag) => format!("zellij:{}", tag),
};
Self::parse(&url).unwrap()
}
}
impl fmt::Display for RunPluginLocation {
fn fmt(&self, f: &mut fmt::Formatter<'_>) -> Result<<