UNPKG

ink

Version:
56 lines 2.49 kB
import ansiEscapes from 'ansi-escapes'; const showCursorEscape = '\u001B[?25h'; const hideCursorEscape = '\u001B[?25l'; export { showCursorEscape, hideCursorEscape }; /** Compare two cursor positions. Returns true if they differ. */ export const cursorPositionChanged = (a, b) => a?.x !== b?.x || a?.y !== b?.y; /** Build escape sequence to move cursor from bottom of output to the target position and show it. Assumes cursor is at (col 0, line visibleLineCount) — i.e. just after the last output line. */ export const buildCursorSuffix = (visibleLineCount, cursorPosition) => { if (!cursorPosition) { return ''; } const moveUp = visibleLineCount - cursorPosition.y; return ((moveUp > 0 ? ansiEscapes.cursorUp(moveUp) : '') + ansiEscapes.cursorTo(cursorPosition.x) + showCursorEscape); }; /** Build escape sequence to move cursor from previousCursorPosition back to the bottom of output. This must be done before eraseLines or any operation that assumes cursor is at the bottom. */ export const buildReturnToBottom = (previousLineCount, previousCursorPosition) => { if (!previousCursorPosition) { return ''; } // PreviousLineCount includes trailing newline, so visible lines = previousLineCount - 1 // cursor is at previousCursorPosition.y, need to go to line (previousLineCount - 1) const down = previousLineCount - 1 - previousCursorPosition.y; return ((down > 0 ? ansiEscapes.cursorDown(down) : '') + ansiEscapes.cursorTo(0)); }; /** Build the escape sequence for cursor-only updates (output unchanged, cursor moved). Hides cursor if it was previously shown, returns to bottom, then repositions. */ export const buildCursorOnlySequence = (input) => { const hidePrefix = input.cursorWasShown ? hideCursorEscape : ''; const returnToBottom = buildReturnToBottom(input.previousLineCount, input.previousCursorPosition); const cursorSuffix = buildCursorSuffix(input.visibleLineCount, input.cursorPosition); return hidePrefix + returnToBottom + cursorSuffix; }; /** Build the prefix that hides cursor and returns to bottom before erasing or rewriting. Returns empty string if cursor was not shown. */ export const buildReturnToBottomPrefix = (cursorWasShown, previousLineCount, previousCursorPosition) => { if (!cursorWasShown) { return ''; } return (hideCursorEscape + buildReturnToBottom(previousLineCount, previousCursorPosition)); }; //# sourceMappingURL=cursor-helpers.js.map