Skip to content
Merged
Show file tree
Hide file tree
Changes from 2 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
3 changes: 2 additions & 1 deletion src/vs/workbench/browser/parts/editor/breadcrumbsControl.ts
Original file line number Diff line number Diff line change
Expand Up @@ -629,7 +629,8 @@ registerAction2(class ToggleBreadcrumb extends Action2 {
{ id: MenuId.CommandPalette },
{ id: MenuId.MenubarAppearanceMenu, group: '4_editor', order: 2 },
{ id: MenuId.NotebookToolbar, group: 'notebookLayout', order: 2 },
{ id: MenuId.StickyScrollContext }
{ id: MenuId.StickyScrollContext },
{ id: MenuId.NotebookStickyScrollContext, group: 'notebookView', order: 2 }
]
});
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -246,6 +246,10 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditorD
return this._notebookViewModel?.notebookDocument;
}

get notebookStickyScroll(): NotebookStickyScroll {
return this._notebookStickyScroll;
}

get isReadOnly() {
return this._notebookViewModel?.options.isReadOnly ?? false;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,9 @@ import { foldingCollapsedIcon, foldingExpandedIcon } from 'vs/editor/contrib/fol
import { MarkupCellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/markupCellViewModel';
import { FoldingController } from 'vs/workbench/contrib/notebook/browser/controller/foldingController';
import { NotebookOptionsChangeEvent } from 'vs/workbench/contrib/notebook/browser/notebookOptions';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { INotebookEditorService } from 'vs/workbench/contrib/notebook/browser/services/notebookEditorService';
import { isNotebookEditorInput } from 'vs/workbench/contrib/notebook/common/notebookEditorInput';

export class ToggleNotebookStickyScroll extends Action2 {

Expand All @@ -44,7 +47,11 @@ export class ToggleNotebookStickyScroll extends Action2 {
},
menu: [
{ id: MenuId.CommandPalette },
{ id: MenuId.NotebookStickyScrollContext }
{
id: MenuId.NotebookStickyScrollContext,
group: 'notebookView',
order: 2
}
]
});
}
Expand All @@ -56,6 +63,43 @@ export class ToggleNotebookStickyScroll extends Action2 {
}
}

export class RunInSectionStickyScroll extends Action2 {
constructor() {
super({
id: 'notebook.action.runInSection',
title: {
...localize2('runInSectionStickyScroll', "Run Section"),
mnemonicTitle: localize({ key: 'mirunInSectionStickyScroll', comment: ['&& denotes a mnemonic'] }, "&&Run Section"),
},
menu: [
{
id: MenuId.NotebookStickyScrollContext,
group: 'notebookExecution',
order: 1
}
]
});
}

override async run(accessor: ServicesAccessor): Promise<void> {
const editorService = accessor.get(IEditorService);
const notebookEditorService = accessor.get(INotebookEditorService);

const activeInput = editorService.activeEditorPane?.input;
const isNotebook = isNotebookEditorInput(activeInput);
if (!isNotebook) {
return;
}
const notebookEditor = notebookEditorService.retrieveExistingWidgetFromURI(activeInput.resource)?.value;
if (!notebookEditor) {
return;
}

const notebookStickyScrollComponent = notebookEditor.notebookStickyScroll;
notebookStickyScrollComponent.executeStickySection();
}
}

export class NotebookStickyLine extends Disposable {
constructor(
public readonly element: HTMLElement,
Expand All @@ -78,14 +122,6 @@ export class NotebookStickyLine extends Disposable {
}
}));

// folding icon hovers
// this._register(DOM.addDisposableListener(this.element, DOM.EventType.MOUSE_OVER, () => {
// this.foldingIcon.setVisible(true);
// }));
// this._register(DOM.addDisposableListener(this.element, DOM.EventType.MOUSE_OUT, () => {
// this.foldingIcon.setVisible(false);
// }));

}

private toggleFoldRange(currentState: CellFoldingState) {
Expand Down Expand Up @@ -145,6 +181,7 @@ export class NotebookStickyScroll extends Disposable {
private readonly _onDidChangeNotebookStickyScroll = this._register(new Emitter<number>());
readonly onDidChangeNotebookStickyScroll: Event<number> = this._onDidChangeNotebookStickyScroll.event;

private targetStickyElement: HTMLElement | null = null;

getDomNode(): HTMLElement {
return this.domNode;
Expand Down Expand Up @@ -209,6 +246,30 @@ export class NotebookStickyScroll extends Disposable {
menuId: MenuId.NotebookStickyScrollContext,
getAnchor: () => event,
});
this.targetStickyElement = event.target;
}

public executeStickySection() {
// get the cells that are in the section
if (!this.targetStickyElement) {
return;
}

const selectedElement = this.targetStickyElement.parentElement;
const selectedOutlineEntry = Array.from(this.currentStickyLines.values()).find(entry => entry.line.element.contains(selectedElement))?.line.entry;
if (!selectedOutlineEntry) {
return;
}

const flatList: OutlineEntry[] = [];
selectedOutlineEntry.asFlatList(flatList);

// execute cells with INotebookEditor executeNotebookCells
const cellViewModels = flatList.map(entry => entry.cell);
this.notebookEditor.executeNotebookCells(cellViewModels);

// clear stickyElement target
this.targetStickyElement = null;
}

private updateConfig(e: NotebookOptionsChangeEvent) {
Expand Down Expand Up @@ -384,6 +445,7 @@ export class NotebookStickyScroll extends Disposable {
stickyHeader.innerText = entry.label;

stickyElement.append(stickyFoldingIcon.domNode, stickyHeader);

return new NotebookStickyLine(stickyElement, stickyFoldingIcon, stickyHeader, entry, notebookEditor);
}

Expand Down Expand Up @@ -490,3 +552,4 @@ export function computeContent(notebookEditor: INotebookEditor, notebookCellList
}

registerAction2(ToggleNotebookStickyScroll);
registerAction2(RunInSectionStickyScroll);
Original file line number Diff line number Diff line change
Expand Up @@ -374,3 +374,9 @@ export function isCompositeNotebookEditorInput(thing: unknown): thing is ICompos
&& Array.isArray((<ICompositeNotebookEditorInput>thing).editorInputs)
&& ((<ICompositeNotebookEditorInput>thing).editorInputs.every(input => input instanceof NotebookEditorInput));
}

export function isNotebookEditorInput(thing: unknown): thing is NotebookEditorInput {
return !!thing
&& typeof thing === 'object'
&& thing instanceof NotebookEditorInput;
}