( input: string, initialState: State, initialBuffer: string, flush: boolean, x10Mouse: boolean, )
| 97 | } |
| 98 | |
| 99 | function tokenize( |
| 100 | input: string, |
| 101 | initialState: State, |
| 102 | initialBuffer: string, |
| 103 | flush: boolean, |
| 104 | x10Mouse: boolean, |
| 105 | ): { tokens: Token[]; state: InternalState } { |
| 106 | const tokens: Token[] = [] |
| 107 | const result: InternalState = { |
| 108 | state: initialState, |
| 109 | buffer: '', |
| 110 | } |
| 111 | |
| 112 | const data = initialBuffer + input |
| 113 | let i = 0 |
| 114 | let textStart = 0 |
| 115 | let seqStart = 0 |
| 116 | |
| 117 | const flushText = (): void => { |
| 118 | if (i > textStart) { |
| 119 | const text = data.slice(textStart, i) |
| 120 | if (text) { |
| 121 | tokens.push({ type: 'text', value: text }) |
| 122 | } |
| 123 | } |
| 124 | textStart = i |
| 125 | } |
| 126 | |
| 127 | const emitSequence = (seq: string): void => { |
| 128 | if (seq) { |
| 129 | tokens.push({ type: 'sequence', value: seq }) |
| 130 | } |
| 131 | result.state = 'ground' |
| 132 | textStart = i |
| 133 | } |
| 134 | |
| 135 | while (i < data.length) { |
| 136 | const code = data.charCodeAt(i) |
| 137 | |
| 138 | switch (result.state) { |
| 139 | case 'ground': |
| 140 | if (code === C0.ESC) { |
| 141 | flushText() |
| 142 | seqStart = i |
| 143 | result.state = 'escape' |
| 144 | i++ |
| 145 | } else { |
| 146 | i++ |
| 147 | } |
| 148 | break |
| 149 | |
| 150 | case 'escape': |
| 151 | if (code === ESC_TYPE.CSI) { |
| 152 | result.state = 'csi' |
| 153 | i++ |
| 154 | } else if (code === ESC_TYPE.OSC) { |
| 155 | result.state = 'osc' |
| 156 | i++ |
no test coverage detected