Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Notebook API Support #12442

Merged
merged 94 commits into from
Aug 31, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
94 commits
Select commit Hold shift + click to select a range
b17fe8a
Add notebook package to Theia
msujew Feb 27, 2023
e60b44f
working getting notebook contributions
jonah-iden Feb 28, 2023
0e5f2b6
working onNotebook activation event;
jonah-iden Mar 1, 2023
c84990b
basic backend frontend communication with registering serializers
jonah-iden Mar 3, 2023
a98e3b1
render messaging rpc api
jonah-iden Mar 3, 2023
76bf6e8
basic widget for notebooks working
jonah-iden Mar 9, 2023
77230ba
titles for noetbook editor + and working language support for cell ed…
jonah-iden Mar 10, 2023
0f0d9dc
fixed activating serializers before opening notebook document; added …
jonah-iden Mar 27, 2023
63ff3eb
notebook document dirty and save listeners
jonah-iden Mar 27, 2023
a450866
document dirty and save listeners
jonah-iden Mar 27, 2023
ecadf6c
baisc saving of notebooks implemented
jonah-iden Mar 28, 2023
ba6ca53
basic toolbar implementation for selected cell
jonah-iden Mar 30, 2023
2c989f1
notebook edit framework and edit and delete actions
jonah-iden Mar 31, 2023
a301b32
context key basics
jonah-iden Apr 11, 2023
d0e5726
notebook editor closable; removed when clause since no support for it…
jonah-iden Apr 11, 2023
ff50115
fixed saving
jonah-iden Apr 11, 2023
6ffcbd4
hardcoded flag for deactivating unfinished notebook support
jonah-iden Apr 11, 2023
3e09a16
basic add cell buttons (no functionality)
jonah-iden Apr 11, 2023
3f3ea80
all smaller review comments
jonah-iden Apr 19, 2023
409f36d
notebookModel and notebookCellModel injectable
jonah-iden Apr 19, 2023
2df5b29
better dependency injection for notebookEditor widget and the cell re…
jonah-iden Apr 19, 2023
6513d4f
fixed activation events. explicit onNotebook, implicit on NotebookSer…
jonah-iden Apr 20, 2023
d493d0b
correct dirty change after saving
jonah-iden Apr 20, 2023
c675a88
updated notebook package to 1.36.0
jonah-iden Apr 20, 2023
82f20d6
removed uneccessary comment
jonah-iden Apr 21, 2023
7461bd9
react key for cellDivider
jonah-iden Apr 21, 2023
04f6830
removed duplicate interface
jonah-iden Apr 21, 2023
edf747c
update notebook packege to 1.37.0
jonah-iden May 2, 2023
43e9058
review comments
jonah-iden May 19, 2023
157b49e
stop using createInline()
jonah-iden May 26, 2023
c19dd8c
more review comment changes:
jonah-iden May 26, 2023
80deb5e
renamed Event
jonah-iden Jun 12, 2023
7870a2b
updated version to 1.38.0
jonah-iden Jun 16, 2023
39a299b
basics for notebook ContextKeys implemented
jonah-iden Jun 19, 2023
73321be
context keys working for cells
jonah-iden Jun 19, 2023
9c4b12b
cell toolbar menu item order; fixed cell editor sizing
jonah-iden Jun 20, 2023
c394140
added basic logic for adding new cells
jonah-iden Jun 20, 2023
b6529ca
fixed file headers
jonah-iden Jun 20, 2023
0b9fc42
include vscode.ipynb by default
jonah-iden Jun 22, 2023
3809ce2
basiscs for notebook cell Execution API
jonah-iden Jun 22, 2023
a3b01e4
basic api for cell execution and jupyter extension support
jonah-iden Jun 29, 2023
77ca418
basic kernel creation and selection
jonah-iden Jul 13, 2023
021a227
increased version to 1.39.0
jonah-iden Jul 13, 2023
8e5a462
basic showing cell outputs
jonah-iden Jul 14, 2023
7247029
cleanup, correct cell updating and basic api for notebook-edits (not …
jonah-iden Jul 17, 2023
928161c
fixed Element already has context attribute Error
jonah-iden Jul 17, 2023
3195f48
fixed cell document odes allready exists error
jonah-iden Jul 19, 2023
35849da
fixed notebook not scrollable when mouse in editor
jonah-iden Jul 19, 2023
6e3079e
api and contributions for notebook renderers
jonah-iden Jul 20, 2023
cb7dc84
Improve editor performance
msujew Jul 24, 2023
cdd8739
basic cell rendering in iframes working
jonah-iden Jul 26, 2023
7ea5f8f
actually fixed document allready exists error
jonah-iden Jul 26, 2023
3a7f070
only display output webview when outputs
jonah-iden Jul 26, 2023
a1f5f8c
some fixes for displaying outputs
jonah-iden Jul 26, 2023
d237e9e
small fix for images, so the output height is determined correctly
jonah-iden Jul 27, 2023
49ec33c
scrolling propagation from output webview to parent working
jonah-iden Jul 28, 2023
f37cce4
smaller output layouting changes
jonah-iden Jul 28, 2023
8e08f1c
added sidebar menu for cells
jonah-iden Jul 28, 2023
098077d
Improve a few rendering issues, cleanup CSS
msujew Jul 28, 2023
0545249
Fix notebook widget startup rendering
msujew Jul 28, 2023
ac5244a
working sidebar and change presentation for outputs
jonah-iden Jul 31, 2023
f6ca0dd
merge issue fixes
jonah-iden Jul 31, 2023
4220260
quickfix for ouput action menu
jonah-iden Jul 31, 2023
e62a686
small fix for ouput webview horizontal size
jonah-iden Jul 31, 2023
a1ed1ca
fix for previous css fix
jonah-iden Jul 31, 2023
65b58bf
save outputs and notebook dirty on output change
jonah-iden Jul 31, 2023
1233170
basic cell status view (still kind of bugged
jonah-iden Aug 1, 2023
e2f5699
fixed notebook code-cell status-bar
jonah-iden Aug 2, 2023
9cbf5ac
renamed Dto methods since they dont
jonah-iden Aug 2, 2023
13e5746
fixed issue with no document found when notebook is restored
jonah-iden Aug 2, 2023
7b18f0f
basic notebook toolbar
jonah-iden Aug 7, 2023
305f4fc
working kernel chooser
jonah-iden Aug 7, 2023
1880a57
persisting kernel selection
jonah-iden Aug 7, 2023
c02e5a6
upgraded notebook to 1.40
jonah-iden Aug 7, 2023
26b2324
fixed no document error with adding new code cell;
jonah-iden Aug 8, 2023
f00e110
added notebook/cell/execution contribution menu;
jonah-iden Aug 9, 2023
3c1664a
basic undo redo for notebook-editor
jonah-iden Aug 9, 2023
fbf1662
fixes for setting current active editor
jonah-iden Aug 9, 2023
976741c
added drag and drop moving of cells
jonah-iden Aug 10, 2023
1527850
Set editor dirty on any edit operation
msujew Aug 11, 2023
55a5435
Fix formatting
msujew Aug 11, 2023
04859d7
Fix notebook editor resize behavior
msujew Aug 11, 2023
474faf9
Fix broken monaco editor
msujew Aug 11, 2023
9cb19ff
removed @stubbed for most of notebook-api;
jonah-iden Aug 11, 2023
6a0a3b9
fixed build for api changes
jonah-iden Aug 11, 2023
374dcdb
fixed lint
jonah-iden Aug 11, 2023
ab1727a
basics for creating new untitled notebooks
jonah-iden Aug 11, 2023
e8dd288
Fix issues after latest commit
msujew Aug 16, 2023
0ef597d
Don't cache matched notebook types
msujew Aug 16, 2023
f3a031c
fixed multiple smaller issues
jonah-iden Aug 22, 2023
6409051
basic wokring creating new empty notebook;
jonah-iden Aug 23, 2023
a89eb2e
basic saveAs functionality for untitle notebooks
jonah-iden Aug 23, 2023
b7fcb31
Fix bugs, typos, and improve notebook behavior
msujew Aug 25, 2023
9add50f
Fix notebook header rendering
msujew Aug 28, 2023
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
1 change: 1 addition & 0 deletions examples/browser/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
"@theia/mini-browser": "1.40.0",
"@theia/monaco": "1.40.0",
"@theia/navigator": "1.40.0",
"@theia/notebook": "1.40.0",
"@theia/outline-view": "1.40.0",
"@theia/output": "1.40.0",
"@theia/plugin-dev": "1.40.0",
Expand Down
3 changes: 3 additions & 0 deletions examples/browser/tsconfig.json
Original file line number Diff line number Diff line change
Expand Up @@ -65,6 +65,9 @@
{
"path": "../../packages/navigator"
},
{
"path": "../../packages/notebook"
},
{
"path": "../../packages/outline-view"
},
Expand Down
1 change: 0 additions & 1 deletion package.json
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,6 @@
"vscode.git-base",
"vscode.github",
"vscode.github-authentication",
"vscode.ipynb",
"vscode.microsoft-authentication",
"ms-vscode.references-view"
]
Expand Down
43 changes: 41 additions & 2 deletions packages/core/src/browser/saveable.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@

import { Widget } from '@phosphor/widgets';
import { Message } from '@phosphor/messaging';
import { Event } from '../common/event';
import { Emitter, Event } from '../common/event';
import { MaybePromise } from '../common/types';
import { Key } from './keyboard/keys';
import { AbstractDialog } from './dialogs';
import { waitForClosed } from './widgets';
import { nls } from '../common/nls';
import { isObject } from '../common';
import { Disposable, isObject } from '../common';

export interface Saveable {
readonly dirty: boolean;
Expand Down Expand Up @@ -50,6 +50,45 @@ export interface SaveableSource {
readonly saveable: Saveable;
}

export class SaveableDelegate implements Saveable {
jonah-iden marked this conversation as resolved.
Show resolved Hide resolved
dirty = false;
protected readonly onDirtyChangedEmitter = new Emitter<void>();

get onDirtyChanged(): Event<void> {
return this.onDirtyChangedEmitter.event;
}
autoSave: 'off' | 'afterDelay' | 'onFocusChange' | 'onWindowChange' = 'off';

async save(options?: SaveOptions): Promise<void> {
await this.delegate?.save(options);
}

revert?(options?: Saveable.RevertOptions): Promise<void>;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Does the Saveable mechanism handle dynamically adding the function members? How would actions like "revert" get enabled when the saveable turns out to support them?

createSnapshot?(): Saveable.Snapshot;
applySnapshot?(snapshot: object): void;

protected delegate?: Saveable;
protected toDispose?: Disposable;

set(delegate: Saveable): void {
jonah-iden marked this conversation as resolved.
Show resolved Hide resolved
this.toDispose?.dispose();
this.delegate = delegate;
this.toDispose = this.delegate.onDirtyChanged(() => {
this.dirty = delegate.dirty;
this.onDirtyChangedEmitter.fire();
});
this.autoSave = delegate.autoSave;
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

How will users pick up that the autosave setting of the delegate has changed?

if (this.dirty !== delegate.dirty) {
this.dirty = delegate.dirty;
this.onDirtyChangedEmitter.fire();
}
this.revert = delegate.revert?.bind(delegate);
this.createSnapshot = delegate.createSnapshot?.bind(delegate);
this.applySnapshot = delegate.applySnapshot?.bind(delegate);
}

}

export namespace Saveable {
export interface RevertOptions {
/**
Expand Down
20 changes: 20 additions & 0 deletions packages/core/src/common/array-utils.ts
Original file line number Diff line number Diff line change
Expand Up @@ -106,4 +106,24 @@ export namespace ArrayUtils {
export function coalesce<T>(array: ReadonlyArray<T | undefined | null>): T[] {
return <T[]>array.filter(e => !!e);
}

/**
* groups array elements through a comparator function
* @param data array of elements to group
* @param compare comparator function: return of 0 means should group, anything above means not group
* @returns array of arrays with grouped elements
*/
export function groupBy<T>(data: ReadonlyArray<T>, compare: (a: T, b: T) => number): T[][] {
jonah-iden marked this conversation as resolved.
Show resolved Hide resolved
const result: T[][] = [];
let currentGroup: T[] | undefined = undefined;
for (const element of data.slice(0).sort(compare)) {
if (!currentGroup || compare(currentGroup[0], element) !== 0) {
currentGroup = [element];
result.push(currentGroup);
} else {
currentGroup.push(element);
}
}
return result;
}
}
14 changes: 12 additions & 2 deletions packages/core/src/common/event.ts
Original file line number Diff line number Diff line change
Expand Up @@ -16,7 +16,7 @@

/* eslint-disable @typescript-eslint/no-explicit-any */

import { Disposable, DisposableGroup } from './disposable';
import { Disposable, DisposableGroup, DisposableCollection } from './disposable';
import { MaybePromise } from './types';

/**
Expand Down Expand Up @@ -67,6 +67,16 @@ export namespace Event {
set maxListeners(maxListeners: number) { }
});
}

/**
* Given a collection of events, returns a single event which emits whenever any of the provided events emit.
*/
export function any<T>(...events: Event<T>[]): Event<T>;
export function any(...events: Event<any>[]): Event<void>;
export function any<T>(...events: Event<T>[]): Event<T> {
return (listener, thisArgs = undefined, disposables?: Disposable[]) =>
new DisposableCollection(...events.map(event => event(e => listener.call(thisArgs, e), undefined, disposables)));
}
}

type Callback = (...args: any[]) => any;
Expand Down Expand Up @@ -276,7 +286,7 @@ export class Emitter<T = any> {
*/
fire(event: T): any {
if (this._callbacks) {
this._callbacks.invoke(event);
return this._callbacks.invoke(event);
}
}

Expand Down
17 changes: 17 additions & 0 deletions packages/core/src/common/types.ts
Original file line number Diff line number Diff line change
Expand Up @@ -56,6 +56,23 @@ export function isFunction<T extends (...args: unknown[]) => unknown>(value: unk
return typeof value === 'function';
}

/**
* @returns whether the provided parameter is an empty JavaScript Object or not.
*/
export function isEmptyObject(obj: unknown): obj is object {
if (!isObject(obj)) {
return false;
}

for (const key in obj) {
jonah-iden marked this conversation as resolved.
Show resolved Hide resolved
if (Object.prototype.hasOwnProperty.call(obj, key)) {
return false;
}
}

return true;
}

export function isObject<T extends object>(value: unknown): value is UnknownObject<T> {
// eslint-disable-next-line no-null/no-null
return typeof value === 'object' && value !== null;
Expand Down
4 changes: 4 additions & 0 deletions packages/core/src/common/uri.ts
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,10 @@ export class URI {
return new URI(Uri.file(path));
}

public static isUri(uri: unknown): boolean {
jonah-iden marked this conversation as resolved.
Show resolved Hide resolved
return Uri.isUri(uri);
}

private readonly codeUri: Uri;
private _path: Path | undefined;

Expand Down
3 changes: 3 additions & 0 deletions packages/editor/src/browser/editor-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,6 +38,7 @@ import { QuickAccessContribution } from '@theia/core/lib/browser/quick-input/qui
import { QuickEditorService } from './quick-editor-service';
import { EditorLanguageStatusService } from './language-status/editor-language-status-service';
import { EditorLineNumberContribution } from './editor-linenumber-contribution';
import { UndoRedoService } from './undo-redo-service';

export default new ContainerModule(bind => {
bindEditorPreferences(bind);
Expand Down Expand Up @@ -86,4 +87,6 @@ export default new ContainerModule(bind => {
bind(ActiveEditorAccess).toSelf().inSingletonScope();
bind(EditorAccess).to(CurrentEditorAccess).inSingletonScope().whenTargetNamed(EditorAccess.CURRENT);
bind(EditorAccess).to(ActiveEditorAccess).inSingletonScope().whenTargetNamed(EditorAccess.ACTIVE);

bind(UndoRedoService).toSelf().inSingletonScope();
});
Original file line number Diff line number Diff line change
Expand Up @@ -94,16 +94,16 @@ export class ResourceEditStack {
this.past.push(element);
}

getClosestPastElement(): StackElement | null {
getClosestPastElement(): StackElement | undefined {
if (this.past.length === 0) {
return null;
return undefined;
}
return this.past[this.past.length - 1];
}

getClosestFutureElement(): StackElement | null {
getClosestFutureElement(): StackElement | undefined {
if (this.future.length === 0) {
return null;
return undefined;
}
return this.future[this.future.length - 1];
}
Expand Down
Loading
Loading