Add back Notebook Completion List IntelliSense (#3520)

* Static notebook intellisense working

* Intellisense dynamic cells working

* Remove launch.json erroneous change

* PR comments #1

* PR feedback to change a minor condition
This commit is contained in:
Chris LaFreniere
2018-12-07 18:04:32 -08:00
committed by GitHub
parent e3bce7172c
commit 5adcabc8de
13 changed files with 189 additions and 56 deletions

View File

@@ -24,11 +24,6 @@ export class ExtHostNotebook implements ExtHostNotebookShape {
private readonly _proxy: MainThreadNotebookShape;
private _adapters = new Map<number, Adapter>();
private _onDidOpenNotebook = new Emitter<sqlops.nb.NotebookDocument>();
private _onDidChangeNotebookCell = new Emitter<sqlops.nb.NotebookCellChangeEvent>();
public readonly onDidOpenNotebookDocument: Event<sqlops.nb.NotebookDocument> = this._onDidOpenNotebook.event;
public readonly onDidChangeNotebookCell: Event<sqlops.nb.NotebookCellChangeEvent> = this._onDidChangeNotebookCell.event;
// Notebook URI to manager lookup.
constructor(_mainContext: IMainContext) {

View File

@@ -12,22 +12,20 @@ import { ok } from 'vs/base/common/assert';
import { Schemas } from 'vs/base/common/network';
import { TPromise } from 'vs/base/common/winjs.base';
import { MainThreadNotebookDocumentsAndEditorsShape } from 'sql/workbench/api/node/sqlExtHost.protocol';
import { MainThreadNotebookDocumentsAndEditorsShape, INotebookModelChangedData } from 'sql/workbench/api/node/sqlExtHost.protocol';
import { CellRange } from 'sql/workbench/api/common/sqlExtHostTypes';
export class ExtHostNotebookDocumentData implements IDisposable {
private _document: sqlops.nb.NotebookDocument;
private _cells: sqlops.nb.NotebookCell[];
private _isDisposed: boolean = false;
constructor(private readonly _proxy: MainThreadNotebookDocumentsAndEditorsShape,
private readonly _uri: URI,
private readonly _providerId: string,
private _isDirty: boolean
private _providerId: string,
private _isDirty: boolean,
private _cells: sqlops.nb.NotebookCell[]
) {
// TODO add cell mapping support
this._cells = [];
}
dispose(): void {
@@ -66,6 +64,14 @@ export class ExtHostNotebookDocumentData implements IDisposable {
}
public onModelChanged(data: INotebookModelChangedData) {
if (data) {
this._isDirty = data.isDirty;
this._cells = data.cells;
this._providerId = data.providerId;
}
}
// ---- range math
private _validateRange(range: sqlops.nb.CellRange): sqlops.nb.CellRange {

View File

@@ -9,7 +9,7 @@ import * as vscode from 'vscode';
import { Event, Emitter } from 'vs/base/common/event';
import { dispose } from 'vs/base/common/lifecycle';
import URI from 'vs/base/common/uri';
import URI, { UriComponents } from 'vs/base/common/uri';
import { Disposable } from 'vs/workbench/api/node/extHostTypes';
import * as typeConverters from 'vs/workbench/api/node/extHostTypeConverters';
import { IMainContext } from 'vs/workbench/api/node/extHost.protocol';
@@ -17,7 +17,7 @@ import { ok } from 'vs/base/common/assert';
import {
SqlMainContext, INotebookDocumentsAndEditorsDelta, ExtHostNotebookDocumentsAndEditorsShape,
MainThreadNotebookDocumentsAndEditorsShape, INotebookShowOptions
MainThreadNotebookDocumentsAndEditorsShape, INotebookShowOptions, INotebookModelChangedData
} from 'sql/workbench/api/node/sqlExtHost.protocol';
import { ExtHostNotebookDocumentData } from 'sql/workbench/api/node/extHostNotebookDocumentData';
import { ExtHostNotebookEditor } from 'sql/workbench/api/node/extHostNotebookEditor';
@@ -33,15 +33,16 @@ export class ExtHostNotebookDocumentsAndEditors implements ExtHostNotebookDocume
private readonly _editors = new Map<string, ExtHostNotebookEditor>();
private readonly _documents = new Map<string, ExtHostNotebookDocumentData>();
private readonly _onDidAddDocuments = new Emitter<ExtHostNotebookDocumentData[]>();
private readonly _onDidRemoveDocuments = new Emitter<ExtHostNotebookDocumentData[]>();
private readonly _onDidChangeVisibleNotebookEditors = new Emitter<ExtHostNotebookEditor[]>();
private readonly _onDidChangeActiveNotebookEditor = new Emitter<ExtHostNotebookEditor>();
private _onDidOpenNotebook = new Emitter<sqlops.nb.NotebookDocument>();
private _onDidChangeNotebookCell = new Emitter<sqlops.nb.NotebookCellChangeEvent>();
readonly onDidAddDocuments: Event<ExtHostNotebookDocumentData[]> = this._onDidAddDocuments.event;
readonly onDidRemoveDocuments: Event<ExtHostNotebookDocumentData[]> = this._onDidRemoveDocuments.event;
readonly onDidChangeVisibleNotebookEditors: Event<ExtHostNotebookEditor[]> = this._onDidChangeVisibleNotebookEditors.event;
readonly onDidChangeActiveNotebookEditor: Event<ExtHostNotebookEditor> = this._onDidChangeActiveNotebookEditor.event;
readonly onDidOpenNotebookDocument: Event<sqlops.nb.NotebookDocument> = this._onDidOpenNotebook.event;
readonly onDidChangeNotebookCell: Event<sqlops.nb.NotebookCellChangeEvent> = this._onDidChangeNotebookCell.event;
constructor(
private readonly _mainContext: IMainContext,
@@ -81,7 +82,8 @@ export class ExtHostNotebookDocumentsAndEditors implements ExtHostNotebookDocume
this._proxy,
resource,
data.providerId,
data.isDirty
data.isDirty,
data.cells
);
this._documents.set(resource.toString(), documentData);
addedDocuments.push(documentData);
@@ -122,11 +124,11 @@ export class ExtHostNotebookDocumentsAndEditors implements ExtHostNotebookDocume
dispose(removedEditors);
// now that the internal state is complete, fire events
if (delta.removedDocuments) {
this._onDidRemoveDocuments.fire(removedDocuments);
if (removedDocuments) {
// TODO add doc close event
}
if (delta.addedDocuments) {
this._onDidAddDocuments.fire(addedDocuments);
if (addedDocuments) {
addedDocuments.forEach(d => this._onDidOpenNotebook.fire(d.document));
}
if (delta.removedEditors || delta.addedEditors) {
@@ -136,6 +138,21 @@ export class ExtHostNotebookDocumentsAndEditors implements ExtHostNotebookDocume
this._onDidChangeActiveNotebookEditor.fire(this.getActiveEditor());
}
}
$acceptModelChanged(uriComponents: UriComponents, e: INotebookModelChangedData): void {
const uri = URI.revive(uriComponents);
const strURL = uri.toString();
let data = this._documents.get(strURL);
if (data) {
data.onModelChanged(e);
this._onDidChangeNotebookCell.fire({
cells: data.document.cells,
notebook: data.document,
kind: undefined
});
}
}
//#endregion
//#region Extension accessible methods

View File

@@ -5,9 +5,11 @@
'use strict';
import * as sqlops from 'sqlops';
import * as util from 'util';
import { extHostNamedCustomer } from 'vs/workbench/api/electron-browser/extHostCustomers';
import { Disposable } from 'vs/base/common/lifecycle';
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
import URI, { UriComponents } from 'vs/base/common/uri';
import { Event, Emitter } from 'vs/base/common/event';
import { IExtHostContext, IUndoStopOptions } from 'vs/workbench/api/node/extHost.protocol';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IEditorGroupsService } from 'vs/workbench/services/group/common/editorGroupsService';
@@ -18,7 +20,7 @@ import { Schemas } from 'vs/base/common/network';
import {
SqlMainContext, MainThreadNotebookDocumentsAndEditorsShape, SqlExtHostContext, ExtHostNotebookDocumentsAndEditorsShape,
INotebookDocumentsAndEditorsDelta, INotebookEditorAddData, INotebookShowOptions, INotebookModelAddedData
INotebookDocumentsAndEditorsDelta, INotebookEditorAddData, INotebookShowOptions, INotebookModelAddedData, INotebookModelChangedData
} from 'sql/workbench/api/node/sqlExtHost.protocol';
import { NotebookInputModel, NotebookInput } from 'sql/parts/notebook/notebookInput';
import { INotebookService, INotebookEditor } from 'sql/services/notebook/notebookService';
@@ -26,11 +28,17 @@ import { TPromise } from 'vs/base/common/winjs.base';
import { getProviderForFileName } from 'sql/parts/notebook/notebookUtils';
import { ISingleNotebookEditOperation } from 'sql/workbench/api/common/sqlExtHostTypes';
import { disposed } from 'vs/base/common/errors';
import { ICellModel, NotebookContentChange } from 'sql/parts/notebook/models/modelInterfaces';
class MainThreadNotebookEditor extends Disposable {
private _contentChangedEmitter = new Emitter<NotebookContentChange>();
public readonly contentChanged: Event<NotebookContentChange> = this._contentChangedEmitter.event;
constructor(public readonly editor: INotebookEditor) {
super();
editor.modelReady.then(model => {
this._register(model.contentChanged((e) => this._contentChangedEmitter.fire(e)));
});
}
public get uri(): URI {
@@ -49,6 +57,10 @@ class MainThreadNotebookEditor extends Disposable {
return this.editor.notebookParams.providerId;
}
public get cells(): ICellModel[] {
return this.editor.cells;
}
public save(): Thenable<boolean> {
return this.editor.save();
}
@@ -253,7 +265,7 @@ export class MainThreadNotebookDocumentsAndEditors extends Disposable implements
private _proxy: ExtHostNotebookDocumentsAndEditorsShape;
private _notebookEditors = new Map<string, MainThreadNotebookEditor>();
private _modelToDisposeMap = new Map<string, IDisposable>();
constructor(
extHostContext: IExtHostContext,
@IInstantiationService private _instantiationService: IInstantiationService,
@@ -398,8 +410,34 @@ export class MainThreadNotebookDocumentsAndEditors extends Disposable implements
if (!empty) {
this._proxy.$acceptDocumentsAndEditorsDelta(extHostDelta);
this.processRemovedDocs(removedDocuments);
this.processAddedDocs(addedEditors);
}
}
processRemovedDocs(removedDocuments: URI[]): void {
if (!removedDocuments) {
return;
}
removedDocuments.forEach(removedDoc => {
let listener = this._modelToDisposeMap.get(removedDoc.toString());
if (listener) {
listener.dispose();
this._modelToDisposeMap.delete(removedDoc.toString());
}
});
}
processAddedDocs(addedEditors: MainThreadNotebookEditor[]): any {
if (!addedEditors) {
return;
}
addedEditors.forEach(editor => {
let modelUrl = editor.uri;
this._modelToDisposeMap.set(editor.uri.toString(), editor.contentChanged((e) => {
this._proxy.$acceptModelChanged(modelUrl, this._toNotebookChangeData(e, editor));
}));
});
}
private _toNotebookEditorAddData(editor: MainThreadNotebookEditor): INotebookEditorAddData {
let addData: INotebookEditorAddData = {
@@ -414,8 +452,54 @@ export class MainThreadNotebookDocumentsAndEditors extends Disposable implements
let addData: INotebookModelAddedData = {
uri: editor.uri,
isDirty: editor.isDirty,
providerId: editor.providerId
providerId: editor.providerId,
cells: this.convertCellModelToNotebookCell(editor.cells)
};
return addData;
}
private _toNotebookChangeData(e: NotebookContentChange, editor: MainThreadNotebookEditor): INotebookModelChangedData {
let changeData: INotebookModelChangedData = {
// Note: we just send all cells for now, not a diff
cells: this.convertCellModelToNotebookCell(editor.cells),
isDirty: e.isDirty,
providerId: editor.providerId,
uri: editor.uri
};
return changeData;
}
private convertCellModelToNotebookCell(cells: ICellModel | ICellModel[]): sqlops.nb.NotebookCell[] {
let notebookCells: sqlops.nb.NotebookCell[] = [];
if (Array.isArray(cells)) {
for (let cell of cells) {
notebookCells.push({
uri: cell.cellUri,
contents: {
cell_type: cell.cellType,
execution_count: undefined,
metadata: {
language: cell.language
},
source: undefined
}
});
}
}
else {
notebookCells.push({
uri: cells.cellUri,
contents: {
cell_type: cells.cellType,
execution_count: undefined,
metadata: {
language: cells.language
},
source: undefined
}
});
}
return notebookCells;
}
}

View File

@@ -432,10 +432,10 @@ export function createApiFactory(
return extHostNotebookDocumentsAndEditors.getAllEditors();
},
get onDidOpenNotebookDocument() {
return extHostNotebook.onDidOpenNotebookDocument;
return extHostNotebookDocumentsAndEditors.onDidOpenNotebookDocument;
},
get onDidChangeNotebookCell() {
return extHostNotebook.onDidChangeNotebookCell;
return extHostNotebookDocumentsAndEditors.onDidChangeNotebookCell;
},
showNotebookDocument(uri: vscode.Uri, showOptions: sqlops.nb.NotebookShowOptions) {
return extHostNotebookDocumentsAndEditors.showNotebookDocument(uri, showOptions);

View File

@@ -797,6 +797,14 @@ export interface INotebookModelAddedData {
uri: UriComponents;
providerId: string;
isDirty: boolean;
cells: sqlops.nb.NotebookCell[];
}
export interface INotebookModelChangedData {
uri: UriComponents;
providerId: string;
isDirty: boolean;
cells: sqlops.nb.NotebookCell[];
}
export interface INotebookEditorAddData {
@@ -815,6 +823,7 @@ export interface INotebookShowOptions {
export interface ExtHostNotebookDocumentsAndEditorsShape {
$acceptDocumentsAndEditorsDelta(delta: INotebookDocumentsAndEditorsDelta): void;
$acceptModelChanged(strURL: UriComponents, e: INotebookModelChangedData);
}
export interface MainThreadNotebookDocumentsAndEditorsShape extends IDisposable {