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