/** * Text selection state for fullscreen mode. * * Tracks a linear selection in screen-buffer coordinates (0-indexed col/row). * Selection is line-based: cells from (startCol, startRow) through * (endCol, endRow) inclusive, wrapping across line boundaries. This matches * terminal-native selection behavior (not rectangular/block). * * The selection is stored as ANCHOR (where the drag started) + FOCUS (where * the cursor is now). The rendered highlight normalizes to start <= end. */ import type { Screen, StylePool } from './screen.js'; type Point = { col: number; row: number; }; export type SelectionState = { /** Where the mouse-down occurred. Null when no selection. */ anchor: Point | null; /** Current drag position (updated on mouse-move while dragging). */ focus: Point | null; /** True between mouse-down and mouse-up. */ isDragging: boolean; /** For word/line mode: the initial word/line bounds from the first * multi-click. Drag extends from this span to the word/line at the * current mouse position so the original word/line stays selected * even when dragging backward past it. Null = char mode. The kind * tells extendSelection whether to snap to word or line boundaries. */ anchorSpan: { lo: Point; hi: Point; kind: 'word' | 'line'; } | null; /** Text from rows that scrolled out ABOVE the viewport during * drag-to-scroll. The screen buffer only holds the current viewport, * so without this accumulator, dragging down past the bottom edge * loses the top of the selection once the anchor clamps. Prepended * to the on-screen text by getSelectedText. Reset on start/clear. */ scrolledOffAbove: string[]; /** Symmetric: rows scrolled out BELOW when dragging up. Appended. */ scrolledOffBelow: string[]; /** Soft-wrap bits parallel to scrolledOffAbove — true means the row * is a continuation of the one before it (the `\n` was inserted by * word-wrap, not in the source). Captured alongside the text at * scroll time since the screen's softWrap bitmap shifts with content. * getSelectedText uses these to join wrapped rows back into logical * lines. */ scrolledOffAboveSW: boolean[]; /** Parallel to scrolledOffBelow. */ scrolledOffBelowSW: boolean[]; /** Pre-clamp anchor row. Set when shiftSelection clamps anchor so a * reverse scroll can restore the true position and pop accumulators. * Without this, PgDn (clamps anchor) -> PgUp leaves anchor at the wrong * row AND scrolledOffAbove stale — highlight != copy. Undefined when * anchor is in-bounds (no clamp debt). Cleared on start/clear. */ virtualAnchorRow?: number; /** Same for focus. */ virtualFocusRow?: number; /** True if the mouse-down that started this selection had the alt * modifier set (SGR button bit 0x08). On macOS xterm.js this is a * signal that VS Code's macOptionClickForcesSelection is OFF — if it * were on, xterm.js would have consumed the event for native selection * and we'd never receive it. Used by the footer to show the right hint. */ lastPressHadAlt: boolean; }; export declare function createSelectionState(): SelectionState; export declare function startSelection(s: SelectionState, col: number, row: number): void; export declare function updateSelection(s: SelectionState, col: number, row: number): void; export declare function finishSelection(s: SelectionState): void; export declare function clearSelection(s: SelectionState): void; export declare function selectWordAt(s: SelectionState, screen: Screen, col: number, row: number): void; export declare function findPlainTextUrlAt(screen: Screen, col: number, row: number): string | undefined; export declare function selectLineAt(s: SelectionState, screen: Screen, row: number): void; export declare function extendSelection(s: SelectionState, screen: Screen, col: number, row: number): void; export type FocusMove = 'left' | 'right' | 'up' | 'down' | 'lineStart' | 'lineEnd'; export declare function moveFocus(s: SelectionState, col: number, row: number): void; export declare function shiftSelection(s: SelectionState, dRow: number, minRow: number, maxRow: number, width: number): void; export declare function shiftAnchor(s: SelectionState, dRow: number, minRow: number, maxRow: number): void; export declare function shiftSelectionForFollow(s: SelectionState, dRow: number, minRow: number, maxRow: number): boolean; export declare function hasSelection(s: SelectionState): boolean; export declare function selectionBounds(s: SelectionState): { start: { col: number; row: number; }; end: { col: number; row: number; }; } | null; export declare function isCellSelected(s: SelectionState, col: number, row: number): boolean; export declare function getSelectedText(s: SelectionState, screen: Screen): string; export declare function captureScrolledRows(s: SelectionState, screen: Screen, firstRow: number, lastRow: number, side: 'above' | 'below'): void; export declare function applySelectionOverlay(screen: Screen, selection: SelectionState, stylePool: StylePool): void; export {}; //# sourceMappingURL=selection.d.ts.map