Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Preliminary live share support (just a simple cell running mirrored o…
…n guest) (#4325) * First commit * Webpanellistener abstraction and new general purpose live share post office * Logic in place * Fix callbacks for non live share mode * Get codelens to show up in liveshare guest * Cells visible, but crashing in execution * Remove the IJupyterExecutionFactory idea * Fix local non shared case to work again * Fix text documents being found on unopened docs * New idea for jupyter server. * Local mode working again * Closer to having code lens work on guest * Communication getting to point of waiting for results * More communication in place * Add getSysInfo to jupyterServer and make executeSilently return data * Trying to get responses to parse * Fix splicing * Get single cell to run across live share * Fix hygiene errors * Abstracting liveshare api for tests * Fix History Simple text to pass. * Get notebook tests to pass * Add the feature flag and fixup new loc strings * Add news entry * Fix code lens/watcher tests. Fix capitilization issue * Rename JupyterExecutionBase and JupyterServerBase back * Some review feedback * More code review feedback. Fix send_info. * Move regexes to the common location * Fix compile-webviews
- Loading branch information
Showing
46 changed files
with
2,060 additions
and
325 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1 @@ | ||
Support live share in Python Interactive window |
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,46 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
'use strict'; | ||
import { inject, injectable } from 'inversify'; | ||
import * as vsls from 'vsls/vscode'; | ||
|
||
import { ILiveShareApi, IWorkspaceService } from '../application/types'; | ||
import { IConfigurationService, IDisposableRegistry } from '../types'; | ||
|
||
// tslint:disable:no-any unified-signatures | ||
|
||
@injectable() | ||
export class LiveShareApi implements ILiveShareApi { | ||
|
||
private supported : boolean = false; | ||
private apiPromise : Promise<vsls.LiveShare | null> | undefined; | ||
|
||
constructor( | ||
@inject(IDisposableRegistry) disposableRegistry : IDisposableRegistry, | ||
@inject(IWorkspaceService) workspace : IWorkspaceService, | ||
@inject(IConfigurationService) private configService : IConfigurationService | ||
) { | ||
const disposable = workspace.onDidChangeConfiguration(e => { | ||
if (e.affectsConfiguration('python.dataScience', undefined)) { | ||
// When config changes happen, recreate our commands. | ||
this.onSettingsChanged(); | ||
} | ||
}); | ||
disposableRegistry.push(disposable); | ||
this.onSettingsChanged(); | ||
} | ||
|
||
public getApi(): Promise<vsls.LiveShare | null> { | ||
return this.apiPromise!; | ||
} | ||
|
||
private onSettingsChanged() { | ||
const supported = this.configService.getSettings().datascience.allowLiveShare; | ||
if (supported !== this.supported) { | ||
this.supported = supported ? true : false; | ||
this.apiPromise = supported ? vsls.getApi() : Promise.resolve(null); | ||
} else if (!this.apiPromise) { | ||
this.apiPromise = Promise.resolve(null); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,7 +1,23 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
|
||
'use strict'; | ||
import { IAsyncDisposable, IDisposable } from '../types'; | ||
|
||
// tslint:disable-next-line:no-empty | ||
export function noop() { } | ||
|
||
export function using<T extends IDisposable>(disposable: T, func: (obj: T) => void) { | ||
try { | ||
func(disposable); | ||
} finally { | ||
disposable.dispose(); | ||
} | ||
} | ||
|
||
export async function usingAsync<T extends IAsyncDisposable, R>(disposable: T, func: (obj: T) => Promise<R>) : Promise<R> { | ||
try { | ||
return await func(disposable); | ||
} finally { | ||
await disposable.dispose(); | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,81 @@ | ||
// Copyright (c) Microsoft Corporation. All rights reserved. | ||
// Licensed under the MIT License. | ||
'use strict'; | ||
import { inject, injectable } from 'inversify'; | ||
import { Disposable, TextEditor, TextEditorEdit } from 'vscode'; | ||
import * as vsls from 'vsls/vscode'; | ||
|
||
import { ICommandManager, ILiveShareApi } from '../common/application/types'; | ||
import { LiveShare } from './constants'; | ||
import { PostOffice } from './liveshare/postOffice'; | ||
import { ICommandBroker } from './types'; | ||
|
||
// tslint:disable:no-any | ||
|
||
// This class acts as a broker between the VSCode command manager and a potential live share session | ||
// It works like so: | ||
// -- If not connected to any live share session, then just register commands as normal | ||
// -- If a host, register commands as normal (as they will be listened to), but when they are hit, post them to all guests | ||
// -- If a guest, register commands as normal (as they will be ignored), but also register for notifications from the host. | ||
@injectable() | ||
export class CommandBroker implements ICommandBroker { | ||
|
||
private postOffice : PostOffice; | ||
constructor( | ||
@inject(ILiveShareApi) liveShare: ILiveShareApi, | ||
@inject(ICommandManager) private commandManager: ICommandManager) { | ||
this.postOffice = new PostOffice(LiveShare.CommandBrokerService, liveShare); | ||
} | ||
|
||
public registerCommand(command: string, callback: (...args: any[]) => void, thisArg?: any): Disposable { | ||
// Modify the callback such that it sends the command to our service | ||
const disposable = this.commandManager.registerCommand(command, (...args: any[]) => this.wrapCallback(command, callback, ...args), thisArg); | ||
|
||
// Register it for lookup | ||
this.register(command, callback, thisArg).ignoreErrors(); | ||
|
||
return disposable; | ||
} | ||
public registerTextEditorCommand(command: string, callback: (textEditor: TextEditor, edit: TextEditorEdit, ...args: any[]) => void, thisArg?: any): Disposable { | ||
// Modify the callback such that it sends the command to our service | ||
const disposable = this.commandManager.registerCommand( | ||
command, | ||
(textEditor: TextEditor, edit: TextEditorEdit, ...args: any[]) => this.wrapTextEditorCallback(command, callback, textEditor, edit, ...args), thisArg); | ||
|
||
// Register it for lookup | ||
this.register(command, callback, thisArg).ignoreErrors(); | ||
|
||
return disposable; | ||
} | ||
public executeCommand<T>(command: string, ...rest: any[]): Thenable<T | undefined> { | ||
// Execute the command but potentially also send to our service too | ||
this.postCommand<T>(command, ...rest).ignoreErrors(); | ||
return this.commandManager.executeCommand(command, ...rest); | ||
} | ||
public getCommands(filterInternal?: boolean): Thenable<string[]> { | ||
// This does not go across to the other side. Just return the command registered locally | ||
return this.commandManager.getCommands(filterInternal); | ||
} | ||
|
||
private async register(command: string, callback: (...args: any[]) => void, thisArg?: any) : Promise<void> { | ||
return this.postOffice.registerCallback(command, callback, thisArg); | ||
} | ||
|
||
private wrapCallback(command: string, callback: (...args: any[]) => void, ...args: any[]) { | ||
// Have the post office handle it. | ||
this.postCommand(command, ...args).ignoreErrors(); | ||
} | ||
|
||
private wrapTextEditorCallback(command: string, callback: (textEditor: TextEditor, edit: TextEditorEdit, ...args: any[]) => void, ...args: any[]) { | ||
// Not really supported at the moment as we don't have a special case for the textEditor. But not using it. | ||
this.postCommand(command, ...args).ignoreErrors(); | ||
} | ||
|
||
private async postCommand<T>(command: string, ...rest: any[]): Promise<void> { | ||
// Make sure we're the host (or none). Guest shouldn't be sending | ||
if (this.postOffice.role() !== vsls.Role.Guest) { | ||
// This means we should send this across to the other side. | ||
return this.postOffice.postCommand(command, ...rest); | ||
} | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.