Skip to content

Commit

Permalink
Update 'workbench.action.positronConsole.executeCode' to be used in Q…
Browse files Browse the repository at this point in the history
…uarto (#3107)

* Update 'workbench.action.positronConsole.executeCode' to be used in Quarto

* Remove monkeying around with `languageId`

* Implement `_executeStatementRangeProvider` command, for extensions to use

* Import new command

* Fix what command returns (statement range, not range)

* Apply suggestions from code review

Co-authored-by: Davis Vaughan <[email protected]>
Signed-off-by: Julia Silge <[email protected]>

* Update return for command

---------

Signed-off-by: Julia Silge <[email protected]>
Co-authored-by: Davis Vaughan <[email protected]>
  • Loading branch information
juliasilge and DavisVaughan authored May 22, 2024
1 parent cd93dea commit 1463261
Show file tree
Hide file tree
Showing 4 changed files with 67 additions and 14 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*---------------------------------------------------------------------------------------------
* Copyright (C) 2024 Posit Software, PBC. All rights reserved.
*--------------------------------------------------------------------------------------------*/

import { LanguageFeatureRegistry } from 'vs/editor/common/languageFeatureRegistry';
import { ILanguageFeaturesService } from 'vs/editor/common/services/languageFeatures';
import * as languages from 'vs/editor/common/languages';
import { onUnexpectedExternalError } from 'vs/base/common/errors';
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
import { assertType } from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
import { IPosition, Position } from 'vs/editor/common/core/position';
import { ITextModel } from 'vs/editor/common/model';
import { IModelService } from 'vs/editor/common/services/model';
import { CancellationToken } from 'vs/base/common/cancellation';


async function provideStatementRange(
registry: LanguageFeatureRegistry<languages.StatementRangeProvider>,
model: ITextModel,
position: Position,
token: CancellationToken
): Promise<languages.IStatementRange | undefined> {

const providers = registry.ordered(model);

for (const provider of providers) {
try {
const result = await provider.provideStatementRange(model, position, token);
if (result) {
return result;
}
} catch (err) {
onUnexpectedExternalError(err);
}
}
return undefined;
}

CommandsRegistry.registerCommand('_executeStatementRangeProvider', async (accessor, ...args: [URI, IPosition]) => {
const [uri, position] = args;
assertType(URI.isUri(uri));
assertType(Position.isIPosition(position));

const model = accessor.get(IModelService).getModel(uri);
if (!model) {
return undefined;
}
const languageFeaturesService = accessor.get(ILanguageFeaturesService);
return await provideStatementRange(
languageFeaturesService.statementRangeProvider,
model,
Position.lift(position),
CancellationToken.None
);
});
1 change: 1 addition & 0 deletions src/vs/editor/editor.all.ts
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,7 @@ import 'vs/editor/contrib/diffEditorBreadcrumbs/browser/contribution';

// --- Start Positron ---
import 'vs/editor/contrib/positronEditorActions/browser/positronEditorActions';
import 'vs/editor/contrib/positronStatementRange/browser/provideStatementRange';
// --- End Positron ---

// Load up these strings even in VSCode, even if they are not used
Expand Down
15 changes: 4 additions & 11 deletions src/vs/workbench/api/common/extHostApiCommands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/

import { StatementRange } from 'positron';
import { isFalsyOrEmpty } from 'vs/base/common/arrays';
import { VSBuffer } from 'vs/base/common/buffer';
import { Schemas, matchesSomeScheme } from 'vs/base/common/network';
Expand Down Expand Up @@ -489,18 +490,10 @@ const newCommands: ApiCommand[] = [
// -- statement range
new ApiCommand(
'vscode.executeStatementRangeProvider', '_executeStatementRangeProvider', 'Execute statement range provider.',
[ApiCommandArgument.Uri,
new ApiCommandArgument<types.Position, IPosition>('position',
'A position in a text document',
// validator: check for a valid position
v => types.Position.isPosition(v),
// converter: convert from vscode.Position to IPosition (API type)
v => {
return typeConverters.Position.from(v);
})],
new ApiCommandResult<IRange, types.Range>('A promise that resolves to a range.', result => {
[ApiCommandArgument.Uri, ApiCommandArgument.Position],
new ApiCommandResult<languages.IStatementRange, StatementRange>('A promise that resolves to a statement range.', result => {
// converter: convert from IRange (API type) to vscode.Range
return typeConverters.Range.to(result);
return { range: typeConverters.Range.to(result.range), code: result.code };
})
),
// --- End Positron
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -264,8 +264,11 @@ export function registerPositronConsoleActions() {
/**
* Runs action.
* @param accessor The services accessor.
* @param opts Options for code execution
* - allowIncomplete: Optionally, should incomplete statements be accepted? If `undefined`, treated as `false`.
* - languageId: Optionally, a language override for the code to execute. If `undefined`, the language of the active text editor is used. Useful for notebooks.
*/
async run(accessor: ServicesAccessor, opts: { allowIncomplete?: boolean } = {}) {
async run(accessor: ServicesAccessor, opts: { allowIncomplete?: boolean; languageId?: string } = {}) {
// Access services.
const editorService = accessor.get(IEditorService);
const languageFeaturesService = accessor.get(ILanguageFeaturesService);
Expand Down Expand Up @@ -495,7 +498,7 @@ export function registerPositronConsoleActions() {
}

// Now that we've gotten this far, ensure we have a target language.
const languageId = editorService.activeTextEditorLanguageId;
const languageId = opts.languageId ? opts.languageId : editorService.activeTextEditorLanguageId;
if (!languageId) {
notificationService.notify({
severity: Severity.Info,
Expand All @@ -509,7 +512,7 @@ export function registerPositronConsoleActions() {
// By default, we don't allow incomplete code to be executed, but the language runtime can override this.
// This means that if allowIncomplete is false or undefined, the incomplete code will not be sent to the backend for execution.
// The console will continue to wait for more input until the user completes the code, or cancels out of the operation.
const { allowIncomplete } = opts;
const allowIncomplete = opts.allowIncomplete;


// Ask the Positron console service to execute the code. Do not focus the console as
Expand Down

0 comments on commit 1463261

Please sign in to comment.