okami.mom/ultraviolet
git clone https://git.nkp.pet/okami.mom/ultraviolet
f678006
upstream
1package uv 2 3import ( 4"context" 5"fmt" 6"image" 7"image/color" 8"strings" 9 10"github.com/charmbracelet/x/ansi" 11"github.com/charmbracelet/x/ansi/kitty" 12) 13 14// Event represents an input event that can be received from an input source. 15type Event interface {} 16 17// EventStreamer is an interface that defines a method to stream events from an 18// input source. It takes a context and a channel to send events to. The 19// streamer should block until the context is done or an error occurs. The 20// channel should never be closed by the streamer, as it is the responsibility 21// of the consumer to close it when done. 22type EventStreamer interface { 23StreamEvents (ctx context.Context ,ch chan <- Event )error 24} 25 26// UnknownEvent represents an unknown event. 27type UnknownEvent string 28 29// String returns a string representation of the unknown event. 30func (e UnknownEvent )String ()string { 31return fmt .Sprintf ("%q" ,string (e )) 32} 33 34// UnknownCsiEvent represents an unknown CSI (Control Sequence Introducer) event. 35type UnknownCsiEvent string 36 37// String returns a string representation of the unknown CSI event. 38func (e UnknownCsiEvent )String ()string { 39return fmt .Sprintf ("%q" ,string (e )) 40} 41 42// UnknownSs3Event represents an unknown SS3 (Single Shift 3) event. 43type UnknownSs3Event string 44 45// String returns a string representation of the unknown SS3 event. 46func (e UnknownSs3Event )String ()string { 47return fmt .Sprintf ("%q" ,string (e )) 48} 49 50// UnknownOscEvent represents an unknown OSC (Operating System Command) event. 51type UnknownOscEvent string 52 53// String returns a string representation of the unknown OSC event. 54func (e UnknownOscEvent )String ()string { 55return fmt .Sprintf ("%q" ,string (e )) 56} 57 58// UnknownDcsEvent represents an unknown DCS (Device Control String) event. 59type UnknownDcsEvent string 60 61// String returns a string representation of the unknown DCS event. 62func (e UnknownDcsEvent )String ()string { 63return fmt .Sprintf ("%q" ,string (e )) 64} 65 66// UnknownSosEvent represents an unknown SOS (Start of String) event. 67type UnknownSosEvent string 68 69// String returns a string representation of the unknown SOS event. 70func (e UnknownSosEvent )String ()string { 71return fmt .Sprintf ("%q" ,string (e )) 72} 73 74// UnknownPmEvent represents an unknown PM (Privacy Message) event. 75type UnknownPmEvent string 76 77// String returns a string representation of the unknown PM event. 78func (e UnknownPmEvent )String ()string { 79return fmt .Sprintf ("%q" ,string (e )) 80} 81 82// UnknownApcEvent represents an unknown APC (Application Program Command) event. 83type UnknownApcEvent string 84 85// String returns a string representation of the unknown APC event. 86func (e UnknownApcEvent )String ()string { 87return fmt .Sprintf ("%q" ,string (e )) 88} 89 90// MultiEvent represents multiple messages event. 91type MultiEvent []Event 92 93// String returns a string representation of the multiple messages event. 94func (e MultiEvent )String ()string { 95var sb strings.Builder 96for _ ,ev := range e { 97fmt .Fprintf (& sb ,"%v\n" ,ev ) 98 } 99return sb .String () 100} 101 102// Size represents the size of the terminal window. 103type Size struct { 104Width int 105Height int 106} 107 108// Bounds returns the bounds corresponding to the size. 109func (s Size )Bounds ()Rectangle { 110return Rectangle { 111Min : image.Point {X :0 ,Y :0 }, 112Max : image.Point {X :s .Width ,Y :s .Height }, 113 } 114} 115 116// WindowSizeEvent represents the window size in cells. 117type WindowSizeEvent Size 118 119// Bounds returns the bounds corresponding to the size. 120func (s WindowSizeEvent )Bounds ()Rectangle { 121return Size (s ).Bounds () 122} 123 124// PixelSizeEvent represents the window size in pixels. 125type PixelSizeEvent Size 126 127// Bounds returns the bounds corresponding to the size. 128func (s PixelSizeEvent )Bounds ()Rectangle { 129return Size (s ).Bounds () 130} 131 132// CellSizeEvent represents the cell size in pixels. 133type CellSizeEvent Size 134 135// Bounds returns the bounds corresponding to the size. 136func (s CellSizeEvent )Bounds ()Rectangle { 137return Size (s ).Bounds () 138} 139 140// KeyPressEvent represents a key press event. 141type KeyPressEvent Key 142 143// MatchString returns true if the [Key] matches one of the given strings. 144// 145// A string can be a key name like "enter", "tab", "a", or a printable 146// character like "1" or " ". It can also have combinations of modifiers like 147// "ctrl+a", "shift+enter", "alt+tab", "ctrl+shift+enter", etc. 148func (k KeyPressEvent )MatchString (s ... string )bool { 149return Key (k ).MatchString (s ... ) 150} 151 152// String implements [fmt.Stringer] and is quite useful for matching key 153// events. For details, on what this returns see [Key.String]. 154func (k KeyPressEvent )String ()string { 155return Key (k ).String () 156} 157 158// Keystroke returns the keystroke representation of the [Key]. While less type 159// safe than looking at the individual fields, it will usually be more 160// convenient and readable to use this method when matching against keys. 161// 162// Note that modifier keys are always printed in the following order: 163// - ctrl 164// - alt 165// - shift 166// - meta 167// - hyper 168// - super 169// 170// For example, you'll always see "ctrl+shift+alt+a" and never 171// "shift+ctrl+alt+a". 172func (k KeyPressEvent )Keystroke ()string { 173return Key (k ).Keystroke () 174} 175 176// Key returns the underlying key event. This is a syntactic sugar for casting 177// the key event to a [Key]. 178func (k KeyPressEvent )Key ()Key { 179return Key (k ) 180} 181 182// KeyReleaseEvent represents a key release event. 183type KeyReleaseEvent Key 184 185// MatchString returns true if the [Key] matches one of the given strings. 186// 187// A string can be a key name like "enter", "tab", "a", or a printable 188// character like "1" or " ". It can also have combinations of modifiers like 189// "ctrl+a", "shift+enter", "alt+tab", "ctrl+shift+enter", etc. 190func (k KeyReleaseEvent )MatchString (s ... string )bool { 191return Key (k ).MatchString (s ... ) 192} 193 194// String implements [fmt.Stringer] and is quite useful for matching key 195// events. For details, on what this returns see [Key.String]. 196func (k KeyReleaseEvent )String ()string { 197return Key (k ).String () 198} 199 200// Keystroke returns the keystroke representation of the [Key]. While less type 201// safe than looking at the individual fields, it will usually be more 202// convenient and readable to use this method when matching against keys. 203// 204// Note that modifier keys are always printed in the following order: 205// - ctrl 206// - alt 207// - shift 208// - meta 209// - hyper 210// - super 211// 212// For example, you'll always see "ctrl+shift+alt+a" and never 213// "shift+ctrl+alt+a". 214func (k KeyReleaseEvent )Keystroke ()string { 215return Key (k ).Keystroke () 216} 217 218// Key returns the underlying key event. This is a convenience method and 219// syntactic sugar to satisfy the [KeyEvent] interface, and cast the key event to 220// [Key]. 221func (k KeyReleaseEvent )Key ()Key { 222return Key (k ) 223} 224 225// KeyEvent represents a key event. This can be either a key press or a key 226// release event. 227type KeyEvent interface { 228 fmt.Stringer 229 230// Key returns the underlying key event. 231Key ()Key 232} 233 234// MouseEvent represents a mouse message. This is a generic mouse message that 235// can represent any kind of mouse event. 236type MouseEvent interface { 237 fmt.Stringer 238 239// Mouse returns the underlying mouse event. 240Mouse ()Mouse 241} 242 243// MouseClickEvent represents a mouse button click event. 244type MouseClickEvent Mouse 245 246// String returns a string representation of the mouse click event. 247func (e MouseClickEvent )String ()string { 248return Mouse (e ).String () 249} 250 251// Mouse returns the underlying mouse event. This is a convenience method and 252// syntactic sugar to satisfy the [MouseEvent] interface, and cast the mouse 253// event to [Mouse]. 254func (e MouseClickEvent )Mouse ()Mouse { 255return Mouse (e ) 256} 257 258// MouseReleaseEvent represents a mouse button release event. 259type MouseReleaseEvent Mouse 260 261// String returns a string representation of the mouse release event. 262func (e MouseReleaseEvent )String ()string { 263return Mouse (e ).String () 264} 265 266// Mouse returns the underlying mouse event. This is a convenience method and 267// syntactic sugar to satisfy the [MouseEvent] interface, and cast the mouse 268// event to [Mouse]. 269func (e MouseReleaseEvent )Mouse ()Mouse { 270return Mouse (e ) 271} 272 273// MouseWheelEvent represents a mouse wheel message event. 274type MouseWheelEvent Mouse 275 276// String returns a string representation of the mouse wheel event. 277func (e MouseWheelEvent )String ()string { 278return Mouse (e ).String () 279} 280 281// Mouse returns the underlying mouse event. This is a convenience method and 282// syntactic sugar to satisfy the [MouseEvent] interface, and cast the mouse 283// event to [Mouse]. 284func (e MouseWheelEvent )Mouse ()Mouse { 285return Mouse (e ) 286} 287 288// MouseMotionEvent represents a mouse motion event. 289type MouseMotionEvent Mouse 290 291// String returns a string representation of the mouse motion event. 292func (e MouseMotionEvent )String ()string { 293m := Mouse (e ) 294if m .Button != 0 { 295return m .String ()+ "+motion" 296 } 297return m .String ()+ "motion" 298} 299 300// Mouse returns the underlying mouse event. This is a convenience method and 301// syntactic sugar to satisfy the [MouseEvent] interface, and cast the mouse 302// event to [Mouse]. 303func (e MouseMotionEvent )Mouse ()Mouse { 304return Mouse (e ) 305} 306 307// CursorPositionEvent represents a cursor position event. Where X is the 308// zero-based column and Y is the zero-based row. 309type CursorPositionEvent struct { 310X ,Y int 311} 312 313// FocusEvent represents a terminal focus event. 314// This occurs when the terminal gains focus. 315type FocusEvent struct {} 316 317// BlurEvent represents a terminal blur event. 318// This occurs when the terminal loses focus. 319type BlurEvent struct {} 320 321// DarkColorSchemeEvent is sent when the operating system is using a dark color 322// scheme. This is typically used to notify applications of the current or new 323// system color scheme. 324type DarkColorSchemeEvent struct {} 325 326// LightColorSchemeEvent is sent when the operating system is using a light color 327// scheme. This is typically used to notify applications of the current or new 328// system color scheme. 329type LightColorSchemeEvent struct {} 330 331// PasteEvent is an message that is emitted when a terminal receives pasted text 332// using bracketed-paste. 333type PasteEvent struct { 334// Content is the pasted text content. 335Content string 336} 337 338// String returns the pasted content as a string. 339func (e PasteEvent )String ()string { 340return e .Content 341} 342 343// PasteStartEvent is an message that is emitted when the terminal starts the 344// bracketed-paste text. 345type PasteStartEvent struct {} 346 347// PasteEndEvent is an message that is emitted when the terminal ends the 348// bracketed-paste text. 349type PasteEndEvent struct {} 350 351// TerminalVersionEvent is a message that represents the terminal version. 352type TerminalVersionEvent struct { 353Name string 354} 355 356// String returns the terminal version as a string. 357func (e TerminalVersionEvent )String ()string { 358return e .Name 359} 360 361// ModifyOtherKeysEvent represents a modifyOtherKeys event. 362// 363// 0: disable 364// 1: enable mode 1 365// 2: enable mode 2 366// 367// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Functions-using-CSI-_-ordered-by-the-final-character_s_ 368// See: https://invisible-island.net/xterm/manpage/xterm.html#VT100-Widget-Resources:modifyOtherKeys 369type ModifyOtherKeysEvent struct { 370Mode int 371} 372 373// KittyGraphicsEvent represents a Kitty Graphics response event. 374// 375// See https://sw.kovidgoyal.net/kitty/graphics-protocol/ 376type KittyGraphicsEvent struct { 377Options kitty.Options 378Payload []byte 379} 380 381// KeyboardEnhancementsEvent represents a keyboard enhancements report event. 382type KeyboardEnhancementsEvent struct { 383// Flags are the Kitty Keyboard Enhancement flags. 384// 385// Bit values: 386// 387// 00000001: Disambiguate escape codes 388// 00000010: Report event types 389// 00000100: Report alternate keys 390// 00001000: Report all keys as escape codes 391// 00010000: Report associated text 392// 393// See: https://sw.kovidgoyal.net/kitty/keyboard-protocol/#keyboard-enhancements 394Flags int 395} 396 397// Contains reports whether m contains the given enhancements. 398func (e KeyboardEnhancementsEvent )Contains (enhancements int )bool { 399return e .Flags & enhancements == enhancements 400} 401 402// SupportsKeyDisambiguation returns whether the terminal supports reporting 403// disambiguous keys as escape codes. 404func (e KeyboardEnhancementsEvent )SupportsKeyDisambiguation ()bool { 405return e .Flags & ansi .KittyDisambiguateEscapeCodes != 0 406} 407 408// SupportsKeyReleases returns whether the terminal supports key release 409// events. 410func (e KeyboardEnhancementsEvent )SupportsKeyReleases ()bool { 411return e .Flags & ansi .KittyReportEventTypes != 0 412} 413 414// SupportsUniformKeyLayout returns whether the terminal supports reporting key 415// events as though they were on a PC-101 layout. 416func (e KeyboardEnhancementsEvent )SupportsUniformKeyLayout ()bool { 417return e .SupportsKeyDisambiguation ()&& 418e .Flags & ansi .KittyReportAlternateKeys != 0 && 419e .Flags & ansi .KittyReportAllKeysAsEscapeCodes != 0 420} 421 422// PrimaryDeviceAttributesEvent is an event that represents the terminal 423// primary device attributes. 424// 425// Common attributes include: 426// - 1 132 columns 427// - 2 Printer port 428// - 4 Sixel 429// - 6 Selective erase 430// - 7 Soft character set (DRCS) 431// - 8 User-defined keys (UDKs) 432// - 9 National replacement character sets (NRCS) (International terminal only) 433// - 12 Yugoslavian (SCS) 434// - 15 Technical character set 435// - 18 Windowing capability 436// - 21 Horizontal scrolling 437// - 23 Greek 438// - 24 Turkish 439// - 42 ISO Latin-2 character set 440// - 44 PCTerm 441// - 45 Soft key map 442// - 46 ASCII emulation 443// 444// See [ansi.PrimaryDeviceAttributes] for more details. 445type PrimaryDeviceAttributesEvent []int 446 447// SecondaryDeviceAttributesEvent is an event that represents the terminal 448// secondary device attributes. 449// 450// See [ansi.SecondaryDeviceAttributes] for more details. 451type SecondaryDeviceAttributesEvent []int 452 453// TertiaryDeviceAttributesEvent is an event that represents the terminal 454// tertiary device attributes. 455// 456// See [ansi.TertiaryDeviceAttributes] for more details. 457type TertiaryDeviceAttributesEvent string 458 459// ModeReportEvent is a message that represents a mode report event (DECRPM). 460// 461// See: https://vt100.net/docs/vt510-rm/DECRPM.html 462type ModeReportEvent struct { 463// Mode is the mode number. 464Mode ansi.Mode 465 466// Value is the mode value. 467Value ansi.ModeSetting 468} 469 470// ForegroundColorEvent represents a foreground color event. This event is 471// emitted when the terminal requests the terminal foreground color using 472// [ansi.RequestForegroundColor]. 473type ForegroundColorEvent struct { color.Color } 474 475// String returns the hex representation of the color. 476func (e ForegroundColorEvent )String ()string { 477return colorToHex (e .Color ) 478} 479 480// IsDark returns whether the color is dark. 481func (e ForegroundColorEvent )IsDark ()bool { 482return isDarkColor (e .Color ) 483} 484 485// BackgroundColorEvent represents a background color event. This event is 486// emitted when the terminal requests the terminal background color using 487// [ansi.RequestBackgroundColor]. 488type BackgroundColorEvent struct { color.Color } 489 490// String returns the hex representation of the color. 491func (e BackgroundColorEvent )String ()string { 492return colorToHex (e ) 493} 494 495// IsDark returns whether the color is dark. 496func (e BackgroundColorEvent )IsDark ()bool { 497return isDarkColor (e .Color ) 498} 499 500// CursorColorEvent represents a cursor color change event. This event is 501// emitted when the program requests the terminal cursor color using 502// [ansi.RequestCursorColor]. 503type CursorColorEvent struct { color.Color } 504 505// String returns the hex representation of the color. 506func (e CursorColorEvent )String ()string { 507return colorToHex (e ) 508} 509 510// IsDark returns whether the color is dark. 511func (e CursorColorEvent )IsDark ()bool { 512return isDarkColor (e ) 513} 514 515// WindowOpEvent is a window operation (XTWINOPS) report event. This is used to 516// report various window operations such as reporting the window size or cell 517// size. 518type WindowOpEvent struct { 519Op int 520Args []int 521} 522 523// CapabilityEvent represents a Termcap/Terminfo response event. Termcap 524// responses are generated by the terminal in response to RequestTermcap 525// (XTGETTCAP) requests. 526// 527// See: https://invisible-island.net/xterm/ctlseqs/ctlseqs.html#h3-Operating-System-Commands 528type CapabilityEvent struct { 529Content string 530} 531 532// String returns the capability content. 533func (e CapabilityEvent )String ()string { 534return e .Content 535} 536 537// ClipboardSelection represents a clipboard selection. The most common 538// clipboard selections are "system" and "primary" and selections. 539type ClipboardSelection = byte 540 541// Clipboard selections. 542const ( 543SystemClipboard ClipboardSelection = ansi .SystemClipboard 544PrimaryClipboard ClipboardSelection = ansi .PrimaryClipboard 545) 546 547// ClipboardEvent is a clipboard read message event. This message is emitted when 548// a terminal receives an OSC52 clipboard read message event. 549type ClipboardEvent struct { 550Content string 551Selection ClipboardSelection 552} 553 554// String returns the string representation of the clipboard message. 555func (e ClipboardEvent )String ()string { 556return e .Content 557} 558 559// Clipboard returns the clipboard selection. This can be either 560// [SystemClipboard] 'c' or [PrimaryClipboard] 'p'. 561func (e ClipboardEvent )Clipboard ()ClipboardSelection { 562return e .Selection 563} 564 565// ignoredEvent represents a sequence event that is ignored by the terminal 566// reader. This is used to ignore certain sequences that can be canceled. 567type ignoredEvent string