* Moves the characters from `start` and `end` to `index`.
(start: number, end: number, index: number)
| 488 | * Moves the characters from `start` and `end` to `index`. |
| 489 | */ |
| 490 | move(start: number, end: number, index: number): this { |
| 491 | start = start + this.offset |
| 492 | end = end + this.offset |
| 493 | index = index + this.offset |
| 494 | |
| 495 | if (start === end) |
| 496 | return this |
| 497 | |
| 498 | if (index >= start && index <= end) { |
| 499 | throw new MagicStringError('cannot move a selection inside itself') |
| 500 | } |
| 501 | |
| 502 | if (DEBUG) |
| 503 | this.stats.time('move') |
| 504 | |
| 505 | this._split(start) |
| 506 | this._split(end) |
| 507 | this._split(index) |
| 508 | |
| 509 | const first = this.byStart.get(start) |
| 510 | const last = this.byEnd.get(end) |
| 511 | |
| 512 | // The splicing below assumes the chunks spanning [start, end) are still a |
| 513 | // forward run in the current list. An earlier move can have interleaved a |
| 514 | // chunk from outside the range, or put `last` before `first`, and then the |
| 515 | // pointer rewrites produce a cycle rather than an error, so toString() and |
| 516 | // generateMap() loop forever. |
| 517 | // |
| 518 | // Only move() reorders chunks, so this is skipped until one has run, which |
| 519 | // keeps the common single-move case free of the walk. |
| 520 | if (this.hasMovedChunks) { |
| 521 | let cursor = first |
| 522 | while (cursor !== last) { |
| 523 | cursor = cursor.next |
| 524 | if (!cursor || cursor.start < start || cursor.end > end) { |
| 525 | throw new MagicStringError( |
| 526 | `cannot move ${start} to ${end} because an earlier move split that range`, |
| 527 | ) |
| 528 | } |
| 529 | } |
| 530 | } |
| 531 | |
| 532 | const oldLeft = first.previous |
| 533 | const oldRight = last.next |
| 534 | |
| 535 | const newRight = this.byStart.get(index) |
| 536 | if (!newRight && last === this.lastChunk) |
| 537 | return this |
| 538 | const newLeft = newRight ? newRight.previous : this.lastChunk |
| 539 | |
| 540 | if (oldLeft) |
| 541 | oldLeft.next = oldRight |
| 542 | if (oldRight) |
| 543 | oldRight.previous = oldLeft |
| 544 | |
| 545 | if (newLeft) |
| 546 | newLeft.next = first |
| 547 | if (newRight) |