use std::ffi::OsString;
use super::{
Chainable, Effects, Op, Operation, Safety, Scope, SessionTarget, Slot, WindowSlot, WindowTarget,
};
use super::{Resolver, WINDOW_FORMAT};
use crate::Command;
use crate::window::assignment;
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct NewWindow {
pub(crate) target: SessionTarget,
#[cfg_attr(
feature = "serde",
serde(
serialize_with = "crate::plan::wire::optional_argument",
deserialize_with = "crate::plan::wire::parse_optional_argument"
)
)]
name: Option<OsString>,
#[cfg_attr(
feature = "serde",
serde(
serialize_with = "crate::plan::wire::optional_argument",
deserialize_with = "crate::plan::wire::parse_optional_argument"
)
)]
start_directory: Option<OsString>,
#[cfg_attr(
feature = "serde",
serde(
serialize_with = "crate::plan::wire::optional_argument",
deserialize_with = "crate::plan::wire::parse_optional_argument"
)
)]
command: Option<OsString>,
#[cfg_attr(
feature = "serde",
serde(
serialize_with = "crate::plan::wire::pairs",
deserialize_with = "crate::plan::wire::parse_pairs"
)
)]
environment: Vec<(OsString, OsString)>,
index: Option<u32>,
focus: bool,
}
impl NewWindow {
#[must_use]
pub fn new(target: impl Into<SessionTarget>) -> Self {
Self {
target: target.into(),
name: None,
start_directory: None,
command: None,
environment: Vec::new(),
index: None,
focus: false,
}
}
#[must_use]
pub const fn index(mut self, index: u32) -> Self {
self.index = Some(index);
self
}
#[must_use]
pub fn environment(mut self, name: impl Into<OsString>, value: impl Into<OsString>) -> Self {
self.environment.push((name.into(), value.into()));
self
}
#[must_use]
pub const fn focus(mut self) -> Self {
self.focus = true;
self
}
pub(crate) const fn focuses(&self) -> bool {
self.focus
}
#[must_use]
pub fn name(mut self, name: impl Into<OsString>) -> Self {
self.name = Some(name.into());
self
}
#[must_use]
pub fn start_directory(mut self, directory: impl Into<OsString>) -> Self {
self.start_directory = Some(directory.into());
self
}
#[must_use]
pub fn command(mut self, command: impl Into<OsString>) -> Self {
self.command = Some(command.into());
self
}
pub(crate) fn render(&self, resolve: Resolver<'_>) -> Option<Command> {
let mut token = self.target.token(resolve)?;
token.push(":");
if let Some(index) = self.index {
token.push(index.to_string());
}
let mut command = Command::new("new-window")
.arg("-P")
.arg("-F")
.arg(WINDOW_FORMAT)
.arg("-t")
.arg(token);
if !self.focus {
command = command.arg("-d");
}
if let Some(name) = &self.name {
command = command.arg("-n").arg(name.clone());
}
if let Some(directory) = &self.start_directory {
command = command.arg("-c").arg(directory.clone());
}
for (name, value) in &self.environment {
command = command.arg("-e").arg(assignment(name, value));
}
if let Some(shell_command) = &self.command {
command = command.arg(shell_command.clone());
}
Some(command)
}
}
operation!(
NewWindow,
creates = Slot<WindowSlot>,
effects = Effects {
creates: Some(Scope::Window),
..Effects::MUTATING
},
safety = Safety::Mutating
);
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SelectWindow {
pub(crate) target: WindowTarget,
}
impl SelectWindow {
#[must_use]
pub fn new(target: impl Into<WindowTarget>) -> Self {
Self {
target: target.into(),
}
}
pub(crate) fn render(&self, resolve: Resolver<'_>) -> Option<Command> {
Some(
Command::new("select-window")
.arg("-t")
.arg(self.target.token(resolve)?),
)
}
}
operation!(
SelectWindow,
creates = (),
effects = Effects {
idempotent: true,
..Effects::MUTATING
},
safety = Safety::Mutating,
chainable
);
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct RenameWindow {
pub(crate) target: WindowTarget,
#[cfg_attr(
feature = "serde",
serde(
serialize_with = "crate::plan::wire::argument",
deserialize_with = "crate::plan::wire::parse_argument"
)
)]
name: OsString,
}
impl RenameWindow {
#[must_use]
pub fn new(target: impl Into<WindowTarget>, name: impl Into<OsString>) -> Self {
Self {
target: target.into(),
name: name.into(),
}
}
pub(crate) fn render(&self, resolve: Resolver<'_>) -> Option<Command> {
Some(
Command::new("rename-window")
.arg("-t")
.arg(self.target.token(resolve)?)
.arg("--")
.arg(self.name.clone()),
)
}
}
operation!(
RenameWindow,
creates = (),
effects = Effects {
idempotent: true,
..Effects::MUTATING
},
safety = Safety::Mutating,
chainable
);
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct KillWindow {
pub(crate) target: WindowTarget,
}
impl KillWindow {
#[must_use]
pub fn new(target: impl Into<WindowTarget>) -> Self {
Self {
target: target.into(),
}
}
pub(crate) fn render(&self, resolve: Resolver<'_>) -> Option<Command> {
Some(
Command::new("kill-window")
.arg("-t")
.arg(self.target.token(resolve)?),
)
}
}
operation!(
KillWindow,
creates = (),
effects = Effects {
destructive: true,
..Effects::MUTATING
},
safety = Safety::Destructive,
chainable
);
#[derive(Clone, Debug)]
#[cfg_attr(feature = "serde", derive(serde::Serialize, serde::Deserialize))]
pub struct SelectLayout {
pub(crate) target: WindowTarget,
#[cfg_attr(
feature = "serde",
serde(
serialize_with = "crate::plan::wire::argument",
deserialize_with = "crate::plan::wire::parse_argument"
)
)]
layout: OsString,
}
impl SelectLayout {
#[must_use]
pub fn new(target: impl Into<WindowTarget>, layout: impl Into<OsString>) -> Self {
Self {
target: target.into(),
layout: layout.into(),
}
}
pub(crate) fn render(&self, resolve: Resolver<'_>) -> Option<Command> {
Some(
Command::new("select-layout")
.arg("-t")
.arg(self.target.token(resolve)?)
.arg("--")
.arg(self.layout.clone()),
)
}
}
operation!(
SelectLayout,
creates = (),
effects = Effects {
idempotent: true,
..Effects::MUTATING
},
safety = Safety::Mutating,
chainable
);