1pub mod ansi_utils;
38pub mod badge;
39pub mod cell;
40pub mod color;
41pub mod color_utils;
42pub mod conformance_level;
43pub mod coprocess;
44pub mod cursor;
45#[macro_use]
46pub mod debug;
47pub mod ffi;
48pub mod grapheme;
49pub mod graphics;
50pub mod grid;
51pub mod html_export;
52pub mod macros;
53pub mod mouse;
54pub mod observer;
55pub mod pty_error;
56pub mod pty_session;
57#[cfg(feature = "python")]
58pub mod python_bindings;
59pub mod screenshot;
60pub mod shell_integration;
61pub mod sixel;
62pub mod streaming;
63pub mod terminal;
64pub mod text_utils;
65pub mod tmux_control;
66pub mod unicode_normalization_config;
67pub mod unicode_width_config;
68pub mod zone;
69
70pub use unicode_normalization_config::NormalizationForm;
72
73pub use unicode_width_config::{
75 char_width, char_width_cjk, is_east_asian_ambiguous, str_width, str_width_cjk, AmbiguousWidth,
76 UnicodeVersion, WidthConfig,
77};
78
79pub use terminal::{
81 RecordingEvent, RecordingEventType, RecordingExportFormat, RecordingFormat, RecordingSession,
82};
83
84pub use badge::{
86 decode_badge_format, evaluate_badge_format, BadgeFormatChanged, BadgeFormatError,
87 SessionVariables,
88};
89
90#[cfg(feature = "python")]
91use pyo3::exceptions::{PyIOError, PyRuntimeError};
92#[cfg(feature = "python")]
93use pyo3::prelude::*;
94
95#[cfg(feature = "python")]
97pub use python_bindings::{
98 decode_client_message, decode_server_message, encode_client_message, encode_server_message,
99 py_adjust_contrast_rgb, py_adjust_hue, py_adjust_saturation, py_char_width, py_char_width_cjk,
100 py_color_luminance, py_complementary_color, py_contrast_ratio, py_darken_rgb, py_hex_to_rgb,
101 py_hsl_to_rgb, py_is_dark_color, py_is_east_asian_ambiguous, py_lighten_rgb, py_meets_wcag_aa,
102 py_meets_wcag_aaa, py_mix_colors, py_perceived_brightness_rgb, py_rgb_to_ansi_256,
103 py_rgb_to_hex, py_rgb_to_hsl, py_str_width, py_str_width_cjk, PyAmbiguousWidth, PyAttributes,
104 PyBenchmarkResult, PyBenchmarkSuite, PyBookmark, PyClipboardEntry, PyClipboardHistoryEntry,
105 PyClipboardSyncEvent, PyColorHSL, PyColorHSV, PyColorPalette, PyCommandExecution,
106 PyComplianceReport, PyComplianceTest, PyCoprocessConfig, PyCursorStyle, PyCwdChange,
107 PyDamageRegion, PyDetectedItem, PyEscapeSequenceProfile, PyFrameTiming, PyGraphic,
108 PyImageDimension, PyImageFormat, PyImagePlacement, PyImageProtocol, PyInlineImage,
109 PyJoinedLines, PyLineDiff, PyMacro, PyMacroEvent, PyMouseEncoding, PyMouseEvent,
110 PyMousePosition, PyNormalizationForm, PyNotificationConfig, PyNotificationEvent, PyPaneState,
111 PyPerformanceMetrics, PyProfilingData, PyProgressBar, PyProgressState, PyPtyTerminal,
112 PyRecordingEvent, PyRecordingSession, PyRegexMatch, PyRenderingHint, PyScreenSnapshot,
113 PyScrollbackStats, PySearchMatch, PySelection, PySelectionMode, PySessionState,
114 PyShellIntegration, PyShellIntegrationStats, PySnapshotDiff, PyStreamingConfig,
115 PyStreamingServer, PyTerminal, PyTmuxNotification, PyTrigger, PyTriggerAction, PyTriggerMatch,
116 PyUnderlineStyle, PyUnicodeVersion, PyWidthConfig, PyWindowLayout,
117};
118
119#[cfg(feature = "python")]
121impl From<pty_error::PtyError> for PyErr {
122 fn from(err: pty_error::PtyError) -> PyErr {
123 match err {
124 pty_error::PtyError::ProcessSpawnError(msg) => {
125 PyRuntimeError::new_err(format!("Failed to spawn process: {}", msg))
126 }
127 pty_error::PtyError::ProcessExitedError(code) => {
128 PyRuntimeError::new_err(format!("Process has exited with code: {}", code))
129 }
130 pty_error::PtyError::IoError(err) => PyIOError::new_err(err.to_string()),
131 pty_error::PtyError::ResizeError(msg) => {
132 PyRuntimeError::new_err(format!("Failed to resize PTY: {}", msg))
133 }
134 pty_error::PtyError::NotStartedError => {
135 PyRuntimeError::new_err("PTY session has not been started")
136 }
137 pty_error::PtyError::LockError(msg) => {
138 PyRuntimeError::new_err(format!("Mutex lock error: {}", msg))
139 }
140 }
141 }
142}
143
144#[cfg(feature = "python")]
146#[pymodule(gil_used = true)]
147fn _native(m: &Bound<'_, PyModule>) -> PyResult<()> {
148 m.add("SIXEL_DISABLED", "disabled")?;
150 m.add("SIXEL_PIXELS", "pixels")?;
151 m.add("SIXEL_HALFBLOCKS", "halfblocks")?;
152
153 m.add_class::<PyTerminal>()?;
155 m.add_class::<PyPtyTerminal>()?;
156 m.add_class::<PyAttributes>()?;
157 m.add_class::<PyScreenSnapshot>()?;
158 m.add_class::<PyShellIntegration>()?;
159 m.add_class::<PyGraphic>()?;
160 m.add_class::<PyImagePlacement>()?;
161 m.add_class::<PyImageDimension>()?;
162 m.add_class::<PyTmuxNotification>()?;
163 m.add_class::<PyCursorStyle>()?;
164 m.add_class::<PyUnderlineStyle>()?;
165 m.add_class::<PyMouseEncoding>()?;
166 m.add_class::<PySearchMatch>()?;
167 m.add_class::<PyDetectedItem>()?;
168 m.add_class::<PySelection>()?;
169 m.add_class::<PySelectionMode>()?;
170 m.add_class::<PyScrollbackStats>()?;
171 m.add_class::<PyBookmark>()?;
172 m.add_class::<PyPerformanceMetrics>()?;
173 m.add_class::<PyFrameTiming>()?;
174 m.add_class::<PyColorHSV>()?;
175 m.add_class::<PyColorHSL>()?;
176 m.add_class::<PyColorPalette>()?;
177 m.add_class::<PyJoinedLines>()?;
178 m.add_class::<PyClipboardEntry>()?;
179 m.add_class::<PyMouseEvent>()?;
180 m.add_class::<PyMousePosition>()?;
181 m.add_class::<PyDamageRegion>()?;
182 m.add_class::<PyRenderingHint>()?;
183 m.add_class::<PyEscapeSequenceProfile>()?;
184 m.add_class::<PyProfilingData>()?;
185 m.add_class::<PyLineDiff>()?;
186 m.add_class::<PySnapshotDiff>()?;
187 m.add_class::<PyRegexMatch>()?;
188 m.add_class::<PyPaneState>()?;
189 m.add_class::<PyWindowLayout>()?;
190 m.add_class::<PySessionState>()?;
191 m.add_class::<PyImageProtocol>()?;
192 m.add_class::<PyImageFormat>()?;
193 m.add_class::<PyInlineImage>()?;
194 m.add_class::<PyBenchmarkResult>()?;
195 m.add_class::<PyBenchmarkSuite>()?;
196 m.add_class::<PyComplianceTest>()?;
197 m.add_class::<PyComplianceReport>()?;
198 m.add_class::<PyClipboardSyncEvent>()?;
199 m.add_class::<PyClipboardHistoryEntry>()?;
200 m.add_class::<PyCommandExecution>()?;
201 m.add_class::<PyShellIntegrationStats>()?;
202 m.add_class::<PyCwdChange>()?;
203 m.add_class::<PyNotificationEvent>()?;
204 m.add_class::<PyNotificationConfig>()?;
205 m.add_class::<PyRecordingEvent>()?;
206 m.add_class::<PyRecordingSession>()?;
207 m.add_class::<PyMacro>()?;
208 m.add_class::<PyMacroEvent>()?;
209 m.add_class::<PyStreamingServer>()?;
210 m.add_class::<PyStreamingConfig>()?;
211 m.add_class::<PyProgressState>()?;
212 m.add_class::<PyProgressBar>()?;
213 m.add_class::<PyUnicodeVersion>()?;
214 m.add_class::<PyAmbiguousWidth>()?;
215 m.add_class::<PyWidthConfig>()?;
216 m.add_class::<PyNormalizationForm>()?;
217 m.add_class::<PyTrigger>()?;
218 m.add_class::<PyTriggerMatch>()?;
219 m.add_class::<PyTriggerAction>()?;
220 m.add_class::<PyCoprocessConfig>()?;
221
222 m.add_function(wrap_pyfunction!(py_perceived_brightness_rgb, m)?)?;
224 m.add_function(wrap_pyfunction!(py_adjust_contrast_rgb, m)?)?;
225 m.add_function(wrap_pyfunction!(py_lighten_rgb, m)?)?;
226 m.add_function(wrap_pyfunction!(py_darken_rgb, m)?)?;
227 m.add_function(wrap_pyfunction!(py_color_luminance, m)?)?;
228 m.add_function(wrap_pyfunction!(py_is_dark_color, m)?)?;
229 m.add_function(wrap_pyfunction!(py_contrast_ratio, m)?)?;
230 m.add_function(wrap_pyfunction!(py_meets_wcag_aa, m)?)?;
231 m.add_function(wrap_pyfunction!(py_meets_wcag_aaa, m)?)?;
232 m.add_function(wrap_pyfunction!(py_mix_colors, m)?)?;
233 m.add_function(wrap_pyfunction!(py_rgb_to_hsl, m)?)?;
234 m.add_function(wrap_pyfunction!(py_hsl_to_rgb, m)?)?;
235 m.add_function(wrap_pyfunction!(py_adjust_saturation, m)?)?;
236 m.add_function(wrap_pyfunction!(py_adjust_hue, m)?)?;
237 m.add_function(wrap_pyfunction!(py_complementary_color, m)?)?;
238 m.add_function(wrap_pyfunction!(py_rgb_to_hex, m)?)?;
239 m.add_function(wrap_pyfunction!(py_hex_to_rgb, m)?)?;
240 m.add_function(wrap_pyfunction!(py_rgb_to_ansi_256, m)?)?;
241
242 m.add_function(wrap_pyfunction!(py_char_width, m)?)?;
244 m.add_function(wrap_pyfunction!(py_char_width_cjk, m)?)?;
245 m.add_function(wrap_pyfunction!(py_str_width, m)?)?;
246 m.add_function(wrap_pyfunction!(py_str_width_cjk, m)?)?;
247 m.add_function(wrap_pyfunction!(py_is_east_asian_ambiguous, m)?)?;
248
249 m.add_function(wrap_pyfunction!(encode_server_message, m)?)?;
251 m.add_function(wrap_pyfunction!(decode_server_message, m)?)?;
252 m.add_function(wrap_pyfunction!(encode_client_message, m)?)?;
253 m.add_function(wrap_pyfunction!(decode_client_message, m)?)?;
254
255 Ok(())
256}