| 1382 | * this is applied to next.screen during scroll fast path. |
| 1383 | */ |
| 1384 | export function shiftRows( |
| 1385 | screen: Screen, |
| 1386 | top: number, |
| 1387 | bottom: number, |
| 1388 | n: number, |
| 1389 | ): void { |
| 1390 | if (n === 0 || top < 0 || bottom >= screen.height || top > bottom) return |
| 1391 | const w = screen.width |
| 1392 | const cells64 = screen.cells64 |
| 1393 | const noSel = screen.noSelect |
| 1394 | const sw = screen.softWrap |
| 1395 | const contentEnd = screen.contentEnd |
| 1396 | const absN = Math.abs(n) |
| 1397 | if (absN > bottom - top) { |
| 1398 | cells64.fill(EMPTY_CELL_VALUE, top * w, (bottom + 1) * w) |
| 1399 | noSel.fill(0, top * w, (bottom + 1) * w) |
| 1400 | sw.fill(0, top, bottom + 1) |
| 1401 | contentEnd.fill(0, top, bottom + 1) |
| 1402 | return |
| 1403 | } |
| 1404 | if (n > 0) { |
| 1405 | // SU: row top+n..bottom → top..bottom-n; clear bottom-n+1..bottom |
| 1406 | cells64.copyWithin(top * w, (top + n) * w, (bottom + 1) * w) |
| 1407 | noSel.copyWithin(top * w, (top + n) * w, (bottom + 1) * w) |
| 1408 | sw.copyWithin(top, top + n, bottom + 1) |
| 1409 | contentEnd.copyWithin(top, top + n, bottom + 1) |
| 1410 | cells64.fill(EMPTY_CELL_VALUE, (bottom - n + 1) * w, (bottom + 1) * w) |
| 1411 | noSel.fill(0, (bottom - n + 1) * w, (bottom + 1) * w) |
| 1412 | sw.fill(0, bottom - n + 1, bottom + 1) |
| 1413 | contentEnd.fill(0, bottom - n + 1, bottom + 1) |
| 1414 | } else { |
| 1415 | // SD: row top..bottom+n → top-n..bottom; clear top..top-n-1 |
| 1416 | cells64.copyWithin((top - n) * w, top * w, (bottom + n + 1) * w) |
| 1417 | noSel.copyWithin((top - n) * w, top * w, (bottom + n + 1) * w) |
| 1418 | sw.copyWithin(top - n, top, bottom + n + 1) |
| 1419 | contentEnd.copyWithin(top - n, top, bottom + n + 1) |
| 1420 | cells64.fill(EMPTY_CELL_VALUE, top * w, (top - n) * w) |
| 1421 | noSel.fill(0, top * w, (top - n) * w) |
| 1422 | sw.fill(0, top, top - n) |
| 1423 | contentEnd.fill(0, top, top - n) |
| 1424 | } |
| 1425 | } |
| 1426 | |
| 1427 | // Matches OSC 8 ; ; URI BEL |
| 1428 | const OSC8_REGEX = new RegExp(`^${ESC}\\]8${SEP}${SEP}([^${BEL}]*)${BEL}$`) |