Merge branch 'main' into fix/improve-marker-placements

This commit is contained in:
Chapman Pendery
2024-04-16 20:24:39 -07:00
committed by GitHub
11 changed files with 159 additions and 88 deletions
@@ -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();
}
@@ -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() {