Skip to content

Commit

Permalink
feat(layout): specify only tab name in tabs section (#722)
Browse files Browse the repository at this point in the history
Allow specifying only the tab name in the `tabs` section

- For example this is now possible:
```
tabs:
  - name: first
    parts:
      - direction: Vertical
      - direction: Vertical
  - name: second
  - name: third
```
  For that the tab section defaults the direction to
  `direction::Horizontal`

- Adds an error upon specifying a tab name inside the `parts` section
  of the tab-layout
  • Loading branch information
a-kenji committed Sep 21, 2021
1 parent 71b600b commit bbe2583
Show file tree
Hide file tree
Showing 2 changed files with 47 additions and 69 deletions.
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

0 comments on commit bbe2583

Please sign in to comment.