Books/search within notebook (#8426)

* initial commit

* get notebook content

* skeleton for find in notebookModel

* add search function and keyboard shortcut

* add command for hiding find widget

* started on search logic

* continue search logic

* continue search logic

* add findcountchange listener

* notebook find position

* added css class

* hide find widget

* focus find input

* search for multiple occurrences in one line

* start notebook find decorations

* start adding decorations to notebook model

* added editor_model_defaults

* added cursor position

* merged master and resolved husky erros

* initial changes added to Lucyls base implementation

* pass NotebbokRange instead of Range to decorations

* changes after merging master

* temp changes for testing

* style updates from vscode merge

* implemented the empty methods and added supporting functionality from textModel

* just a little error checking

* It gets more and more yellow

* making highlight work between code cells

* highlight only word

* remove highlight on close and maintain the position

* cleanup of unused references

* clean up

* find between code cells refactored

* highlight markdown line and scroll to it

* find index fix

* find index fix

* code clean up

* remove commented code

* tslint fix for: Cannot use global 'NodeJS'

* linting rule fixes

* deltaDecoration base implementation on the base class

* moced class defnitions from interface fikle

* updated action names

* DOM.addClass instead of overwriting

* resooved conflicts

* moved 'find' code away from notebookmodel to sep class

* moved find realted code to seperate folder

* created notebookFindModel

* clean up

* highlight color changes

* spacing and typo fixes

* highlight correct element for nested elements

* do not iterate through paragraphs and li

* find accross notebooks

* keep track of index

* clear decorations on close

* floating promises

* maintain search context

Co-authored-by: Lucy Zhang <lucyzhang929@gmail.com>
Co-authored-by: Chris LaFreniere <40371649+chlafreniere@users.noreply.github.com>
This commit is contained in:
Maddy
2019-12-19 17:21:03 -08:00
committed by GitHub
parent 102d820935
commit 778a34a9d2
22 changed files with 2236 additions and 41 deletions

View File

@@ -22,7 +22,9 @@ import { ICapabilitiesService } from 'sql/platform/capabilities/common/capabilit
import { localize } from 'vs/nls';
import { NotebookModel } from 'sql/workbench/contrib/notebook/browser/models/notebookModel';
import { mssqlProviderName } from 'sql/platform/connection/common/constants';
import { IModelDecorationsChangeAccessor } from 'vs/editor/common/model';
import { IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvents';
import { NotebookRange, NotebookFindMatch } from 'sql/workbench/contrib/notebook/find/notebookFindDecorations';
export interface IClientSessionOptions {
notebookUri: URI;
@@ -258,7 +260,7 @@ export interface INotebookModel {
/**
* The active cell for this model. May be undefined
*/
readonly activeCell: ICellModel;
activeCell: ICellModel | undefined;
/**
* Client Session in the notebook, used for sending requests to the notebook service
@@ -395,6 +397,8 @@ export interface INotebookModel {
getApplicableConnectionProviderIds(kernelName: string): string[];
updateActiveCell(cell: ICellModel): void;
/**
* Get the standardKernelWithProvider by name
* @param name The kernel name
@@ -408,13 +412,63 @@ export interface INotebookModel {
standardKernels: IStandardKernelWithProvider[];
/**
* Updates the model's view of an active cell to the new active cell
* @param cell New active cell
*/
updateActiveCell(cell: ICellModel);
requestConnection(): Promise<boolean>;
}
export interface INotebookFindModel {
/** Get the find count */
getFindCount(): number;
/** Get the find index */
getFindIndex(): number;
/** find the next match */
findNext(): Promise<NotebookRange>;
/** find the previous match */
findPrevious(): Promise<NotebookRange>;
/** search the notebook model for the given exp up to maxMatch occurances */
find(exp: string, maxMatches?: number): Promise<NotebookRange>;
/** clear the results of the find */
clearFind(): void;
/** return the find results with their ranges */
findArray: NotebookRange[];
/**
* Get the range associated with a decoration.
* @param id The decoration id.
* @return The decoration range or null if the decoration was not found.
*/
getDecorationRange(id: string): NotebookRange | null;
/**
* Get the range associated with a decoration.
* @param callback that accepts changeAccessor which applies the decorations
* @param ownerId the owner id
* @return The decoration range or null if the decoration was not found.
*/
changeDecorations<T>(callback: (changeAccessor: IModelDecorationsChangeAccessor) => T, ownerId: number): T | null;
/**
* Get the maximum legal column for line at `lineNumber`
*/
getLineMaxColumn(lineNumber: number): number;
/**
* Get the number of lines in the model.
*/
getLineCount(): number;
findMatches: NotebookFindMatch[];
findExpression: string;
/** Emit event when the find count changes */
onFindCountChange: Event<number>;
}
export interface NotebookContentChange {

View File

@@ -31,6 +31,7 @@ import { UntitledTextEditorInput } from 'vs/workbench/common/editor/untitledText
import { ResourceEditorInput } from 'vs/workbench/common/editor/resourceEditorInput';
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
import { BinaryEditorModel } from 'vs/workbench/common/editor/binaryEditorModel';
import { NotebookFindModel } from 'sql/workbench/contrib/notebook/find/notebookFindModel';
export type ModeViewSaveHandler = (handle: number) => Thenable<boolean>;
@@ -165,7 +166,7 @@ export class NotebookEditorModel extends EditorModel {
return this.getNotebookModel() !== undefined;
}
private getNotebookModel(): INotebookModel {
public getNotebookModel(): INotebookModel {
let editor = this.notebookService.findNotebookEditor(this.notebookUri);
if (editor) {
return editor.model;
@@ -203,6 +204,8 @@ export abstract class NotebookInput extends EditorInput {
private _modelResolveInProgress: boolean = false;
private _modelResolved: Deferred<void> = new Deferred<void>();
private _notebookFindModel: NotebookFindModel;
constructor(private _title: string,
private resource: URI,
private _textInput: TextInput,
@@ -233,6 +236,13 @@ export abstract class NotebookInput extends EditorInput {
return this.resource;
}
public get notebookFindModel(): NotebookFindModel {
if (!this._notebookFindModel) {
this._notebookFindModel = new NotebookFindModel(this._model.getNotebookModel());
}
return this._notebookFindModel;
}
public get contentManager(): IContentManager {
if (!this._contentManager) {
this._contentManager = this.instantiationService.createInstance(NotebookEditorContentManager, this);

View File

@@ -360,7 +360,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
return cell;
}
public updateActiveCell(cell: ICellModel) {
public updateActiveCell(cell: ICellModel): void {
if (this._activeCell) {
this._activeCell.active = false;
}
@@ -426,8 +426,8 @@ export class NotebookModel extends Disposable implements INotebookModel {
return this._activeCell;
}
public set activeCell(value: ICellModel) {
this._activeCell = value;
public set activeCell(cell: ICellModel) {
this._activeCell = cell;
}
private notifyError(error: string): void {
@@ -597,7 +597,7 @@ export class NotebookModel extends Disposable implements INotebookModel {
public changeKernel(displayName: string): void {
this._contextsLoadingEmitter.fire();
this.doChangeKernel(displayName, true);
this.doChangeKernel(displayName, true).catch(e => this.logService.error(e));
}
private async doChangeKernel(displayName: string, mustSetProvider: boolean = true, restoreOnFail: boolean = true): Promise<void> {
@@ -776,8 +776,8 @@ export class NotebookModel extends Disposable implements INotebookModel {
public dispose(): void {
super.dispose();
this.disconnectAttachToConnections();
this.handleClosed();
this.disconnectAttachToConnections().catch(e => this.logService.error(e));
this.handleClosed().catch(e => this.logService.error(e));
}
public async handleClosed(): Promise<void> {
@@ -998,5 +998,4 @@ export class NotebookModel extends Disposable implements INotebookModel {
this._contentChangedEmitter.fire(changeInfo);
}
}