Skip to content

Commit

Permalink
Merge remote-tracking branch 'upstream/main'
Browse files Browse the repository at this point in the history
  • Loading branch information
dabreadman committed Dec 9, 2024
2 parents 74d1ebb + d0507ca commit 910a378
Show file tree
Hide file tree
Showing 40 changed files with 1,184 additions and 992 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,17 @@ function updateContent(c: EmbeddedRegion, content: string): string {
if (!c.attributeValue && c.languageId === 'javascript') {
return content.replace(`<!--`, `/* `).replace(`-->`, ` */`);
}
if (c.languageId === 'css') {
const quoteEscape = /(&quot;|&#34;)/g;
return content.replace(quoteEscape, (match, _, offset) => {
const spaces = ' '.repeat(match.length - 1);
const afterChar = content[offset + match.length];
if (!afterChar || afterChar.includes(' ')) {
return `${spaces}"`;
}
return `"${spaces}`;
});
}
return content;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -128,4 +128,12 @@ suite('HTML Embedded Support', () => {
assertEmbeddedLanguageContent('<div onKeyUp=return\n/><script>foo();</script>', 'javascript', ' return;\n foo(); ');
});

test('Script content - HTML escape characters', function (): any {
assertEmbeddedLanguageContent('<div style="font-family: &quot;Arial&quot;"></div>', 'css', ' __{font-family: " Arial "} ');
assertEmbeddedLanguageContent('<div style="font-family: &#34;Arial&#34;"></div>', 'css', ' __{font-family: " Arial "} ');
assertEmbeddedLanguageContent('<div style="font-family: &quot;Arial&#34;"></div>', 'css', ' __{font-family: " Arial "} ');
assertEmbeddedLanguageContent('<div style="font-family:&quot; Arial &quot; "></div>', 'css', ' __{font-family: " Arial " } ');
assertEmbeddedLanguageContent('<div style="font-family: Arial"></div>', 'css', ' __{font-family: Arial} ');
});

});
2 changes: 1 addition & 1 deletion extensions/typescript-language-features/package.nls.json
Original file line number Diff line number Diff line change
Expand Up @@ -225,7 +225,7 @@
"configuration.tsserver.web.typeAcquisition.enabled": "Enable/disable package acquisition on the web. This enables IntelliSense for imported packages. Requires `#typescript.tsserver.web.projectWideIntellisense.enabled#`. Currently not supported for Safari.",
"configuration.tsserver.nodePath": "Run TS Server on a custom Node installation. This can be a path to a Node executable, or 'node' if you want VS Code to detect a Node installation.",
"configuration.updateImportsOnPaste": "Enable updating imports when pasting code. Requires TypeScript 5.7+.\n\nBy default this shows a option to update imports after pasting. You can use the `#editor.pasteAs.preferences#` setting to update imports automatically when pasting: `\"editor.pasteAs.preferences\": [ \"text.updateImports.jsts\" ]`.",
"configuration.expandableHover": "Enable/disable expanding on hover.",
"configuration.expandableHover": "Enable expanding/contracting the hover to reveal more/less information from the TS server.",
"walkthroughs.nodejsWelcome.title": "Get started with JavaScript and Node.js",
"walkthroughs.nodejsWelcome.description": "Make the most of Visual Studio Code's first-class JavaScript experience.",
"walkthroughs.nodejsWelcome.downloadNode.forMacOrWindows.title": "Install Node.js",
Expand Down
9 changes: 7 additions & 2 deletions src/vs/base/common/errors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -126,20 +126,22 @@ export interface SerializedError {
readonly message: string;
readonly stack: string;
readonly noTelemetry: boolean;
readonly cause?: SerializedError;
}

export function transformErrorForSerialization(error: Error): SerializedError;
export function transformErrorForSerialization(error: any): any;
export function transformErrorForSerialization(error: any): any {
if (error instanceof Error) {
const { name, message } = error;
const { name, message, cause } = error;
const stack: string = (<any>error).stacktrace || (<any>error).stack;
return {
$isError: true,
name,
message,
stack,
noTelemetry: ErrorNoTelemetry.isErrorNoTelemetry(error)
noTelemetry: ErrorNoTelemetry.isErrorNoTelemetry(error),
cause: cause ? transformErrorForSerialization(cause) : undefined
};
}

Expand All @@ -157,6 +159,9 @@ export function transformErrorFromSerialization(data: SerializedError): Error {
}
error.message = data.message;
error.stack = data.stack;
if (data.cause) {
error.cause = transformErrorFromSerialization(data.cause);
}
return error;
}

