Skip to content
Open
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
2 changes: 1 addition & 1 deletion apps/vscode/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -1516,7 +1516,7 @@
"nanoid": "^4.0.0",
"p-queue": "^8.0.1",
"picomatch": "^2.3.1",
"@posit-dev/positron": "^0.1.0",
"@posit-dev/positron": "^0.2.4",
"quarto-core": "*",
"quarto-lsp": "*",
"quarto-utils": "*",
Expand Down
113 changes: 0 additions & 113 deletions apps/vscode/src/@types/hooks.d.ts

This file was deleted.

9 changes: 5 additions & 4 deletions apps/vscode/src/host/index.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,11 +18,12 @@ import vscode, { DocumentSelector, Disposable, WebviewPanelOptions, WebviewOptio

import { CellExecutor, cellExecutorForLanguage, executableLanguages, isKnitrDocument } from "./executors";
import { EditorToolbarProvider } from "./toolbar";
import { hasHooks, hooksExtensionHost } from "./hooks";
import { positronExtensionHost } from "./positron";
import { TextDocument } from "vscode";
import { MarkdownEngine } from "../markdown/engine";
import { WebviewPanel } from "vscode";
import { ViewColumn } from "vscode";
import { tryAcquirePositronApi } from "@posit-dev/positron";

export type { CellExecutor };
export type { EditorToolbarProvider, ToolbarItem, ToolbarCommand, ToolbarButton, ToolbarMenu } from './toolbar';
Expand Down Expand Up @@ -58,7 +59,7 @@ export interface HostHelpTopicProvider {

/**
* There are currently two extension hosts:
* - [`hooksExtensionHost`](./hooks.ts) for Positron
* - [`positronExtensionHost`](./hooks.ts) for Positron
* - [`defaultExtensionHost`](./index.ts) otherwise
*/
export interface ExtensionHost {
Expand Down Expand Up @@ -99,8 +100,8 @@ export interface ExtensionHost {
}

export function extensionHost(): ExtensionHost {
if (hasHooks()) {
return hooksExtensionHost();
if (tryAcquirePositronApi()) {
return positronExtensionHost();
} else {
return defaultExtensionHost();
}
Expand Down
71 changes: 25 additions & 46 deletions apps/vscode/src/host/hooks.ts → apps/vscode/src/host/positron.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
/*
* hooks.ts
* positron.ts
*
* Positron-specific functionality.
*
Expand All @@ -16,16 +16,16 @@
*/

import * as vscode from 'vscode';
import * as hooks from 'positron';
import * as positron 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, unadjustedLine } from "../vdoc/vdoc";
import { Position, Range } from 'vscode';
import { Uri } from 'vscode';
import { tryAcquirePositronApi } from '@posit-dev/positron';

/**
* Check if inline output is enabled in Positron settings.
Expand All @@ -37,28 +37,7 @@ export function isInlineOutputEnabled(): boolean {
.get<boolean>("enabled", false);
}

declare global {
function acquirePositronApi(): hooks.PositronApi;
}

let api: hooks.PositronApi | null | undefined;

export function hooksApi(): hooks.PositronApi | null {
if (api === undefined) {
try {
api = acquirePositronApi();
} catch {
api = null;
}
}
return api;
}

export function hasHooks() {
return !!hooksApi();
}

export function hooksExtensionHost(): ExtensionHost {
export function positronExtensionHost(): ExtensionHost {
return {
// supported executable languages (we delegate to the default for langugaes
// w/o runtimes so we support all languages)
Expand All @@ -67,13 +46,13 @@ export function hooksExtensionHost(): ExtensionHost {
cellExecutorForLanguage: async (language: string, document: vscode.TextDocument, engine: MarkdownEngine, silent?: boolean)
: Promise<CellExecutor | undefined> => {
switch (language) {
// use hooks for known runtimes
// use positron api for known runtimes
case "python":
case "csharp":
case "r":
return {
execute: async (blocks: string[], editorUri?: vscode.Uri, executionMetadata?: Record<string, unknown>[]): Promise<void> => {
const runtime = hooksApi()?.runtime;
const runtime = tryAcquirePositronApi()?.runtime;

if (runtime === undefined) {
// Can't do anything without a runtime
Expand All @@ -98,7 +77,7 @@ export function hooksExtensionHost(): ExtensionHost {
undefined, // The error behavior
undefined, // An optional observer
undefined, // The specific session ID in which to execute
editorUri, // The document URI
editorUri, // The document URI
metadata
);
}
Expand All @@ -124,7 +103,7 @@ export function hooksExtensionHost(): ExtensionHost {
return position;
},
executeInlineCells: async (documentUri: vscode.Uri, cellRanges: Range[], executionMetadata?: Record<string, unknown>[]): Promise<void> => {
const runtime = hooksApi()?.runtime;
const runtime = tryAcquirePositronApi()?.runtime;

if (runtime === undefined) {
// Can't do anything without a runtime
Expand All @@ -142,18 +121,18 @@ export function hooksExtensionHost(): ExtensionHost {
},

registerStatementRangeProvider: (engine: MarkdownEngine): vscode.Disposable => {
const hooks = hooksApi();
if (hooks) {
return hooks.languages.registerStatementRangeProvider('quarto',
const positronApi = tryAcquirePositronApi();
if (positronApi) {
return positronApi.languages.registerStatementRangeProvider('quarto',
new EmbeddedStatementRangeProvider(engine));
}
return new vscode.Disposable(() => { });
},

registerHelpTopicProvider: (engine: MarkdownEngine): vscode.Disposable => {
const hooks = hooksApi();
if (hooks) {
return hooks.languages.registerHelpTopicProvider('quarto',
const positronApi = tryAcquirePositronApi();
if (positronApi) {
return positronApi.languages.registerHelpTopicProvider('quarto',
new EmbeddedHelpTopicProvider(engine));
}
return new vscode.Disposable(() => { });
Expand All @@ -167,7 +146,7 @@ export function hooksExtensionHost(): ExtensionHost {
): HostWebviewPanel => {

// create preview panel
const panel = hooksApi()?.window.createPreviewPanel(
const panel = tryAcquirePositronApi()?.window.createPreviewPanel(
viewType,
title,
preserveFocus,
Expand All @@ -180,14 +159,14 @@ export function hooksExtensionHost(): ExtensionHost {
)!;

// adapt to host interface
return new HookWebviewPanel(panel);
return new PositronWebviewPanel(panel);
}
};
}


class HookWebviewPanel implements HostWebviewPanel {
constructor(private readonly panel_: hooks.PreviewPanel) { }
class PositronWebviewPanel implements HostWebviewPanel {
constructor(private readonly panel_: positron.PreviewPanel) { }

get webview() { return this.panel_.webview; };
get visible() { return this.panel_.visible; };
Expand All @@ -211,7 +190,7 @@ class EmbeddedStatementRangeProvider implements HostStatementRangeProvider {
async provideStatementRange(
document: vscode.TextDocument,
position: vscode.Position,
token: vscode.CancellationToken): Promise<hooks.StatementRange | undefined> {
token: vscode.CancellationToken): Promise<positron.StatementRange | undefined> {
const vdoc = await virtualDoc(document, position, this._engine, VirtualDocStyle.Block);

if (!vdoc) {
Expand All @@ -220,16 +199,16 @@ class EmbeddedStatementRangeProvider implements HostStatementRangeProvider {

return await withVirtualDocUri(vdoc, document.uri, "statementRange", async (uri: vscode.Uri) => {
try {
const result = await vscode.commands.executeCommand<hooks.StatementRange>(
const result = await vscode.commands.executeCommand<positron.StatementRange>(
"vscode.executeStatementRangeProvider",
uri,
adjustedPosition(vdoc.language, position)
);
return { range: unadjustedRange(vdoc.language, result.range), code: result.code };
} catch (err) {
let hooks = hooksApi();
let positronApi = tryAcquirePositronApi();

if (!hooks) {
if (!positronApi) {
throw err;
}

Expand All @@ -238,14 +217,14 @@ class EmbeddedStatementRangeProvider implements HostStatementRangeProvider {
// We can't use `semver.lt()` because calendar versioning isn't compatible with semver due to the
// leading `0` in `03`. Instead, we use lexicographic string comparison and rely on the year and
// month to be zero padded so sorting always works correctly.
if (hooks.version < "2026.03.0") {
if (positronApi.version < "2026.03.0") {
throw err;
}

if (err instanceof hooks.StatementRangeSyntaxError) {
if (err instanceof positronApi.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);
throw new positronApi.StatementRangeSyntaxError(err.line ? unadjustedLine(vdoc.language, err.line) : undefined);
} else {
// Rethrow unrecognized error
throw err;
Expand Down
18 changes: 0 additions & 18 deletions apps/vscode/src/lsp/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -538,21 +538,3 @@ function unadjustSymbolRanges(
};
});
}

/**
* Creates a diagnostic handler middleware that filters out diagnostics from virtual documents
*
* @returns A handler function for the middleware
*/
export function createDiagnosticFilter() {
return (uri: Uri, diagnostics: Diagnostic[], next: HandleDiagnosticsSignature) => {
// If this is not a virtual document, pass through all diagnostics
if (!isVirtualDoc(uri)) {
next(uri, diagnostics);
return;
}

// For virtual documents, filter out all diagnostics
next(uri, []);
};
}
2 changes: 1 addition & 1 deletion apps/vscode/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ import { activateEditor } from "./providers/editor/editor";
import { activateCopyFiles } from "./providers/copyfiles";
import { activateZotero } from "./providers/zotero/zotero";
import { extensionHost } from "./host";
import { isInlineOutputEnabled } from "./host/hooks";
import { isInlineOutputEnabled } from "./host/positron";
import { initQuartoContext, getSourceDescription } from "quarto-core";
import { configuredQuartoPath } from "./core/quarto";
import { activateDenoConfig } from "./providers/deno-config";
Expand Down
Loading
Loading