Path: blob/main/src/vs/editor/common/cursor/cursorColumnSelection.ts
3294 views
/*---------------------------------------------------------------------------------------------1* Copyright (c) Microsoft Corporation. All rights reserved.2* Licensed under the MIT License. See License.txt in the project root for license information.3*--------------------------------------------------------------------------------------------*/45import { CursorConfiguration, ICursorSimpleModel, SingleCursorState, IColumnSelectData, SelectionStartKind } from '../cursorCommon.js';6import { Position } from '../core/position.js';7import { Range } from '../core/range.js';89export class ColumnSelection {1011public static columnSelect(config: CursorConfiguration, model: ICursorSimpleModel, fromLineNumber: number, fromVisibleColumn: number, toLineNumber: number, toVisibleColumn: number): IColumnSelectResult {12const lineCount = Math.abs(toLineNumber - fromLineNumber) + 1;13const reversed = (fromLineNumber > toLineNumber);14const isRTL = (fromVisibleColumn > toVisibleColumn);15const isLTR = (fromVisibleColumn < toVisibleColumn);1617const result: SingleCursorState[] = [];1819// console.log(`fromVisibleColumn: ${fromVisibleColumn}, toVisibleColumn: ${toVisibleColumn}`);2021for (let i = 0; i < lineCount; i++) {22const lineNumber = fromLineNumber + (reversed ? -i : i);2324const startColumn = config.columnFromVisibleColumn(model, lineNumber, fromVisibleColumn);25const endColumn = config.columnFromVisibleColumn(model, lineNumber, toVisibleColumn);26const visibleStartColumn = config.visibleColumnFromColumn(model, new Position(lineNumber, startColumn));27const visibleEndColumn = config.visibleColumnFromColumn(model, new Position(lineNumber, endColumn));2829// console.log(`lineNumber: ${lineNumber}: visibleStartColumn: ${visibleStartColumn}, visibleEndColumn: ${visibleEndColumn}`);3031if (isLTR) {32if (visibleStartColumn > toVisibleColumn) {33continue;34}35if (visibleEndColumn < fromVisibleColumn) {36continue;37}38}3940if (isRTL) {41if (visibleEndColumn > fromVisibleColumn) {42continue;43}44if (visibleStartColumn < toVisibleColumn) {45continue;46}47}4849result.push(new SingleCursorState(50new Range(lineNumber, startColumn, lineNumber, startColumn), SelectionStartKind.Simple, 0,51new Position(lineNumber, endColumn), 052));53}5455if (result.length === 0) {56// We are after all the lines, so add cursor at the end of each line57for (let i = 0; i < lineCount; i++) {58const lineNumber = fromLineNumber + (reversed ? -i : i);59const maxColumn = model.getLineMaxColumn(lineNumber);6061result.push(new SingleCursorState(62new Range(lineNumber, maxColumn, lineNumber, maxColumn), SelectionStartKind.Simple, 0,63new Position(lineNumber, maxColumn), 064));65}66}6768return {69viewStates: result,70reversed: reversed,71fromLineNumber: fromLineNumber,72fromVisualColumn: fromVisibleColumn,73toLineNumber: toLineNumber,74toVisualColumn: toVisibleColumn75};76}7778public static columnSelectLeft(config: CursorConfiguration, model: ICursorSimpleModel, prevColumnSelectData: IColumnSelectData): IColumnSelectResult {79let toViewVisualColumn = prevColumnSelectData.toViewVisualColumn;80if (toViewVisualColumn > 0) {81toViewVisualColumn--;82}8384return ColumnSelection.columnSelect(config, model, prevColumnSelectData.fromViewLineNumber, prevColumnSelectData.fromViewVisualColumn, prevColumnSelectData.toViewLineNumber, toViewVisualColumn);85}8687public static columnSelectRight(config: CursorConfiguration, model: ICursorSimpleModel, prevColumnSelectData: IColumnSelectData): IColumnSelectResult {88let maxVisualViewColumn = 0;89const minViewLineNumber = Math.min(prevColumnSelectData.fromViewLineNumber, prevColumnSelectData.toViewLineNumber);90const maxViewLineNumber = Math.max(prevColumnSelectData.fromViewLineNumber, prevColumnSelectData.toViewLineNumber);91for (let lineNumber = minViewLineNumber; lineNumber <= maxViewLineNumber; lineNumber++) {92const lineMaxViewColumn = model.getLineMaxColumn(lineNumber);93const lineMaxVisualViewColumn = config.visibleColumnFromColumn(model, new Position(lineNumber, lineMaxViewColumn));94maxVisualViewColumn = Math.max(maxVisualViewColumn, lineMaxVisualViewColumn);95}9697let toViewVisualColumn = prevColumnSelectData.toViewVisualColumn;98if (toViewVisualColumn < maxVisualViewColumn) {99toViewVisualColumn++;100}101102return this.columnSelect(config, model, prevColumnSelectData.fromViewLineNumber, prevColumnSelectData.fromViewVisualColumn, prevColumnSelectData.toViewLineNumber, toViewVisualColumn);103}104105public static columnSelectUp(config: CursorConfiguration, model: ICursorSimpleModel, prevColumnSelectData: IColumnSelectData, isPaged: boolean): IColumnSelectResult {106const linesCount = isPaged ? config.pageSize : 1;107const toViewLineNumber = Math.max(1, prevColumnSelectData.toViewLineNumber - linesCount);108return this.columnSelect(config, model, prevColumnSelectData.fromViewLineNumber, prevColumnSelectData.fromViewVisualColumn, toViewLineNumber, prevColumnSelectData.toViewVisualColumn);109}110111public static columnSelectDown(config: CursorConfiguration, model: ICursorSimpleModel, prevColumnSelectData: IColumnSelectData, isPaged: boolean): IColumnSelectResult {112const linesCount = isPaged ? config.pageSize : 1;113const toViewLineNumber = Math.min(model.getLineCount(), prevColumnSelectData.toViewLineNumber + linesCount);114return this.columnSelect(config, model, prevColumnSelectData.fromViewLineNumber, prevColumnSelectData.fromViewVisualColumn, toViewLineNumber, prevColumnSelectData.toViewVisualColumn);115}116}117118export interface IColumnSelectResult {119viewStates: SingleCursorState[];120reversed: boolean;121fromLineNumber: number;122fromVisualColumn: number;123toLineNumber: number;124toVisualColumn: number;125}126127128