Merge pull request #115630 from microsoft/rebornix/multi-selection
multi selection for notebook cells
This commit is contained in:
commit
acb300b004
13 changed files with 72 additions and 219 deletions
|
@ -1303,7 +1303,7 @@ suite('notebook working copy', () => {
|
|||
|
||||
assert.notEqual(firstNotebookEditor, secondNotebookEditor);
|
||||
assert.equal(firstNotebookEditor?.document, secondNotebookEditor?.document, 'split notebook editors share the same document');
|
||||
assert.notEqual(firstNotebookEditor?.asWebviewUri(vscode.Uri.file('./hello.png')), secondNotebookEditor?.asWebviewUri(vscode.Uri.file('./hello.png')));
|
||||
// assert.notEqual(firstNotebookEditor?.asWebviewUri(vscode.Uri.file('./hello.png')), secondNotebookEditor?.asWebviewUri(vscode.Uri.file('./hello.png')));
|
||||
|
||||
await saveAllFilesAndCloseAll(resource);
|
||||
|
||||
|
|
|
@ -21,7 +21,6 @@ export function smokeTestActivate(context: vscode.ExtensionContext): any {
|
|||
}));
|
||||
|
||||
context.subscriptions.push(vscode.notebook.registerNotebookContentProvider('notebookSmokeTest', {
|
||||
onDidChangeNotebook: new vscode.EventEmitter<vscode.NotebookDocumentEditEvent>().event,
|
||||
openNotebook: async (_resource: vscode.Uri) => {
|
||||
const dto: vscode.NotebookData = {
|
||||
languages: ['typescript'],
|
||||
|
|
|
@ -9,10 +9,7 @@ import { smokeTestActivate } from './notebookSmokeTestMain';
|
|||
export function activate(context: vscode.ExtensionContext): any {
|
||||
smokeTestActivate(context);
|
||||
|
||||
const _onDidChangeNotebook = new vscode.EventEmitter<vscode.NotebookDocumentEditEvent | vscode.NotebookDocumentContentChangeEvent>();
|
||||
context.subscriptions.push(_onDidChangeNotebook);
|
||||
context.subscriptions.push(vscode.notebook.registerNotebookContentProvider('notebookCoreTest', {
|
||||
onDidChangeNotebook: _onDidChangeNotebook.event,
|
||||
openNotebook: async (_resource: vscode.Uri) => {
|
||||
if (/.*empty\-.*\.vsctestnb$/.test(_resource.path)) {
|
||||
return {
|
||||
|
@ -91,7 +88,7 @@ export function activate(context: vscode.ExtensionContext): any {
|
|||
return;
|
||||
}
|
||||
|
||||
const previousOutputs = cell.outputs;
|
||||
// const previousOutputs = cell.outputs;
|
||||
const newOutputs: vscode.CellOutput[] = [{
|
||||
outputKind: vscode.CellOutputKind.Rich,
|
||||
data: {
|
||||
|
@ -100,20 +97,6 @@ export function activate(context: vscode.ExtensionContext): any {
|
|||
}];
|
||||
|
||||
cell.outputs = newOutputs;
|
||||
|
||||
_onDidChangeNotebook.fire({
|
||||
document: document,
|
||||
undo: () => {
|
||||
if (cell) {
|
||||
cell.outputs = previousOutputs;
|
||||
}
|
||||
},
|
||||
redo: () => {
|
||||
if (cell) {
|
||||
cell.outputs = newOutputs;
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
},
|
||||
cancelCellExecution: async (_document: vscode.NotebookDocument, _cell: vscode.NotebookCell) => { }
|
||||
|
@ -151,7 +134,6 @@ export function activate(context: vscode.ExtensionContext): any {
|
|||
return;
|
||||
}
|
||||
|
||||
const previousOutputs = cell.outputs;
|
||||
const newOutputs: vscode.CellOutput[] = [{
|
||||
outputKind: vscode.CellOutputKind.Rich,
|
||||
data: {
|
||||
|
@ -160,20 +142,6 @@ export function activate(context: vscode.ExtensionContext): any {
|
|||
}];
|
||||
|
||||
cell.outputs = newOutputs;
|
||||
|
||||
_onDidChangeNotebook.fire({
|
||||
document: document,
|
||||
undo: () => {
|
||||
if (cell) {
|
||||
cell.outputs = previousOutputs;
|
||||
}
|
||||
},
|
||||
redo: () => {
|
||||
if (cell) {
|
||||
cell.outputs = newOutputs;
|
||||
}
|
||||
}
|
||||
});
|
||||
return;
|
||||
},
|
||||
cancelCellExecution: async (_document: vscode.NotebookDocument, _cell: vscode.NotebookCell) => { }
|
||||
|
|
71
src/vs/vscode.proposed.d.ts
vendored
71
src/vs/vscode.proposed.d.ts
vendored
|
@ -1237,30 +1237,6 @@ declare module 'vscode' {
|
|||
// @rebornix REMOVE/REplace NotebookCommunication
|
||||
// todo@API fishy? notebooks are public objects, there should be a "global" events for this
|
||||
readonly onDidDispose: Event<void>;
|
||||
|
||||
/**
|
||||
* Fired when the output hosting webview posts a message.
|
||||
*/
|
||||
// @rebornix REMOVE
|
||||
// todo@API notebook editors are public -> ANY extension can listen to these event
|
||||
readonly onDidReceiveMessage: Event<any>;
|
||||
/**
|
||||
* Post a message to the output hosting webview.
|
||||
*
|
||||
* Messages are only delivered if the editor is live.
|
||||
*
|
||||
* @param message Body of the message. This must be a string or other json serializable object.
|
||||
*/
|
||||
// @rebornix REMOVE
|
||||
// todo@API notebook editors are public -> ANY extension can send messages
|
||||
postMessage(message: any): Thenable<boolean>;
|
||||
|
||||
/**
|
||||
* Convert a uri for the local file system to one that can be used inside outputs webview.
|
||||
*/
|
||||
// @rebornix REMOVE
|
||||
// todo@API unsure about that, how do you this when executing a cell without having an editor
|
||||
asWebviewUri(localResource: Uri): Uri;
|
||||
}
|
||||
|
||||
// todo@API stale?
|
||||
|
@ -1357,48 +1333,6 @@ declare module 'vscode' {
|
|||
readonly metadata: NotebookDocumentMetadata;
|
||||
}
|
||||
|
||||
interface NotebookDocumentContentChangeEvent {
|
||||
|
||||
/**
|
||||
* The document that the edit is for.
|
||||
*/
|
||||
readonly document: NotebookDocument;
|
||||
}
|
||||
|
||||
// @rebornix p2, remove
|
||||
// todo@API is this still needed? With transient metadata have we everything covered?
|
||||
interface NotebookDocumentEditEvent {
|
||||
|
||||
/**
|
||||
* The document that the edit is for.
|
||||
*/
|
||||
readonly document: NotebookDocument;
|
||||
|
||||
/**
|
||||
* Undo the edit operation.
|
||||
*
|
||||
* This is invoked by VS Code when the user undoes this edit. To implement `undo`, your
|
||||
* extension should restore the document and editor to the state they were in just before this
|
||||
* edit was added to VS Code's internal edit stack by `onDidChangeCustomDocument`.
|
||||
*/
|
||||
undo(): Thenable<void> | void;
|
||||
|
||||
/**
|
||||
* Redo the edit operation.
|
||||
*
|
||||
* This is invoked by VS Code when the user redoes this edit. To implement `redo`, your
|
||||
* extension should restore the document and editor to the state they were in just after this
|
||||
* edit was added to VS Code's internal edit stack by `onDidChangeCustomDocument`.
|
||||
*/
|
||||
redo(): Thenable<void> | void;
|
||||
|
||||
/**
|
||||
* Display name describing the edit.
|
||||
*
|
||||
* This will be shown to users in the UI for undo/redo operations.
|
||||
*/
|
||||
readonly label?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
* Communication object passed to the {@link NotebookContentProvider} and
|
||||
|
@ -1625,11 +1559,6 @@ declare module 'vscode' {
|
|||
export interface NotebookContentProvider {
|
||||
readonly options?: NotebookDocumentContentOptions;
|
||||
readonly onDidChangeNotebookContentOptions?: Event<NotebookDocumentContentOptions>;
|
||||
|
||||
// @rebornix
|
||||
// todo@API should be removed
|
||||
readonly onDidChangeNotebook: Event<NotebookDocumentContentChangeEvent | NotebookDocumentEditEvent>;
|
||||
|
||||
/**
|
||||
* Content providers should always use [file system providers](#FileSystemProvider) to
|
||||
* resolve the raw content for `uri` as the resouce is not necessarily a file on disk.
|
||||
|
|
|
@ -10,7 +10,6 @@ import { Emitter } from 'vs/base/common/event';
|
|||
import { IRelativePattern } from 'vs/base/common/glob';
|
||||
import { combinedDisposable, Disposable, DisposableStore, dispose, IDisposable, IReference } from 'vs/base/common/lifecycle';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IExtUri } from 'vs/base/common/resources';
|
||||
import { URI, UriComponents } from 'vs/base/common/uri';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
|
@ -31,7 +30,6 @@ import { IEditorGroup, IEditorGroupsService, preferredSideBySideGroupDirection }
|
|||
import { openEditorWith } from 'vs/workbench/services/editor/common/editorOpenWith';
|
||||
import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService';
|
||||
import { IUriIdentityService } from 'vs/workbench/services/uriIdentity/common/uriIdentity';
|
||||
import { IWorkingCopyService } from 'vs/workbench/services/workingCopy/common/workingCopyService';
|
||||
import { ExtHostContext, ExtHostNotebookShape, IExtHostContext, INotebookCellStatusBarEntryDto, INotebookDocumentsAndEditorsDelta, INotebookDocumentShowOptions, INotebookModelAddedData, MainContext, MainThreadNotebookShape, NotebookEditorRevealType, NotebookExtensionDescription } from '../common/extHost.protocol';
|
||||
|
||||
class DocumentAndEditorState {
|
||||
|
@ -131,7 +129,6 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
|||
@IAccessibilityService private readonly accessibilityService: IAccessibilityService,
|
||||
@ILogService private readonly logService: ILogService,
|
||||
@INotebookCellStatusBarService private readonly cellStatusBarService: INotebookCellStatusBarService,
|
||||
@IWorkingCopyService private readonly _workingCopyService: IWorkingCopyService,
|
||||
@INotebookEditorModelResolverService private readonly _notebookModelResolverService: INotebookEditorModelResolverService,
|
||||
@IUriIdentityService private readonly _uriIdentityService: IUriIdentityService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
|
@ -605,20 +602,6 @@ export class MainThreadNotebooks extends Disposable implements MainThreadNoteboo
|
|||
return false;
|
||||
}
|
||||
|
||||
$onUndoableContentChange(resource: UriComponents, viewType: string, editId: number, label: string | undefined): void {
|
||||
const textModel = this._notebookService.getNotebookTextModel(URI.from(resource));
|
||||
|
||||
if (textModel) {
|
||||
textModel.handleUnknownUndoableEdit(label, () => {
|
||||
const isDirty = this._workingCopyService.isDirty(textModel.uri.with({ scheme: Schemas.vscodeNotebook }));
|
||||
return this._proxy.$undoNotebook(textModel.viewType, textModel.uri, editId, isDirty);
|
||||
}, () => {
|
||||
const isDirty = this._workingCopyService.isDirty(textModel.uri.with({ scheme: Schemas.vscodeNotebook }));
|
||||
return this._proxy.$redoNotebook(textModel.viewType, textModel.uri, editId, isDirty);
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
$onContentChange(resource: UriComponents, viewType: string): void {
|
||||
const textModel = this._notebookService.getNotebookTextModel(URI.from(resource));
|
||||
|
||||
|
|
|
@ -809,7 +809,6 @@ export interface MainThreadNotebookShape extends IDisposable {
|
|||
$registerNotebookEditorDecorationType(key: string, options: INotebookDecorationRenderOptions): void;
|
||||
$removeNotebookEditorDecorationType(key: string): void;
|
||||
$trySetDecorations(id: string, range: ICellRange, decorationKey: string): void;
|
||||
$onUndoableContentChange(resource: UriComponents, viewType: string, editId: number, label: string | undefined): void;
|
||||
$onContentChange(resource: UriComponents, viewType: string): void;
|
||||
}
|
||||
|
||||
|
@ -1805,9 +1804,6 @@ export interface ExtHostNotebookShape {
|
|||
$acceptEditorPropertiesChanged(id: string, data: INotebookEditorPropertiesChangeData): void;
|
||||
$acceptDocumentPropertiesChanged(uriComponents: UriComponents, data: INotebookDocumentPropertiesChangeData): void;
|
||||
$acceptDocumentAndEditorsDelta(delta: INotebookDocumentsAndEditorsDelta): void;
|
||||
$undoNotebook(viewType: string, uri: UriComponents, editId: number, isDirty: boolean): Promise<void>;
|
||||
$redoNotebook(viewType: string, uri: UriComponents, editId: number, isDirty: boolean): Promise<void>;
|
||||
|
||||
}
|
||||
|
||||
export interface ExtHostStorageShape {
|
||||
|
|
|
@ -321,23 +321,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
|||
this._notebookContentProviders.set(viewType, { extension, provider });
|
||||
const listeners: vscode.Disposable[] = [];
|
||||
|
||||
listeners.push(provider.onDidChangeNotebook
|
||||
? provider.onDidChangeNotebook(e => {
|
||||
const document = this._documents.get(URI.revive(e.document.uri));
|
||||
|
||||
if (!document) {
|
||||
throw new Error(`Notebook document ${e.document.uri.toString()} not found`);
|
||||
}
|
||||
|
||||
if (isEditEvent(e)) {
|
||||
const editId = document.addEdit(e);
|
||||
this._proxy.$onUndoableContentChange(e.document.uri, viewType, editId, e.label);
|
||||
} else {
|
||||
this._proxy.$onContentChange(e.document.uri, viewType);
|
||||
}
|
||||
})
|
||||
: Disposable.None);
|
||||
|
||||
listeners.push(provider.onDidChangeNotebookContentOptions
|
||||
? provider.onDidChangeNotebookContentOptions(() => {
|
||||
this._proxy.$updateNotebookProviderOptions(viewType, provider.options);
|
||||
|
@ -544,26 +527,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
|||
return false;
|
||||
}
|
||||
|
||||
async $undoNotebook(viewType: string, uri: UriComponents, editId: number, isDirty: boolean): Promise<void> {
|
||||
const document = this._documents.get(URI.revive(uri));
|
||||
if (!document) {
|
||||
return;
|
||||
}
|
||||
|
||||
document.undo(editId, isDirty);
|
||||
|
||||
}
|
||||
|
||||
async $redoNotebook(viewType: string, uri: UriComponents, editId: number, isDirty: boolean): Promise<void> {
|
||||
const document = this._documents.get(URI.revive(uri));
|
||||
if (!document) {
|
||||
return;
|
||||
}
|
||||
|
||||
document.redo(editId, isDirty);
|
||||
}
|
||||
|
||||
|
||||
async $backup(viewType: string, uri: UriComponents, cancellation: CancellationToken): Promise<string | undefined> {
|
||||
const document = this._documents.get(URI.revive(uri));
|
||||
const provider = this._notebookContentProviders.get(viewType);
|
||||
|
@ -892,11 +855,6 @@ export class ExtHostNotebookController implements ExtHostNotebookShape, ExtHostN
|
|||
}
|
||||
}
|
||||
|
||||
function isEditEvent(e: vscode.NotebookDocumentEditEvent | vscode.NotebookDocumentContentChangeEvent): e is vscode.NotebookDocumentEditEvent {
|
||||
return typeof (e as vscode.NotebookDocumentEditEvent).undo === 'function'
|
||||
&& typeof (e as vscode.NotebookDocumentEditEvent).redo === 'function';
|
||||
}
|
||||
|
||||
export class NotebookCellStatusBarItemInternal extends Disposable {
|
||||
private static NEXT_ID = 0;
|
||||
|
||||
|
|
|
@ -15,7 +15,6 @@ import { CellKind, INotebookDocumentPropertiesChangeData, IWorkspaceCellEditDto,
|
|||
import { ExtHostDocumentsAndEditors, IExtHostModelAddedData } from 'vs/workbench/api/common/extHostDocumentsAndEditors';
|
||||
import { CellEditType, CellOutputKind, diff, IMainCellDto, IProcessedOutput, NotebookCellMetadata, NotebookCellsChangedEventDto, NotebookCellsChangeType, NotebookCellsSplice2, notebookDocumentMetadataDefaults } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import * as vscode from 'vscode';
|
||||
import { Cache } from './cache';
|
||||
|
||||
|
||||
interface IObservable<T> {
|
||||
|
@ -231,8 +230,6 @@ export class ExtHostNotebookDocument extends Disposable {
|
|||
private _disposed = false;
|
||||
private _languages: string[] = [];
|
||||
|
||||
private readonly _edits = new Cache<vscode.NotebookDocumentEditEvent>('notebook documents');
|
||||
|
||||
constructor(
|
||||
private readonly _proxy: MainThreadNotebookShape,
|
||||
private readonly _documentsAndEditors: ExtHostDocumentsAndEditors,
|
||||
|
@ -496,37 +493,4 @@ export class ExtHostNotebookDocument extends Disposable {
|
|||
getCellIndex(cell: ExtHostCell): number {
|
||||
return this._cells.indexOf(cell);
|
||||
}
|
||||
|
||||
addEdit(item: vscode.NotebookDocumentEditEvent): number {
|
||||
return this._edits.add([item]);
|
||||
}
|
||||
|
||||
async undo(editId: number, isDirty: boolean): Promise<void> {
|
||||
await this.getEdit(editId).undo();
|
||||
// if (!isDirty) {
|
||||
// this.disposeBackup();
|
||||
// }
|
||||
}
|
||||
|
||||
async redo(editId: number, isDirty: boolean): Promise<void> {
|
||||
await this.getEdit(editId).redo();
|
||||
// if (!isDirty) {
|
||||
// this.disposeBackup();
|
||||
// }
|
||||
}
|
||||
|
||||
private getEdit(editId: number): vscode.NotebookDocumentEditEvent {
|
||||
const edit = this._edits.get(editId, 0);
|
||||
if (!edit) {
|
||||
throw new Error('No edit found');
|
||||
}
|
||||
|
||||
return edit;
|
||||
}
|
||||
|
||||
disposeEdits(editIds: number[]): void {
|
||||
for (const id of editIds) {
|
||||
this._edits.delete(id);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -351,6 +351,7 @@ export interface INotebookEditor extends IEditor, ICommonNotebookEditor {
|
|||
getOverflowContainerDomNode(): HTMLElement;
|
||||
getInnerWebview(): Webview | undefined;
|
||||
getSelectionHandles(): number[];
|
||||
getSelectionViewModels(): ICellViewModel[];
|
||||
|
||||
/**
|
||||
* Focus the notebook editor cell list
|
||||
|
|
|
@ -300,6 +300,14 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
return this.viewModel?.selectionHandles || [];
|
||||
}
|
||||
|
||||
getSelectionViewModels(): ICellViewModel[] {
|
||||
if (!this.viewModel) {
|
||||
return [];
|
||||
}
|
||||
|
||||
return this.viewModel.selectionHandles.map(handle => this.viewModel!.getCellByHandle(handle)) as ICellViewModel[];
|
||||
}
|
||||
|
||||
hasModel(): this is IActiveNotebookEditor {
|
||||
return !!this._notebookViewModel;
|
||||
}
|
||||
|
@ -475,7 +483,7 @@ export class NotebookEditorWidget extends Disposable implements INotebookEditor
|
|||
horizontalScrolling: false,
|
||||
keyboardSupport: false,
|
||||
mouseSupport: true,
|
||||
multipleSelectionSupport: false,
|
||||
multipleSelectionSupport: true,
|
||||
enableKeyboardNavigation: true,
|
||||
additionalScrollHeight: 0,
|
||||
transformOptimization: false, //(isMacintosh && isNative) || getTitleBarStyle(this.configurationService, this.environmentService) === 'native',
|
||||
|
@ -2130,6 +2138,13 @@ export const focusedCellBackground = registerColor('notebook.focusedCellBackgrou
|
|||
hc: null
|
||||
}, nls.localize('focusedCellBackground', "The background color of a cell when the cell is focused."));
|
||||
|
||||
export const selectedCellBackground = registerColor('notebook.selectedCellBackground', {
|
||||
dark: null,
|
||||
light: null,
|
||||
hc: null
|
||||
}, nls.localize('selectedCellBackground', "The background color of a cell when the cell is selected."));
|
||||
|
||||
|
||||
export const cellHoverBackground = registerColor('notebook.cellHoverBackground', {
|
||||
dark: transparent(focusedCellBackground, .5),
|
||||
light: transparent(focusedCellBackground, .7),
|
||||
|
@ -2266,6 +2281,14 @@ registerThemingParticipant((theme, collector) => {
|
|||
collector.addRule(`.notebookOverlay .code-cell-row.focused .cell-collapsed-part { background-color: ${focusedCellBackgroundColor} !important; }`);
|
||||
}
|
||||
|
||||
const selectedCellBackgroundColor = theme.getColor(selectedCellBackground);
|
||||
if (selectedCellBackground) {
|
||||
collector.addRule(`.notebookOverlay .monaco-list.selection-multiple .markdown-cell-row.selected { background-color: ${selectedCellBackgroundColor} !important; }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list.selection-multiple .code-cell-row.selected { background-color: ${selectedCellBackgroundColor} !important; }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list.selection-multiple .markdown-cell-row.selected .cell-focus-indicator-bottom { background-color: ${selectedCellBackgroundColor} !important; }`);
|
||||
collector.addRule(`.notebookOverlay .monaco-list.selection-multiple .code-cell-row.selected .cell-focus-indicator-bottom { background-color: ${selectedCellBackgroundColor} !important; }`);
|
||||
}
|
||||
|
||||
const cellHoverBackgroundColor = theme.getColor(cellHoverBackground);
|
||||
if (cellHoverBackgroundColor) {
|
||||
collector.addRule(`.notebookOverlay .code-cell-row:not(.focused):hover .cell-focus-indicator,
|
||||
|
|
|
@ -27,12 +27,12 @@ import { IStorageService, StorageScope, StorageTarget } from 'vs/platform/storag
|
|||
import { NotebookExtensionDescription } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { Memento } from 'vs/workbench/common/memento';
|
||||
import { INotebookEditorContribution, notebookProviderExtensionPoint, notebookRendererExtensionPoint } from 'vs/workbench/contrib/notebook/browser/extensionPoint';
|
||||
import { CellEditState, getActiveNotebookEditor, INotebookEditor, NotebookEditorOptions, updateEditorTopPadding } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { CellEditState, getActiveNotebookEditor, ICellViewModel, INotebookEditor, NotebookEditorOptions, updateEditorTopPadding } from 'vs/workbench/contrib/notebook/browser/notebookBrowser';
|
||||
import { NotebookKernelProviderAssociationRegistry, NotebookViewTypesExtensionRegistry, updateNotebookKernelProvideAssociationSchema } from 'vs/workbench/contrib/notebook/browser/notebookKernelAssociation';
|
||||
import { CellViewModel } from 'vs/workbench/contrib/notebook/browser/viewModel/notebookViewModel';
|
||||
import { NotebookCellTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookCellTextModel';
|
||||
import { NotebookTextModel } from 'vs/workbench/contrib/notebook/common/model/notebookTextModel';
|
||||
import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, BUILTIN_RENDERER_ID, CellKind, CellOutputKind, DisplayOrderKey, IDisplayOutput, INotebookDecorationRenderOptions, INotebookKernelInfo2, INotebookKernelProvider, INotebookRendererInfo, INotebookTextModel, IOrderedMimeType, ITransformedDisplayOutputDto, mimeTypeIsAlwaysSecure, mimeTypeSupportedByCore, notebookDocumentFilterMatch, NotebookEditorPriority, NOTEBOOK_DISPLAY_ORDER, RENDERER_NOT_AVAILABLE, sortMimeTypes } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { ACCESSIBLE_NOTEBOOK_DISPLAY_ORDER, BUILTIN_RENDERER_ID, CellEditType, CellKind, CellOutputKind, DisplayOrderKey, ICellEditOperation, IDisplayOutput, INotebookDecorationRenderOptions, INotebookKernelInfo2, INotebookKernelProvider, INotebookRendererInfo, INotebookTextModel, IOrderedMimeType, ITransformedDisplayOutputDto, mimeTypeIsAlwaysSecure, mimeTypeSupportedByCore, notebookDocumentFilterMatch, NotebookEditorPriority, NOTEBOOK_DISPLAY_ORDER, RENDERER_NOT_AVAILABLE, sortMimeTypes } from 'vs/workbench/contrib/notebook/common/notebookCommon';
|
||||
import { NotebookOutputRendererInfo } from 'vs/workbench/contrib/notebook/common/notebookOutputRenderer';
|
||||
import { NotebookEditorDescriptor, NotebookProviderInfo } from 'vs/workbench/contrib/notebook/common/notebookProvider';
|
||||
import { IMainNotebookController, INotebookService } from 'vs/workbench/contrib/notebook/common/notebookService';
|
||||
|
@ -437,8 +437,8 @@ export class NotebookService extends Disposable implements INotebookService, ICu
|
|||
return false;
|
||||
}
|
||||
|
||||
const { editor, activeCell } = getContext();
|
||||
if (!editor || !activeCell) {
|
||||
const { editor } = getContext();
|
||||
if (!editor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -449,8 +449,14 @@ export class NotebookService extends Disposable implements INotebookService, ICu
|
|||
|
||||
const clipboardService = accessor.get<IClipboardService>(IClipboardService);
|
||||
const notebookService = accessor.get<INotebookService>(INotebookService);
|
||||
clipboardService.writeText(activeCell.getText());
|
||||
notebookService.setToCopy([activeCell.model], true);
|
||||
const selectedCells = editor.getSelectionViewModels();
|
||||
|
||||
if (!selectedCells.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
clipboardService.writeText(selectedCells.map(cell => cell.getText()).join('\n'));
|
||||
notebookService.setToCopy(selectedCells.map(cell => cell.model), true);
|
||||
|
||||
return true;
|
||||
}));
|
||||
|
@ -573,8 +579,8 @@ export class NotebookService extends Disposable implements INotebookService, ICu
|
|||
return false;
|
||||
}
|
||||
|
||||
const { editor, activeCell } = getContext();
|
||||
if (!editor || !activeCell) {
|
||||
const { editor } = getContext();
|
||||
if (!editor) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -590,9 +596,20 @@ export class NotebookService extends Disposable implements INotebookService, ICu
|
|||
|
||||
const clipboardService = accessor.get<IClipboardService>(IClipboardService);
|
||||
const notebookService = accessor.get<INotebookService>(INotebookService);
|
||||
clipboardService.writeText(activeCell.getText());
|
||||
viewModel.deleteCell(viewModel.getCellIndex(activeCell), true);
|
||||
notebookService.setToCopy([activeCell.model], false);
|
||||
const selectedCells = editor.getSelectionViewModels();
|
||||
|
||||
if (!selectedCells.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
clipboardService.writeText(selectedCells.map(cell => cell.getText()).join('\n'));
|
||||
|
||||
const edits: ICellEditOperation[] = selectedCells.map(cell => [cell, viewModel.getCellIndex(cell)] as [ICellViewModel, number]).sort((a, b) => b[1] - a[1]).map(value => {
|
||||
return { editType: CellEditType.Replace, index: value[1], count: 1, cells: [] };
|
||||
});
|
||||
|
||||
viewModel.notebookDocument.applyEdits(viewModel.notebookDocument.versionId, edits, true, editor.getSelectionHandles(), () => { return undefined; }, undefined, true);
|
||||
notebookService.setToCopy(selectedCells.map(cell => cell.model), false);
|
||||
|
||||
return true;
|
||||
});
|
||||
|
|
|
@ -368,7 +368,7 @@ export class NotebookCellList extends WorkbenchList<CellViewModel> implements ID
|
|||
const viewSelections = model.selectionHandles.map(handle => {
|
||||
return model.getCellByHandle(handle);
|
||||
}).filter(cell => !!cell).map(cell => this._getViewIndexUpperBound(cell!));
|
||||
this.setFocus(viewSelections, undefined, true);
|
||||
this.setSelection(viewSelections, undefined, true);
|
||||
}));
|
||||
|
||||
const hiddenRanges = model.getHiddenRanges();
|
||||
|
@ -592,6 +592,18 @@ export class NotebookCellList extends WorkbenchList<CellViewModel> implements ID
|
|||
}
|
||||
|
||||
setFocus(indexes: number[], browserEvent?: UIEvent, ignoreTextModelUpdate?: boolean): void {
|
||||
// if (!indexes.length) {
|
||||
// return;
|
||||
// }
|
||||
|
||||
// if (this._viewModel && !ignoreTextModelUpdate) {
|
||||
// this._viewModel.selectionHandles = indexes.map(index => this.element(index)).map(cell => cell.handle);
|
||||
// }
|
||||
|
||||
super.setFocus(indexes, browserEvent);
|
||||
}
|
||||
|
||||
setSelection(indexes: number[], browserEvent?: UIEvent | undefined, ignoreTextModelUpdate?: boolean) {
|
||||
if (!indexes.length) {
|
||||
return;
|
||||
}
|
||||
|
@ -600,7 +612,7 @@ export class NotebookCellList extends WorkbenchList<CellViewModel> implements ID
|
|||
this._viewModel.selectionHandles = indexes.map(index => this.element(index)).map(cell => cell.handle);
|
||||
}
|
||||
|
||||
super.setFocus(indexes, browserEvent);
|
||||
super.setSelection(indexes, browserEvent);
|
||||
}
|
||||
|
||||
revealElementsInView(range: ICellRange) {
|
||||
|
|
|
@ -66,6 +66,9 @@ export class TestNotebookEditor implements INotebookEditor {
|
|||
|
||||
constructor(
|
||||
) { }
|
||||
getSelectionViewModels(): ICellViewModel[] {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
revealCellRangeInView(range: ICellRange): void {
|
||||
throw new Error('Method not implemented.');
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue