Skip to content

Commit cabd23b

Browse files
authored
Mark code that was directly injected into the R runtime by the R runtime with a special ID; detect and add that code to the console input history (#8277)
1 parent eb5b8d3 commit cabd23b

File tree

5 files changed

+21
-12
lines changed

5 files changed

+21
-12
lines changed

extensions/positron-r/src/commands.ts

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55

66
import * as vscode from 'vscode';
77
import * as positron from 'positron';
8-
import { PromiseHandles } from './util';
8+
import { generateDirectInjectionId, PromiseHandles } from './util';
99
import { checkInstalled } from './session';
1010
import { getRPackageName } from './contexts';
1111
import { getRPackageTasks } from './tasks';
@@ -110,8 +110,9 @@ export async function registerCommands(context: vscode.ExtensionContext, runtime
110110
return;
111111
}
112112

113+
// Temporary measure - generate a direct injection ID so this code execution will be added to the console history.
113114
session.execute(`library(${packageName})`,
114-
randomUUID(),
115+
generateDirectInjectionId(),
115116
positron.RuntimeCodeExecutionMode.Interactive,
116117
positron.RuntimeErrorBehavior.Continue);
117118
}
@@ -218,7 +219,7 @@ export async function registerCommands(context: vscode.ExtensionContext, runtime
218219
if (isInstalled) {
219220
const session = await positron.runtime.getForegroundSession();
220221
if (session) {
221-
session.execute(`renv::init()`, randomUUID(), positron.RuntimeCodeExecutionMode.Interactive, positron.RuntimeErrorBehavior.Continue);
222+
session.execute(`renv::init()`, generateDirectInjectionId(), positron.RuntimeCodeExecutionMode.Interactive, positron.RuntimeErrorBehavior.Continue);
222223
} else {
223224
console.debug('[r.renvInit] no session available');
224225
}

extensions/positron-r/src/hyperlink.ts

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import * as positron from 'positron';
77
import * as vscode from 'vscode';
88
import { randomUUID } from 'crypto';
99
import { RSession } from './session';
10+
import { generateDirectInjectionId } from './util.js';
1011

1112
export async function handleRCode(runtime: RSession, code: string): Promise<void> {
1213
const match = matchRunnable(code);
@@ -64,9 +65,10 @@ async function handleManuallyRunnable(_runtime: RSession, code: string) {
6465
}
6566

6667
function handleAutomaticallyRunnable(runtime: RSession, code: string) {
68+
// Temporary measure - generate a direct injection ID so this code execution will be added to the console history.
6769
runtime.execute(
6870
code,
69-
randomUUID(),
71+
generateDirectInjectionId(),
7072
positron.RuntimeCodeExecutionMode.Transient,
7173
positron.RuntimeErrorBehavior.Continue
7274
);

extensions/positron-r/src/util.ts

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@
55

66
import * as fs from 'fs';
77
import { LOGGER } from './extension';
8+
import { randomUUID } from 'crypto';
89

910
export class PromiseHandles<T> {
1011
resolve!: (value: T | Promise<T>) => void;
@@ -90,3 +91,11 @@ export function removeSurroundingQuotes(x: string): string {
9091

9192
return x;
9293
}
94+
95+
/**
96+
* Generates a unique ID for direct injection of code into the runtime.
97+
* @returns A unique ID for direct injection of code into the runtime.
98+
*/
99+
export function generateDirectInjectionId(): string {
100+
return `direct-injection-${randomUUID()}`;
101+
}

extensions/vscode-api-tests/src/singlefolder-tests/positron/runtime.test.ts

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -753,15 +753,13 @@ suite('positron API - executeCode', () => {
753753
'print("event")', // code
754754
false, // focus
755755
false, // allowIncomplete
756-
positron.RuntimeCodeExecutionMode.Interactive,
757-
positron.RuntimeErrorBehavior.Stop
758756
);
759757

760758
// Assert that the event matches the expected values
761759
assert.ok(event, 'Event should be fired');
762760
assert.strictEqual(event.languageId, 'test', 'Language ID should match');
763761
assert.strictEqual(event.code, 'print("event")', 'Code should match');
764-
assert.strictEqual(event.attribution.source, positron.CodeAttributionSource.Interactive,
762+
assert.strictEqual(event.attribution.source, positron.CodeAttributionSource.Extension,
765763
'Correctly attributed to execution via an extension');
766764
});
767765

src/vs/workbench/services/positronConsole/browser/positronConsoleService.ts

Lines changed: 4 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -2039,11 +2039,10 @@ class PositronConsoleInstance extends Disposable implements IPositronConsoleInst
20392039
)
20402040
);
20412041

2042-
// Detect incoming code that was not sent by the console input (that is not prefixed
2043-
// by 'fragment-'). When this happens, fire the onDidExecuteCode event so the code gets
2044-
// added to the console history. In the fullness of time, it would be ideal for the
2045-
// runtime to emit an event for this, but for now we can detect it.
2046-
if (!languageRuntimeMessageInput.parent_id.startsWith('fragment-')) {
2042+
// As a temporary measure, to be replaced soon with an event from the runtime, detect code
2043+
// that was injected into the runtime directly (not via the console input). When this happens,
2044+
// fire the onDidExecuteCode event so the code gets added to the console history.
2045+
if (languageRuntimeMessageInput.parent_id.startsWith('direct-injection-')) {
20472046
// Get the session's language ID. It will always be defined for a runtime session.
20482047
const languageId = this.session?.runtimeMetadata?.languageId;
20492048
if (!languageId) {

0 commit comments

Comments
 (0)