Expand Down
2 changes: 1 addition & 1 deletion src/vs/base/common/filters.ts
Original file line number Diff line number Diff line change
Expand Up @@ -675,7 +675,7 @@ export function fuzzyScore(pattern: string, patternLow: string, patternStart: nu
}

let diagScore = 0;
if (score !== Number.MAX_SAFE_INTEGER) {
if (score !== Number.MIN_SAFE_INTEGER) {
canComeDiag = true;
diagScore = score + _table[row - 1][column - 1];
}
Expand Down
51 changes: 51 additions & 0 deletions src/vs/base/test/common/errors.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,8 @@
import assert from 'assert';
import { toErrorMessage } from '../../common/errorMessage.js';
import { ensureNoDisposablesAreLeakedInTestSuite } from './utils.js';
import { transformErrorForSerialization, transformErrorFromSerialization } from '../../common/errors.js';
import { assertType } from '../../common/types.js';

suite('Errors', () => {
ensureNoDisposablesAreLeakedInTestSuite();
Expand Down Expand Up @@ -33,4 +35,53 @@ suite('Errors', () => {
assert.ok(toErrorMessage(error, true).length > 'An unknown error occurred. Please consult the log for more details.'.length);
}
});

test('Transform Error for Serialization', function () {
const error = new Error('Test error');
const serializedError = transformErrorForSerialization(error);
assert.strictEqual(serializedError.name, 'Error');
assert.strictEqual(serializedError.message, 'Test error');
assert.strictEqual(serializedError.stack, error.stack);
assert.strictEqual(serializedError.noTelemetry, false);
assert.strictEqual(serializedError.cause, undefined);
});

test('Transform Error with Cause for Serialization', function () {
const cause = new Error('Cause error');
const error = new Error('Test error', { cause });
const serializedError = transformErrorForSerialization(error);
assert.strictEqual(serializedError.name, 'Error');
assert.strictEqual(serializedError.message, 'Test error');
assert.strictEqual(serializedError.stack, error.stack);
assert.strictEqual(serializedError.noTelemetry, false);
assert.ok(serializedError.cause);
assert.strictEqual(serializedError.cause?.name, 'Error');
assert.strictEqual(serializedError.cause?.message, 'Cause error');
assert.strictEqual(serializedError.cause?.stack, cause.stack);
});

test('Transform Error from Serialization', function () {
const serializedError = transformErrorForSerialization(new Error('Test error'));
const error = transformErrorFromSerialization(serializedError);
assert.strictEqual(error.name, 'Error');
assert.strictEqual(error.message, 'Test error');
assert.strictEqual(error.stack, serializedError.stack);
assert.strictEqual(error.cause, undefined);
});

test('Transform Error with Cause from Serialization', function () {
const cause = new Error('Cause error');
const serializedCause = transformErrorForSerialization(cause);
const error = new Error('Test error', { cause });
const serializedError = transformErrorForSerialization(error);
const deserializedError = transformErrorFromSerialization(serializedError);
assert.strictEqual(deserializedError.name, 'Error');
assert.strictEqual(deserializedError.message, 'Test error');
assert.strictEqual(deserializedError.stack, serializedError.stack);
assert.ok(deserializedError.cause);
assertType(deserializedError.cause instanceof Error);
assert.strictEqual(deserializedError.cause?.name, 'Error');
assert.strictEqual(deserializedError.cause?.message, 'Cause error');
assert.strictEqual(deserializedError.cause?.stack, serializedCause.stack);
});
});
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ function _toIColor(r: number, g: number, b: number, a: number): IColor {
function _findRange(model: IDocumentColorComputerTarget, match: RegExpMatchArray): IRange | undefined {
const index = match.index;
const length = match[0].length;
if (!index) {
if (index === undefined) {
return;
}
const startPosition = model.positionAt(index);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -394,7 +394,7 @@ export class StickyScrollController extends Disposable implements IEditorContrib
if (!foldingIcon) {
return;
}
toggleCollapseState(this._foldingModel, Number.MAX_VALUE, [line]);
toggleCollapseState(this._foldingModel, 1, [line]);
foldingIcon.isCollapsed = !foldingIcon.isCollapsed;
const scrollTop = (foldingIcon.isCollapsed ?
this._editor.getTopForLineNumber(foldingIcon.foldingEndLine)
Expand Down
2 changes: 1 addition & 1 deletion src/vs/editor/contrib/suggest/browser/suggestWidget.ts
Original file line number Diff line number Diff line change
Expand Up @@ -928,7 +928,7 @@ export class SuggestWidget implements IDisposable {
typicalHalfwidthCharacterWidth: fontInfo.typicalHalfwidthCharacterWidth,
verticalPadding: 22,
horizontalPadding: 14,
defaultSize: new dom.Dimension(430, statusBarHeight + 12 * itemHeight + borderHeight)
defaultSize: new dom.Dimension(430, statusBarHeight + 12 * itemHeight)
};
}

Expand Down
3 changes: 2 additions & 1 deletion src/vs/editor/contrib/suggest/browser/wordContextKey.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,11 @@ import { IDisposable } from '../../../../base/common/lifecycle.js';
import { ICodeEditor } from '../../../browser/editorBrowser.js';
import { EditorOption } from '../../../common/config/editorOptions.js';
import { IContextKey, IContextKeyService, RawContextKey } from '../../../../platform/contextkey/common/contextkey.js';
import { localize } from '../../../../nls.js';

export class WordContextKey {

static readonly AtEnd = new RawContextKey<boolean>('atEndOfWord', false);
static readonly AtEnd = new RawContextKey<boolean>('atEndOfWord', false, { type: 'boolean', description: localize('desc', "A context key that is true when at the end of a word. Note that this is only defined when tab-completions are enabled") });

private readonly _ckAtEnd: IContextKey<boolean>;
private readonly _configListener: IDisposable;
Expand Down
4 changes: 4 additions & 0 deletions src/vs/platform/configuration/common/configuration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,10 @@ export function removeFromValueTree(valueTree: any, key: string): void {
}

function doRemoveFromValueTree(valueTree: any, segments: string[]): void {
if (!valueTree) {
return;
}

const first = segments.shift()!;
if (segments.length === 0) {
// Reached last segment
Expand Down
1 change: 1 addition & 0 deletions src/vs/platform/userDataSync/common/extensionsSync.ts
Original file line number Diff line number Diff line change
Expand Up @@ -485,6 +485,7 @@ export class LocalExtensionsProvider {
installGivenVersion: e.pinned && !!e.version,
pinned: e.pinned,
installPreReleaseVersion: e.preRelease,
preRelease: e.preRelease,
profileLocation: profile.extensionsResource,
isApplicationScoped: e.isApplicationScoped,
context: { [EXTENSION_INSTALL_SKIP_WALKTHROUGH_CONTEXT]: true, [EXTENSION_INSTALL_SOURCE_CONTEXT]: ExtensionInstallSource.SETTINGS_SYNC }
Expand Down
6 changes: 3 additions & 3 deletions src/vs/workbench/api/browser/mainThreadDocumentsAndEditors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ import { diffSets, diffMaps } from '../../../base/common/collections.js';
import { IPaneCompositePartService } from '../../services/panecomposite/browser/panecomposite.js';
import { ViewContainerLocation } from '../../common/views.js';
import { IConfigurationService } from '../../../platform/configuration/common/configuration.js';
import { IDirtyDiffModelService } from '../../contrib/scm/browser/dirtyDiffModel.js';
import { IQuickDiffModelService } from '../../contrib/scm/browser/quickDiffModel.js';


class TextEditorSnapshot {
Expand Down Expand Up @@ -298,14 +298,14 @@ export class MainThreadDocumentsAndEditors {
@IClipboardService private readonly _clipboardService: IClipboardService,
@IPathService pathService: IPathService,
@IConfigurationService configurationService: IConfigurationService,
@IDirtyDiffModelService dirtyDiffModelService: IDirtyDiffModelService
@IQuickDiffModelService quickDiffModelService: IQuickDiffModelService
) {
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostDocumentsAndEditors);

this._mainThreadDocuments = this._toDispose.add(new MainThreadDocuments(extHostContext, this._modelService, this._textFileService, fileService, textModelResolverService, environmentService, uriIdentityService, workingCopyFileService, pathService));
extHostContext.set(MainContext.MainThreadDocuments, this._mainThreadDocuments);

this._mainThreadEditors = this._toDispose.add(new MainThreadTextEditors(this, extHostContext, codeEditorService, this._editorService, this._editorGroupService, configurationService, dirtyDiffModelService, uriIdentityService));
this._mainThreadEditors = this._toDispose.add(new MainThreadTextEditors(this, extHostContext, codeEditorService, this._editorService, this._editorGroupService, configurationService, quickDiffModelService, uriIdentityService));
extHostContext.set(MainContext.MainThreadTextEditors, this._mainThreadEditors);

// It is expected that the ctor of the state computer calls our `_onDelta`.
Expand Down
52 changes: 31 additions & 21 deletions src/vs/workbench/api/browser/mainThreadEditors.ts
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ import { IExtHostContext } from '../../services/extensions/common/extHostCustome
import { IEditorControl } from '../../common/editor.js';
import { getCodeEditor, ICodeEditor } from '../../../editor/browser/editorBrowser.js';
import { IConfigurationService } from '../../../platform/configuration/common/configuration.js';
import { IDirtyDiffModelService } from '../../contrib/scm/browser/dirtyDiffModel.js';
import { IQuickDiffModelService } from '../../contrib/scm/browser/quickDiffModel.js';
import { autorun, constObservable, derived, derivedOpts, IObservable, observableFromEvent } from '../../../base/common/observable.js';
import { IUriIdentityService } from '../../../platform/uriIdentity/common/uriIdentity.js';
import { isITextModel } from '../../../editor/common/model.js';
Expand Down Expand Up @@ -61,7 +61,7 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
@IEditorService private readonly _editorService: IEditorService,
@IEditorGroupsService private readonly _editorGroupService: IEditorGroupsService,
@IConfigurationService private readonly _configurationService: IConfigurationService,
@IDirtyDiffModelService private readonly _dirtyDiffModelService: IDirtyDiffModelService,
@IQuickDiffModelService private readonly _quickDiffModelService: IQuickDiffModelService,
@IUriIdentityService private readonly _uriIdentityService: IUriIdentityService
) {
this._instanceId = String(++MainThreadTextEditors.INSTANCE_COUNT);
Expand Down Expand Up @@ -96,7 +96,7 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
this._proxy.$acceptEditorPropertiesChanged(id, data);
}));

const diffInformationObs = this._getTextEditorDiffInformation(textEditor);
const diffInformationObs = this._getTextEditorDiffInformation(textEditor, toDispose);
toDispose.push(autorun(reader => {
const diffInformation = diffInformationObs.read(reader);
this._proxy.$acceptEditorDiffInformation(id, diffInformation);
Expand Down Expand Up @@ -131,17 +131,17 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
return result;
}

private _getTextEditorDiffInformation(textEditor: MainThreadTextEditor): IObservable<ITextEditorDiffInformation[] | undefined> {
private _getTextEditorDiffInformation(textEditor: MainThreadTextEditor, toDispose: IDisposable[]): IObservable<ITextEditorDiffInformation[] | undefined> {
const codeEditor = textEditor.getCodeEditor();
if (!codeEditor) {
return constObservable(undefined);
}

// Check if the TextModel belongs to a DiffEditor
const diffEditors = this._codeEditorService.listDiffEditors();
const [diffEditor] = diffEditors.filter(d =>
d.getOriginalEditor().getId() === codeEditor.getId() ||
d.getModifiedEditor().getId() === codeEditor.getId());
const [diffEditor] = this._codeEditorService.listDiffEditors()
.filter(d =>
d.getOriginalEditor().getId() === codeEditor.getId() ||
d.getModifiedEditor().getId() === codeEditor.getId());

const editorModelObs = diffEditor
? observableFromEvent(this, diffEditor.onDidChangeModel, () => diffEditor.getModel())
Expand All @@ -159,13 +159,14 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {

// TextEditor
if (isITextModel(editorModel)) {
const dirtyDiffModel = this._dirtyDiffModelService.getDirtyDiffModel(editorModelUri);
if (!dirtyDiffModel) {
const quickDiffModelRef = this._quickDiffModelService.createQuickDiffModelReference(editorModelUri);
if (!quickDiffModelRef) {
return constObservable(undefined);
}

return observableFromEvent(this, dirtyDiffModel.onDidChange, () => {
return dirtyDiffModel.getQuickDiffResults()
toDispose.push(quickDiffModelRef);
return observableFromEvent(this, quickDiffModelRef.object.onDidChange, () => {
return quickDiffModelRef.object.getQuickDiffResults()
.map(result => ({
original: result.original,
modified: result.modified,
Expand All @@ -178,13 +179,14 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
// we can provide multiple "original resources" to diff with the modified
// resource.
const diffAlgorithm = this._configurationService.getValue<DiffAlgorithmName>('diffEditor.diffAlgorithm');
const dirtyDiffModel = this._dirtyDiffModelService.getDiffModel(editorModelUri, diffAlgorithm);
if (!dirtyDiffModel) {
const quickDiffModelRef = this._quickDiffModelService.createQuickDiffModelReference(editorModelUri, { algorithm: diffAlgorithm });
if (!quickDiffModelRef) {
return constObservable(undefined);
}

return observableFromEvent(Event.any(dirtyDiffModel.onDidChange, diffEditor.onDidUpdateDiff), () => {
const dirtyDiffInformation = dirtyDiffModel.getQuickDiffResults()
toDispose.push(quickDiffModelRef);
return observableFromEvent(Event.any(quickDiffModelRef.object.onDidChange, diffEditor.onDidUpdateDiff), () => {
const quickDiffInformation = quickDiffModelRef.object.getQuickDiffResults()
.map(result => ({
original: result.original,
modified: result.modified,
Expand All @@ -198,7 +200,7 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
changes: diffChanges.map(change => change as LineRangeMapping)
}];

return [...dirtyDiffInformation, ...diffInformation];
return [...quickDiffInformation, ...diffInformation];
});
});

Expand Down Expand Up @@ -389,11 +391,19 @@ export class MainThreadTextEditors implements MainThreadTextEditorsShape {
return Promise.resolve([]);
}

const dirtyDiffModel = this._dirtyDiffModelService.getDirtyDiffModel(codeEditor.getModel().uri);
const scmQuickDiff = dirtyDiffModel?.quickDiffs.find(quickDiff => quickDiff.isSCM);
const scmQuickDiffChanges = dirtyDiffModel?.changes.filter(change => change.label === scmQuickDiff?.label);
const quickDiffModelRef = this._quickDiffModelService.createQuickDiffModelReference(codeEditor.getModel().uri);
if (!quickDiffModelRef) {
return Promise.resolve([]);
}

return Promise.resolve(scmQuickDiffChanges?.map(change => change.change) ?? []);
try {
const scmQuickDiff = quickDiffModelRef.object.quickDiffs.find(quickDiff => quickDiff.isSCM);
const scmQuickDiffChanges = quickDiffModelRef.object.changes.filter(change => change.label === scmQuickDiff?.label);

return Promise.resolve(scmQuickDiffChanges.map(change => change.change) ?? []);
} finally {
quickDiffModelRef.dispose();
}
}
}

Expand Down
9 changes: 7 additions & 2 deletions src/vs/workbench/api/common/extHostTypes.ts
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@ import { FileSystemProviderErrorCode, markAsFileSystemProviderError } from '../.
import { RemoteAuthorityResolverErrorCode } from '../../../platform/remote/common/remoteAuthorityResolver.js';
import { CellEditType, ICellMetadataEdit, IDocumentMetadataEdit, isTextStreamMime } from '../../contrib/notebook/common/notebookCommon.js';
import { IRelativePatternDto } from './extHost.protocol.js';
import { TextEditorSelectionSource } from '../../../platform/editor/common/editor.js';

/**
* @deprecated
Expand Down Expand Up @@ -1943,11 +1944,15 @@ export enum DecorationRangeBehavior {
}

export namespace TextEditorSelectionChangeKind {
export function fromValue(s: string | undefined) {
export function fromValue(s: TextEditorSelectionSource | string | undefined) {
switch (s) {
case 'keyboard': return TextEditorSelectionChangeKind.Keyboard;
case 'mouse': return TextEditorSelectionChangeKind.Mouse;
case 'api': return TextEditorSelectionChangeKind.Command;
case 'api':
case TextEditorSelectionSource.PROGRAMMATIC:
case TextEditorSelectionSource.JUMP:
case TextEditorSelectionSource.NAVIGATION:
return TextEditorSelectionChangeKind.Command;
}
return undefined;
}
Expand Down
Loading

0 comments on commit 910a378

Please sign in to comment.