(screen: VirtualScreen, targetX: number, targetY: number)
| 1700 | } |
| 1701 | |
| 1702 | function moveCursorTo(screen: VirtualScreen, targetX: number, targetY: number) { |
| 1703 | const dx = targetX - screen.cursor.x |
| 1704 | const dy = targetY - screen.cursor.y |
| 1705 | const inPendingWrap = screen.cursor.x >= screen.viewportWidth |
| 1706 | |
| 1707 | if (dx === 0 && dy === 0) { |
| 1708 | recordMoveCursorStats('noop') |
| 1709 | return |
| 1710 | } |
| 1711 | |
| 1712 | if (inPendingWrap) { |
| 1713 | recordMoveCursorStats('pending-wrap') |
| 1714 | screen.txn(() => [ |
| 1715 | [CARRIAGE_RETURN, { type: 'cursorMove', x: targetX, y: dy }], |
| 1716 | { dx, dy }, |
| 1717 | ]) |
| 1718 | return |
| 1719 | } |
| 1720 | |
| 1721 | if (dy !== 0) { |
| 1722 | if (dy === 1) { |
| 1723 | recordMoveCursorStats( |
| 1724 | targetX === 0 |
| 1725 | ? 'line-change-next-row-home' |
| 1726 | : 'line-change-next-row-offset', |
| 1727 | ) |
| 1728 | if (targetX === 0) { |
| 1729 | screen.txn(prev => [[CARRIAGE_RETURN, NEWLINE], { dx: -prev.x, dy: 1 }]) |
| 1730 | return |
| 1731 | } |
| 1732 | screen.txn(prev => [ |
| 1733 | [CARRIAGE_RETURN, NEWLINE, { type: 'cursorMove', x: targetX, y: 0 }], |
| 1734 | { dx: targetX - prev.x, dy: 1 }, |
| 1735 | ]) |
| 1736 | return |
| 1737 | } else { |
| 1738 | recordMoveCursorStats( |
| 1739 | targetX === 0 |
| 1740 | ? 'line-change-multi-row-home' |
| 1741 | : 'line-change-multi-row-offset', |
| 1742 | ) |
| 1743 | } |
| 1744 | screen.txn(() => [ |
| 1745 | [CARRIAGE_RETURN, { type: 'cursorMove', x: targetX, y: dy }], |
| 1746 | { dx, dy }, |
| 1747 | ]) |
| 1748 | return |
| 1749 | } |
| 1750 | |
| 1751 | recordMoveCursorStats('same-line') |
| 1752 | screen.txn(() => [[{ type: 'cursorMove', x: dx, y: dy }], { dx, dy }]) |
| 1753 | } |
| 1754 | |
| 1755 | /** |
| 1756 | * Identify emoji where the terminal's wcwidth may disagree with Unicode. |
no test coverage detected