( terminal: Terminal, diff: Diff, skipSyncMarkers = false, )
| 188 | } |
| 189 | |
| 190 | export function writeDiffToTerminal( |
| 191 | terminal: Terminal, |
| 192 | diff: Diff, |
| 193 | skipSyncMarkers = false, |
| 194 | ): void { |
| 195 | // No output if there are no patches |
| 196 | if (diff.length === 0) { |
| 197 | return |
| 198 | } |
| 199 | |
| 200 | // BSU/ESU wrapping is opt-out to keep main-screen behavior unchanged. |
| 201 | // Callers pass skipSyncMarkers=true when the terminal doesn't support |
| 202 | // DEC 2026 (e.g. tmux) AND the cost matters (high-frequency alt-screen). |
| 203 | const useSync = !skipSyncMarkers |
| 204 | |
| 205 | // Buffer all writes into a single string to avoid multiple write calls |
| 206 | let buffer = useSync ? BSU : '' |
| 207 | |
| 208 | for (const patch of diff) { |
| 209 | switch (patch.type) { |
| 210 | case 'stdout': |
| 211 | buffer += patch.content |
| 212 | break |
| 213 | case 'clear': |
| 214 | if (patch.count > 0) { |
| 215 | buffer += eraseLines(patch.count) |
| 216 | } |
| 217 | break |
| 218 | case 'clearTerminal': |
| 219 | buffer += getClearTerminalSequence() |
| 220 | break |
| 221 | case 'cursorHide': |
| 222 | buffer += HIDE_CURSOR |
| 223 | break |
| 224 | case 'cursorShow': |
| 225 | buffer += SHOW_CURSOR |
| 226 | break |
| 227 | case 'cursorMove': |
| 228 | buffer += cursorMove(patch.x, patch.y) |
| 229 | break |
| 230 | case 'cursorTo': |
| 231 | buffer += cursorTo(patch.col) |
| 232 | break |
| 233 | case 'carriageReturn': |
| 234 | buffer += '\r' |
| 235 | break |
| 236 | case 'hyperlink': |
| 237 | buffer += link(patch.uri) |
| 238 | break |
| 239 | case 'styleStr': |
| 240 | buffer += patch.str |
| 241 | break |
| 242 | } |
| 243 | } |
| 244 | |
| 245 | // Add synchronized update end and flush buffer |
| 246 | if (useSync) buffer += ESU |
| 247 | terminal.stdout.write(buffer) |
no test coverage detected