Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat(layout): specify only tab name in tabs section #722

Merged
merged 1 commit into from Sep 21, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
85 changes: 18 additions & 67 deletions zellij-utils/src/input/config.rs
Expand Up @@ -45,9 +45,8 @@ pub enum ConfigError {
IoPath(io::Error, PathBuf),
// Internal Deserialization Error
FromUtf8(std::string::FromUtf8Error),
// Missing the tab section in the layout.
Layout(LayoutMissingTabSectionError),
LayoutPartAndTab(LayoutPartAndTabError),
// Naming a part in a tab is unsupported
LayoutNameInTab(LayoutNameInTabError),
}

impl Default for Config {
Expand Down Expand Up @@ -139,70 +138,32 @@ impl Config {

// TODO: Split errors up into separate modules
#[derive(Debug, Clone)]
pub struct LayoutMissingTabSectionError;
#[derive(Debug, Clone)]
pub struct LayoutPartAndTabError;

impl fmt::Display for LayoutMissingTabSectionError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"MissingTabSectionError:
There needs to be exactly one `tabs` section specified in the layout file, for example:
---
direction: Horizontal
parts:
- direction: Vertical
- direction: Vertical
tabs:
- direction: Vertical
- direction: Vertical
- direction: Vertical
"
)
}
}

impl std::error::Error for LayoutMissingTabSectionError {
fn description(&self) -> &str {
"One tab must be specified per Layout."
}
}
pub struct LayoutNameInTabError;

impl fmt::Display for LayoutPartAndTabError {
impl fmt::Display for LayoutNameInTabError {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
write!(
f,
"LayoutPartAndTabError:
The `tabs` and `parts` section should not be specified on the same level in the layout file, for example:
"LayoutNameInTabError:
The `parts` inside the `tabs` can't be named. For example:
---
direction: Horizontal
parts:
- direction: Vertical
- direction: Vertical
tabs:
- direction: Vertical
- direction: Vertical
- direction: Vertical

should rather be specified as:
---
direction: Horizontal
parts:
- direction: Vertical
- direction: Vertical
tabs:
- direction: Vertical
name: main
parts:
- direction: Vertical
name: section # <== The part section can't be named.
- direction: Vertical
- direction: Vertical
name: test
"
)
}
}

impl std::error::Error for LayoutPartAndTabError {
impl std::error::Error for LayoutNameInTabError {
fn description(&self) -> &str {
"The `tabs` and parts section should not be specified on the same level."
"The `parts` inside the `tabs` can't be named."
}
}

Expand All @@ -215,10 +176,7 @@ impl Display for ConfigError {
}
ConfigError::Serde(ref err) => write!(formatter, "Deserialization error: {}", err),
ConfigError::FromUtf8(ref err) => write!(formatter, "FromUtf8Error: {}", err),
ConfigError::Layout(ref err) => {
write!(formatter, "There was an error in the layout file, {}", err)
}
ConfigError::LayoutPartAndTab(ref err) => {
ConfigError::LayoutNameInTab(ref err) => {
write!(formatter, "There was an error in the layout file, {}", err)
}
}
Expand All @@ -232,8 +190,7 @@ impl std::error::Error for ConfigError {
ConfigError::IoPath(ref err, _) => Some(err),
ConfigError::Serde(ref err) => Some(err),
ConfigError::FromUtf8(ref err) => Some(err),
ConfigError::Layout(ref err) => Some(err),
ConfigError::LayoutPartAndTab(ref err) => Some(err),
ConfigError::LayoutNameInTab(ref err) => Some(err),
}
}
}
Expand All @@ -256,15 +213,9 @@ impl From<std::string::FromUtf8Error> for ConfigError {
}
}

impl From<LayoutMissingTabSectionError> for ConfigError {
fn from(err: LayoutMissingTabSectionError) -> ConfigError {
ConfigError::Layout(err)
}
}

impl From<LayoutPartAndTabError> for ConfigError {
fn from(err: LayoutPartAndTabError) -> ConfigError {
ConfigError::LayoutPartAndTab(err)
impl From<LayoutNameInTabError> for ConfigError {
fn from(err: LayoutNameInTabError) -> ConfigError {
ConfigError::LayoutNameInTab(err)
}
}

Expand Down
31 changes: 29 additions & 2 deletions zellij-utils/src/input/layout.rs
Expand Up @@ -9,7 +9,10 @@
// 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},
input::{
command::RunCommand,
config::{ConfigError, LayoutNameInTabError},
},
pane_size::{Dimension, PaneGeom},
setup,
};
Expand Down Expand Up @@ -106,7 +109,12 @@ impl LayoutFromYaml {
let layout: Option<LayoutFromYaml> = serde_yaml::from_str(&layout)?;

match layout {
Some(layout) => Ok(layout),
Some(layout) => {
for tab in layout.tabs.clone() {
tab.check()?;
}
Ok(layout)
}
None => Ok(LayoutFromYaml::default()),
}
}
Expand Down Expand Up @@ -220,6 +228,7 @@ impl LayoutTemplate {
#[derive(Debug, Serialize, Deserialize, Clone, PartialEq)]
#[serde(crate = "self::serde")]
pub struct TabLayout {
#[serde(default)]
pub direction: Direction,
#[serde(default)]
pub borderless: bool,
Expand All @@ -231,6 +240,18 @@ pub struct TabLayout {
pub name: String,
}

impl TabLayout {
fn check(&self) -> Result<TabLayout, ConfigError> {
for part in self.parts.iter() {
part.check()?;
if !part.name.is_empty() {
return Err(ConfigError::LayoutNameInTab(LayoutNameInTabError));
}
}
Ok(self.clone())
}
}

impl Layout {
pub fn total_terminal_panes(&self) -> usize {
let mut total_panes = 0;
Expand Down Expand Up @@ -467,6 +488,12 @@ impl Default for LayoutFromYaml {
}
}

impl Default for Direction {
fn default() -> Self {
Direction::Horizontal
}
}

// The unit test location.
#[cfg(test)]
#[path = "./unit/layout_test.rs"]
Expand Down