diff --git a/extensions/positron-r/src/commands.ts b/extensions/positron-r/src/commands.ts index 953548493744..9b63f97a32f2 100644 --- a/extensions/positron-r/src/commands.ts +++ b/extensions/positron-r/src/commands.ts @@ -5,7 +5,7 @@ import * as vscode from 'vscode'; import * as positron from 'positron'; -import { PromiseHandles } from './util'; +import { generateDirectInjectionId, PromiseHandles } from './util'; import { checkInstalled } from './session'; import { getRPackageName } from './contexts'; import { getRPackageTasks } from './tasks'; @@ -110,8 +110,9 @@ export async function registerCommands(context: vscode.ExtensionContext, runtime return; } + // Temporary measure - generate a direct injection ID so this code execution will be added to the console history. session.execute(`library(${packageName})`, - randomUUID(), + generateDirectInjectionId(), positron.RuntimeCodeExecutionMode.Interactive, positron.RuntimeErrorBehavior.Continue); } @@ -218,7 +219,7 @@ export async function registerCommands(context: vscode.ExtensionContext, runtime if (isInstalled) { const session = await positron.runtime.getForegroundSession(); if (session) { - session.execute(`renv::init()`, randomUUID(), positron.RuntimeCodeExecutionMode.Interactive, positron.RuntimeErrorBehavior.Continue); + session.execute(`renv::init()`, generateDirectInjectionId(), positron.RuntimeCodeExecutionMode.Interactive, positron.RuntimeErrorBehavior.Continue); } else { console.debug('[r.renvInit] no session available'); } diff --git a/extensions/positron-r/src/hyperlink.ts b/extensions/positron-r/src/hyperlink.ts index 1fe5e778e942..9b0aa7b01af3 100644 --- a/extensions/positron-r/src/hyperlink.ts +++ b/extensions/positron-r/src/hyperlink.ts @@ -7,6 +7,7 @@ import * as positron from 'positron'; import * as vscode from 'vscode'; import { randomUUID } from 'crypto'; import { RSession } from './session'; +import { generateDirectInjectionId } from './util.js'; export async function handleRCode(runtime: RSession, code: string): Promise { const match = matchRunnable(code); @@ -64,9 +65,10 @@ async function handleManuallyRunnable(_runtime: RSession, code: string) { } function handleAutomaticallyRunnable(runtime: RSession, code: string) { + // Temporary measure - generate a direct injection ID so this code execution will be added to the console history. runtime.execute( code, - randomUUID(), + generateDirectInjectionId(), positron.RuntimeCodeExecutionMode.Transient, positron.RuntimeErrorBehavior.Continue ); diff --git a/extensions/positron-r/src/util.ts b/extensions/positron-r/src/util.ts index dabcf102ba14..e0ca077afc2f 100644 --- a/extensions/positron-r/src/util.ts +++ b/extensions/positron-r/src/util.ts @@ -5,6 +5,7 @@ import * as fs from 'fs'; import { LOGGER } from './extension'; +import { randomUUID } from 'crypto'; export class PromiseHandles { resolve!: (value: T | Promise) => void; @@ -90,3 +91,11 @@ export function removeSurroundingQuotes(x: string): string { return x; } + +/** + * Generates a unique ID for direct injection of code into the runtime. + * @returns A unique ID for direct injection of code into the runtime. + */ +export function generateDirectInjectionId(): string { + return `direct-injection-${randomUUID()}`; +} diff --git a/extensions/vscode-api-tests/src/singlefolder-tests/positron/runtime.test.ts b/extensions/vscode-api-tests/src/singlefolder-tests/positron/runtime.test.ts index 3a5d3f773f0d..d0207fb6ef0e 100644 --- a/extensions/vscode-api-tests/src/singlefolder-tests/positron/runtime.test.ts +++ b/extensions/vscode-api-tests/src/singlefolder-tests/positron/runtime.test.ts @@ -753,15 +753,13 @@ suite('positron API - executeCode', () => { 'print("event")', // code false, // focus false, // allowIncomplete - positron.RuntimeCodeExecutionMode.Interactive, - positron.RuntimeErrorBehavior.Stop ); // Assert that the event matches the expected values assert.ok(event, 'Event should be fired'); assert.strictEqual(event.languageId, 'test', 'Language ID should match'); assert.strictEqual(event.code, 'print("event")', 'Code should match'); - assert.strictEqual(event.attribution.source, positron.CodeAttributionSource.Interactive, + assert.strictEqual(event.attribution.source, positron.CodeAttributionSource.Extension, 'Correctly attributed to execution via an extension'); }); diff --git a/src/vs/workbench/services/positronConsole/browser/positronConsoleService.ts b/src/vs/workbench/services/positronConsole/browser/positronConsoleService.ts index e65bf1acd678..018b45eb2d87 100644 --- a/src/vs/workbench/services/positronConsole/browser/positronConsoleService.ts +++ b/src/vs/workbench/services/positronConsole/browser/positronConsoleService.ts @@ -2039,11 +2039,10 @@ class PositronConsoleInstance extends Disposable implements IPositronConsoleInst ) ); - // Detect incoming code that was not sent by the console input (that is not prefixed - // by 'fragment-'). When this happens, fire the onDidExecuteCode event so the code gets - // added to the console history. In the fullness of time, it would be ideal for the - // runtime to emit an event for this, but for now we can detect it. - if (!languageRuntimeMessageInput.parent_id.startsWith('fragment-')) { + // As a temporary measure, to be replaced soon with an event from the runtime, detect code + // that was injected into the runtime directly (not via the console input). When this happens, + // fire the onDidExecuteCode event so the code gets added to the console history. + if (languageRuntimeMessageInput.parent_id.startsWith('direct-injection-')) { // Get the session's language ID. It will always be defined for a runtime session. const languageId = this.session?.runtimeMetadata?.languageId; if (!languageId) {