use std::borrow::Cow;
#[derive(Debug, Clone, Copy, PartialEq, Eq)]
pub enum PromptKind {
Primary,
Secondary,
Right,
}
pub trait SemanticPromptMarkers: Send + Sync {
fn prompt_start(&self, kind: PromptKind) -> Cow<'_, str>;
fn command_input_start(&self) -> Cow<'_, str>;
}
#[derive(Debug, Clone, Copy, Default)]
pub struct Osc133Markers;
impl Osc133Markers {
pub fn boxed() -> Box<dyn SemanticPromptMarkers> {
Box::new(Self)
}
}
impl SemanticPromptMarkers for Osc133Markers {
fn prompt_start(&self, kind: PromptKind) -> Cow<'_, str> {
match kind {
PromptKind::Primary => Cow::Borrowed("\x1b]133;A;k=i\x1b\\"), PromptKind::Secondary => Cow::Borrowed("\x1b]133;A;k=s\x1b\\"), PromptKind::Right => Cow::Borrowed("\x1b]133;P;k=r\x1b\\"),
}
}
fn command_input_start(&self) -> Cow<'_, str> {
Cow::Borrowed("\x1b]133;B\x1b\\")
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct Osc133ClickEventsMarkers;
impl Osc133ClickEventsMarkers {
pub fn boxed() -> Box<dyn SemanticPromptMarkers> {
Box::new(Self)
}
}
impl SemanticPromptMarkers for Osc133ClickEventsMarkers {
fn prompt_start(&self, kind: PromptKind) -> Cow<'_, str> {
match kind {
PromptKind::Primary => Cow::Borrowed("\x1b]133;A;k=i;click_events=1\x1b\\"),
PromptKind::Secondary => Cow::Borrowed("\x1b]133;A;k=s;click_events=1\x1b\\"),
PromptKind::Right => Cow::Borrowed("\x1b]133;P;k=r\x1b\\"),
}
}
fn command_input_start(&self) -> Cow<'_, str> {
Cow::Borrowed("\x1b]133;B\x1b\\")
}
}
#[derive(Debug, Clone, Copy, Default)]
pub struct Osc633Markers;
impl Osc633Markers {
pub fn boxed() -> Box<dyn SemanticPromptMarkers> {
Box::new(Self)
}
}
impl SemanticPromptMarkers for Osc633Markers {
fn prompt_start(&self, kind: PromptKind) -> Cow<'_, str> {
match kind {
PromptKind::Primary => Cow::Borrowed("\x1b]633;A;k=i\x1b\\"), PromptKind::Secondary => Cow::Borrowed("\x1b]633;A;k=s\x1b\\"), PromptKind::Right => Cow::Borrowed("\x1b]633;P;k=r\x1b\\"),
}
}
fn command_input_start(&self) -> Cow<'_, str> {
Cow::Borrowed("\x1b]633;B\x1b\\")
}
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn test_osc133_primary_prompt_start() {
let markers = Osc133Markers;
assert_eq!(
markers.prompt_start(PromptKind::Primary).as_ref(),
"\x1b]133;A;k=i\x1b\\" );
}
#[test]
fn test_osc133_secondary_prompt_start() {
let markers = Osc133Markers;
assert_eq!(
markers.prompt_start(PromptKind::Secondary).as_ref(),
"\x1b]133;A;k=s\x1b\\" );
}
#[test]
fn test_osc133_right_prompt_start() {
let markers = Osc133Markers;
assert_eq!(
markers.prompt_start(PromptKind::Right).as_ref(),
"\x1b]133;P;k=r\x1b\\"
);
}
#[test]
fn test_osc133_command_input_start() {
let markers = Osc133Markers;
assert_eq!(markers.command_input_start().as_ref(), "\x1b]133;B\x1b\\");
}
#[test]
fn test_osc133_click_events_primary_prompt_start() {
let markers = Osc133ClickEventsMarkers;
assert_eq!(
markers.prompt_start(PromptKind::Primary).as_ref(),
"\x1b]133;A;k=i;click_events=1\x1b\\"
);
}
#[test]
fn test_osc133_click_events_secondary_prompt_start() {
let markers = Osc133ClickEventsMarkers;
assert_eq!(
markers.prompt_start(PromptKind::Secondary).as_ref(),
"\x1b]133;A;k=s;click_events=1\x1b\\"
);
}
#[test]
fn test_osc133_click_events_right_prompt_start() {
let markers = Osc133ClickEventsMarkers;
assert_eq!(
markers.prompt_start(PromptKind::Right).as_ref(),
"\x1b]133;P;k=r\x1b\\"
);
}
#[test]
fn test_osc133_click_events_command_input_start() {
let markers = Osc133ClickEventsMarkers;
assert_eq!(markers.command_input_start().as_ref(), "\x1b]133;B\x1b\\");
}
#[test]
fn test_osc633_primary_prompt_start() {
let markers = Osc633Markers;
assert_eq!(
markers.prompt_start(PromptKind::Primary).as_ref(),
"\x1b]633;A;k=i\x1b\\"
);
}
#[test]
fn test_osc633_secondary_prompt_start() {
let markers = Osc633Markers;
assert_eq!(
markers.prompt_start(PromptKind::Secondary).as_ref(),
"\x1b]633;A;k=s\x1b\\"
);
}
#[test]
fn test_osc633_right_prompt_start() {
let markers = Osc633Markers;
assert_eq!(
markers.prompt_start(PromptKind::Right).as_ref(),
"\x1b]633;P;k=r\x1b\\"
);
}
#[test]
fn test_osc633_command_input_start() {
let markers = Osc633Markers;
assert_eq!(markers.command_input_start().as_ref(), "\x1b]633;B\x1b\\");
}
#[test]
fn test_string_terminator_is_st_not_bel() {
let osc133 = Osc133Markers;
let osc633 = Osc633Markers;
assert!(!osc133.prompt_start(PromptKind::Primary).contains('\x07'));
assert!(!osc133.command_input_start().contains('\x07'));
assert!(!osc633.prompt_start(PromptKind::Primary).contains('\x07'));
assert!(!osc633.command_input_start().contains('\x07'));
assert!(osc133.prompt_start(PromptKind::Primary).contains("\x1b\\"));
assert!(osc633.prompt_start(PromptKind::Primary).contains("\x1b\\"));
}
}