@@ -7,9 +7,11 @@ const osc = @This();
const std = @import ( " std " ) ;
const builtin = @import ( " builtin " ) ;
const build_options = @import ( " terminal_options " ) ;
const mem = std . mem ;
const assert = std . debug . assert ;
const Allocator = mem . Allocator ;
const LibEnum = @import ( " ../lib/enum.zig " ) . Enum ;
const RGB = @import ( " color.zig " ) . RGB ;
const kitty_color = @import ( " kitty/color.zig " ) ;
const osc_color = @import ( " osc/color.zig " ) ;
@@ -17,26 +19,26 @@ pub const color = osc_color;
const log = std . log . scoped ( . osc ) ;
pub const Command = union ( enum ) {
pub const Command = union ( Key ) {
/// This generally shouldn't ever be set except as an initial zero value.
/// Ignore it.
invalid ,
/// Set the window title of the terminal
///
/// If title mode 0 is set text is expect to be hex encoded (i.e. utf-8
/// If title mode 0 is set text is expect to be hex encoded (i.e. utf-8
/// with each code unit further encoded with two hex digits).
///
/// If title mode 2 is set or the terminal is setup for unconditional
/// utf-8 titles text is interpreted as utf-8. Else text is interpreted
/// as latin1.
change_window_title : [ ] const u8 ,
change_window_title : [ : 0 ] const u8 ,
/// Set the icon of the terminal window. The name of the icon is not
/// well defined, so this is currently ignored by Ghostty at the time
/// of writing this. We just parse it so that we don't get parse errors
/// in the log.
change_window_icon : [ ] const u8 ,
change_window_icon : [ : 0 ] const u8 ,
/// First do a fresh-line. Then start a new command, and enter prompt mode:
/// Subsequent text (until a OSC "133;B" or OSC "133;I" command) is a
@@ -52,7 +54,7 @@ pub const Command = union(enum) {
/// - secondary: a non-editable continuation line
/// - right: a right-aligned prompt that may need adjustment during reflow
prompt_start : struct {
aid : ? [ ] const u8 = null ,
aid : ? [ : 0 ] const u8 = null ,
kind : enum { primary , continuation , secondary , right } = . primary ,
redraw : bool = true ,
} ,
@@ -94,7 +96,7 @@ pub const Command = union(enum) {
/// contents is set on the clipboard.
clipboard_contents : struct {
kind : u8 ,
data : [ ] const u8 ,
data : [ : 0 ] const u8 ,
} ,
/// OSC 7. Reports the current working directory of the shell. This is
@@ -104,7 +106,7 @@ pub const Command = union(enum) {
report_pwd : struct {
/// The reported pwd value. This is not checked for validity. It should
/// be a file URL but it is up to the caller to utilize this value.
value : [ ] const u8 ,
value : [ : 0 ] const u8 ,
} ,
/// OSC 22. Set the mouse shape. There doesn't seem to be a standard
@@ -112,7 +114,7 @@ pub const Command = union(enum) {
/// are moving towards using the W3C CSS cursor names. For OSC parsing,
/// we just parse whatever string is given.
mouse_shape : struct {
value : [ ] const u8 ,
value : [ : 0 ] const u8 ,
} ,
/// OSC color operations to set, reset, or report color settings. Some OSCs
@@ -136,14 +138,14 @@ pub const Command = union(enum) {
/// Show a desktop notification (OSC 9 or OSC 777)
show_desktop_notification : struct {
title : [ ] const u8 ,
body : [ ] const u8 ,
title : [ : 0 ] const u8 ,
body : [ : 0 ] const u8 ,
} ,
/// Start a hyperlink (OSC 8)
hyperlink_start : struct {
id : ? [ ] const u8 = null ,
uri : [ ] const u8 ,
id : ? [ : 0 ] const u8 = null ,
uri : [ : 0 ] const u8 ,
} ,
/// End a hyperlink (OSC 8)
@@ -155,12 +157,12 @@ pub const Command = union(enum) {
} ,
/// ConEmu show GUI message box (OSC 9;2)
conemu_show_message_box : [ ] const u8 ,
conemu_show_message_box : [ : 0 ] const u8 ,
/// ConEmu change tab title (OSC 9;3)
conemu_change_tab_title : union ( enum ) {
reset ,
value : [ ] const u8 ,
value : [ : 0 ] const u8 ,
} ,
/// ConEmu progress report (OSC 9;4)
@@ -170,7 +172,35 @@ pub const Command = union(enum) {
conemu_wait_input ,
/// ConEmu GUI macro (OSC 9;6)
conemu_guimacro : [ ] const u8 ,
conemu_guimacro : [ : 0 ] const u8 ,
pub const Key = LibEnum (
if ( build_options . c_abi ) . c else . zig ,
// NOTE: Order matters, see LibEnum documentation.
& . {
" invalid " ,
" change_window_title " ,
" change_window_icon " ,
" prompt_start " ,
" prompt_end " ,
" end_of_input " ,
" end_of_command " ,
" clipboard_contents " ,
" report_pwd " ,
" mouse_shape " ,
" color_operation " ,
" kitty_color_protocol " ,
" show_desktop_notification " ,
" hyperlink_start " ,
" hyperlink_end " ,
" conemu_sleep " ,
" conemu_show_message_box " ,
" conemu_change_tab_title " ,
" conemu_progress_report " ,
" conemu_wait_input " ,
" conemu_guimacro " ,
} ,
) ;
pub const ProgressReport = struct {
pub const State = enum ( c_int ) {
@@ -275,7 +305,7 @@ pub const Parser = struct {
/// Temporary state that is dependent on the current state.
temp_state : union {
/// Current string parameter being populated
str : * [ ] const u8 ,
str : * [ : 0 ] const u8 ,
/// Current numeric parameter being populated
num : u16 ,
@@ -431,7 +461,7 @@ pub const Parser = struct {
self . reset ( ) ;
}
/// Reset the parser star t.
/// Reset the parser state .
pub fn reset ( self : * Parser ) void {
// If the state is already empty then we do nothing because
// we may touch uninitialized memory.
@@ -468,7 +498,10 @@ pub const Parser = struct {
// If our buffer is full then we're invalid, so we set our state
// accordingly and indicate the sequence is incomplete so that we
// don't accidentally issue a command when ending.
if ( self . buf_idx > = self . buf . len ) {
//
// We always keep space for 1 byte at the end to null-terminate
// values.
if ( self . buf_idx > = self . buf . len - 1 ) {
if ( self . state ! = . invalid ) {
log . warn (
" OSC sequence too long (> {d}), ignoring. state={} " ,
@@ -1007,7 +1040,8 @@ pub const Parser = struct {
. notification_title = > switch ( c ) {
';' = > {
self . command . show_desktop_notification . title = self . buf [ self . buf_start . . self . buf_idx - 1 ] ;
self . buf [ self . buf_idx - 1 ] = 0 ;
self . command . show_desktop_notification . title = self . buf [ self . buf_start . . self . buf_idx - 1 : 0 ] ;
self . temp_state = . { . str = & self . command . show_desktop_notification . body } ;
self . buf_start = self . buf_idx ;
self . state = . string ;
@@ -1376,7 +1410,8 @@ pub const Parser = struct {
fn endHyperlink ( self : * Parser ) void {
switch ( self . command ) {
. hyperlink_start = > | * v | {
const value = self . buf [ self . buf_start . . self . buf_ idx ] ;
self . buf [ self . buf_idx ] = 0 ;
const value = self . buf [ self . buf_start . . self . buf_idx : 0 ] ;
if ( v . id = = null and value . len = = 0 ) {
self . command = . { . hyperlink_end = { } } ;
return ;
@@ -1390,10 +1425,12 @@ pub const Parser = struct {
}
fn endHyperlinkOptionValue ( self : * Parser ) void {
const value = if ( self . buf_start = = self . buf_idx )
const value : [ : 0 ] const u8 = if ( self . buf_start = = self . buf_idx )
" "
else
self . buf [ self . buf_start . . self . buf_idx - 1 ] ;
else buf : {
self . buf [ self . buf_idx - 1 ] = 0 ;
break : buf self . buf [ self . buf_start . . self . buf_idx - 1 : 0 ] ;
} ;
if ( mem . eql ( u8 , self . temp_state . key , " id " ) ) {
switch ( self . command ) {
@@ -1408,7 +1445,11 @@ pub const Parser = struct {
}
fn endSemanticOptionValue ( self : * Parser ) void {
const value = self . buf [ self . buf_start . . self . buf_idx ] ;
const value = value : {
self . buf [ self . buf_idx ] = 0 ;
defer self . buf_idx + = 1 ;
break : value self . buf [ self . buf_start . . self . buf_idx : 0 ] ;
} ;
if ( mem . eql ( u8 , self . temp_state . key , " aid " ) ) {
switch ( self . command ) {
@@ -1465,7 +1506,9 @@ pub const Parser = struct {
}
fn endString ( self : * Parser ) void {
self . temp_state . str . * = self . buf [ self . buf_start . . self . buf_idx ] ;
self . buf [ self . buf_idx ] = 0 ;
defer self . buf_idx + = 1 ;
self . temp_state . str . * = self . buf [ self . buf_start . . self . buf_idx : 0 ] ;
}
fn endConEmuSleepValue ( self : * Parser ) void {
@@ -1559,15 +1602,25 @@ pub const Parser = struct {
}
fn endAllocableString ( self : * Parser ) void {
const alloc = self . alloc . ? ;
const list = self . buf_dynamic . ? ;
self . temp_state . str . * = list . items ;
list . append ( alloc , 0 ) catch {
log . warn ( " allocation failed on allocable string termination " , . { } ) ;
self . temp_state . str . * = " " ;
return ;
} ;
self . temp_state . str . * = list . items [ 0 . . list . items . len - 1 : 0 ] ;
}
/// End the sequence and return the command, if any. If the return value
/// is null, then no valid command was found. The optional terminator_ch
/// is the final character in the OSC sequence. This is used to determine
/// the response terminator.
pub fn end ( self : * Parser , terminator_ch : ? u8 ) ? Command {
///
/// The returned pointer is only valid until the next call to the parser.
/// Callers should copy out any data they wish to retain across calls.
pub fn end ( self : * Parser , terminator_ch : ? u8 ) ? * Command {
if ( ! self . complete ) {
if ( comptime ! builtin . is_test ) log . warn (
" invalid OSC command: {s} " ,
@@ -1626,7 +1679,7 @@ pub const Parser = struct {
else = > { } ,
}
return self . command ;
return & self . command ;
}
} ;
@@ -1642,7 +1695,7 @@ test "OSC: change_window_title" {
p . next ( ';' ) ;
p . next ( 'a' ) ;
p . next ( 'b' ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . change_window_title ) ;
try testing . expectEqualStrings ( " ab " , cmd . change_window_title ) ;
}
@@ -1655,7 +1708,7 @@ test "OSC: change_window_title with 2" {
p . next ( ';' ) ;
p . next ( 'a' ) ;
p . next ( 'b' ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . change_window_title ) ;
try testing . expectEqualStrings ( " ab " , cmd . change_window_title ) ;
}
@@ -1677,7 +1730,7 @@ test "OSC: change_window_title with utf8" {
p . next ( 0xE2 ) ;
p . next ( 0x80 ) ;
p . next ( 0x90 ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . change_window_title ) ;
try testing . expectEqualStrings ( " — ‐ " , cmd . change_window_title ) ;
}
@@ -1688,7 +1741,7 @@ test "OSC: change_window_title empty" {
var p : Parser = . init ( ) ;
p . next ( '2' ) ;
p . next ( ';' ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . change_window_title ) ;
try testing . expectEqualStrings ( " " , cmd . change_window_title ) ;
}
@@ -1701,7 +1754,7 @@ test "OSC: change_window_icon" {
p . next ( ';' ) ;
p . next ( 'a' ) ;
p . next ( 'b' ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . change_window_icon ) ;
try testing . expectEqualStrings ( " ab " , cmd . change_window_icon ) ;
}
@@ -1714,7 +1767,7 @@ test "OSC: prompt_start" {
const input = " 133;A " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . prompt_start ) ;
try testing . expect ( cmd . prompt_start . aid = = null ) ;
try testing . expect ( cmd . prompt_start . redraw ) ;
@@ -1728,7 +1781,7 @@ test "OSC: prompt_start with single option" {
const input = " 133;A;aid=14 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . prompt_start ) ;
try testing . expectEqualStrings ( " 14 " , cmd . prompt_start . aid . ? ) ;
}
@@ -1741,7 +1794,7 @@ test "OSC: prompt_start with redraw disabled" {
const input = " 133;A;redraw=0 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . prompt_start ) ;
try testing . expect ( ! cmd . prompt_start . redraw ) ;
}
@@ -1754,7 +1807,7 @@ test "OSC: prompt_start with redraw invalid value" {
const input = " 133;A;redraw=42 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . prompt_start ) ;
try testing . expect ( cmd . prompt_start . redraw ) ;
try testing . expect ( cmd . prompt_start . kind = = . primary ) ;
@@ -1768,7 +1821,7 @@ test "OSC: prompt_start with continuation" {
const input = " 133;A;k=c " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . prompt_start ) ;
try testing . expect ( cmd . prompt_start . kind = = . continuation ) ;
}
@@ -1781,7 +1834,7 @@ test "OSC: prompt_start with secondary" {
const input = " 133;A;k=s " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . prompt_start ) ;
try testing . expect ( cmd . prompt_start . kind = = . secondary ) ;
}
@@ -1794,7 +1847,7 @@ test "OSC: end_of_command no exit code" {
const input = " 133;D " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . end_of_command ) ;
}
@@ -1806,7 +1859,7 @@ test "OSC: end_of_command with exit code" {
const input = " 133;D;25 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . end_of_command ) ;
try testing . expectEqual ( @as ( u8 , 25 ) , cmd . end_of_command . exit_code . ? ) ;
}
@@ -1819,7 +1872,7 @@ test "OSC: prompt_end" {
const input = " 133;B " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . prompt_end ) ;
}
@@ -1831,7 +1884,7 @@ test "OSC: end_of_input" {
const input = " 133;C " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . end_of_input ) ;
}
@@ -1843,7 +1896,7 @@ test "OSC: get/set clipboard" {
const input = " 52;s;? " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . clipboard_contents ) ;
try testing . expect ( cmd . clipboard_contents . kind = = 's' ) ;
try testing . expectEqualStrings ( " ? " , cmd . clipboard_contents . data ) ;
@@ -1857,7 +1910,7 @@ test "OSC: get/set clipboard (optional parameter)" {
const input = " 52;;? " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . clipboard_contents ) ;
try testing . expect ( cmd . clipboard_contents . kind = = 'c' ) ;
try testing . expectEqualStrings ( " ? " , cmd . clipboard_contents . data ) ;
@@ -1872,7 +1925,7 @@ test "OSC: get/set clipboard with allocator" {
const input = " 52;s;? " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . clipboard_contents ) ;
try testing . expect ( cmd . clipboard_contents . kind = = 's' ) ;
try testing . expectEqualStrings ( " ? " , cmd . clipboard_contents . data ) ;
@@ -1887,7 +1940,7 @@ test "OSC: clear clipboard" {
const input = " 52;; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . clipboard_contents ) ;
try testing . expect ( cmd . clipboard_contents . kind = = 'c' ) ;
try testing . expectEqualStrings ( " " , cmd . clipboard_contents . data ) ;
@@ -1901,7 +1954,7 @@ test "OSC: report pwd" {
const input = " 7;file:///tmp/example " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . report_pwd ) ;
try testing . expectEqualStrings ( " file:///tmp/example " , cmd . report_pwd . value ) ;
}
@@ -1913,7 +1966,7 @@ test "OSC: report pwd empty" {
const input = " 7; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . report_pwd ) ;
try testing . expectEqualStrings ( " " , cmd . report_pwd . value ) ;
}
@@ -1926,7 +1979,7 @@ test "OSC: pointer cursor" {
const input = " 22;pointer " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . mouse_shape ) ;
try testing . expectEqualStrings ( " pointer " , cmd . mouse_shape . value ) ;
}
@@ -1943,6 +1996,36 @@ test "OSC: longer than buffer" {
try testing . expect ( p . complete = = false ) ;
}
test " OSC: one shorter than buffer length " {
const testing = std . testing ;
var p : Parser = . init ( ) ;
const prefix = " 0; " ;
const title = " a " * * ( Parser . MAX_BUF - prefix . len - 1 ) ;
const input = prefix + + title ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( null ) . ? . * ;
try testing . expect ( cmd = = . change_window_title ) ;
try testing . expectEqualStrings ( title , cmd . change_window_title ) ;
}
test " OSC: exactly at buffer length " {
const testing = std . testing ;
var p : Parser = . init ( ) ;
const prefix = " 0; " ;
const title = " a " * * ( Parser . MAX_BUF - prefix . len ) ;
const input = prefix + + title ;
for ( input ) | ch | p . next ( ch ) ;
// This should be null because we always reserve space for a null terminator.
try testing . expect ( p . end ( null ) = = null ) ;
try testing . expect ( p . complete = = false ) ;
}
test " OSC: OSC 9;1 ConEmu sleep " {
const testing = std . testing ;
@@ -1951,7 +2034,7 @@ test "OSC: OSC 9;1 ConEmu sleep" {
const input = " 9;1;420 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_sleep ) ;
try testing . expectEqual ( 420 , cmd . conemu_sleep . duration_ms ) ;
@@ -1965,7 +2048,7 @@ test "OSC: OSC 9;1 ConEmu sleep with no value default to 100ms" {
const input = " 9;1; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_sleep ) ;
try testing . expectEqual ( 100 , cmd . conemu_sleep . duration_ms ) ;
@@ -1979,7 +2062,7 @@ test "OSC: OSC 9;1 conemu sleep cannot exceed 10000ms" {
const input = " 9;1;12345 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_sleep ) ;
try testing . expectEqual ( 10000 , cmd . conemu_sleep . duration_ms ) ;
@@ -1993,7 +2076,7 @@ test "OSC: OSC 9;1 conemu sleep invalid input" {
const input = " 9;1;foo " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_sleep ) ;
try testing . expectEqual ( 100 , cmd . conemu_sleep . duration_ms ) ;
@@ -2007,7 +2090,7 @@ test "OSC: OSC 9;1 conemu sleep -> desktop notification 1" {
const input = " 9;1 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " 1 " , cmd . show_desktop_notification . body ) ;
@@ -2021,7 +2104,7 @@ test "OSC: OSC 9;1 conemu sleep -> desktop notification 2" {
const input = " 9;1a " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " 1a " , cmd . show_desktop_notification . body ) ;
@@ -2035,7 +2118,7 @@ test "OSC: OSC 9 show desktop notification" {
const input = " 9;Hello world " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " " , cmd . show_desktop_notification . title ) ;
try testing . expectEqualStrings ( " Hello world " , cmd . show_desktop_notification . body ) ;
@@ -2049,7 +2132,7 @@ test "OSC: OSC 9 show single character desktop notification" {
const input = " 9;H " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " " , cmd . show_desktop_notification . title ) ;
try testing . expectEqualStrings ( " H " , cmd . show_desktop_notification . body ) ;
@@ -2063,7 +2146,7 @@ test "OSC: OSC 777 show desktop notification with title" {
const input = " 777;notify;Title;Body " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( cmd . show_desktop_notification . title , " Title " ) ;
try testing . expectEqualStrings ( cmd . show_desktop_notification . body , " Body " ) ;
@@ -2077,7 +2160,7 @@ test "OSC: OSC 9;2 ConEmu message box" {
const input = " 9;2;hello world " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_show_message_box ) ;
try testing . expectEqualStrings ( " hello world " , cmd . conemu_show_message_box ) ;
}
@@ -2090,7 +2173,7 @@ test "OSC: 9;2 ConEmu message box invalid input" {
const input = " 9;2 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " 2 " , cmd . show_desktop_notification . body ) ;
}
@@ -2103,7 +2186,7 @@ test "OSC: 9;2 ConEmu message box empty message" {
const input = " 9;2; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_show_message_box ) ;
try testing . expectEqualStrings ( " " , cmd . conemu_show_message_box ) ;
}
@@ -2116,7 +2199,7 @@ test "OSC: 9;2 ConEmu message box spaces only message" {
const input = " 9;2; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_show_message_box ) ;
try testing . expectEqualStrings ( " " , cmd . conemu_show_message_box ) ;
}
@@ -2129,7 +2212,7 @@ test "OSC: OSC 9;2 message box -> desktop notification 1" {
const input = " 9;2 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " 2 " , cmd . show_desktop_notification . body ) ;
@@ -2143,7 +2226,7 @@ test "OSC: OSC 9;2 message box -> desktop notification 2" {
const input = " 9;2a " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " 2a " , cmd . show_desktop_notification . body ) ;
@@ -2157,7 +2240,7 @@ test "OSC: 9;3 ConEmu change tab title" {
const input = " 9;3;foo bar " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_change_tab_title ) ;
try testing . expectEqualStrings ( " foo bar " , cmd . conemu_change_tab_title . value ) ;
}
@@ -2170,7 +2253,7 @@ test "OSC: 9;3 ConEmu change tab title reset" {
const input = " 9;3; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
const expected_command : Command = . { . conemu_change_tab_title = . reset } ;
try testing . expectEqual ( expected_command , cmd ) ;
@@ -2184,7 +2267,7 @@ test "OSC: 9;3 ConEmu change tab title spaces only" {
const input = " 9;3; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_change_tab_title ) ;
try testing . expectEqualStrings ( " " , cmd . conemu_change_tab_title . value ) ;
@@ -2198,7 +2281,7 @@ test "OSC: OSC 9;3 change tab title -> desktop notification 1" {
const input = " 9;3 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " 3 " , cmd . show_desktop_notification . body ) ;
@@ -2212,7 +2295,7 @@ test "OSC: OSC 9;3 message box -> desktop notification 2" {
const input = " 9;3a " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " 3a " , cmd . show_desktop_notification . body ) ;
@@ -2226,7 +2309,7 @@ test "OSC: OSC 9;4 ConEmu progress set" {
const input = " 9;4;1;100 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . set ) ;
try testing . expect ( cmd . conemu_progress_report . progress = = 100 ) ;
@@ -2240,7 +2323,7 @@ test "OSC: OSC 9;4 ConEmu progress set overflow" {
const input = " 9;4;1;900 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . set ) ;
try testing . expectEqual ( 100 , cmd . conemu_progress_report . progress ) ;
@@ -2254,7 +2337,7 @@ test "OSC: OSC 9;4 ConEmu progress set single digit" {
const input = " 9;4;1;9 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . set ) ;
try testing . expect ( cmd . conemu_progress_report . progress = = 9 ) ;
@@ -2268,7 +2351,7 @@ test "OSC: OSC 9;4 ConEmu progress set double digit" {
const input = " 9;4;1;94 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . set ) ;
try testing . expectEqual ( 94 , cmd . conemu_progress_report . progress ) ;
@@ -2282,7 +2365,7 @@ test "OSC: OSC 9;4 ConEmu progress set extra semicolon ignored" {
const input = " 9;4;1;100 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . set ) ;
try testing . expectEqual ( 100 , cmd . conemu_progress_report . progress ) ;
@@ -2296,7 +2379,7 @@ test "OSC: OSC 9;4 ConEmu progress remove with no progress" {
const input = " 9;4;0; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . remove ) ;
try testing . expect ( cmd . conemu_progress_report . progress = = null ) ;
@@ -2310,7 +2393,7 @@ test "OSC: OSC 9;4 ConEmu progress remove with double semicolon" {
const input = " 9;4;0;; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . remove ) ;
try testing . expect ( cmd . conemu_progress_report . progress = = null ) ;
@@ -2324,7 +2407,7 @@ test "OSC: OSC 9;4 ConEmu progress remove ignores progress" {
const input = " 9;4;0;100 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . remove ) ;
try testing . expect ( cmd . conemu_progress_report . progress = = null ) ;
@@ -2338,7 +2421,7 @@ test "OSC: OSC 9;4 ConEmu progress remove extra semicolon" {
const input = " 9;4;0;100; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . remove ) ;
}
@@ -2351,7 +2434,7 @@ test "OSC: OSC 9;4 ConEmu progress error" {
const input = " 9;4;2 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . @ " error " ) ;
try testing . expect ( cmd . conemu_progress_report . progress = = null ) ;
@@ -2365,7 +2448,7 @@ test "OSC: OSC 9;4 ConEmu progress error with progress" {
const input = " 9;4;2;100 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . @ " error " ) ;
try testing . expect ( cmd . conemu_progress_report . progress = = 100 ) ;
@@ -2379,7 +2462,7 @@ test "OSC: OSC 9;4 progress pause" {
const input = " 9;4;4 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . pause ) ;
try testing . expect ( cmd . conemu_progress_report . progress = = null ) ;
@@ -2393,7 +2476,7 @@ test "OSC: OSC 9;4 ConEmu progress pause with progress" {
const input = " 9;4;4;100 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_progress_report ) ;
try testing . expect ( cmd . conemu_progress_report . state = = . pause ) ;
try testing . expect ( cmd . conemu_progress_report . progress = = 100 ) ;
@@ -2407,7 +2490,7 @@ test "OSC: OSC 9;4 progress -> desktop notification 1" {
const input = " 9;4 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " 4 " , cmd . show_desktop_notification . body ) ;
@@ -2421,7 +2504,7 @@ test "OSC: OSC 9;4 progress -> desktop notification 2" {
const input = " 9;4; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " 4; " , cmd . show_desktop_notification . body ) ;
@@ -2435,7 +2518,7 @@ test "OSC: OSC 9;4 progress -> desktop notification 3" {
const input = " 9;4;5 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " 4;5 " , cmd . show_desktop_notification . body ) ;
@@ -2449,7 +2532,7 @@ test "OSC: OSC 9;4 progress -> desktop notification 4" {
const input = " 9;4;5a " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " 4;5a " , cmd . show_desktop_notification . body ) ;
@@ -2463,7 +2546,7 @@ test "OSC: OSC 9;5 ConEmu wait input" {
const input = " 9;5 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_wait_input ) ;
}
@@ -2475,7 +2558,7 @@ test "OSC: OSC 9;5 ConEmu wait ignores trailing characters" {
const input = " 9;5;foo " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_wait_input ) ;
}
@@ -2499,7 +2582,7 @@ test "OSC: hyperlink" {
const input = " 8;;http://example.com " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . hyperlink_start ) ;
try testing . expectEqualStrings ( cmd . hyperlink_start . uri , " http://example.com " ) ;
}
@@ -2512,7 +2595,7 @@ test "OSC: hyperlink with id set" {
const input = " 8;id=foo;http://example.com " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . hyperlink_start ) ;
try testing . expectEqualStrings ( cmd . hyperlink_start . id . ? , " foo " ) ;
try testing . expectEqualStrings ( cmd . hyperlink_start . uri , " http://example.com " ) ;
@@ -2526,7 +2609,7 @@ test "OSC: hyperlink with empty id" {
const input = " 8;id=;http://example.com " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . hyperlink_start ) ;
try testing . expectEqual ( null , cmd . hyperlink_start . id ) ;
try testing . expectEqualStrings ( cmd . hyperlink_start . uri , " http://example.com " ) ;
@@ -2540,7 +2623,7 @@ test "OSC: hyperlink with incomplete key" {
const input = " 8;id;http://example.com " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . hyperlink_start ) ;
try testing . expectEqual ( null , cmd . hyperlink_start . id ) ;
try testing . expectEqualStrings ( cmd . hyperlink_start . uri , " http://example.com " ) ;
@@ -2554,7 +2637,7 @@ test "OSC: hyperlink with empty key" {
const input = " 8;=value;http://example.com " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . hyperlink_start ) ;
try testing . expectEqual ( null , cmd . hyperlink_start . id ) ;
try testing . expectEqualStrings ( cmd . hyperlink_start . uri , " http://example.com " ) ;
@@ -2568,7 +2651,7 @@ test "OSC: hyperlink with empty key and id" {
const input = " 8;=value:id=foo;http://example.com " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . hyperlink_start ) ;
try testing . expectEqualStrings ( cmd . hyperlink_start . id . ? , " foo " ) ;
try testing . expectEqualStrings ( cmd . hyperlink_start . uri , " http://example.com " ) ;
@@ -2594,7 +2677,7 @@ test "OSC: hyperlink end" {
const input = " 8;; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . hyperlink_end ) ;
}
@@ -2608,7 +2691,7 @@ test "OSC: kitty color protocol" {
const input = " 21;foreground=?;background=rgb:f0/f8/ff;cursor=aliceblue;cursor_text;visual_bell=;selection_foreground=#xxxyyzz;selection_background=?;selection_background=#aabbcc;2=?;3=rgbi:1.0/1.0/1.0 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . kitty_color_protocol ) ;
try testing . expectEqual ( @as ( usize , 9 ) , cmd . kitty_color_protocol . list . items . len ) ;
{
@@ -2690,7 +2773,7 @@ test "OSC: kitty color protocol double reset" {
const input = " 21;foreground=?;background=rgb:f0/f8/ff;cursor=aliceblue;cursor_text;visual_bell=;selection_foreground=#xxxyyzz;selection_background=?;selection_background=#aabbcc;2=?;3=rgbi:1.0/1.0/1.0 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . kitty_color_protocol ) ;
p . reset ( ) ;
@@ -2706,7 +2789,7 @@ test "OSC: kitty color protocol reset after invalid" {
const input = " 21;foreground=?;background=rgb:f0/f8/ff;cursor=aliceblue;cursor_text;visual_bell=;selection_foreground=#xxxyyzz;selection_background=?;selection_background=#aabbcc;2=?;3=rgbi:1.0/1.0/1.0 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . kitty_color_protocol ) ;
p . reset ( ) ;
@@ -2727,7 +2810,7 @@ test "OSC: kitty color protocol no key" {
const input = " 21; " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . kitty_color_protocol ) ;
try testing . expectEqual ( 0 , cmd . kitty_color_protocol . list . items . len ) ;
}
@@ -2741,7 +2824,7 @@ test "OSC: 9;6: ConEmu guimacro 1" {
const input = " 9;6;a " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_guimacro ) ;
try testing . expectEqualStrings ( " a " , cmd . conemu_guimacro ) ;
}
@@ -2755,7 +2838,7 @@ test "OSC: 9;6: ConEmu guimacro 2" {
const input = " 9;6;ab " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . conemu_guimacro ) ;
try testing . expectEqualStrings ( " ab " , cmd . conemu_guimacro ) ;
}
@@ -2769,7 +2852,7 @@ test "OSC: 9;6: ConEmu guimacro 3 incomplete -> desktop notification" {
const input = " 9;6 " ;
for ( input ) | ch | p . next ( ch ) ;
const cmd = p . end ( '\x1b' ) . ? ;
const cmd = p . end ( '\x1b' ) . ? . * ;
try testing . expect ( cmd = = . show_desktop_notification ) ;
try testing . expectEqualStrings ( " 6 " , cmd . show_desktop_notification . body ) ;
}