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

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions apps/vscode/build.ts
Original file line number Diff line number Diff line change
Expand Up @@ -24,14 +24,14 @@ const testFiles = glob.sync("src/test/*.ts");
const testBuildOptions = {
entryPoints: testFiles,
outdir: 'test-out',
external: ['vscode', 'mocha', 'glob'],
external: ['vscode', 'positron', 'mocha', 'glob'],
sourcemap: true,
};

const defaultBuildOptions = {
entryPoints: ['./src/main.ts'],
outfile: './out/main.js',
external: ['vscode'],
external: ['vscode', 'positron'],
minify: !dev,
dev
};
Expand Down
5 changes: 5 additions & 0 deletions apps/vscode/src/@types/hooks.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -58,6 +58,11 @@ declare module 'positron' {
readonly code?: string;
}

export class StatementRangeSyntaxError extends Error {
readonly line?: number;
constructor(line?: number);
}

export interface PositronWindow {
createPreviewPanel(
viewType: string,
Expand Down
29 changes: 22 additions & 7 deletions apps/vscode/src/host/hooks.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@
import * as vscode from 'vscode';
import * as hooks from 'positron';

import semver from "semver";
import { ExtensionHost, HostWebviewPanel, HostStatementRangeProvider, HostHelpTopicProvider } from '.';
import { CellExecutor, cellExecutorForLanguage, executableLanguages, isKnitrDocument, pythonWithReticulate } from './executors';
import { ExecuteQueue } from './execute-queue';
import { MarkdownEngine } from '../markdown/engine';
import { virtualDoc, adjustedPosition, unadjustedRange, withVirtualDocUri, VirtualDocStyle } from "../vdoc/vdoc";
import { virtualDoc, adjustedPosition, unadjustedRange, withVirtualDocUri, VirtualDocStyle, unadjustedLine } from "../vdoc/vdoc";
import { Position, Range } from 'vscode';
import { Uri } from 'vscode';

Expand Down Expand Up @@ -200,18 +201,32 @@ class EmbeddedStatementRangeProvider implements HostStatementRangeProvider {
position: vscode.Position,
token: vscode.CancellationToken): Promise<hooks.StatementRange | undefined> {
const vdoc = await virtualDoc(document, position, this._engine, VirtualDocStyle.Block);
if (vdoc) {
return await withVirtualDocUri(vdoc, document.uri, "statementRange", async (uri: vscode.Uri) => {

if (!vdoc) {
return undefined;
}

return await withVirtualDocUri(vdoc, document.uri, "statementRange", async (uri: vscode.Uri) => {
try {
const result = await vscode.commands.executeCommand<hooks.StatementRange>(
"vscode.executeStatementRangeProvider",
uri,
adjustedPosition(vdoc.language, position)
);
return { range: unadjustedRange(vdoc.language, result.range), code: result.code };
});
} else {
return undefined;
}
} catch (err) {
// TODO: Remove this once `apps/vscode/package.json` bumps to `"positron": "^2026.03.0"` or higher.
// For now we avoid aggressive bumping due to https://github.com/posit-dev/positron/issues/11321.
if (semver.gte(hooks.version, "2026.03.0")) {
if (err instanceof hooks.StatementRangeSyntaxError) {
// Rethrow syntax error with unadjusted line number, so Positron's notification will
// jump to the correct line
throw new hooks.StatementRangeSyntaxError(err.line ? unadjustedLine(vdoc.language, err.line) : undefined);
}
}
Comment on lines +218 to +226
Copy link
Collaborator Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Version guarding on the expected next positron release of "2026.03.0"

throw err;
}
});
};
}

Expand Down
14 changes: 11 additions & 3 deletions apps/vscode/src/vdoc/vdoc.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,13 +240,21 @@ export function isBlockOfLanguage(language: EmbeddedLanguage) {
};
}

// adjust position for inject
// adjust line for inject
export function adjustedLine(language: EmbeddedLanguage, line: number): number {
return line + (language.inject?.length || 0);
}

export function unadjustedLine(language: EmbeddedLanguage, line: number): number {
return line - (language.inject?.length || 0);
}

export function adjustedPosition(language: EmbeddedLanguage, pos: Position) {
return new Position(pos.line + (language.inject?.length || 0), pos.character);
return new Position(adjustedLine(language, pos.line), pos.character);
}

export function unadjustedPosition(language: EmbeddedLanguage, pos: Position) {
return new Position(pos.line - (language.inject?.length || 0), pos.character);
return new Position(unadjustedLine(language, pos.line), pos.character);
}

export function unadjustedRange(language: EmbeddedLanguage, range: Range) {
Expand Down
Loading