| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379 |
- /*---------------------------------------------------------------------------------------------
- * Copyright (c) Microsoft Corporation. All rights reserved.
- * Licensed under the MIT License. See License.txt in the project root for license information.
- *--------------------------------------------------------------------------------------------*/
- import { Position } from './position.js';
- /**
- * A range in the editor. (startLineNumber,startColumn) is <= (endLineNumber,endColumn)
- */
- export class Range {
- constructor(startLineNumber, startColumn, endLineNumber, endColumn) {
- if ((startLineNumber > endLineNumber) || (startLineNumber === endLineNumber && startColumn > endColumn)) {
- this.startLineNumber = endLineNumber;
- this.startColumn = endColumn;
- this.endLineNumber = startLineNumber;
- this.endColumn = startColumn;
- }
- else {
- this.startLineNumber = startLineNumber;
- this.startColumn = startColumn;
- this.endLineNumber = endLineNumber;
- this.endColumn = endColumn;
- }
- }
- /**
- * Test if this range is empty.
- */
- isEmpty() {
- return Range.isEmpty(this);
- }
- /**
- * Test if `range` is empty.
- */
- static isEmpty(range) {
- return (range.startLineNumber === range.endLineNumber && range.startColumn === range.endColumn);
- }
- /**
- * Test if position is in this range. If the position is at the edges, will return true.
- */
- containsPosition(position) {
- return Range.containsPosition(this, position);
- }
- /**
- * Test if `position` is in `range`. If the position is at the edges, will return true.
- */
- static containsPosition(range, position) {
- if (position.lineNumber < range.startLineNumber || position.lineNumber > range.endLineNumber) {
- return false;
- }
- if (position.lineNumber === range.startLineNumber && position.column < range.startColumn) {
- return false;
- }
- if (position.lineNumber === range.endLineNumber && position.column > range.endColumn) {
- return false;
- }
- return true;
- }
- /**
- * Test if `position` is in `range`. If the position is at the edges, will return false.
- * @internal
- */
- static strictContainsPosition(range, position) {
- if (position.lineNumber < range.startLineNumber || position.lineNumber > range.endLineNumber) {
- return false;
- }
- if (position.lineNumber === range.startLineNumber && position.column <= range.startColumn) {
- return false;
- }
- if (position.lineNumber === range.endLineNumber && position.column >= range.endColumn) {
- return false;
- }
- return true;
- }
- /**
- * Test if range is in this range. If the range is equal to this range, will return true.
- */
- containsRange(range) {
- return Range.containsRange(this, range);
- }
- /**
- * Test if `otherRange` is in `range`. If the ranges are equal, will return true.
- */
- static containsRange(range, otherRange) {
- if (otherRange.startLineNumber < range.startLineNumber || otherRange.endLineNumber < range.startLineNumber) {
- return false;
- }
- if (otherRange.startLineNumber > range.endLineNumber || otherRange.endLineNumber > range.endLineNumber) {
- return false;
- }
- if (otherRange.startLineNumber === range.startLineNumber && otherRange.startColumn < range.startColumn) {
- return false;
- }
- if (otherRange.endLineNumber === range.endLineNumber && otherRange.endColumn > range.endColumn) {
- return false;
- }
- return true;
- }
- /**
- * Test if `range` is strictly in this range. `range` must start after and end before this range for the result to be true.
- */
- strictContainsRange(range) {
- return Range.strictContainsRange(this, range);
- }
- /**
- * Test if `otherRange` is strictly in `range` (must start after, and end before). If the ranges are equal, will return false.
- */
- static strictContainsRange(range, otherRange) {
- if (otherRange.startLineNumber < range.startLineNumber || otherRange.endLineNumber < range.startLineNumber) {
- return false;
- }
- if (otherRange.startLineNumber > range.endLineNumber || otherRange.endLineNumber > range.endLineNumber) {
- return false;
- }
- if (otherRange.startLineNumber === range.startLineNumber && otherRange.startColumn <= range.startColumn) {
- return false;
- }
- if (otherRange.endLineNumber === range.endLineNumber && otherRange.endColumn >= range.endColumn) {
- return false;
- }
- return true;
- }
- /**
- * A reunion of the two ranges.
- * The smallest position will be used as the start point, and the largest one as the end point.
- */
- plusRange(range) {
- return Range.plusRange(this, range);
- }
- /**
- * A reunion of the two ranges.
- * The smallest position will be used as the start point, and the largest one as the end point.
- */
- static plusRange(a, b) {
- let startLineNumber;
- let startColumn;
- let endLineNumber;
- let endColumn;
- if (b.startLineNumber < a.startLineNumber) {
- startLineNumber = b.startLineNumber;
- startColumn = b.startColumn;
- }
- else if (b.startLineNumber === a.startLineNumber) {
- startLineNumber = b.startLineNumber;
- startColumn = Math.min(b.startColumn, a.startColumn);
- }
- else {
- startLineNumber = a.startLineNumber;
- startColumn = a.startColumn;
- }
- if (b.endLineNumber > a.endLineNumber) {
- endLineNumber = b.endLineNumber;
- endColumn = b.endColumn;
- }
- else if (b.endLineNumber === a.endLineNumber) {
- endLineNumber = b.endLineNumber;
- endColumn = Math.max(b.endColumn, a.endColumn);
- }
- else {
- endLineNumber = a.endLineNumber;
- endColumn = a.endColumn;
- }
- return new Range(startLineNumber, startColumn, endLineNumber, endColumn);
- }
- /**
- * A intersection of the two ranges.
- */
- intersectRanges(range) {
- return Range.intersectRanges(this, range);
- }
- /**
- * A intersection of the two ranges.
- */
- static intersectRanges(a, b) {
- let resultStartLineNumber = a.startLineNumber;
- let resultStartColumn = a.startColumn;
- let resultEndLineNumber = a.endLineNumber;
- let resultEndColumn = a.endColumn;
- const otherStartLineNumber = b.startLineNumber;
- const otherStartColumn = b.startColumn;
- const otherEndLineNumber = b.endLineNumber;
- const otherEndColumn = b.endColumn;
- if (resultStartLineNumber < otherStartLineNumber) {
- resultStartLineNumber = otherStartLineNumber;
- resultStartColumn = otherStartColumn;
- }
- else if (resultStartLineNumber === otherStartLineNumber) {
- resultStartColumn = Math.max(resultStartColumn, otherStartColumn);
- }
- if (resultEndLineNumber > otherEndLineNumber) {
- resultEndLineNumber = otherEndLineNumber;
- resultEndColumn = otherEndColumn;
- }
- else if (resultEndLineNumber === otherEndLineNumber) {
- resultEndColumn = Math.min(resultEndColumn, otherEndColumn);
- }
- // Check if selection is now empty
- if (resultStartLineNumber > resultEndLineNumber) {
- return null;
- }
- if (resultStartLineNumber === resultEndLineNumber && resultStartColumn > resultEndColumn) {
- return null;
- }
- return new Range(resultStartLineNumber, resultStartColumn, resultEndLineNumber, resultEndColumn);
- }
- /**
- * Test if this range equals other.
- */
- equalsRange(other) {
- return Range.equalsRange(this, other);
- }
- /**
- * Test if range `a` equals `b`.
- */
- static equalsRange(a, b) {
- return (!!a &&
- !!b &&
- a.startLineNumber === b.startLineNumber &&
- a.startColumn === b.startColumn &&
- a.endLineNumber === b.endLineNumber &&
- a.endColumn === b.endColumn);
- }
- /**
- * Return the end position (which will be after or equal to the start position)
- */
- getEndPosition() {
- return Range.getEndPosition(this);
- }
- /**
- * Return the end position (which will be after or equal to the start position)
- */
- static getEndPosition(range) {
- return new Position(range.endLineNumber, range.endColumn);
- }
- /**
- * Return the start position (which will be before or equal to the end position)
- */
- getStartPosition() {
- return Range.getStartPosition(this);
- }
- /**
- * Return the start position (which will be before or equal to the end position)
- */
- static getStartPosition(range) {
- return new Position(range.startLineNumber, range.startColumn);
- }
- /**
- * Transform to a user presentable string representation.
- */
- toString() {
- return '[' + this.startLineNumber + ',' + this.startColumn + ' -> ' + this.endLineNumber + ',' + this.endColumn + ']';
- }
- /**
- * Create a new range using this range's start position, and using endLineNumber and endColumn as the end position.
- */
- setEndPosition(endLineNumber, endColumn) {
- return new Range(this.startLineNumber, this.startColumn, endLineNumber, endColumn);
- }
- /**
- * Create a new range using this range's end position, and using startLineNumber and startColumn as the start position.
- */
- setStartPosition(startLineNumber, startColumn) {
- return new Range(startLineNumber, startColumn, this.endLineNumber, this.endColumn);
- }
- /**
- * Create a new empty range using this range's start position.
- */
- collapseToStart() {
- return Range.collapseToStart(this);
- }
- /**
- * Create a new empty range using this range's start position.
- */
- static collapseToStart(range) {
- return new Range(range.startLineNumber, range.startColumn, range.startLineNumber, range.startColumn);
- }
- // ---
- static fromPositions(start, end = start) {
- return new Range(start.lineNumber, start.column, end.lineNumber, end.column);
- }
- static lift(range) {
- if (!range) {
- return null;
- }
- return new Range(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn);
- }
- /**
- * Test if `obj` is an `IRange`.
- */
- static isIRange(obj) {
- return (obj
- && (typeof obj.startLineNumber === 'number')
- && (typeof obj.startColumn === 'number')
- && (typeof obj.endLineNumber === 'number')
- && (typeof obj.endColumn === 'number'));
- }
- /**
- * Test if the two ranges are touching in any way.
- */
- static areIntersectingOrTouching(a, b) {
- // Check if `a` is before `b`
- if (a.endLineNumber < b.startLineNumber || (a.endLineNumber === b.startLineNumber && a.endColumn < b.startColumn)) {
- return false;
- }
- // Check if `b` is before `a`
- if (b.endLineNumber < a.startLineNumber || (b.endLineNumber === a.startLineNumber && b.endColumn < a.startColumn)) {
- return false;
- }
- // These ranges must intersect
- return true;
- }
- /**
- * Test if the two ranges are intersecting. If the ranges are touching it returns true.
- */
- static areIntersecting(a, b) {
- // Check if `a` is before `b`
- if (a.endLineNumber < b.startLineNumber || (a.endLineNumber === b.startLineNumber && a.endColumn <= b.startColumn)) {
- return false;
- }
- // Check if `b` is before `a`
- if (b.endLineNumber < a.startLineNumber || (b.endLineNumber === a.startLineNumber && b.endColumn <= a.startColumn)) {
- return false;
- }
- // These ranges must intersect
- return true;
- }
- /**
- * A function that compares ranges, useful for sorting ranges
- * It will first compare ranges on the startPosition and then on the endPosition
- */
- static compareRangesUsingStarts(a, b) {
- if (a && b) {
- const aStartLineNumber = a.startLineNumber | 0;
- const bStartLineNumber = b.startLineNumber | 0;
- if (aStartLineNumber === bStartLineNumber) {
- const aStartColumn = a.startColumn | 0;
- const bStartColumn = b.startColumn | 0;
- if (aStartColumn === bStartColumn) {
- const aEndLineNumber = a.endLineNumber | 0;
- const bEndLineNumber = b.endLineNumber | 0;
- if (aEndLineNumber === bEndLineNumber) {
- const aEndColumn = a.endColumn | 0;
- const bEndColumn = b.endColumn | 0;
- return aEndColumn - bEndColumn;
- }
- return aEndLineNumber - bEndLineNumber;
- }
- return aStartColumn - bStartColumn;
- }
- return aStartLineNumber - bStartLineNumber;
- }
- const aExists = (a ? 1 : 0);
- const bExists = (b ? 1 : 0);
- return aExists - bExists;
- }
- /**
- * A function that compares ranges, useful for sorting ranges
- * It will first compare ranges on the endPosition and then on the startPosition
- */
- static compareRangesUsingEnds(a, b) {
- if (a.endLineNumber === b.endLineNumber) {
- if (a.endColumn === b.endColumn) {
- if (a.startLineNumber === b.startLineNumber) {
- return a.startColumn - b.startColumn;
- }
- return a.startLineNumber - b.startLineNumber;
- }
- return a.endColumn - b.endColumn;
- }
- return a.endLineNumber - b.endLineNumber;
- }
- /**
- * Test if the range spans multiple lines.
- */
- static spansMultipleLines(range) {
- return range.endLineNumber > range.startLineNumber;
- }
- toJSON() {
- return this;
- }
- }
|