()
| 593 | } |
| 594 | |
| 595 | prevWord(): Cursor { |
| 596 | if (this.isAtStart()) { |
| 597 | return this |
| 598 | } |
| 599 | |
| 600 | // Use Intl.Segmenter for proper word boundary detection (including CJK) |
| 601 | const wordBoundaries = this.measuredText.getWordBoundaries() |
| 602 | |
| 603 | // Find the previous word start boundary before current position |
| 604 | // We need to iterate in reverse to find the previous word |
| 605 | let prevWordStart: number | null = null |
| 606 | |
| 607 | for (const boundary of wordBoundaries) { |
| 608 | if (!boundary.isWordLike) continue |
| 609 | |
| 610 | // If we're at or after the start of this word, but this word starts before us |
| 611 | if (boundary.start < this.offset) { |
| 612 | // If we're inside this word (not at the start), go to its start |
| 613 | if (this.offset > boundary.start && this.offset <= boundary.end) { |
| 614 | return new Cursor(this.measuredText, boundary.start) |
| 615 | } |
| 616 | // Otherwise, remember this as a candidate for previous word |
| 617 | prevWordStart = boundary.start |
| 618 | } |
| 619 | } |
| 620 | |
| 621 | if (prevWordStart !== null) { |
| 622 | return new Cursor(this.measuredText, prevWordStart) |
| 623 | } |
| 624 | |
| 625 | return new Cursor(this.measuredText, 0) |
| 626 | } |
| 627 | |
| 628 | // Vim-specific word methods |
| 629 | // In Vim, a "word" is either: |
no test coverage detected