Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

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: 0 additions & 1 deletion experiments.json

This file was deleted.

1 change: 1 addition & 0 deletions news/2 Fixes/5879.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
Fix shift+enter to work in newly created files with cells.
33 changes: 24 additions & 9 deletions src/client/datascience/editor-integration/codelensprovider.ts
Original file line number Diff line number Diff line change
Expand Up @@ -4,24 +4,44 @@
import { inject, injectable } from 'inversify';
import * as vscode from 'vscode';

import { IDocumentManager } from '../../common/application/types';
import { ICommandManager, IDocumentManager } from '../../common/application/types';
import { ContextKey } from '../../common/contextKey';
import { IConfigurationService, IDataScienceSettings } from '../../common/types';
import { IServiceContainer } from '../../ioc/types';
import { EditorContexts } from '../constants';
import { ICodeWatcher, IDataScienceCodeLensProvider } from '../types';

@injectable()
export class DataScienceCodeLensProvider implements IDataScienceCodeLensProvider {
private activeCodeWatchers: ICodeWatcher[] = [];
constructor(@inject(IServiceContainer) private serviceContainer: IServiceContainer,
@inject(IDocumentManager) private documentManager: IDocumentManager,
@inject(IConfigurationService) private configuration: IConfigurationService)
@inject(IConfigurationService) private configuration: IConfigurationService,
@inject(ICommandManager) private commandManager: ICommandManager
)
{
}

