diff --git a/src/vs/vscode.d.ts b/src/vs/vscode.d.ts index 66450265731..da6724612b8 100644 --- a/src/vs/vscode.d.ts +++ b/src/vs/vscode.d.ts @@ -427,14 +427,23 @@ declare namespace vscode { union(other: Range): Range; /** - * Create a new range derived from this range. + * Derived a new range from this range. * * @param start A position that should be used as start. The default value is the [current start](#Range.start). * @param end A position that should be used as end. The default value is the [current end](#Range.end). * @return A range derived from this range with the given start and end position. - * If start and end are not different this range will be returned. + * If start and end are not different `this` range will be returned. */ with(start?: Position, end?: Position): Range; + + /** + * Derived a new range from this range. + * + * @param change An object that describes a change to this range. + * @return A range that reflects the given change. Will return `this` range if the change + * is not changing anything. + */ + with (change: { start ?: Position, end ?: Position }): Range; } /** @@ -940,8 +949,8 @@ declare namespace vscode { /** * Derive a new Uri from this Uri. * - * @param change An object that describes a change. - * @return A new Uri that reflects the changes. Will return `this` Uri if the change + * @param change An object that describes a change to this Uri. + * @return A new Uri that reflects the given change. Will return `this` Uri if the change * is not changing anything. * @sample ``` let file = Uri.parse('before:some/file/path'); diff --git a/src/vs/workbench/api/node/extHostTypes.ts b/src/vs/workbench/api/node/extHostTypes.ts index 8ee71f8eaa4..4e1afe3c2c3 100644 --- a/src/vs/workbench/api/node/extHostTypes.ts +++ b/src/vs/workbench/api/node/extHostTypes.ts @@ -63,6 +63,20 @@ export class Position { return result; } + static is(other: any): other is Position { + if (!other) { + return false; + } + if (other instanceof Position) { + return true; + } + let {line, character} = other; + if (typeof line === 'number' && typeof character === 'number') { + return true; + } + return false; + } + private _line: number; private _character: number; @@ -246,7 +260,26 @@ export class Range { return this._start.line === this._end.line; } - with(start: Position = this.start, end: Position = this.end): Range { + with(change: { start?: Position, end?: Position }): Range; + with(start?: Position, end?: Position): Range; + with(startOrChange: Position | { start?: Position, end?: Position }, end: Position = this.end): Range { + + if (startOrChange === null || end === null) { + throw illegalArgument(); + } + + let start: Position; + if (!startOrChange) { + start = this.start; + + } else if (Position.is(startOrChange)) { + start = startOrChange; + + } else { + start = startOrChange.start || this.start; + end = startOrChange.end || this.end; + } + if (start.isEqual(this._start) && end.isEqual(this.end)) { return this; } diff --git a/src/vs/workbench/test/node/api/extHostTypes.test.ts b/src/vs/workbench/test/node/api/extHostTypes.test.ts index 6d1c4f4a57b..c6a6ba659bb 100644 --- a/src/vs/workbench/test/node/api/extHostTypes.test.ts +++ b/src/vs/workbench/test/node/api/extHostTypes.test.ts @@ -267,6 +267,11 @@ suite('ExtHostTypes', function() { assert.ok(range.with(range.start, range.end) === range); assert.ok(range.with(new types.Position(1, 1)) === range); assert.ok(range.with(undefined, new types.Position(2, 11)) === range); + assert.ok(range.with() === range); + assert.ok(range.with({ start: range.start }) === range); + assert.ok(range.with({ start: new types.Position(1, 1) }) === range); + assert.ok(range.with({ end: range.end }) === range); + assert.ok(range.with({ end: new types.Position(2, 11) }) === range); let res = range.with(undefined, new types.Position(9, 8)); assert.equal(res.end.line, 9); @@ -274,6 +279,18 @@ suite('ExtHostTypes', function() { assert.equal(res.start.line, 1); assert.equal(res.start.character, 1); + res = range.with({ end: new types.Position(9, 8) }); + assert.equal(res.end.line, 9); + assert.equal(res.end.character, 8); + assert.equal(res.start.line, 1); + assert.equal(res.start.character, 1); + + res = range.with({ end: new types.Position(9, 8), start: new types.Position(2, 3)}); + assert.equal(res.end.line, 9); + assert.equal(res.end.character, 8); + assert.equal(res.start.line, 2); + assert.equal(res.start.character, 3); + assert.throws(() => range.with(null)); assert.throws(() => range.with(undefined, null)); });