* Normalize selection coordinates (handle backward selection) * Returns coordinates in VIEWPORT space for rendering, clamped to visible area
()
| 770 | * Returns coordinates in VIEWPORT space for rendering, clamped to visible area |
| 771 | */ |
| 772 | private normalizeSelection(): SelectionCoordinates | null { |
| 773 | if (!this.selectionStart || !this.selectionEnd) return null; |
| 774 | |
| 775 | let { col: startCol, absoluteRow: startAbsRow } = this.selectionStart; |
| 776 | let { col: endCol, absoluteRow: endAbsRow } = this.selectionEnd; |
| 777 | |
| 778 | // Swap if selection goes backwards |
| 779 | if (startAbsRow > endAbsRow || (startAbsRow === endAbsRow && startCol > endCol)) { |
| 780 | [startCol, endCol] = [endCol, startCol]; |
| 781 | [startAbsRow, endAbsRow] = [endAbsRow, startAbsRow]; |
| 782 | } |
| 783 | |
| 784 | // Convert to viewport coordinates |
| 785 | let startRow = this.absoluteRowToViewport(startAbsRow); |
| 786 | let endRow = this.absoluteRowToViewport(endAbsRow); |
| 787 | |
| 788 | // Clamp to visible viewport range |
| 789 | const dims = this.wasmTerm.getDimensions(); |
| 790 | const maxRow = dims.rows - 1; |
| 791 | |
| 792 | // If entire selection is outside viewport, return null |
| 793 | if (endRow < 0 || startRow > maxRow) { |
| 794 | return null; |
| 795 | } |
| 796 | |
| 797 | // Clamp rows to visible range, adjusting columns for partial rows |
| 798 | if (startRow < 0) { |
| 799 | startRow = 0; |
| 800 | startCol = 0; // Selection starts from beginning of first visible row |
| 801 | } |
| 802 | if (endRow > maxRow) { |
| 803 | endRow = maxRow; |
| 804 | endCol = dims.cols - 1; // Selection extends to end of last visible row |
| 805 | } |
| 806 | |
| 807 | return { startCol, startRow, endCol, endRow }; |
| 808 | } |
| 809 | |
| 810 | /** |
| 811 | * Get word boundaries at a cell position |
no test coverage detected