mirror of
https://github.com/microsoft/vscode.git
synced 2026-08-05 12:55:10 +01:00
Merge branch 'main' into fix/improve-marker-placements
This commit is contained in:
@@ -12,7 +12,7 @@ import { IListAccessibilityProvider } from 'vs/base/browser/ui/list/listWidget';
|
||||
import { IDataSource, ITreeNode, ITreeRenderer } from 'vs/base/browser/ui/tree/tree';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { FuzzyScore, createMatches } from 'vs/base/common/filters';
|
||||
import { Disposable, DisposableStore, IDisposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, DisposableStore, IDisposable, toDisposable, type IReference } from 'vs/base/common/lifecycle';
|
||||
import { ThemeIcon } from 'vs/base/common/themables';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { getIconClassesForLanguageId } from 'vs/editor/common/services/getIconClasses';
|
||||
@@ -51,6 +51,7 @@ import { IOutlinePane } from 'vs/workbench/contrib/outline/browser/outline';
|
||||
import { Codicon } from 'vs/base/common/codicons';
|
||||
import { NOTEBOOK_IS_ACTIVE_EDITOR } from 'vs/workbench/contrib/notebook/common/notebookContextKeys';
|
||||
import { NotebookOutlineConstants } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineEntryFactory';
|
||||
import { INotebookCellOutlineProviderFactory } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineProviderFactory';
|
||||
|
||||
class NotebookOutlineTemplate {
|
||||
|
||||
@@ -337,7 +338,7 @@ export class NotebookCellOutline implements IOutline<OutlineEntry> {
|
||||
readonly onDidChange: Event<OutlineChangeEvent> = this._onDidChange.event;
|
||||
|
||||
get entries(): OutlineEntry[] {
|
||||
return this._outlineProvider?.entries ?? [];
|
||||
return this._outlineProviderReference?.object?.entries ?? [];
|
||||
}
|
||||
|
||||
private readonly _entriesDisposables = new DisposableStore();
|
||||
@@ -347,10 +348,10 @@ export class NotebookCellOutline implements IOutline<OutlineEntry> {
|
||||
readonly outlineKind = 'notebookCells';
|
||||
|
||||
get activeElement(): OutlineEntry | undefined {
|
||||
return this._outlineProvider?.activeElement;
|
||||
return this._outlineProviderReference?.object?.activeElement;
|
||||
}
|
||||
|
||||
private _outlineProvider: NotebookCellOutlineProvider | undefined;
|
||||
private _outlineProviderReference: IReference<NotebookCellOutlineProvider> | undefined;
|
||||
private readonly _localDisposables = new DisposableStore();
|
||||
|
||||
constructor(
|
||||
@@ -363,14 +364,14 @@ export class NotebookCellOutline implements IOutline<OutlineEntry> {
|
||||
const installSelectionListener = () => {
|
||||
const notebookEditor = _editor.getControl();
|
||||
if (!notebookEditor?.hasModel()) {
|
||||
this._outlineProvider?.dispose();
|
||||
this._outlineProvider = undefined;
|
||||
this._outlineProviderReference?.dispose();
|
||||
this._outlineProviderReference = undefined;
|
||||
this._localDisposables.clear();
|
||||
} else {
|
||||
this._outlineProvider?.dispose();
|
||||
this._outlineProviderReference?.dispose();
|
||||
this._localDisposables.clear();
|
||||
this._outlineProvider = instantiationService.createInstance(NotebookCellOutlineProvider, notebookEditor, _target);
|
||||
this._localDisposables.add(this._outlineProvider.onDidChange(e => {
|
||||
this._outlineProviderReference = instantiationService.invokeFunction((accessor) => accessor.get(INotebookCellOutlineProviderFactory).getOrCreate(notebookEditor, _target));
|
||||
this._localDisposables.add(this._outlineProviderReference.object.onDidChange(e => {
|
||||
this._onDidChange.fire(e);
|
||||
}));
|
||||
}
|
||||
@@ -411,7 +412,7 @@ export class NotebookCellOutline implements IOutline<OutlineEntry> {
|
||||
return result;
|
||||
}
|
||||
},
|
||||
quickPickDataSource: instantiationService.createInstance(NotebookQuickPickProvider, () => (this._outlineProvider?.entries ?? [])),
|
||||
quickPickDataSource: instantiationService.createInstance(NotebookQuickPickProvider, () => (this._outlineProviderReference?.object?.entries ?? [])),
|
||||
treeDataSource,
|
||||
delegate,
|
||||
renderers,
|
||||
@@ -425,7 +426,7 @@ export class NotebookCellOutline implements IOutline<OutlineEntry> {
|
||||
const showCodeCellSymbols = configurationService.getValue<boolean>(NotebookSetting.outlineShowCodeCellSymbols);
|
||||
const showMarkdownHeadersOnly = configurationService.getValue<boolean>(NotebookSetting.outlineShowMarkdownHeadersOnly);
|
||||
|
||||
for (const entry of parent instanceof NotebookCellOutline ? (this._outlineProvider?.entries ?? []) : parent.children) {
|
||||
for (const entry of parent instanceof NotebookCellOutline ? (this._outlineProviderReference?.object?.entries ?? []) : parent.children) {
|
||||
if (entry.cell.cellKind === CellKind.Markup) {
|
||||
if (!showMarkdownHeadersOnly) {
|
||||
yield entry;
|
||||
@@ -444,14 +445,14 @@ export class NotebookCellOutline implements IOutline<OutlineEntry> {
|
||||
}
|
||||
|
||||
async setFullSymbols(cancelToken: CancellationToken) {
|
||||
await this._outlineProvider?.setFullSymbols(cancelToken);
|
||||
await this._outlineProviderReference?.object?.setFullSymbols(cancelToken);
|
||||
}
|
||||
|
||||
get uri(): URI | undefined {
|
||||
return this._outlineProvider?.uri;
|
||||
return this._outlineProviderReference?.object?.uri;
|
||||
}
|
||||
get isEmpty(): boolean {
|
||||
return this._outlineProvider?.isEmpty ?? true;
|
||||
return this._outlineProviderReference?.object?.isEmpty ?? true;
|
||||
}
|
||||
async reveal(entry: OutlineEntry, options: IEditorOptions, sideBySide: boolean): Promise<void> {
|
||||
await this._editorService.openEditor({
|
||||
@@ -530,7 +531,7 @@ export class NotebookCellOutline implements IOutline<OutlineEntry> {
|
||||
this._onDidChange.dispose();
|
||||
this._dispoables.dispose();
|
||||
this._entriesDisposables.dispose();
|
||||
this._outlineProvider?.dispose();
|
||||
this._outlineProviderReference?.dispose();
|
||||
this._localDisposables.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -57,6 +57,7 @@ import { ILabelService } from 'vs/platform/label/common/label';
|
||||
import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editorGroupsService';
|
||||
import { NotebookRendererMessagingService } from 'vs/workbench/contrib/notebook/browser/services/notebookRendererMessagingServiceImpl';
|
||||
import { INotebookRendererMessagingService } from 'vs/workbench/contrib/notebook/common/notebookRendererMessagingService';
|
||||
import { INotebookCellOutlineProviderFactory, NotebookCellOutlineProviderFactory } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineProviderFactory';
|
||||
|
||||
// Editor Controller
|
||||
import 'vs/workbench/contrib/notebook/browser/controller/coreActions';
|
||||
@@ -755,6 +756,7 @@ registerSingleton(INotebookExecutionStateService, NotebookExecutionStateService,
|
||||
registerSingleton(INotebookRendererMessagingService, NotebookRendererMessagingService, InstantiationType.Delayed);
|
||||
registerSingleton(INotebookKeymapService, NotebookKeymapService, InstantiationType.Delayed);
|
||||
registerSingleton(INotebookLoggingService, NotebookLoggingService, InstantiationType.Delayed);
|
||||
registerSingleton(INotebookCellOutlineProviderFactory, NotebookCellOutlineProviderFactory, InstantiationType.Delayed);
|
||||
|
||||
const schemas: IJSONSchemaMap = {};
|
||||
function isConfigurationPropertySchema(x: IConfigurationPropertySchema | { [path: string]: IConfigurationPropertySchema }): x is IConfigurationPropertySchema {
|
||||
|
||||
@@ -260,6 +260,7 @@ export interface ICellViewModel extends IGenericCellViewModel {
|
||||
focusedOutputId?: string | undefined;
|
||||
outputIsHovered: boolean;
|
||||
getText(): string;
|
||||
getAlternativeId(): number;
|
||||
getTextLength(): number;
|
||||
getHeight(lineHeight: number): number;
|
||||
metadata: NotebookCellMetadata;
|
||||
|
||||
@@ -96,10 +96,8 @@ import { Schemas } from 'vs/base/common/network';
|
||||
import { DropIntoEditorController } from 'vs/editor/contrib/dropOrPasteInto/browser/dropIntoEditorController';
|
||||
import { CopyPasteController } from 'vs/editor/contrib/dropOrPasteInto/browser/copyPasteController';
|
||||
import { NotebookStickyScroll } from 'vs/workbench/contrib/notebook/browser/viewParts/notebookEditorStickyScroll';
|
||||
import { NotebookCellOutlineProvider } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineProvider';
|
||||
import { AccessibilityVerbositySettingId } from 'vs/workbench/contrib/accessibility/browser/accessibilityConfiguration';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { OutlineTarget } from 'vs/workbench/services/outline/browser/outline';
|
||||
import { PixelRatio } from 'vs/base/browser/pixelRatio';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { PreventDefaultContextMenuItemsContextKeyName } from 'vs/workbench/contrib/webview/browser/webview.contribution';
|
||||
@@ -278,7 +276,6 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
|
||||
public readonly scopedContextKeyService: IContextKeyService;
|
||||
private readonly instantiationService: IInstantiationService;
|
||||
private readonly _notebookOptions: NotebookOptions;
|
||||
public readonly _notebookOutline: NotebookCellOutlineProvider;
|
||||
|
||||
private _currentProgress: IProgressRunner | undefined;
|
||||
|
||||
@@ -335,8 +332,6 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
|
||||
|
||||
this._register(this.instantiationService.createInstance(NotebookEditorContextKeys, this));
|
||||
|
||||
this._notebookOutline = this._register(this.instantiationService.createInstance(NotebookCellOutlineProvider, this, OutlineTarget.QuickPick));
|
||||
|
||||
this._register(notebookKernelService.onDidChangeSelectedNotebooks(e => {
|
||||
if (isEqual(e.notebook, this.viewModel?.uri)) {
|
||||
this._loadKernelPreloads();
|
||||
@@ -1054,7 +1049,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
|
||||
}
|
||||
|
||||
private _registerNotebookStickyScroll() {
|
||||
this._notebookStickyScroll = this._register(this.instantiationService.createInstance(NotebookStickyScroll, this._notebookStickyScrollContainer, this, this._notebookOutline, this._list));
|
||||
this._notebookStickyScroll = this._register(this.instantiationService.createInstance(NotebookStickyScroll, this._notebookStickyScrollContainer, this, this._list));
|
||||
|
||||
const localDisposableStore = this._register(new DisposableStore());
|
||||
|
||||
|
||||
@@ -307,6 +307,10 @@ export abstract class BaseCellViewModel extends Disposable {
|
||||
return this.model.getValue();
|
||||
}
|
||||
|
||||
getAlternativeId(): number {
|
||||
return this.model.alternativeId;
|
||||
}
|
||||
|
||||
getTextLength(): number {
|
||||
return this.model.getTextLength();
|
||||
}
|
||||
|
||||
+21
-13
@@ -27,10 +27,25 @@ type entryDesc = {
|
||||
kind: SymbolKind;
|
||||
};
|
||||
|
||||
function getMarkdownHeadersInCellFallbackToHtmlTags(fullContent: string) {
|
||||
const headers = Array.from(getMarkdownHeadersInCell(fullContent));
|
||||
if (headers.length) {
|
||||
return headers;
|
||||
}
|
||||
// no markdown syntax headers, try to find html tags
|
||||
const match = fullContent.match(/<h([1-6]).*>(.*)<\/h\1>/i);
|
||||
if (match) {
|
||||
const level = parseInt(match[1]);
|
||||
const text = match[2].trim();
|
||||
headers.push({ depth: level, text });
|
||||
}
|
||||
return headers;
|
||||
}
|
||||
|
||||
export class NotebookOutlineEntryFactory {
|
||||
|
||||
private cellOutlineEntryCache: Record<string, entryDesc[]> = {};
|
||||
|
||||
private readonly cachedMarkdownOutlineEntries = new WeakMap<ICellViewModel, { alternativeId: number; headers: { depth: number, text: string }[] }>();
|
||||
constructor(
|
||||
private readonly executionStateService: INotebookExecutionStateService
|
||||
) { }
|
||||
@@ -48,22 +63,15 @@ export class NotebookOutlineEntryFactory {
|
||||
|
||||
if (isMarkdown) {
|
||||
const fullContent = cell.getText().substring(0, 10000);
|
||||
for (const { depth, text } of getMarkdownHeadersInCell(fullContent)) {
|
||||
const cache = this.cachedMarkdownOutlineEntries.get(cell);
|
||||
const headers = cache?.alternativeId === cell.getAlternativeId() ? cache.headers : Array.from(getMarkdownHeadersInCellFallbackToHtmlTags(fullContent));
|
||||
this.cachedMarkdownOutlineEntries.set(cell, { alternativeId: cell.getAlternativeId(), headers });
|
||||
|
||||
for (const { depth, text } of headers) {
|
||||
hasHeader = true;
|
||||
entries.push(new OutlineEntry(index++, depth, cell, text, false, false));
|
||||
}
|
||||
|
||||
if (!hasHeader) {
|
||||
// no markdown syntax headers, try to find html tags
|
||||
const match = fullContent.match(/<h([1-6]).*>(.*)<\/h\1>/i);
|
||||
if (match) {
|
||||
hasHeader = true;
|
||||
const level = parseInt(match[1]);
|
||||
const text = match[2].trim();
|
||||
entries.push(new OutlineEntry(index++, level, cell, text, false, false));
|
||||
}
|
||||
}
|
||||
|
||||
if (!hasHeader) {
|
||||
content = renderMarkdownAsPlaintext({ value: content });
|
||||
}
|
||||
|
||||
@@ -4,20 +4,21 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { DisposableStore, MutableDisposable, combinedDisposable } from 'vs/base/common/lifecycle';
|
||||
import { DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
import { isEqual } from 'vs/base/common/resources';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IMarkerService } from 'vs/platform/markers/common/markers';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { IActiveNotebookEditor, ICellViewModel, INotebookEditor, INotebookViewCellsUpdateEvent } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellKind, NotebookSetting } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { INotebookExecutionStateService, NotebookExecutionType, type ICellExecutionStateChangedEvent, type IExecutionStateChangedEvent } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
|
||||
import { IActiveNotebookEditor, ICellViewModel, INotebookEditor, type INotebookViewCellsUpdateEvent } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellKind, NotebookCellsChangeType, NotebookSetting } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { INotebookExecutionStateService, NotebookExecutionType } from 'vs/workbench/contrib/notebook/common/notebookExecutionStateService';
|
||||
import { OutlineChangeEvent, OutlineConfigKeys, OutlineTarget } from 'vs/workbench/services/outline/browser/outline';
|
||||
import { OutlineEntry } from './OutlineEntry';
|
||||
import { IOutlineModelService } from 'vs/editor/contrib/documentSymbols/browser/outlineModel';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { NotebookOutlineConstants, NotebookOutlineEntryFactory } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineEntryFactory';
|
||||
import { Delayer } from 'vs/base/common/async';
|
||||
|
||||
export class NotebookCellOutlineProvider {
|
||||
private readonly _disposables = new DisposableStore();
|
||||
@@ -41,7 +42,6 @@ export class NotebookCellOutlineProvider {
|
||||
}
|
||||
|
||||
private readonly _outlineEntryFactory: NotebookOutlineEntryFactory;
|
||||
|
||||
constructor(
|
||||
private readonly _editor: INotebookEditor,
|
||||
private readonly _target: OutlineTarget,
|
||||
@@ -53,29 +53,34 @@ export class NotebookCellOutlineProvider {
|
||||
) {
|
||||
this._outlineEntryFactory = new NotebookOutlineEntryFactory(notebookExecutionStateService);
|
||||
|
||||
const selectionListener = new MutableDisposable();
|
||||
this._disposables.add(selectionListener);
|
||||
|
||||
selectionListener.value = combinedDisposable(
|
||||
Event.debounce<void, void>(
|
||||
_editor.onDidChangeSelection,
|
||||
(last, _current) => last,
|
||||
200
|
||||
)(this._recomputeActive, this),
|
||||
Event.debounce<INotebookViewCellsUpdateEvent, INotebookViewCellsUpdateEvent>(
|
||||
_editor.onDidChangeViewCells,
|
||||
(last, _current) => last ?? _current,
|
||||
200
|
||||
)(this._recomputeState, this)
|
||||
this._disposables.add(Event.debounce<void, void>(
|
||||
_editor.onDidChangeSelection,
|
||||
(last, _current) => last,
|
||||
200
|
||||
)(() => {
|
||||
this._recomputeActive();
|
||||
}, this))
|
||||
this._disposables.add(Event.debounce<INotebookViewCellsUpdateEvent, INotebookViewCellsUpdateEvent>(
|
||||
_editor.onDidChangeViewCells,
|
||||
(last, _current) => last ?? _current,
|
||||
200
|
||||
)(() => {
|
||||
this._recomputeActive();
|
||||
}, this)
|
||||
);
|
||||
|
||||
// .3s of a delay is sufficient, 100-200s is too quick and will unnecessarily block the ui thread.
|
||||
// Given we're only updating the outline when the user types, we can afford to wait a bit.
|
||||
const delayer = this._disposables.add(new Delayer<void>(300));
|
||||
const delayedRecompute = () => delayer.trigger(() => this._recomputeState());
|
||||
|
||||
this._disposables.add(_configurationService.onDidChangeConfiguration(e => {
|
||||
if (e.affectsConfiguration(NotebookSetting.outlineShowMarkdownHeadersOnly) ||
|
||||
e.affectsConfiguration(NotebookSetting.outlineShowCodeCells) ||
|
||||
e.affectsConfiguration(NotebookSetting.outlineShowCodeCellSymbols) ||
|
||||
e.affectsConfiguration(NotebookSetting.breadcrumbsShowCodeCells)
|
||||
) {
|
||||
this._recomputeState();
|
||||
delayedRecompute();
|
||||
}
|
||||
}));
|
||||
|
||||
@@ -84,17 +89,28 @@ export class NotebookCellOutlineProvider {
|
||||
}));
|
||||
|
||||
this._disposables.add(
|
||||
Event.debounce<ICellExecutionStateChangedEvent | IExecutionStateChangedEvent>(
|
||||
notebookExecutionStateService.onDidChangeExecution,
|
||||
(last, _current) => last ?? _current,
|
||||
200)(e => {
|
||||
if (e.type === NotebookExecutionType.cell && !!this._editor.textModel && e.affectsNotebook(this._editor.textModel?.uri)) {
|
||||
this._recomputeState();
|
||||
}
|
||||
})
|
||||
notebookExecutionStateService.onDidChangeExecution(e => {
|
||||
if (e.type === NotebookExecutionType.cell && !!this._editor.textModel && e.affectsNotebook(this._editor.textModel?.uri)) {
|
||||
delayedRecompute();
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
this._recomputeState();
|
||||
const disposable = this._disposables.add(new DisposableStore());
|
||||
const monitorModelChanges = () => {
|
||||
disposable.clear();
|
||||
if (!this._editor.textModel) {
|
||||
return;
|
||||
}
|
||||
disposable.add(this._editor.textModel.onDidChangeContent(contentChanges => {
|
||||
if (contentChanges.rawEvents.some(c => c.kind === NotebookCellsChangeType.ChangeCellContent)) {
|
||||
delayedRecompute();
|
||||
}
|
||||
}));
|
||||
}
|
||||
this._disposables.add(this._editor.onDidChangeModel(monitorModelChanges));
|
||||
monitorModelChanges();
|
||||
this._recomputeState()
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
@@ -104,10 +120,6 @@ export class NotebookCellOutlineProvider {
|
||||
this._disposables.dispose();
|
||||
}
|
||||
|
||||
init(): void {
|
||||
this._recomputeState();
|
||||
}
|
||||
|
||||
async setFullSymbols(cancelToken: CancellationToken) {
|
||||
const notebookEditorWidget = this._editor;
|
||||
|
||||
@@ -126,7 +138,6 @@ export class NotebookCellOutlineProvider {
|
||||
|
||||
this._recomputeState();
|
||||
}
|
||||
|
||||
private _recomputeState(): void {
|
||||
this._entriesDisposables.clear();
|
||||
this._activeEntry = undefined;
|
||||
@@ -159,11 +170,6 @@ export class NotebookCellOutlineProvider {
|
||||
const entries: OutlineEntry[] = [];
|
||||
for (const cell of notebookCells) {
|
||||
entries.push(...this._outlineEntryFactory.getOutlineEntries(cell, this._target, entries.length));
|
||||
// send an event whenever any of the cells change
|
||||
this._entriesDisposables.add(cell.model.onDidChangeContent(() => {
|
||||
this._recomputeState();
|
||||
this._onDidChange.fire({});
|
||||
}));
|
||||
}
|
||||
|
||||
// build a tree from the list of entries
|
||||
|
||||
@@ -0,0 +1,39 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ReferenceCollection, type IReference } from 'vs/base/common/lifecycle';
|
||||
import { IInstantiationService, createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import type { INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { NotebookCellOutlineProvider } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineProvider';
|
||||
import type { OutlineTarget } from 'vs/workbench/services/outline/browser/outline';
|
||||
|
||||
class NotebookCellOutlineProviderReferenceCollection extends ReferenceCollection<NotebookCellOutlineProvider> {
|
||||
constructor(@IInstantiationService private readonly instantiationService: IInstantiationService) {
|
||||
super();
|
||||
}
|
||||
protected override createReferencedObject(_key: string, editor: INotebookEditor, target: OutlineTarget): NotebookCellOutlineProvider {
|
||||
return this.instantiationService.createInstance(NotebookCellOutlineProvider, editor, target);
|
||||
}
|
||||
protected override destroyReferencedObject(_key: string, object: NotebookCellOutlineProvider): void {
|
||||
object.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
export const INotebookCellOutlineProviderFactory = createDecorator<INotebookCellOutlineProviderFactory>('INotebookCellOutlineProviderFactory');
|
||||
|
||||
export interface INotebookCellOutlineProviderFactory {
|
||||
getOrCreate(editor: INotebookEditor, target: OutlineTarget): IReference<NotebookCellOutlineProvider>
|
||||
}
|
||||
|
||||
export class NotebookCellOutlineProviderFactory implements INotebookCellOutlineProviderFactory {
|
||||
private readonly _data: NotebookCellOutlineProviderReferenceCollection;
|
||||
constructor(@IInstantiationService instantiationService: IInstantiationService) {
|
||||
this._data = instantiationService.createInstance(NotebookCellOutlineProviderReferenceCollection);
|
||||
}
|
||||
|
||||
getOrCreate(editor: INotebookEditor, target: OutlineTarget): IReference<NotebookCellOutlineProvider> {
|
||||
return this._data.acquire(editor.getId(), editor, target);
|
||||
}
|
||||
}
|
||||
@@ -7,7 +7,7 @@ import * as DOM from 'vs/base/browser/dom';
|
||||
import { EventType as TouchEventType } from 'vs/base/browser/touch';
|
||||
import { StandardMouseEvent } from 'vs/base/browser/mouseEvent';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, DisposableStore, type IReference } from 'vs/base/common/lifecycle';
|
||||
import { MenuId } from 'vs/platform/actions/common/actions';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { CellFoldingState, INotebookEditor } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
@@ -22,6 +22,9 @@ import { MarkupCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewM
|
||||
import { FoldingController } from 'vs/workbench/contrib/notebook/browser/controller/foldingController';
|
||||
import { NotebookOptionsChangeEvent } from 'vs/workbench/contrib/notebook/browser/notebookOptions';
|
||||
import { NotebookSectionArgs } from 'vs/workbench/contrib/notebook/browser/controller/sectionActions';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { INotebookCellOutlineProviderFactory } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineProviderFactory';
|
||||
import { OutlineTarget } from 'vs/workbench/services/outline/browser/outline';
|
||||
|
||||
export class NotebookStickyLine extends Disposable {
|
||||
constructor(
|
||||
@@ -102,6 +105,7 @@ export class NotebookStickyScroll extends Disposable {
|
||||
|
||||
private readonly _onDidChangeNotebookStickyScroll = this._register(new Emitter<number>());
|
||||
readonly onDidChangeNotebookStickyScroll: Event<number> = this._onDidChangeNotebookStickyScroll.event;
|
||||
private notebookOutlineReference?: IReference<NotebookCellOutlineProvider>;
|
||||
|
||||
getDomNode(): HTMLElement {
|
||||
return this.domNode;
|
||||
@@ -139,9 +143,9 @@ export class NotebookStickyScroll extends Disposable {
|
||||
constructor(
|
||||
private readonly domNode: HTMLElement,
|
||||
private readonly notebookEditor: INotebookEditor,
|
||||
private readonly notebookOutline: NotebookCellOutlineProvider,
|
||||
private readonly notebookCellList: INotebookCellList,
|
||||
@IContextMenuService private readonly _contextMenuService: IContextMenuService,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -187,37 +191,37 @@ export class NotebookStickyScroll extends Disposable {
|
||||
this.init();
|
||||
} else {
|
||||
this._disposables.clear();
|
||||
this.notebookOutline.dispose();
|
||||
this.notebookOutlineReference?.dispose();
|
||||
this.disposeCurrentStickyLines();
|
||||
DOM.clearNode(this.domNode);
|
||||
this.updateDisplay();
|
||||
}
|
||||
} else if (e.stickyScrollMode && this.notebookEditor.notebookOptions.getDisplayOptions().stickyScrollEnabled) {
|
||||
this.updateContent(computeContent(this.notebookEditor, this.notebookCellList, this.notebookOutline.entries, this.getCurrentStickyHeight()));
|
||||
} else if (e.stickyScrollMode && this.notebookEditor.notebookOptions.getDisplayOptions().stickyScrollEnabled && this.notebookOutlineReference?.object) {
|
||||
this.updateContent(computeContent(this.notebookEditor, this.notebookCellList, this.notebookOutlineReference?.object?.entries, this.getCurrentStickyHeight()));
|
||||
}
|
||||
}
|
||||
|
||||
private init() {
|
||||
this.notebookOutline.init();
|
||||
this.updateContent(computeContent(this.notebookEditor, this.notebookCellList, this.notebookOutline.entries, this.getCurrentStickyHeight()));
|
||||
const { object: notebookOutlineReference } = this.notebookOutlineReference = this.instantiationService.invokeFunction((accessor) => accessor.get(INotebookCellOutlineProviderFactory).getOrCreate(this.notebookEditor, OutlineTarget.QuickPick));
|
||||
this._register(this.notebookOutlineReference);
|
||||
this.updateContent(computeContent(this.notebookEditor, this.notebookCellList, notebookOutlineReference.entries, this.getCurrentStickyHeight()));
|
||||
|
||||
this._disposables.add(this.notebookOutline.onDidChange(() => {
|
||||
const recompute = computeContent(this.notebookEditor, this.notebookCellList, this.notebookOutline.entries, this.getCurrentStickyHeight());
|
||||
this._disposables.add(notebookOutlineReference.onDidChange(() => {
|
||||
const recompute = computeContent(this.notebookEditor, this.notebookCellList, notebookOutlineReference.entries, this.getCurrentStickyHeight());
|
||||
if (!this.compareStickyLineMaps(recompute, this.currentStickyLines)) {
|
||||
this.updateContent(recompute);
|
||||
}
|
||||
}));
|
||||
|
||||
this._disposables.add(this.notebookEditor.onDidAttachViewModel(() => {
|
||||
this.notebookOutline.init();
|
||||
this.updateContent(computeContent(this.notebookEditor, this.notebookCellList, this.notebookOutline.entries, this.getCurrentStickyHeight()));
|
||||
this.updateContent(computeContent(this.notebookEditor, this.notebookCellList, notebookOutlineReference.entries, this.getCurrentStickyHeight()));
|
||||
}));
|
||||
|
||||
this._disposables.add(this.notebookEditor.onDidScroll(() => {
|
||||
const d = new Delayer(100);
|
||||
d.trigger(() => {
|
||||
d.dispose();
|
||||
const recompute = computeContent(this.notebookEditor, this.notebookCellList, this.notebookOutline.entries, this.getCurrentStickyHeight());
|
||||
const recompute = computeContent(this.notebookEditor, this.notebookCellList, notebookOutlineReference.entries, this.getCurrentStickyHeight());
|
||||
if (!this.compareStickyLineMaps(recompute, this.currentStickyLines)) {
|
||||
this.updateContent(recompute);
|
||||
}
|
||||
@@ -365,7 +369,7 @@ export class NotebookStickyScroll extends Disposable {
|
||||
override dispose() {
|
||||
this._disposables.dispose();
|
||||
this.disposeCurrentStickyLines();
|
||||
this.notebookOutline.dispose();
|
||||
this.notebookOutlineReference?.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,6 +67,7 @@ import { mainWindow } from 'vs/base/browser/window';
|
||||
import { TestCodeEditorService } from 'vs/editor/test/browser/editorTestServices';
|
||||
import { IInlineChatService } from 'vs/workbench/contrib/inlineChat/common/inlineChat';
|
||||
import { InlineChatServiceImpl } from 'vs/workbench/contrib/inlineChat/common/inlineChatServiceImpl';
|
||||
import { INotebookCellOutlineProviderFactory, NotebookCellOutlineProviderFactory } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookOutlineProviderFactory';
|
||||
|
||||
export class TestCell extends NotebookCellTextModel {
|
||||
constructor(
|
||||
@@ -200,6 +201,7 @@ export function setupInstantiationService(disposables: DisposableStore) {
|
||||
instantiationService.stub(INotebookCellStatusBarService, disposables.add(new NotebookCellStatusBarService()));
|
||||
instantiationService.stub(ICodeEditorService, disposables.add(new TestCodeEditorService(testThemeService)));
|
||||
instantiationService.stub(IInlineChatService, instantiationService.createInstance(InlineChatServiceImpl));
|
||||
instantiationService.stub(INotebookCellOutlineProviderFactory, instantiationService.createInstance(NotebookCellOutlineProviderFactory));
|
||||
return instantiationService;
|
||||
}
|
||||
|
||||
@@ -228,6 +230,7 @@ function _createTestNotebookEditor(instantiationService: TestInstantiationServic
|
||||
|
||||
let visibleRanges: ICellRange[] = [{ start: 0, end: 100 }];
|
||||
|
||||
const id = Date.now().toString();
|
||||
const notebookEditor: IActiveNotebookEditorDelegate = new class extends mock<IActiveNotebookEditorDelegate>() {
|
||||
// eslint-disable-next-line local/code-must-use-super-dispose
|
||||
override dispose() {
|
||||
@@ -313,7 +316,7 @@ function _createTestNotebookEditor(instantiationService: TestInstantiationServic
|
||||
visibleRanges = _ranges;
|
||||
}
|
||||
|
||||
override getId(): string { return ''; }
|
||||
override getId(): string { return id; }
|
||||
override setScrollTop(scrollTop: number): void {
|
||||
cellList.scrollTop = scrollTop;
|
||||
}
|
||||
|
||||
@@ -137,6 +137,9 @@ __vsc_escape_value() {
|
||||
# Send the IsWindows property if the environment looks like Windows
|
||||
if [[ "$(uname -s)" =~ ^CYGWIN*|MINGW*|MSYS* ]]; then
|
||||
builtin printf '\e]633;P;IsWindows=True\a'
|
||||
__vsc_is_windows=1
|
||||
else
|
||||
__vsc_is_windows=0
|
||||
fi
|
||||
|
||||
# Allow verifying $BASH_COMMAND doesn't have aliases resolved via history when the right HISTCONTROL
|
||||
@@ -168,7 +171,12 @@ __vsc_prompt_end() {
|
||||
}
|
||||
|
||||
__vsc_update_cwd() {
|
||||
builtin printf '\e]633;P;Cwd=%s\a' "$(__vsc_escape_value "$PWD")"
|
||||
if [ "$__vsc_is_windows" = "1" ]; then
|
||||
__vsc_cwd="$(cygpath -m "$PWD")"
|
||||
else
|
||||
__vsc_cwd="$PWD"
|
||||
fi
|
||||
builtin printf '\e]633;P;Cwd=%s\a' "$(__vsc_escape_value "$__vsc_cwd")"
|
||||
}
|
||||
|
||||
__vsc_update_prompt_height() {
|
||||
|
||||
Reference in New Issue
Block a user