Skip to content

Commit acb5e98

Browse files
authored
More portions of liveshare working (#4361)
For #3581 Get live share to work when server session already started. Fix problems with closing/reopening on the guest side reusing old results Still to do: - Add telemetry for liveshare sessions - Add functional tests to verify liveshare algorithms (probably do this next) <!-- If an item below does not apply to you, then go ahead and check it off as "done" and strikethrough the text, e.g.: - [x] ~Has unit tests & system/integration tests~ --> - [x] Pull request represents a single change (i.e. not fixing disparate/unrelated things in a single PR) - [x] Title summarizes what is changing - [x] Has a [news entry](https://github.com/Microsoft/vscode-python/tree/master/news) file (remember to thank yourself!) - [ ] Has sufficient logging. - [ ] Has telemetry for enhancements. - [x] Unit tests & system/integration tests are added/updated - [ ] [Test plan](https://github.com/Microsoft/vscode-python/blob/master/.github/test_plan.md) is updated as appropriate - [ ] [`package-lock.json`](https://github.com/Microsoft/vscode-python/blob/master/package-lock.json) has been regenerated by running `npm install` (if dependencies have changed)
1 parent 8efae04 commit acb5e98

34 files changed

Lines changed: 691 additions & 423 deletions

news/1 Enhancements/3581.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1 +1 @@
1-
Support live share in Python Interactive window
1+
Support live share in Python Interactive window (experimental)

news/2 Fixes/4237.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
Fix problem with webview panel not being dockable anywhere but view column 2.

src/client/common/application/webPanel.ts

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ export class WebPanel implements IWebPanel {
4747
public async show() {
4848
await this.loadPromise;
4949
if (this.panel) {
50-
this.panel.reveal(ViewColumn.Two, true);
50+
this.panel.reveal(this.panel.viewColumn, true);
5151
}
5252
}
5353

@@ -73,7 +73,7 @@ export class WebPanel implements IWebPanel {
7373
// Reset when the current panel is closed
7474
this.disposableRegistry.push(this.panel.onDidDispose(() => {
7575
this.panel = undefined;
76-
this.listener.dispose();
76+
this.listener.dispose().ignoreErrors();
7777
}));
7878

7979
this.disposableRegistry.push(this.panel.webview.onDidReceiveMessage(message => {

src/client/common/utils/misc.ts

Lines changed: 23 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -1,23 +1,23 @@
1-
// Copyright (c) Microsoft Corporation. All rights reserved.
2-
// Licensed under the MIT License.
3-
'use strict';
4-
import { IAsyncDisposable, IDisposable } from '../types';
5-
6-
// tslint:disable-next-line:no-empty
7-
export function noop() { }
8-
9-
export function using<T extends IDisposable>(disposable: T, func: (obj: T) => void) {
10-
try {
11-
func(disposable);
12-
} finally {
13-
disposable.dispose();
14-
}
15-
}
16-
17-
export async function usingAsync<T extends IAsyncDisposable, R>(disposable: T, func: (obj: T) => Promise<R>) : Promise<R> {
18-
try {
19-
return await func(disposable);
20-
} finally {
21-
await disposable.dispose();
22-
}
23-
}
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
'use strict';
4+
import { IAsyncDisposable, IDisposable } from '../types';
5+
6+
// tslint:disable-next-line:no-empty
7+
export function noop() { }
8+
9+
export function using<T extends IDisposable>(disposable: T, func: (obj: T) => void) {
10+
try {
11+
func(disposable);
12+
} finally {
13+
disposable.dispose();
14+
}
15+
}
16+
17+
export async function usingAsync<T extends IAsyncDisposable, R>(disposable: T, func: (obj: T) => Promise<R>) : Promise<R> {
18+
try {
19+
return await func(disposable);
20+
} finally {
21+
await disposable.dispose();
22+
}
23+
}

src/client/datascience/cellFactory.ts

Lines changed: 7 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ import { CellMatcher } from './cellMatcher';
1111
import { appendLineFeed, generateMarkdownFromCodeLines } from './common';
1212
import { CellState, ICell } from './types';
1313

14-
function generateCodeCell(code: string[], file: string, line: number, id?: string) : ICell {
14+
function generateCodeCell(code: string[], file: string, line: number, id: string) : ICell {
1515
// Code cells start out with just source and no outputs.
1616
return {
1717
data: {
@@ -21,17 +21,17 @@ function generateCodeCell(code: string[], file: string, line: number, id?: strin
2121
metadata: {},
2222
execution_count: 0
2323
},
24-
id: id ? id : uuid(),
24+
id: id,
2525
file: file,
2626
line: line,
2727
state: CellState.init
2828
};
2929

3030
}
3131

32-
function generateMarkdownCell(code: string[], file: string, line: number, id?: string) : ICell {
32+
function generateMarkdownCell(code: string[], file: string, line: number, id: string) : ICell {
3333
return {
34-
id: id ? id : uuid(),
34+
id: id,
3535
file: file,
3636
line: line,
3737
state: CellState.finished,
@@ -44,7 +44,7 @@ function generateMarkdownCell(code: string[], file: string, line: number, id?: s
4444

4545
}
4646

47-
export function generateCells(settings: IDataScienceSettings | undefined, code: string, file: string, line: number, splitMarkdown?: boolean, id?: string) : ICell[] {
47+
export function generateCells(settings: IDataScienceSettings | undefined, code: string, file: string, line: number, splitMarkdown: boolean, id: string) : ICell[] {
4848
// Determine if we have a markdown cell/ markdown and code cell combined/ or just a code cell
4949
const split = code.splitLines({trim: false});
5050
const firstLine = split[0];
@@ -56,7 +56,7 @@ export function generateCells(settings: IDataScienceSettings | undefined, code:
5656
if (firstNonMarkdown >= 0) {
5757
return [
5858
generateMarkdownCell(split.slice(0, firstNonMarkdown), file, line, id),
59-
generateCodeCell(split.slice(firstNonMarkdown), file, line + firstNonMarkdown)
59+
generateCodeCell(split.slice(firstNonMarkdown), file, line + firstNonMarkdown, id)
6060
];
6161
} else {
6262
// Just a single markdown cell
@@ -119,6 +119,6 @@ export function generateCellsFromDocument(document: TextDocument, settings?: IDa
119119
// For each one, get its text and turn it into a cell
120120
return Array.prototype.concat(...ranges.map(r => {
121121
const code = document.getText(r.range);
122-
return generateCells(settings, code, document.fileName, r.range.start.line);
122+
return generateCells(settings, code, document.fileName, r.range.start.line, false, uuid());
123123
}));
124124
}

src/client/datascience/constants.ts

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -67,11 +67,15 @@ export namespace HistoryMessages {
6767
export const StartProgress = 'start_progress';
6868
export const StopProgress = 'stop_progress';
6969
export const Interrupt = 'interrupt';
70-
export const SendInfo = 'send_info';
7170
export const SubmitNewCell = 'submit_new_cell';
7271
export const UpdateSettings = 'update_settings';
7372
}
7473

74+
export namespace HistoryNonLiveShareMessages {
75+
export const SendInfo = 'send_info';
76+
export const Started = 'started';
77+
}
78+
7579
export enum Telemetry {
7680
ImportNotebook = 'DATASCIENCE.IMPORT_NOTEBOOK',
7781
RunCell = 'DATASCIENCE.RUN_CELL',

src/client/datascience/datascience.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -80,60 +80,60 @@ export class DataScience implements IDataScience {
8080
}
8181
}
8282

83-
public async runAllCells(file: string): Promise<void> {
83+
public async runAllCells(file: string, id: string): Promise<void> {
8484
this.dataScienceSurveyBanner.showBanner().ignoreErrors();
8585

8686
let codeWatcher = this.getCodeWatcher(file);
8787
if (!codeWatcher) {
8888
codeWatcher = this.getCurrentCodeWatcher();
8989
}
9090
if (codeWatcher) {
91-
return codeWatcher.runAllCells();
91+
return codeWatcher.runAllCells(id);
9292
} else {
9393
return Promise.resolve();
9494
}
9595
}
9696

9797
// Note: see codewatcher.ts where the runcell command args are attached. The reason we don't have any
9898
// objects for parameters is because they can't be recreated when passing them through the LiveShare API
99-
public async runCell(file: string, startLine: number, startChar: number, endLine: number, endChar: number): Promise<void> {
99+
public async runCell(file: string, startLine: number, startChar: number, endLine: number, endChar: number, id: string): Promise<void> {
100100
this.dataScienceSurveyBanner.showBanner().ignoreErrors();
101101
const codeWatcher = this.getCodeWatcher(file);
102102
if (codeWatcher) {
103-
return codeWatcher.runCell(new vscode.Range(startLine, startChar, endLine, endChar));
103+
return codeWatcher.runCell(new vscode.Range(startLine, startChar, endLine, endChar), id);
104104
} else {
105-
return this.runCurrentCell();
105+
return this.runCurrentCell(id);
106106
}
107107
}
108108

109-
public async runCurrentCell(): Promise<void> {
109+
public async runCurrentCell(id: string): Promise<void> {
110110
this.dataScienceSurveyBanner.showBanner().ignoreErrors();
111111

112112
const activeCodeWatcher = this.getCurrentCodeWatcher();
113113
if (activeCodeWatcher) {
114-
return activeCodeWatcher.runCurrentCell();
114+
return activeCodeWatcher.runCurrentCell(id);
115115
} else {
116116
return Promise.resolve();
117117
}
118118
}
119119

120-
public async runCurrentCellAndAdvance(): Promise<void> {
120+
public async runCurrentCellAndAdvance(id: string): Promise<void> {
121121
this.dataScienceSurveyBanner.showBanner().ignoreErrors();
122122

123123
const activeCodeWatcher = this.getCurrentCodeWatcher();
124124
if (activeCodeWatcher) {
125-
return activeCodeWatcher.runCurrentCellAndAdvance();
125+
return activeCodeWatcher.runCurrentCellAndAdvance(id);
126126
} else {
127127
return Promise.resolve();
128128
}
129129
}
130130

131-
public async runSelectionOrLine(): Promise<void> {
131+
public async runSelectionOrLine(id: string): Promise<void> {
132132
this.dataScienceSurveyBanner.showBanner().ignoreErrors();
133133

134134
const activeCodeWatcher = this.getCurrentCodeWatcher();
135135
if (activeCodeWatcher) {
136-
return activeCodeWatcher.runSelectionOrLine(this.documentManager.activeTextEditor);
136+
return activeCodeWatcher.runSelectionOrLine(this.documentManager.activeTextEditor, id);
137137
} else {
138138
return Promise.resolve();
139139
}

src/client/datascience/editor-integration/codewatcher.ts

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -76,7 +76,7 @@ export class CodeWatcher implements ICodeWatcher {
7676
}
7777

7878
@captureTelemetry(Telemetry.RunAllCells)
79-
public async runAllCells() {
79+
public async runAllCells(id: string) {
8080
const activeHistory = this.historyProvider.getOrCreateActive();
8181

8282
// Run all of our code lenses, they should always be ordered in the file so we can just
@@ -87,7 +87,7 @@ export class CodeWatcher implements ICodeWatcher {
8787
const range: Range = new Range(lens.command.arguments[1], lens.command.arguments[2], lens.command.arguments[3], lens.command.arguments[4]);
8888
if (this.document && range) {
8989
const code = this.document.getText(range);
90-
await activeHistory.addCode(code, this.getFileName(), range.start.line);
90+
await activeHistory.addCode(code, this.getFileName(), range.start.line, id);
9191
}
9292
}
9393
}
@@ -96,13 +96,13 @@ export class CodeWatcher implements ICodeWatcher {
9696
if (this.codeLenses.length === 0) {
9797
if (this.document) {
9898
const code = this.document.getText();
99-
await activeHistory.addCode(code, this.getFileName(), 0);
99+
await activeHistory.addCode(code, this.getFileName(), 0, id);
100100
}
101101
}
102102
}
103103

104104
@captureTelemetry(Telemetry.RunSelectionOrLine)
105-
public async runSelectionOrLine(activeEditor : TextEditor | undefined) {
105+
public async runSelectionOrLine(activeEditor : TextEditor | undefined, id: string) {
106106
const activeHistory = this.historyProvider.getOrCreateActive();
107107

108108
if (this.document && activeEditor &&
@@ -119,20 +119,20 @@ export class CodeWatcher implements ICodeWatcher {
119119
}
120120

121121
if (code && code.trim().length) {
122-
await activeHistory.addCode(code, this.getFileName(), activeEditor.selection.start.line, activeEditor);
122+
await activeHistory.addCode(code, this.getFileName(), activeEditor.selection.start.line, id, activeEditor);
123123
}
124124
}
125125
}
126126

127127
@captureTelemetry(Telemetry.RunCell)
128-
public async runCell(range: Range) {
128+
public async runCell(range: Range, id: string) {
129129
const activeHistory = this.historyProvider.getOrCreateActive();
130130
if (this.document) {
131131
// Use that to get our code.
132132
const code = this.document.getText(range);
133133

134134
try {
135-
await activeHistory.addCode(code, this.getFileName(), range.start.line, this.documentManager.activeTextEditor);
135+
await activeHistory.addCode(code, this.getFileName(), range.start.line, id, this.documentManager.activeTextEditor);
136136
} catch (err) {
137137
this.handleError(err);
138138
}
@@ -141,22 +141,22 @@ export class CodeWatcher implements ICodeWatcher {
141141
}
142142

143143
@captureTelemetry(Telemetry.RunCurrentCell)
144-
public async runCurrentCell() {
144+
public async runCurrentCell(id: string) {
145145
if (!this.documentManager.activeTextEditor || !this.documentManager.activeTextEditor.document) {
146146
return;
147147
}
148148

149149
for (const lens of this.codeLenses) {
150150
// Check to see which RunCell lens range overlaps the current selection start
151151
if (lens.range.contains(this.documentManager.activeTextEditor.selection.start) && lens.command && lens.command.command === Commands.RunCell) {
152-
await this.runCell(lens.range);
152+
await this.runCell(lens.range, id);
153153
break;
154154
}
155155
}
156156
}
157157

158158
@captureTelemetry(Telemetry.RunCurrentCellAndAdvance)
159-
public async runCurrentCellAndAdvance() {
159+
public async runCurrentCellAndAdvance(id: string) {
160160
if (!this.documentManager.activeTextEditor || !this.documentManager.activeTextEditor.document) {
161161
return;
162162
}
@@ -191,7 +191,7 @@ export class CodeWatcher implements ICodeWatcher {
191191
}
192192

193193
// Run the cell after moving the selection
194-
await this.runCell(currentRunCellLens.range);
194+
await this.runCell(currentRunCellLens.range, id);
195195
}
196196
}
197197

0 commit comments

Comments
 (0)