MCPcopy Index your code
hub / github.com/codeaashu/claude-code / parseMultipleKeypresses

Function parseMultipleKeypresses

src/ink/parse-keypress.ts:213–302  ·  view source on GitHub ↗
(
  prevState: KeyParseState,
  input: Buffer | string | null = '',
)

Source from the content-addressed store, hash-verified

211}
212
213export function parseMultipleKeypresses(
214 prevState: KeyParseState,
215 input: Buffer | string | null = '',
216): [ParsedInput[], KeyParseState] {
217 const isFlush = input === null
218 const inputString = isFlush ? '' : inputToString(input)
219
220 // Get or create tokenizer
221 const tokenizer = prevState._tokenizer ?? createTokenizer({ x10Mouse: true })
222
223 // Tokenize the input
224 const tokens = isFlush ? tokenizer.flush() : tokenizer.feed(inputString)
225
226 // Convert tokens to parsed keys, handling paste mode
227 const keys: ParsedInput[] = []
228 let inPaste = prevState.mode === 'IN_PASTE'
229 let pasteBuffer = prevState.pasteBuffer
230
231 for (const token of tokens) {
232 if (token.type === 'sequence') {
233 if (token.value === PASTE_START) {
234 inPaste = true
235 pasteBuffer = ''
236 } else if (token.value === PASTE_END) {
237 // Always emit a paste key, even for empty pastes. This allows
238 // downstream handlers to detect empty pastes (e.g., for clipboard
239 // image handling on macOS). The paste content may be empty string.
240 keys.push(createPasteKey(pasteBuffer))
241 inPaste = false
242 pasteBuffer = ''
243 } else if (inPaste) {
244 // Sequences inside paste are treated as literal text
245 pasteBuffer += token.value
246 } else {
247 const response = parseTerminalResponse(token.value)
248 if (response) {
249 keys.push({ kind: 'response', sequence: token.value, response })
250 } else {
251 const mouse = parseMouseEvent(token.value)
252 if (mouse) {
253 keys.push(mouse)
254 } else {
255 keys.push(parseKeypress(token.value))
256 }
257 }
258 }
259 } else if (token.type === 'text') {
260 if (inPaste) {
261 pasteBuffer += token.value
262 } else if (
263 /^\[<\d+;\d+;\d+[Mm]$/.test(token.value) ||
264 /^\[M[\x60-\x7f][\x20-\uffff]{2}$/.test(token.value)
265 ) {
266 // Orphaned SGR/X10 mouse tail (fullscreen only — mouse tracking is off
267 // otherwise). A heavy render blocked the event loop past App's 50ms
268 // flush timer, so the buffered ESC was flushed as a lone Escape and
269 // the continuation `[<btn;col;rowM` arrived as text. Re-synthesize
270 // with the ESC prefix so the scroll event still fires instead of

Callers 1

AppClass · 0.85

Calls 10

inputToStringFunction · 0.85
createTokenizerFunction · 0.85
createPasteKeyFunction · 0.85
parseTerminalResponseFunction · 0.85
parseMouseEventFunction · 0.85
parseKeypressFunction · 0.85
feedMethod · 0.80
flushMethod · 0.45
pushMethod · 0.45
bufferMethod · 0.45

Tested by

no test coverage detected