()
| 618 | } |
| 619 | |
| 620 | prevWord(): Cursor { |
| 621 | if (this.isAtStart()) { |
| 622 | return this |
| 623 | } |
| 624 | |
| 625 | // Use Intl.Segmenter for proper word boundary detection (including CJK) |
| 626 | const wordBoundaries = this.measuredText.getWordBoundaries() |
| 627 | |
| 628 | // Find the previous word start boundary before current position |
| 629 | // We need to iterate in reverse to find the previous word |
| 630 | let prevWordStart: number | null = null |
| 631 | |
| 632 | for (const boundary of wordBoundaries) { |
| 633 | if (!boundary.isWordLike) continue |
| 634 | |
| 635 | // If we're at or after the start of this word, but this word starts before us |
| 636 | if (boundary.start < this.offset) { |
| 637 | // If we're inside this word (not at the start), go to its start |
| 638 | if (this.offset > boundary.start && this.offset <= boundary.end) { |
| 639 | return new Cursor(this.measuredText, boundary.start) |
| 640 | } |
| 641 | // Otherwise, remember this as a candidate for previous word |
| 642 | prevWordStart = boundary.start |
| 643 | } |
| 644 | } |
| 645 | |
| 646 | if (prevWordStart !== null) { |
| 647 | return new Cursor(this.measuredText, prevWordStart) |
| 648 | } |
| 649 | |
| 650 | return new Cursor(this.measuredText, 0) |
| 651 | } |
| 652 | |
| 653 | // Vim-specific word methods |
| 654 | // In Vim, a "word" is either: |
no test coverage detected