use serde::{Deserialize, Serialize};
use std::path::PathBuf;
use crate::{
ControlModeRequest, HandshakeRequest, PaneTarget, SdkWaitId, SdkWaitOwnerId, SessionName,
Target, WindowTarget,
};
#[path = "request/show.rs"]
mod show;
pub use show::ShowHooksRequest;
pub use show::{ShowEnvironmentRequest, ShowOptionsRequest};
#[path = "request/layout.rs"]
mod layout;
pub use layout::{
NextLayoutRequest, PreviousLayoutRequest, SelectCustomLayoutRequest, SelectLayoutRequest,
SelectLayoutTarget, SelectOldLayoutRequest, SpreadLayoutRequest,
};
#[path = "request/pane.rs"]
mod pane;
pub use pane::{
BreakPaneRequest, DisplayPanesRequest, JoinPaneRequest, KillPaneRequest, LastPaneRequest,
MovePaneRequest, PaneOutputCursorRequest, PaneOutputSubscriptionStart, PaneSnapshotRequest,
PaneSplitSize, PipePaneRequest, ResizePaneRequest, RespawnPaneRequest,
SelectPaneAdjacentRequest, SelectPaneDirection, SelectPaneMarkRequest, SelectPaneRequest,
SendKeysExtRequest, SendKeysRequest, SplitWindowExtRequest, SplitWindowRequest,
SplitWindowTarget, SubscribePaneOutputRequest, SwapPaneDirection, SwapPaneRequest,
UnsubscribePaneOutputRequest,
};
#[path = "request/window.rs"]
mod window;
pub use window::{
KillWindowRequest, LastWindowRequest, LinkWindowRequest, ListWindowsRequest, MoveWindowRequest,
MoveWindowTarget, NewWindowRequest, NextWindowRequest, PreviousWindowRequest,
RenameWindowRequest, ResizeWindowAdjustment, ResizeWindowRequest, RespawnWindowRequest,
RotateWindowDirection, RotateWindowRequest, SelectWindowRequest, SwapWindowRequest,
};
#[path = "request/target.rs"]
mod target;
pub use target::{ResolveTargetRequest, ResolveTargetType};
#[path = "request/session.rs"]
mod session;
pub use session::{
HasSessionRequest, KillSessionRequest, ListSessionsRequest, NewSessionExtRequest,
NewSessionRequest, RenameSessionRequest,
};
#[path = "request/server.rs"]
mod server;
pub use server::{
KillServerRequest, LockClientRequest, LockServerRequest, LockSessionRequest,
ServerAccessRequest,
};
#[path = "request/client.rs"]
mod client;
pub use client::{
AttachSessionExt2Request, AttachSessionExtRequest, AttachSessionRequest,
DetachClientExtRequest, DetachClientRequest, ListClientsRequest, RefreshClientRequest,
SuspendClientRequest, SwitchClientExt2Request, SwitchClientExt3Request, SwitchClientExtRequest,
SwitchClientRequest,
};
#[path = "request/keys.rs"]
mod keys;
pub use keys::{
BindKeyRequest, ClockModeRequest, CopyModeRequest, ListKeysRequest, SendPrefixRequest,
UnbindKeyRequest,
};
#[path = "request/options.rs"]
mod options;
pub use options::{
SetEnvironmentMode, SetEnvironmentRequest, SetHookMutationRequest, SetHookRequest,
SetOptionByNameRequest, SetOptionRequest,
};
#[path = "request/buffer.rs"]
mod buffer;
pub use buffer::{
CapturePaneRequest, ClearHistoryRequest, DeleteBufferRequest, ListBuffersRequest,
LoadBufferRequest, PasteBufferRequest, SaveBufferRequest, SetBufferRequest, ShowBufferRequest,
};
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub enum Request {
NewSession(NewSessionRequest),
HasSession(HasSessionRequest),
KillSession(KillSessionRequest),
NewWindow(NewWindowRequest),
KillWindow(KillWindowRequest),
SelectWindow(SelectWindowRequest),
RenameWindow(RenameWindowRequest),
NextWindow(NextWindowRequest),
PreviousWindow(PreviousWindowRequest),
LastWindow(LastWindowRequest),
ListWindows(ListWindowsRequest),
MoveWindow(MoveWindowRequest),
SwapWindow(SwapWindowRequest),
RotateWindow(RotateWindowRequest),
SplitWindow(SplitWindowRequest),
SwapPane(SwapPaneRequest),
LastPane(LastPaneRequest),
JoinPane(JoinPaneRequest),
BreakPane(BreakPaneRequest),
KillPane(KillPaneRequest),
SelectLayout(SelectLayoutRequest),
ResizePane(ResizePaneRequest),
DisplayPanes(DisplayPanesRequest),
SelectPane(SelectPaneRequest),
SelectPaneAdjacent(SelectPaneAdjacentRequest),
SendKeys(SendKeysRequest),
AttachSession(AttachSessionRequest),
SwitchClient(SwitchClientRequest),
DetachClient(DetachClientRequest),
SetOption(SetOptionRequest),
SetEnvironment(SetEnvironmentRequest),
SetHook(SetHookRequest),
NextLayout(NextLayoutRequest),
PreviousLayout(PreviousLayoutRequest),
ShowOptions(ShowOptionsRequest),
ShowEnvironment(ShowEnvironmentRequest),
SetBuffer(SetBufferRequest),
ShowBuffer(ShowBufferRequest),
PasteBuffer(PasteBufferRequest),
ListBuffers(ListBuffersRequest),
DeleteBuffer(DeleteBufferRequest),
LoadBuffer(LoadBufferRequest),
SaveBuffer(SaveBufferRequest),
CapturePane(CapturePaneRequest),
DisplayMessage(DisplayMessageRequest),
RunShell(RunShellRequest),
IfShell(IfShellRequest),
WaitFor(WaitForRequest),
RenameSession(RenameSessionRequest),
ListSessions(ListSessionsRequest),
ListPanes(ListPanesRequest),
SourceFile(SourceFileRequest),
SetOptionByName(SetOptionByNameRequest),
SetHookMutation(SetHookMutationRequest),
ShowHooks(ShowHooksRequest),
SendKeysExt(SendKeysExtRequest),
SwitchClientExt(SwitchClientExtRequest),
BindKey(BindKeyRequest),
UnbindKey(UnbindKeyRequest),
ListKeys(ListKeysRequest),
SendPrefix(SendPrefixRequest),
ClearHistory(ClearHistoryRequest),
CopyMode(CopyModeRequest),
ControlMode(ControlModeRequest),
ClockMode(ClockModeRequest),
ShowMessages(ShowMessagesRequest),
NewSessionExt(NewSessionExtRequest),
AttachSessionExt(AttachSessionExtRequest),
SwitchClientExt2(SwitchClientExt2Request),
SelectCustomLayout(SelectCustomLayoutRequest),
SelectOldLayout(SelectOldLayoutRequest),
SpreadLayout(SpreadLayoutRequest),
KillServer(KillServerRequest),
LockServer(LockServerRequest),
LockSession(LockSessionRequest),
LockClient(LockClientRequest),
ServerAccess(ServerAccessRequest),
RefreshClient(RefreshClientRequest),
ListClients(ListClientsRequest),
SuspendClient(SuspendClientRequest),
DetachClientExt(DetachClientExtRequest),
AttachSessionExt2(AttachSessionExt2Request),
SwitchClientExt3(SwitchClientExt3Request),
ResizeWindow(ResizeWindowRequest),
RespawnWindow(RespawnWindowRequest),
MovePane(MovePaneRequest),
PipePane(PipePaneRequest),
RespawnPane(RespawnPaneRequest),
LinkWindow(LinkWindowRequest),
UnlinkWindow(UnlinkWindowRequest),
SelectPaneMark(SelectPaneMarkRequest),
ResolveTarget(ResolveTargetRequest),
SplitWindowExt(SplitWindowExtRequest),
Handshake(HandshakeRequest),
PaneSnapshot(PaneSnapshotRequest),
SubscribePaneOutput(SubscribePaneOutputRequest),
UnsubscribePaneOutput(UnsubscribePaneOutputRequest),
PaneOutputCursor(PaneOutputCursorRequest),
SdkWaitForOutput(SdkWaitForOutputRequest),
CancelSdkWait(CancelSdkWaitRequest),
}
impl Request {
#[must_use]
pub const fn command_name(&self) -> &'static str {
match self {
Self::NewSession(_) => "new-session",
Self::HasSession(_) => "has-session",
Self::KillSession(_) => "kill-session",
Self::NewWindow(_) => "new-window",
Self::KillWindow(_) => "kill-window",
Self::SelectWindow(_) => "select-window",
Self::RenameWindow(_) => "rename-window",
Self::NextWindow(_) => "next-window",
Self::PreviousWindow(_) => "previous-window",
Self::LastWindow(_) => "last-window",
Self::ListWindows(_) => "list-windows",
Self::LinkWindow(_) => "link-window",
Self::MoveWindow(_) => "move-window",
Self::SwapWindow(_) => "swap-window",
Self::RotateWindow(_) => "rotate-window",
Self::SplitWindow(_) | Self::SplitWindowExt(_) => "split-window",
Self::SwapPane(_) => "swap-pane",
Self::LastPane(_) => "last-pane",
Self::JoinPane(_) => "join-pane",
Self::BreakPane(_) => "break-pane",
Self::KillPane(_) => "kill-pane",
Self::SelectLayout(_) => "select-layout",
Self::ResizePane(_) => "resize-pane",
Self::DisplayPanes(_) => "display-panes",
Self::SelectPane(_) | Self::SelectPaneAdjacent(_) | Self::SelectPaneMark(_) => {
"select-pane"
}
Self::SendKeys(_) => "send-keys",
Self::AttachSession(_) => "attach-session",
Self::SwitchClient(_) => "switch-client",
Self::DetachClient(_) => "detach-client",
Self::SetOption(_) => "set-option",
Self::SetEnvironment(_) => "set-environment",
Self::SetHook(_) => "set-hook",
Self::NextLayout(_) => "next-layout",
Self::PreviousLayout(_) => "previous-layout",
Self::ShowOptions(_) => "show-options",
Self::ShowEnvironment(_) => "show-environment",
Self::SetBuffer(_) => "set-buffer",
Self::ShowBuffer(_) => "show-buffer",
Self::PasteBuffer(_) => "paste-buffer",
Self::ListBuffers(_) => "list-buffers",
Self::DeleteBuffer(_) => "delete-buffer",
Self::LoadBuffer(_) => "load-buffer",
Self::SaveBuffer(_) => "save-buffer",
Self::CapturePane(_) => "capture-pane",
Self::PaneSnapshot(_) => "pane-snapshot",
Self::SubscribePaneOutput(_) => "subscribe-pane-output",
Self::UnsubscribePaneOutput(_) => "unsubscribe-pane-output",
Self::PaneOutputCursor(_) => "pane-output-cursor",
Self::SdkWaitForOutput(_) => "sdk-wait-output",
Self::CancelSdkWait(_) => "cancel-sdk-wait",
Self::DisplayMessage(_) => "display-message",
Self::ResolveTarget(_) => "resolve-target",
Self::RunShell(_) => "run-shell",
Self::IfShell(_) => "if-shell",
Self::WaitFor(_) => "wait-for",
Self::RenameSession(_) => "rename-session",
Self::ListSessions(_) => "list-sessions",
Self::ListPanes(_) => "list-panes",
Self::SourceFile(_) => "source-file",
Self::UnlinkWindow(_) => "unlink-window",
Self::SetOptionByName(_) => "set-option",
Self::SetHookMutation(_) => "set-hook",
Self::ShowHooks(_) => "show-hooks",
Self::SendKeysExt(_) => "send-keys",
Self::SwitchClientExt(_) => "switch-client",
Self::BindKey(_) => "bind-key",
Self::UnbindKey(_) => "unbind-key",
Self::ListKeys(_) => "list-keys",
Self::SendPrefix(_) => "send-prefix",
Self::ClearHistory(_) => "clear-history",
Self::CopyMode(_) => "copy-mode",
Self::ControlMode(_) => "control-mode",
Self::ClockMode(_) => "clock-mode",
Self::ShowMessages(_) => "show-messages",
Self::NewSessionExt(_) => "new-session",
Self::AttachSessionExt(_) => "attach-session",
Self::SwitchClientExt2(_) => "switch-client",
Self::SelectCustomLayout(_) => "select-layout",
Self::SelectOldLayout(_) => "select-layout",
Self::SpreadLayout(_) => "select-layout",
Self::ResizeWindow(_) => "resize-window",
Self::RespawnWindow(_) => "respawn-window",
Self::MovePane(_) => "move-pane",
Self::PipePane(_) => "pipe-pane",
Self::RespawnPane(_) => "respawn-pane",
Self::KillServer(_) => "kill-server",
Self::LockServer(_) => "lock-server",
Self::LockSession(_) => "lock-session",
Self::LockClient(_) => "lock-client",
Self::ServerAccess(_) => "server-access",
Self::RefreshClient(_) => "refresh-client",
Self::ListClients(_) => "list-clients",
Self::SuspendClient(_) => "suspend-client",
Self::DetachClientExt(_) => "detach-client",
Self::AttachSessionExt2(_) => "attach-session",
Self::SwitchClientExt3(_) => "switch-client",
Self::Handshake(_) => "handshake",
}
}
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct DisplayMessageRequest {
pub target: Option<Target>,
pub print: bool,
pub message: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ShowMessagesRequest {
pub jobs: bool,
pub terminals: bool,
pub target_client: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct RunShellRequest {
pub command: String,
pub background: bool,
#[serde(default)]
pub as_commands: bool,
#[serde(default)]
pub show_stderr: bool,
#[serde(default)]
pub delay_seconds: Option<RunShellDelaySeconds>,
#[serde(default)]
pub start_directory: Option<PathBuf>,
#[serde(default)]
pub target: Option<PaneTarget>,
}
#[derive(Debug, Clone, Copy, Serialize, Deserialize)]
pub struct RunShellDelaySeconds(pub f64);
impl RunShellDelaySeconds {
#[must_use]
pub const fn as_secs_f64(self) -> f64 {
self.0
}
}
impl PartialEq for RunShellDelaySeconds {
fn eq(&self, other: &Self) -> bool {
self.0.to_bits() == other.0.to_bits()
}
}
impl Eq for RunShellDelaySeconds {}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct IfShellRequest {
pub condition: String,
pub format_mode: bool,
pub then_command: String,
pub else_command: Option<String>,
pub target: Option<Target>,
pub caller_cwd: Option<PathBuf>,
#[serde(default)]
pub background: bool,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SourceFileRequest {
pub paths: Vec<String>,
pub quiet: bool,
pub parse_only: bool,
pub verbose: bool,
pub expand_paths: bool,
pub target: Option<PaneTarget>,
pub caller_cwd: Option<PathBuf>,
pub stdin: Option<String>,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct UnlinkWindowRequest {
pub target: WindowTarget,
#[serde(default)]
pub kill_if_last: bool,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub enum WaitForMode {
Wait,
Signal,
Lock,
Unlock,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct WaitForRequest {
pub channel: String,
pub mode: WaitForMode,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct SdkWaitForOutputRequest {
pub owner_id: SdkWaitOwnerId,
pub wait_id: SdkWaitId,
pub target: PaneTarget,
pub bytes: Vec<u8>,
pub start: PaneOutputSubscriptionStart,
}
#[derive(Debug, Clone, Copy, PartialEq, Eq, Serialize, Deserialize)]
pub struct CancelSdkWaitRequest {
pub owner_id: SdkWaitOwnerId,
pub wait_id: SdkWaitId,
}
#[derive(Debug, Clone, PartialEq, Eq, Serialize, Deserialize)]
pub struct ListPanesRequest {
pub target: SessionName,
#[serde(default)]
pub target_window_index: Option<u32>,
pub format: Option<String>,
}
#[cfg(test)]
#[path = "request/compat_tests.rs"]
mod compat_tests;
#[cfg(test)]
mod tests {
use super::*;
use crate::{
OptionScopeSelector, PaneTarget, ScopeSelector, SelectPaneDirection, SetOptionMode,
SplitDirection,
};
fn alpha() -> SessionName {
SessionName::new("alpha").expect("valid session")
}
fn pane() -> PaneTarget {
PaneTarget::new(alpha(), 0)
}
#[test]
fn request_command_names_cover_extended_aliases_and_internal_tags() {
assert_eq!(
Request::NewSessionExt(NewSessionExtRequest {
session_name: None,
working_directory: None,
detached: true,
size: None,
environment: None,
group_target: None,
attach_if_exists: false,
detach_other_clients: false,
kill_other_clients: false,
flags: None,
window_name: None,
print_session_info: false,
print_format: None,
command: None,
})
.command_name(),
"new-session"
);
assert_eq!(
Request::SplitWindowExt(SplitWindowExtRequest {
target: SplitWindowTarget::Pane(pane()),
direction: SplitDirection::Vertical,
before: false,
environment: None,
command: None,
})
.command_name(),
"split-window"
);
assert_eq!(
Request::SelectPaneAdjacent(SelectPaneAdjacentRequest {
target: pane(),
direction: SelectPaneDirection::Right,
})
.command_name(),
"select-pane"
);
assert_eq!(
Request::SelectPaneMark(SelectPaneMarkRequest {
target: pane(),
clear: false,
title: None,
})
.command_name(),
"select-pane"
);
assert_eq!(
Request::SetOptionByName(SetOptionByNameRequest {
scope: OptionScopeSelector::ServerGlobal,
name: "status".to_owned(),
value: Some("on".to_owned()),
mode: SetOptionMode::Replace,
only_if_unset: false,
unset: false,
unset_pane_overrides: false,
})
.command_name(),
"set-option"
);
assert_eq!(
Request::SetHookMutation(SetHookMutationRequest {
scope: ScopeSelector::Global,
hook: crate::HookName::AfterNewSession,
command: None,
lifecycle: crate::HookLifecycle::Persistent,
append: false,
unset: true,
run_immediately: false,
index: None,
})
.command_name(),
"set-hook"
);
assert_eq!(
Request::AttachSessionExt2(AttachSessionExt2Request {
target: Some(alpha()),
target_spec: None,
detach_other_clients: false,
kill_other_clients: false,
read_only: false,
skip_environment_update: false,
flags: None,
working_directory: None,
client_terminal: crate::ClientTerminalContext::default(),
client_size: None,
})
.command_name(),
"attach-session"
);
assert_eq!(
Request::SwitchClientExt3(SwitchClientExt3Request {
target_client: None,
target: Some("alpha:0.0".to_owned()),
key_table: None,
last_session: false,
next_session: false,
previous_session: false,
toggle_read_only: false,
sort_order: None,
skip_environment_update: false,
zoom: false,
})
.command_name(),
"switch-client"
);
assert_eq!(
Request::ResolveTarget(ResolveTargetRequest {
target: Some("alpha:0.0".to_owned()),
target_type: ResolveTargetType::Pane,
window_index: false,
prefer_unattached: false,
})
.command_name(),
"resolve-target"
);
assert_eq!(
Request::Handshake(HandshakeRequest::current()).command_name(),
"handshake"
);
assert_eq!(
Request::SdkWaitForOutput(SdkWaitForOutputRequest {
owner_id: SdkWaitOwnerId::new(1),
wait_id: SdkWaitId::new(1),
target: pane(),
bytes: b"ready".to_vec(),
start: PaneOutputSubscriptionStart::Now,
})
.command_name(),
"sdk-wait-output"
);
assert_eq!(
Request::CancelSdkWait(CancelSdkWaitRequest {
owner_id: SdkWaitOwnerId::new(1),
wait_id: SdkWaitId::new(1),
})
.command_name(),
"cancel-sdk-wait"
);
assert_eq!(
Request::WaitFor(WaitForRequest {
channel: "ready".to_owned(),
mode: WaitForMode::Wait,
})
.command_name(),
"wait-for"
);
}
}