Skip to content

Commit ea09e5c

Browse files
authored
Merge branch 'main' into defaultProfile-env
2 parents 1279e45 + 679f4ce commit ea09e5c

File tree

118 files changed

+1338
-2099
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

118 files changed

+1338
-2099
lines changed

extensions/git/src/git.ts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2525,7 +2525,7 @@ export class Repository {
25252525
// On Windows and macOS ref names are case insensitive so we add --ignore-case
25262526
// to handle the scenario where the user switched to a branch with incorrect
25272527
// casing
2528-
if (isWindows || isMacintosh) {
2528+
if (this.git.compareGitVersionTo('2.12') !== -1 && (isWindows || isMacintosh)) {
25292529
args.push('--ignore-case');
25302530
}
25312531

extensions/vscode-api-tests/src/singlefolder-tests/chat.test.ts

Lines changed: 20 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import * as assert from 'assert';
77
import 'mocha';
8-
import { commands, CancellationToken, ChatContext, ChatRequest, ChatResult, ChatVariableLevel, Disposable, Event, EventEmitter, InteractiveSession, ProviderResult, chat, interactive } from 'vscode';
8+
import { ChatContext, ChatRequest, ChatResult, ChatVariableLevel, Disposable, Event, EventEmitter, chat, commands } from 'vscode';
99
import { DeferredPromise, assertNoRpc, closeAllEditors, disposeAll } from '../utils';
1010

1111
suite('chat', () => {
@@ -31,14 +31,6 @@ suite('chat', () => {
3131
function setupParticipant(): Event<{ request: ChatRequest; context: ChatContext }> {
3232
const emitter = new EventEmitter<{ request: ChatRequest; context: ChatContext }>();
3333
disposables.push(emitter);
34-
disposables.push(interactive.registerInteractiveSessionProvider('provider', {
35-
prepareSession: (_token: CancellationToken): ProviderResult<InteractiveSession> => {
36-
return {
37-
requester: { name: 'test' },
38-
responder: { name: 'test' },
39-
};
40-
},
41-
}));
4234

4335
const participant = chat.createChatParticipant('api-test.participant', (request, context, _progress, _token) => {
4436
emitter.fire({ request, context });
@@ -52,19 +44,29 @@ suite('chat', () => {
5244
const onRequest = setupParticipant();
5345
commands.executeCommand('workbench.action.chat.open', { query: '@participant /hello friend' });
5446

47+
const deferred = new DeferredPromise<void>();
5548
let i = 0;
5649
disposables.push(onRequest(request => {
57-
if (i === 0) {
58-
assert.deepStrictEqual(request.request.command, 'hello');
59-
assert.strictEqual(request.request.prompt, 'friend');
60-
i++;
61-
commands.executeCommand('workbench.action.chat.open', { query: '@participant /hello friend' });
62-
} else {
63-
assert.strictEqual(request.context.history.length, 1);
64-
assert.strictEqual(request.context.history[0].participant, 'api-test.participant');
65-
assert.strictEqual(request.context.history[0].command, 'hello');
50+
try {
51+
if (i === 0) {
52+
assert.deepStrictEqual(request.request.command, 'hello');
53+
assert.strictEqual(request.request.prompt, 'friend');
54+
i++;
55+
setTimeout(() => {
56+
commands.executeCommand('workbench.action.chat.open', { query: '@participant /hello friend' });
57+
}, 0);
58+
} else {
59+
assert.strictEqual(request.context.history.length, 2);
60+
assert.strictEqual(request.context.history[0].participant, 'api-test.participant');
61+
assert.strictEqual(request.context.history[0].command, 'hello');
62+
deferred.complete();
63+
}
64+
} catch (e) {
65+
deferred.error(e);
6666
}
6767
}));
68+
69+
await deferred.p;
6870
});
6971

7072
test('participant and variable', async () => {
@@ -82,15 +84,6 @@ suite('chat', () => {
8284
});
8385

8486
test('result metadata is returned to the followup provider', async () => {
85-
disposables.push(interactive.registerInteractiveSessionProvider('provider', {
86-
prepareSession: (_token: CancellationToken): ProviderResult<InteractiveSession> => {
87-
return {
88-
requester: { name: 'test' },
89-
responder: { name: 'test' },
90-
};
91-
},
92-
}));
93-
9487
const deferred = new DeferredPromise<ChatResult>();
9588
const participant = chat.createChatParticipant('api-test.participant', (_request, _context, _progress, _token) => {
9689
return { metadata: { key: 'value' } };

src/vs/base/browser/ui/list/listView.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -12,15 +12,14 @@ import { SmoothScrollableElement } from 'vs/base/browser/ui/scrollbar/scrollable
1212
import { distinct, equals } from 'vs/base/common/arrays';
1313
import { Delayer, disposableTimeout } from 'vs/base/common/async';
1414
import { memoize } from 'vs/base/common/decorators';
15-
import { Emitter, Event } from 'vs/base/common/event';
15+
import { Emitter, Event, IValueWithChangeEvent } from 'vs/base/common/event';
1616
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
1717
import { IRange, Range } from 'vs/base/common/range';
1818
import { INewScrollDimensions, Scrollable, ScrollbarVisibility, ScrollEvent } from 'vs/base/common/scrollable';
1919
import { ISpliceable } from 'vs/base/common/sequence';
2020
import { IListDragAndDrop, IListDragEvent, IListGestureEvent, IListMouseEvent, IListRenderer, IListTouchEvent, IListVirtualDelegate, ListDragOverEffectPosition, ListDragOverEffectType } from 'vs/base/browser/ui/list/list';
2121
import { IRangeMap, RangeMap, shift } from 'vs/base/browser/ui/list/rangeMap';
2222
import { IRow, RowCache } from 'vs/base/browser/ui/list/rowCache';
23-
import { IObservableValue } from 'vs/base/common/observableValue';
2423
import { BugIndicatingError } from 'vs/base/common/errors';
2524
import { AriaRole } from 'vs/base/browser/ui/aria/aria';
2625
import { ScrollableElementChangeOptions } from 'vs/base/browser/ui/scrollbar/scrollableElementOptions';
@@ -62,7 +61,7 @@ export interface IListViewAccessibilityProvider<T> {
6261
getSetSize?(element: T, index: number, listLength: number): number;
6362
getPosInSet?(element: T, index: number): number;
6463
getRole?(element: T): AriaRole | undefined;
65-
isChecked?(element: T): boolean | IObservableValue<boolean> | undefined;
64+
isChecked?(element: T): boolean | IValueWithChangeEvent<boolean> | undefined;
6665
}
6766

6867
export interface IListViewOptionsUpdate {
@@ -195,7 +194,7 @@ class ListViewAccessibilityProvider<T> implements Required<IListViewAccessibilit
195194
readonly getSetSize: (element: any, index: number, listLength: number) => number;
196195
readonly getPosInSet: (element: any, index: number) => number;
197196
readonly getRole: (element: T) => AriaRole | undefined;
198-
readonly isChecked: (element: T) => boolean | IObservableValue<boolean> | undefined;
197+
readonly isChecked: (element: T) => boolean | IValueWithChangeEvent<boolean> | undefined;
199198

200199
constructor(accessibilityProvider?: IListViewAccessibilityProvider<T>) {
201200
if (accessibilityProvider?.getSetSize) {
@@ -919,7 +918,7 @@ export class ListView<T> implements IListView<T> {
919918
} else if (checked) {
920919
const update = (checked: boolean) => item.row!.domNode.setAttribute('aria-checked', String(!!checked));
921920
update(checked.value);
922-
item.checkedDisposable = checked.onDidChange(update);
921+
item.checkedDisposable = checked.onDidChange(() => update(checked.value));
923922
}
924923

925924
if (item.stale || !item.row.domNode.parentElement) {

src/vs/base/common/arraysFind.ts

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import { Comparator } from './arrays';
77

8-
export function findLast<T>(array: readonly T[], predicate: (item: T) => boolean, fromIdx?: number): T | undefined {
8+
export function findLast<T>(array: readonly T[], predicate: (item: T) => boolean): T | undefined {
99
const idx = findLastIdx(array, predicate);
1010
if (idx === -1) {
1111
return undefined;
@@ -132,7 +132,7 @@ export class MonotonousArray<T> {
132132
/**
133133
* Returns the first item that is equal to or greater than every other item.
134134
*/
135-
export function findFirstMaxBy<T>(array: readonly T[], comparator: Comparator<T>): T | undefined {
135+
export function findFirstMax<T>(array: readonly T[], comparator: Comparator<T>): T | undefined {
136136
if (array.length === 0) {
137137
return undefined;
138138
}
@@ -150,7 +150,7 @@ export function findFirstMaxBy<T>(array: readonly T[], comparator: Comparator<T>
150150
/**
151151
* Returns the last item that is equal to or greater than every other item.
152152
*/
153-
export function findLastMaxBy<T>(array: readonly T[], comparator: Comparator<T>): T | undefined {
153+
export function findLastMax<T>(array: readonly T[], comparator: Comparator<T>): T | undefined {
154154
if (array.length === 0) {
155155
return undefined;
156156
}
@@ -168,11 +168,11 @@ export function findLastMaxBy<T>(array: readonly T[], comparator: Comparator<T>)
168168
/**
169169
* Returns the first item that is equal to or less than every other item.
170170
*/
171-
export function findFirstMinBy<T>(array: readonly T[], comparator: Comparator<T>): T | undefined {
172-
return findFirstMaxBy(array, (a, b) => -comparator(a, b));
171+
export function findFirstMin<T>(array: readonly T[], comparator: Comparator<T>): T | undefined {
172+
return findFirstMax(array, (a, b) => -comparator(a, b));
173173
}
174174

175-
export function findMaxIdxBy<T>(array: readonly T[], comparator: Comparator<T>): number {
175+
export function findMaxIdx<T>(array: readonly T[], comparator: Comparator<T>): number {
176176
if (array.length === 0) {
177177
return -1;
178178
}

src/vs/base/common/event.ts

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1630,3 +1630,36 @@ export class Relay<T> implements IDisposable {
16301630
this.emitter.dispose();
16311631
}
16321632
}
1633+
1634+
export interface IValueWithChangeEvent<T> {
1635+
readonly onDidChange: Event<void>;
1636+
readonly value: T;
1637+
}
1638+
1639+
export class ValueWithChangeEvent<T> implements IValueWithChangeEvent<T> {
1640+
public static const<T>(value: T): IValueWithChangeEvent<T> {
1641+
return new ConstValueWithChangeEvent(value);
1642+
}
1643+
1644+
private readonly _onDidChange = new Emitter<void>();
1645+
readonly onDidChange: Event<void> = this._onDidChange.event;
1646+
1647+
constructor(private _value: T) { }
1648+
1649+
get value(): T {
1650+
return this._value;
1651+
}
1652+
1653+
set value(value: T) {
1654+
if (value !== this._value) {
1655+
this._value = value;
1656+
this._onDidChange.fire(undefined);
1657+
}
1658+
}
1659+
}
1660+
1661+
class ConstValueWithChangeEvent<T> implements IValueWithChangeEvent<T> {
1662+
public readonly onDidChange: Event<void> = Event.None;
1663+
1664+
constructor(readonly value: T) { }
1665+
}

src/vs/base/common/observableInternal/base.ts

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,10 @@ export abstract class ConvenientObservable<T, TChange> implements IObservable<T,
248248
}
249249

250250
public abstract get debugName(): string;
251+
252+
protected get debugValue() {
253+
return this.get();
254+
}
251255
}
252256

253257
export abstract class BaseObservable<T, TChange = void> extends ConvenientObservable<T, TChange> {

src/vs/base/common/observableInternal/promise.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,9 +119,13 @@ export class ObservableLazyPromise<T> {
119119
/**
120120
* Resolves the promise when the observables state matches the predicate.
121121
*/
122+
export function waitForState<T>(observable: IObservable<T | null | undefined>): Promise<T>;
122123
export function waitForState<T, TState extends T>(observable: IObservable<T>, predicate: (state: T) => state is TState, isError?: (state: T) => boolean | unknown | undefined): Promise<TState>;
123124
export function waitForState<T>(observable: IObservable<T>, predicate: (state: T) => boolean, isError?: (state: T) => boolean | unknown | undefined): Promise<T>;
124-
export function waitForState<T>(observable: IObservable<T>, predicate: (state: T) => boolean, isError?: (state: T) => boolean | unknown | undefined): Promise<T> {
125+
export function waitForState<T>(observable: IObservable<T>, predicate?: (state: T) => boolean, isError?: (state: T) => boolean | unknown | undefined): Promise<T> {
126+
if (!predicate) {
127+
predicate = state => state !== null && state !== undefined;
128+
}
125129
return new Promise((resolve, reject) => {
126130
let isImmediateRun = true;
127131
let shouldDispose = false;

src/vs/base/common/observableInternal/utils.ts

Lines changed: 33 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@ import { BaseObservable, ConvenientObservable, IObservable, IObserver, IReader,
1010
import { DebugNameData, Owner, getFunctionName } from 'vs/base/common/observableInternal/debugName';
1111
import { derived, derivedOpts } from 'vs/base/common/observableInternal/derived';
1212
import { getLogger } from 'vs/base/common/observableInternal/logging';
13+
import { IValueWithChangeEvent } from '../event';
1314

1415
/**
1516
* Represents an efficient observable whose value never changes.
@@ -136,7 +137,8 @@ export class FromEventObservable<TArgs, T> extends BaseObservable<T> {
136137
return this.value!;
137138
} else {
138139
// no cache, as there are no subscribers to keep it updated
139-
return this._getValue(undefined);
140+
const value = this._getValue(undefined);
141+
return value;
140142
}
141143
}
142144
}
@@ -413,19 +415,24 @@ export function derivedObservableWithCache<T>(owner: Owner, computeFn: (reader:
413415
return observable;
414416
}
415417

416-
export function derivedObservableWithWritableCache<T>(owner: object, computeFn: (reader: IReader, lastValue: T | undefined) => T): IObservable<T> & { clearCache(transaction: ITransaction): void } {
418+
export function derivedObservableWithWritableCache<T>(owner: object, computeFn: (reader: IReader, lastValue: T | undefined) => T): IObservable<T>
419+
& { clearCache(transaction: ITransaction): void; setCache(newValue: T | undefined, tx: ITransaction | undefined): void } {
417420
let lastValue: T | undefined = undefined;
418-
const counter = observableValue('derivedObservableWithWritableCache.counter', 0);
421+
const onChange = observableSignal('derivedObservableWithWritableCache');
419422
const observable = derived(owner, reader => {
420-
counter.read(reader);
423+
onChange.read(reader);
421424
lastValue = computeFn(reader, lastValue);
422425
return lastValue;
423426
});
424427
return Object.assign(observable, {
425-
clearCache: (transaction: ITransaction) => {
428+
clearCache: (tx: ITransaction) => {
426429
lastValue = undefined;
427-
counter.set(counter.get() + 1, transaction);
430+
onChange.trigger(tx);
428431
},
432+
setCache: (newValue: T | undefined, tx: ITransaction | undefined) => {
433+
lastValue = newValue;
434+
onChange.trigger(tx);
435+
}
429436
});
430437
}
431438

@@ -494,3 +501,23 @@ class ArrayMap<TIn, TOut, TKey> implements IDisposable {
494501
return this._items;
495502
}
496503
}
504+
505+
export class ValueWithChangeEventFromObservable<T> implements IValueWithChangeEvent<T> {
506+
constructor(public readonly observable: IObservable<T>) {
507+
}
508+
509+
get onDidChange(): Event<void> {
510+
return Event.fromObservableLight(this.observable);
511+
}
512+
513+
get value(): T {
514+
return this.observable.get();
515+
}
516+
}
517+
518+
export function observableFromValueWithChangeEvent<T>(_owner: Owner, value: IValueWithChangeEvent<T>): IObservable<T> {
519+
if (value instanceof ValueWithChangeEventFromObservable) {
520+
return value.observable;
521+
}
522+
return observableFromEvent(value.onDidChange, () => value.value);
523+
}

src/vs/base/common/observableValue.ts

Lines changed: 0 additions & 17 deletions
This file was deleted.

src/vs/base/test/common/arrays.test.ts

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -376,7 +376,7 @@ suite('Arrays', () => {
376376
const array = [{ v: 3 }, { v: 5 }, { v: 2 }, { v: 2 }, { v: 2 }, { v: 5 }];
377377

378378
assert.strictEqual(
379-
array.indexOf(arraysFind.findFirstMaxBy(array, arrays.compareBy(v => v.v, arrays.numberComparator))!),
379+
array.indexOf(arraysFind.findFirstMax(array, arrays.compareBy(v => v.v, arrays.numberComparator))!),
380380
1
381381
);
382382
});
@@ -385,7 +385,7 @@ suite('Arrays', () => {
385385
const array = [{ v: 3 }, { v: 5 }, { v: 2 }, { v: 2 }, { v: 2 }, { v: 5 }];
386386

387387
assert.strictEqual(
388-
array.indexOf(arraysFind.findLastMaxBy(array, arrays.compareBy(v => v.v, arrays.numberComparator))!),
388+
array.indexOf(arraysFind.findLastMax(array, arrays.compareBy(v => v.v, arrays.numberComparator))!),
389389
5
390390
);
391391
});
@@ -394,7 +394,7 @@ suite('Arrays', () => {
394394
const array = [{ v: 3 }, { v: 5 }, { v: 2 }, { v: 2 }, { v: 2 }, { v: 5 }];
395395

396396
assert.strictEqual(
397-
array.indexOf(arraysFind.findFirstMinBy(array, arrays.compareBy(v => v.v, arrays.numberComparator))!),
397+
array.indexOf(arraysFind.findFirstMin(array, arrays.compareBy(v => v.v, arrays.numberComparator))!),
398398
2
399399
);
400400
});

0 commit comments

Comments
 (0)