// CodeLensProvider interface
// Some implementation based on DonJayamanne's jupyter extension work
public provideCodeLenses(document: vscode.TextDocument, _token: vscode.CancellationToken):
vscode.CodeLens[] {
public provideCodeLenses(document: vscode.TextDocument, _token: vscode.CancellationToken): vscode.CodeLens[] {
// Get the list of code lens for this document.
const result = this.getCodeLens(document);

// Update the hasCodeCells context at the same time we are asked for codelens as VS code will
// ask whenever a change occurs.
const editorContext = new ContextKey(EditorContexts.HasCodeCells, this.commandManager);
editorContext.set(result && result.length > 0).catch();

return result;
}

// IDataScienceCodeLensProvider interface
public getCodeWatcher(document: vscode.TextDocument): ICodeWatcher | undefined {
return this.matchWatcher(document.fileName, document.version, this.configuration.getSettings().datascience);
}

private getCodeLens(document: vscode.TextDocument): vscode.CodeLens[] {
// Don't provide any code lenses if we have not enabled data science
const settings = this.configuration.getSettings();
if (!settings.datascience.enabled || !settings.datascience.enableCellCodeLens) {
Expand All @@ -46,11 +66,6 @@ export class DataScienceCodeLensProvider implements IDataScienceCodeLensProvider
return newCodeWatcher.getCodeLenses();
}

// IDataScienceCodeLensProvider interface
public getCodeWatcher(document: vscode.TextDocument): ICodeWatcher | undefined {
return this.matchWatcher(document.fileName, document.version, this.configuration.getSettings().datascience);
}

private matchWatcher(fileName: string, version: number, settings: IDataScienceSettings) : ICodeWatcher | undefined {
const index = this.activeCodeWatchers.findIndex(item => item.getFileName() === fileName);
if (index >= 0) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,34 +4,38 @@
import * as TypeMoq from 'typemoq';
import { CancellationTokenSource, TextDocument } from 'vscode';

import { IDocumentManager } from '../../../client/common/application/types';
import { ICommandManager, IDocumentManager } from '../../../client/common/application/types';
import { IConfigurationService, IDataScienceSettings, IPythonSettings } from '../../../client/common/types';
import { DataScienceCodeLensProvider } from '../../../client/datascience/editor-integration/codelensprovider';
import { ICodeWatcher, IDataScienceCodeLensProvider } from '../../../client/datascience/types';
import { IServiceContainer } from '../../../client/ioc/types';

// tslint:disable-next-line: max-func-body-length
suite('DataScienceCodeLensProvider Unit Tests', () => {
let serviceContainer: TypeMoq.IMock<IServiceContainer>;
let configurationService: TypeMoq.IMock<IConfigurationService>;
let codeLensProvider: IDataScienceCodeLensProvider;
let dataScienceSettings: TypeMoq.IMock<IDataScienceSettings>;
let pythonSettings: TypeMoq.IMock<IPythonSettings>;
let documentManager: TypeMoq.IMock<IDocumentManager>;
let commandManager: TypeMoq.IMock<ICommandManager>;
let tokenSource : CancellationTokenSource;

setup(() => {
tokenSource = new CancellationTokenSource();
serviceContainer = TypeMoq.Mock.ofType<IServiceContainer>();
configurationService = TypeMoq.Mock.ofType<IConfigurationService>();
documentManager = TypeMoq.Mock.ofType<IDocumentManager>();
commandManager = TypeMoq.Mock.ofType<ICommandManager>();

pythonSettings = TypeMoq.Mock.ofType<IPythonSettings>();
dataScienceSettings = TypeMoq.Mock.ofType<IDataScienceSettings>();
dataScienceSettings.setup(d => d.enabled).returns(() => true);
pythonSettings.setup(p => p.datascience).returns(() => dataScienceSettings.object);
configurationService.setup(c => c.getSettings(TypeMoq.It.isAny())).returns(() => pythonSettings.object);
commandManager.setup(c => c.executeCommand(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns(() => Promise.resolve());

codeLensProvider = new DataScienceCodeLensProvider(serviceContainer.object, documentManager.object, configurationService.object);
codeLensProvider = new DataScienceCodeLensProvider(serviceContainer.object, documentManager.object, configurationService.object, commandManager.object);
});

test('Initialize Code Lenses one document', () => {
Expand All @@ -49,7 +53,7 @@ suite('DataScienceCodeLensProvider Unit Tests', () => {

targetCodeWatcher.verifyAll();
serviceContainer.verifyAll();
});
});

test('Initialize Code Lenses same doc called', () => {
// Create our document
Expand Down
20 changes: 17 additions & 3 deletions src/test/datascience/editor-integration/codewatcher.unit.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,11 +7,11 @@ import { expect } from 'chai';
import * as TypeMoq from 'typemoq';
import { CancellationTokenSource, CodeLens, Range, Selection, TextEditor } from 'vscode';

import { IApplicationShell, IDocumentManager } from '../../../client/common/application/types';
import { IApplicationShell, ICommandManager, IDocumentManager } from '../../../client/common/application/types';
import { PythonSettings } from '../../../client/common/configSettings';
import { IFileSystem } from '../../../client/common/platform/types';
import { IConfigurationService, ILogger } from '../../../client/common/types';
import { Commands } from '../../../client/datascience/constants';
import { Commands, EditorContexts } from '../../../client/datascience/constants';
import { DataScienceCodeLensProvider } from '../../../client/datascience/editor-integration/codelensprovider';
import { CodeWatcher } from '../../../client/datascience/editor-integration/codewatcher';
import { ICodeWatcher, IHistory, IHistoryProvider } from '../../../client/datascience/types';
Expand All @@ -29,12 +29,14 @@ suite('DataScience Code Watcher Unit Tests', () => {
let historyProvider: TypeMoq.IMock<IHistoryProvider>;
let activeHistory: TypeMoq.IMock<IHistory>;
let documentManager: TypeMoq.IMock<IDocumentManager>;
let commandManager: TypeMoq.IMock<ICommandManager>;
let textEditor: TypeMoq.IMock<TextEditor>;
let fileSystem: TypeMoq.IMock<IFileSystem>;
let configService: TypeMoq.IMock<IConfigurationService>;
let serviceContainer : TypeMoq.IMock<IServiceContainer>;
let helper: TypeMoq.IMock<ICodeExecutionHelper>;
let tokenSource : CancellationTokenSource;
const contexts : Map<string, boolean> = new Map<string, boolean>();
const pythonSettings = new class extends PythonSettings {
public fireChangeEvent() {
this.changed.fire();
Expand All @@ -52,6 +54,7 @@ suite('DataScience Code Watcher Unit Tests', () => {
fileSystem = TypeMoq.Mock.ofType<IFileSystem>();
configService = TypeMoq.Mock.ofType<IConfigurationService>();
helper = TypeMoq.Mock.ofType<ICodeExecutionHelper>();
commandManager = TypeMoq.Mock.ofType<ICommandManager>();

// Setup default settings
pythonSettings.datascience = {
Expand Down Expand Up @@ -94,6 +97,13 @@ suite('DataScience Code Watcher Unit Tests', () => {
// Setup config service
configService.setup(c => c.getSettings()).returns(() => pythonSettings);

commandManager.setup(c => c.executeCommand(TypeMoq.It.isAny(), TypeMoq.It.isAny(), TypeMoq.It.isAny())).returns((c, n, v) => {
if (c === 'setContext') {
contexts.set(n, v);
}
return Promise.resolve();
});

codeWatcher = new CodeWatcher(appShell.object, logger.object, historyProvider.object, fileSystem.object, configService.object, documentManager.object, helper.object);
});

Expand Down Expand Up @@ -657,20 +667,24 @@ testing2`; // Command tests override getText, so just need the ranges here
const inputText = '#%% foobar';
const document = createDocument(inputText, fileName, version, TypeMoq.Times.atLeastOnce());
documentManager.setup(d => d.textDocuments).returns(() => [document.object]);
const codeLensProvider = new DataScienceCodeLensProvider(serviceContainer.object, documentManager.object, configService.object);
const codeLensProvider = new DataScienceCodeLensProvider(serviceContainer.object, documentManager.object, configService.object, commandManager.object);

let result = codeLensProvider.provideCodeLenses(document.object, tokenSource.token);
expect(result, 'result not okay').to.be.ok;
let codeLens = result as CodeLens[];
expect(codeLens.length).to.equal(2, 'Code lens wrong length');

expect(contexts.get(EditorContexts.HasCodeCells)).to.be.equal(true, 'Code cells context not set');

// Change settings
pythonSettings.datascience.codeRegularExpression = '#%%%.*dude';
result = codeLensProvider.provideCodeLenses(document.object, tokenSource.token);
expect(result, 'result not okay').to.be.ok;
codeLens = result as CodeLens[];
expect(codeLens.length).to.equal(0, 'Code lens wrong length');

expect(contexts.get(EditorContexts.HasCodeCells)).to.be.equal(false, 'Code cells context not set');

// Change settings to empty
pythonSettings.datascience.codeRegularExpression = '';
result = codeLensProvider.provideCodeLenses(document.object, tokenSource.token);
Expand Down