Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions build/gulpfile.vscode.ts
Original file line number Diff line number Diff line change
Expand Up @@ -330,6 +330,7 @@ function packageTask(platform: string, arch: string, sourceFolderName: string, d
all = es.merge(all, gulp.src([
'resources/win32/bower.ico',
'resources/win32/c.ico',
'resources/win32/code.ico',
'resources/win32/config.ico',
'resources/win32/cpp.ico',
'resources/win32/csharp.ico',
Expand Down
1 change: 1 addition & 0 deletions build/lib/stylelint/vscode-known-variables.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,6 +24,7 @@
"--vscode-agentSessionReadIndicator-foreground",
"--vscode-agentSessionSelectedBadge-border",
"--vscode-agentSessionSelectedUnfocusedBadge-border",
"--vscode-agentStatusIndicator-background",
"--vscode-badge-background",
"--vscode-badge-foreground",
"--vscode-banner-background",
Expand Down
8 changes: 6 additions & 2 deletions build/win32/code.iss
Original file line number Diff line number Diff line change
Expand Up @@ -288,7 +288,7 @@ Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.code-workspace\OpenW
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.code-workspace\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.code-workspace"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.code-workspace"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Code Workspace}"; Flags: uninsdeletekey; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.code-workspace"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.code-workspace\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#VersionedResourcesFolder}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.code-workspace\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#VersionedResourcesFolder}\resources\app\resources\win32\code.ico"; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.code-workspace\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.code-workspace\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles

Expand Down Expand Up @@ -649,7 +649,7 @@ Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ipynb\OpenWithProgid
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\.ipynb\OpenWithProgids"; ValueType: string; ValueName: "{#RegValueName}.ipynb"; ValueData: ""; Flags: uninsdeletevalue; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ipynb"; ValueType: string; ValueName: ""; ValueData: "{cm:SourceFile,Jupyter}"; Flags: uninsdeletekey; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ipynb"; ValueType: string; ValueName: "AppUserModelID"; ValueData: "{#AppUserId}"; Flags: uninsdeletekey; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ipynb\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#VersionedResourcesFolder}\resources\app\resources\win32\default.ico"; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ipynb\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\{#VersionedResourcesFolder}\resources\app\resources\win32\python.ico"; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ipynb\shell\open"; ValueType: string; ValueName: "Icon"; ValueData: """{app}\{#ExeBasename}.exe"""; Tasks: associatewithfiles
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\{#RegValueName}.ipynb\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: associatewithfiles

Expand Down Expand Up @@ -1301,6 +1301,10 @@ Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Drive\shell\{#RegValu

Root: {#EnvironmentRootKey}; Subkey: "{#EnvironmentKey}"; ValueType: expandsz; ValueName: "Path"; ValueData: "{code:AddToPath|{app}\bin}"; Tasks: addtopath; Check: NeedsAddToPath(ExpandConstant('{app}\bin'))

; App Paths - allows running code from Explorer address bar
Root: {#EnvironmentRootKey}; Subkey: "Software\Microsoft\Windows\CurrentVersion\App Paths\{#ApplicationName}.exe"; ValueType: string; ValueName: ""; ValueData: "{app}\{#ExeBasename}.exe"; Flags: uninsdeletekey
Root: {#EnvironmentRootKey}; Subkey: "Software\Microsoft\Windows\CurrentVersion\App Paths\{#ApplicationName}.exe"; ValueType: string; ValueName: "Path"; ValueData: "{app}"; Flags: uninsdeletekey

[Code]
function IsBackgroundUpdate(): Boolean;
begin
Expand Down
2 changes: 2 additions & 0 deletions src/vs/base/node/osReleaseInfo.ts
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,8 @@ export async function getOSReleaseInfo(errorLogger: (error: string | Error) => v
return releaseInfo;
} catch (err) {
errorLogger(err);
} finally {
await handle.close();
}

return;
Expand Down
22 changes: 14 additions & 8 deletions src/vs/editor/common/model.ts
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ import { IWordAtPosition } from './core/wordHelper.js';
import { FormattingOptions } from './languages.js';
import { ILanguageSelection } from './languages/language.js';
import { IBracketPairsTextModelPart } from './textModelBracketPairs.js';
import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent, IModelTokensChangedEvent, InternalModelContentChangeEvent, ModelFontChangedEvent, ModelInjectedTextChangedEvent, ModelLineHeightChangedEvent } from './textModelEvents.js';
import { IModelContentChangedEvent, IModelDecorationsChangedEvent, IModelLanguageChangedEvent, IModelLanguageConfigurationChangedEvent, IModelOptionsChangedEvent, IModelTokensChangedEvent, ModelFontChangedEvent, ModelLineHeightChangedEvent } from './textModelEvents.js';
import { IModelContentChange } from './model/mirrorTextModel.js';
import { IGuidesTextModelPart } from './textModelGuides.js';
import { ITokenizationTextModelPart } from './tokenizationTextModelPart.js';
Expand All @@ -28,6 +28,7 @@ import { TokenArray } from './tokens/lineTokens.js';
import { IEditorModel } from './editorCommon.js';
import { TextModelEditSource } from './textModelEditSource.js';
import { TextEdit } from './core/edits/textEdit.js';
import { IViewModel } from './viewModel.js';

/**
* Vertical Lane in the overview ruler of the editor.
Expand Down Expand Up @@ -715,6 +716,18 @@ export interface ITextModel {
*/
readonly isForSimpleWidget: boolean;

/**
* Method to register a view model on a model
* @internal
*/
registerViewModel(viewModel: IViewModel): void;

/**
* Method which unregister a view model on a model
* @internal
*/
unregisterViewModel(viewModel: IViewModel): void;

/**
* If true, the text model might contain RTL.
* If false, the text model **contains only** contain LTR.
Expand Down Expand Up @@ -1285,13 +1298,6 @@ export interface ITextModel {
*/
canRedo(): boolean;

/**
* @deprecated Please use `onDidChangeContent` instead.
* An event emitted when the contents of the model have changed.
* @internal
* @event
*/
readonly onDidChangeContentOrInjectedText: Event<InternalModelContentChangeEvent | ModelInjectedTextChangedEvent>;
/**
* An event emitted when the contents of the model have changed.
* @event
Expand Down
72 changes: 40 additions & 32 deletions src/vs/editor/common/model/textModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ import { Color } from '../../../base/common/color.js';
import { BugIndicatingError, illegalArgument, onUnexpectedError } from '../../../base/common/errors.js';
import { Emitter, Event } from '../../../base/common/event.js';
import { IMarkdownString } from '../../../base/common/htmlContent.js';
import { Disposable, IDisposable, MutableDisposable, combinedDisposable } from '../../../base/common/lifecycle.js';
import { Disposable, IDisposable, MutableDisposable } from '../../../base/common/lifecycle.js';
import { listenStream } from '../../../base/common/stream.js';
import * as strings from '../../../base/common/strings.js';
import { ThemeColor } from '../../../base/common/themables.js';
Expand Down Expand Up @@ -54,6 +54,7 @@ import { AttachedViews } from './tokens/abstractSyntaxTokenBackend.js';
import { TokenizationFontDecorationProvider } from './tokens/tokenizationFontDecorationsProvider.js';
import { LineFontChangingDecoration, LineHeightChangingDecoration } from './decorationProvider.js';
import { TokenizationTextModelPart } from './tokens/tokenizationTextModelPart.js';
import { IViewModel } from '../viewModel.js';

export function createTextBufferFactory(text: string): model.ITextBufferFactory {
const builder = new PieceTreeTextBufferBuilder();
Expand Down Expand Up @@ -234,8 +235,6 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati
private readonly _onDidChangeAttached: Emitter<void> = this._register(new Emitter<void>());
public get onDidChangeAttached(): Event<void> { return this._onDidChangeAttached.event; }

private readonly _onDidChangeInjectedText: Emitter<ModelInjectedTextChangedEvent> = this._register(new Emitter<ModelInjectedTextChangedEvent>());

private readonly _onDidChangeLineHeight: Emitter<ModelLineHeightChangedEvent> = this._register(new Emitter<ModelLineHeightChangedEvent>());
public get onDidChangeLineHeight(): Event<ModelLineHeightChangedEvent> { return this._onDidChangeLineHeight.event; }

Expand All @@ -244,13 +243,7 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati

private readonly _eventEmitter: DidChangeContentEmitter = this._register(new DidChangeContentEmitter());
public onDidChangeContent(listener: (e: IModelContentChangedEvent) => void): IDisposable {
return this._eventEmitter.slowEvent((e: InternalModelContentChangeEvent) => listener(e.contentChangedEvent));
}
public onDidChangeContentOrInjectedText(listener: (e: InternalModelContentChangeEvent | ModelInjectedTextChangedEvent) => void): IDisposable {
return combinedDisposable(
this._eventEmitter.fastEvent(e => listener(e)),
this._onDidChangeInjectedText.event(e => listener(e))
);
return this._eventEmitter.event((e: InternalModelContentChangeEvent) => listener(e.contentChangedEvent));
}
//#endregion

Expand Down Expand Up @@ -307,6 +300,7 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati
public get guides(): IGuidesTextModelPart { return this._guidesTextModelPart; }

private readonly _attachedViews = new AttachedViews();
private readonly _viewModels = new Set<IViewModel>();

constructor(
source: string | model.ITextBufferFactory,
Expand Down Expand Up @@ -440,7 +434,6 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati
|| this._tokenizationTextModelPart._hasListeners()
|| this._onDidChangeOptions.hasListeners()
|| this._onDidChangeAttached.hasListeners()
|| this._onDidChangeInjectedText.hasListeners()
|| this._onDidChangeLineHeight.hasListeners()
|| this._onDidChangeFont.hasListeners()
|| this._eventEmitter.hasListeners()
Expand All @@ -453,6 +446,14 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati
}
}

public registerViewModel(viewModel: IViewModel): void {
this._viewModels.add(viewModel);
}

public unregisterViewModel(viewModel: IViewModel): void {
this._viewModels.delete(viewModel);
}

public equalsTextBuffer(other: model.ITextBuffer): boolean {
this._assertNotDisposed();
return this._buffer.equals(other);
Expand All @@ -463,15 +464,21 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati
return this._buffer;
}

private _emitContentChangedEvent(rawChange: ModelRawContentChangedEvent, change: IModelContentChangedEvent): void {
private _emitContentChangedEvent(rawChange: ModelRawContentChangedEvent, change: IModelContentChangedEvent, resultingSelection: Selection[] | null = null): void {
if (this.__isDisposing) {
// Do not confuse listeners by emitting any event after disposing
return;
}
this._tokenizationTextModelPart.handleDidChangeContent(change);
this._bracketPairs.handleDidChangeContent(change);
this._fontTokenDecorationsProvider.handleDidChangeContent(change);
this._eventEmitter.fire(new InternalModelContentChangeEvent(rawChange, change));
const contentChangeEvent = new InternalModelContentChangeEvent(rawChange, change);
// Set resultingSelection early so viewModels can use it for cursor positioning
if (resultingSelection) {
contentChangeEvent.rawContentChangedEvent.resultingSelection = resultingSelection;
}
this._onDidChangeContentOrInjectedText(contentChangeEvent);
this._eventEmitter.fire(contentChangeEvent);
}

public setValue(value: string | model.ITextSnapshot, reason = EditSources.setValue()): void {
Expand Down Expand Up @@ -1461,7 +1468,8 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati
this._eventEmitter.beginDeferredEmit();
this._isUndoing = isUndoing;
this._isRedoing = isRedoing;
this.applyEdits(edits, false);
const operations = this._validateEditOperations(edits);
this._doApplyEdits(operations, false, EditSources.applyEdits(), resultingSelection);
this.setEOL(eol);
this._overwriteAlternativeVersionId(resultingAlternativeVersionId);
} finally {
Expand Down Expand Up @@ -1492,7 +1500,7 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati
}
}

private _doApplyEdits(rawOperations: model.ValidAnnotatedEditOperation[], computeUndoEdits: boolean, reason: TextModelEditSource): void | model.IValidEditOperation[] {
private _doApplyEdits(rawOperations: model.ValidAnnotatedEditOperation[], computeUndoEdits: boolean, reason: TextModelEditSource, resultingSelection: Selection[] | null = null): void | model.IValidEditOperation[] {

const oldLineCount = this._buffer.getLineCount();
const result = this._buffer.applyEdits(rawOperations, this._options.trimAutoWhitespace, computeUndoEdits);
Expand Down Expand Up @@ -1612,7 +1620,8 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati
isFlush: false,
detailedReasons: [reason],
detailedReasonsChangeLengths: [contentChanges.length],
}
},
resultingSelection
);
}

Expand Down Expand Up @@ -1645,7 +1654,7 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati
if (affectedInjectedTextLines && affectedInjectedTextLines.size > 0) {
const affectedLines = Array.from(affectedInjectedTextLines);
const lineChangeEvents = affectedLines.map(lineNumber => new ModelRawLineChanged(lineNumber, this.getLineContent(lineNumber), this._getInjectedTextInLine(lineNumber)));
this._onDidChangeInjectedText.fire(new ModelInjectedTextChangedEvent(lineChangeEvents));
this._onDidChangeContentOrInjectedText(new ModelInjectedTextChangedEvent(lineChangeEvents));
}
this._fireOnDidChangeLineHeight(affectedLineHeights);
this._fireOnDidChangeFont(affectedFontLines);
Expand All @@ -1667,6 +1676,15 @@ export class TextModel extends Disposable implements model.ITextModel, IDecorati
}
}

private _onDidChangeContentOrInjectedText(e: InternalModelContentChangeEvent | ModelInjectedTextChangedEvent): void {
for (const viewModel of this._viewModels) {
viewModel.onDidChangeContentOrInjectedText(e);
}
for (const viewModel of this._viewModels) {
viewModel.emitContentChangeEvent(e);
}
}

public changeDecorations<T>(callback: (changeAccessor: model.IModelDecorationsChangeAccessor) => T, ownerId: number = 0): T | null {
this._assertNotDisposed();

Expand Down Expand Up @@ -2655,13 +2673,8 @@ class DidChangeDecorationsEmitter extends Disposable {

class DidChangeContentEmitter extends Disposable {

/**
* Both `fastEvent` and `slowEvent` work the same way and contain the same events, but first we invoke `fastEvent` and then `slowEvent`.
*/
private readonly _fastEmitter: Emitter<InternalModelContentChangeEvent> = this._register(new Emitter<InternalModelContentChangeEvent>());
public readonly fastEvent: Event<InternalModelContentChangeEvent> = this._fastEmitter.event;
private readonly _slowEmitter: Emitter<InternalModelContentChangeEvent> = this._register(new Emitter<InternalModelContentChangeEvent>());
public readonly slowEvent: Event<InternalModelContentChangeEvent> = this._slowEmitter.event;
private readonly _emitter: Emitter<InternalModelContentChangeEvent> = this._register(new Emitter<InternalModelContentChangeEvent>());
public readonly event: Event<InternalModelContentChangeEvent> = this._emitter.event;

private _deferredCnt: number;
private _deferredEvent: InternalModelContentChangeEvent | null;
Expand All @@ -2673,10 +2686,7 @@ class DidChangeContentEmitter extends Disposable {
}

public hasListeners(): boolean {
return (
this._fastEmitter.hasListeners()
|| this._slowEmitter.hasListeners()
);
return this._emitter.hasListeners();
}

public beginDeferredEmit(): void {
Expand All @@ -2690,8 +2700,7 @@ class DidChangeContentEmitter extends Disposable {
this._deferredEvent.rawContentChangedEvent.resultingSelection = resultingSelection;
const e = this._deferredEvent;
this._deferredEvent = null;
this._fastEmitter.fire(e);
this._slowEmitter.fire(e);
this._emitter.fire(e);
}
}
}
Expand All @@ -2705,7 +2714,6 @@ class DidChangeContentEmitter extends Disposable {
}
return;
}
this._fastEmitter.fire(e);
this._slowEmitter.fire(e);
this._emitter.fire(e);
}
}
2 changes: 1 addition & 1 deletion src/vs/editor/common/viewLayout/viewLayout.ts
Original file line number Diff line number Diff line change
Expand Up @@ -324,7 +324,7 @@ export class ViewLayout extends Disposable implements IViewLayout {
if (maxLineWidth > layoutInfo.contentWidth + fontInfo.typicalHalfwidthCharacterWidth) {
// This is a case where viewport wrapping is on, but the line extends above the viewport
if (minimap.enabled && minimap.side === 'right') {
// We need to accomodate the scrollbar width
// We need to accommodate the scrollbar width
return maxLineWidth + layoutInfo.verticalScrollbarWidth;
}
}
Expand Down
4 changes: 4 additions & 0 deletions src/vs/editor/common/viewModel.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ import { INewScrollPosition, ScrollType } from './editorCommon.js';
import { EditorTheme } from './editorTheme.js';
import { EndOfLinePreference, IGlyphMarginLanesModel, IModelDecorationOptions, ITextModel, TextDirection } from './model.js';
import { ILineBreaksComputer, InjectedText } from './modelLineProjectionData.js';
import { InternalModelContentChangeEvent, ModelInjectedTextChangedEvent } from './textModelEvents.js';
import { BracketGuideOptions, IActiveIndentGuideInfo, IndentGuide } from './textModelGuides.js';
import { IViewLineTokens } from './tokens/lineTokens.js';
import { ViewEventHandler } from './viewEventHandler.js';
Expand Down Expand Up @@ -85,6 +86,9 @@ export interface IViewModel extends ICursorSimpleModel, ISimpleModel {
getPlainTextToCopy(modelRanges: Range[], emptySelectionClipboard: boolean, forceCRLF: boolean): { sourceRanges: Range[]; sourceText: string | string[] };
getRichTextToCopy(modelRanges: Range[], emptySelectionClipboard: boolean): { html: string; mode: string } | null;

onDidChangeContentOrInjectedText(e: InternalModelContentChangeEvent | ModelInjectedTextChangedEvent): void;
emitContentChangeEvent(e: InternalModelContentChangeEvent | ModelInjectedTextChangedEvent): void;

createLineBreaksComputer(): ILineBreaksComputer;

//#region cursor
Expand Down
Loading
Loading