+++ /dev/null
-/**
- * Copyright (c) 2017 The xterm.js authors. All rights reserved.
- * @license MIT
- */
-
-import { IBufferService } from 'common/services/Services';
-
-/**
- * Represents a selection within the buffer. This model only cares about column
- * and row coordinates, not wide characters.
- */
-export class SelectionModel {
- /**
- * Whether select all is currently active.
- */
- public isSelectAllActive: boolean = false;
-
- /**
- * The minimal length of the selection from the start position. When double
- * clicking on a word, the word will be selected which makes the selection
- * start at the start of the word and makes this variable the length.
- */
- public selectionStartLength: number = 0;
-
- /**
- * The [x, y] position the selection starts at.
- */
- public selectionStart: [number, number] | undefined;
-
- /**
- * The [x, y] position the selection ends at.
- */
- public selectionEnd: [number, number] | undefined;
-
- constructor(
- private _bufferService: IBufferService
- ) {
- }
-
- /**
- * Clears the current selection.
- */
- public clearSelection(): void {
- this.selectionStart = undefined;
- this.selectionEnd = undefined;
- this.isSelectAllActive = false;
- this.selectionStartLength = 0;
- }
-
- /**
- * The final selection start, taking into consideration select all.
- */
- public get finalSelectionStart(): [number, number] | undefined {
- if (this.isSelectAllActive) {
- return [0, 0];
- }
-
- if (!this.selectionEnd || !this.selectionStart) {
- return this.selectionStart;
- }
-
- return this.areSelectionValuesReversed() ? this.selectionEnd : this.selectionStart;
- }
-
- /**
- * The final selection end, taking into consideration select all, double click
- * word selection and triple click line selection.
- */
- public get finalSelectionEnd(): [number, number] | undefined {
- if (this.isSelectAllActive) {
- return [this._bufferService.cols, this._bufferService.buffer.ybase + this._bufferService.rows - 1];
- }
-
- if (!this.selectionStart) {
- return undefined;
- }
-
- // Use the selection start + length if the end doesn't exist or they're reversed
- if (!this.selectionEnd || this.areSelectionValuesReversed()) {
- const startPlusLength = this.selectionStart[0] + this.selectionStartLength;
- if (startPlusLength > this._bufferService.cols) {
- return [startPlusLength % this._bufferService.cols, this.selectionStart[1] + Math.floor(startPlusLength / this._bufferService.cols)];
- }
- return [startPlusLength, this.selectionStart[1]];
- }
-
- // Ensure the the word/line is selected after a double/triple click
- if (this.selectionStartLength) {
- // Select the larger of the two when start and end are on the same line
- if (this.selectionEnd[1] === this.selectionStart[1]) {
- return [Math.max(this.selectionStart[0] + this.selectionStartLength, this.selectionEnd[0]), this.selectionEnd[1]];
- }
- }
- return this.selectionEnd;
- }
-
- /**
- * Returns whether the selection start and end are reversed.
- */
- public areSelectionValuesReversed(): boolean {
- const start = this.selectionStart;
- const end = this.selectionEnd;
- if (!start || !end) {
- return false;
- }
- return start[1] > end[1] || (start[1] === end[1] && start[0] > end[0]);
- }
-
- /**
- * Handle the buffer being trimmed, adjust the selection position.
- * @param amount The amount the buffer is being trimmed.
- * @return Whether a refresh is necessary.
- */
- public onTrim(amount: number): boolean {
- // Adjust the selection position based on the trimmed amount.
- if (this.selectionStart) {
- this.selectionStart[1] -= amount;
- }
- if (this.selectionEnd) {
- this.selectionEnd[1] -= amount;
- }
-
- // The selection has moved off the buffer, clear it.
- if (this.selectionEnd && this.selectionEnd[1] < 0) {
- this.clearSelection();
- return true;
- }
-
- // If the selection start is trimmed, ensure the start column is 0.
- if (this.selectionStart && this.selectionStart[1] < 0) {
- this.selectionStart[1] = 0;
- }
- return false;
- }
-}