| 159 | * Key Encoder - converts keyboard events into terminal escape sequences |
| 160 | */ |
| 161 | export class KeyEncoder { |
| 162 | private exports: GhosttyWasmExports; |
| 163 | private encoder: number = 0; |
| 164 | |
| 165 | constructor(exports: GhosttyWasmExports) { |
| 166 | this.exports = exports; |
| 167 | const encoderPtrPtr = this.exports.ghostty_wasm_alloc_opaque(); |
| 168 | const result = this.exports.ghostty_key_encoder_new(0, encoderPtrPtr); |
| 169 | if (result !== 0) throw new Error(`Failed to create key encoder: ${result}`); |
| 170 | const view = new DataView(this.exports.memory.buffer); |
| 171 | this.encoder = view.getUint32(encoderPtrPtr, true); |
| 172 | this.exports.ghostty_wasm_free_opaque(encoderPtrPtr); |
| 173 | } |
| 174 | |
| 175 | setOption(option: KeyEncoderOption, value: boolean | number): void { |
| 176 | const valuePtr = this.exports.ghostty_wasm_alloc_u8(); |
| 177 | const view = new DataView(this.exports.memory.buffer); |
| 178 | view.setUint8(valuePtr, typeof value === 'boolean' ? (value ? 1 : 0) : value); |
| 179 | this.exports.ghostty_key_encoder_setopt(this.encoder, option, valuePtr); |
| 180 | this.exports.ghostty_wasm_free_u8(valuePtr); |
| 181 | } |
| 182 | |
| 183 | setKittyFlags(flags: KittyKeyFlags): void { |
| 184 | this.setOption(KeyEncoderOption.KITTY_KEYBOARD_FLAGS, flags); |
| 185 | } |
| 186 | |
| 187 | encode(event: KeyEvent): Uint8Array { |
| 188 | const eventPtrPtr = this.exports.ghostty_wasm_alloc_opaque(); |
| 189 | const createResult = this.exports.ghostty_key_event_new(0, eventPtrPtr); |
| 190 | if (createResult !== 0) throw new Error(`Failed to create key event: ${createResult}`); |
| 191 | |
| 192 | const view = new DataView(this.exports.memory.buffer); |
| 193 | const eventPtr = view.getUint32(eventPtrPtr, true); |
| 194 | this.exports.ghostty_wasm_free_opaque(eventPtrPtr); |
| 195 | |
| 196 | this.exports.ghostty_key_event_set_action(eventPtr, event.action); |
| 197 | this.exports.ghostty_key_event_set_key(eventPtr, event.key); |
| 198 | this.exports.ghostty_key_event_set_mods(eventPtr, event.mods); |
| 199 | |
| 200 | if (event.utf8) { |
| 201 | const encoder = new TextEncoder(); |
| 202 | const utf8Bytes = encoder.encode(event.utf8); |
| 203 | const utf8Ptr = this.exports.ghostty_wasm_alloc_u8_array(utf8Bytes.length); |
| 204 | new Uint8Array(this.exports.memory.buffer).set(utf8Bytes, utf8Ptr); |
| 205 | this.exports.ghostty_key_event_set_utf8(eventPtr, utf8Ptr, utf8Bytes.length); |
| 206 | this.exports.ghostty_wasm_free_u8_array(utf8Ptr, utf8Bytes.length); |
| 207 | } |
| 208 | |
| 209 | const bufferSize = 32; |
| 210 | const bufPtr = this.exports.ghostty_wasm_alloc_u8_array(bufferSize); |
| 211 | const writtenPtr = this.exports.ghostty_wasm_alloc_usize(); |
| 212 | |
| 213 | const encodeResult = this.exports.ghostty_key_encoder_encode( |
| 214 | this.encoder, |
| 215 | eventPtr, |
| 216 | bufPtr, |
| 217 | bufferSize, |
| 218 | writtenPtr |
nothing calls this directly
no outgoing calls
no test coverage detected
searching dependent graphs…