Press n or j to go to the next uncovered block, b, p or k for the previous block.
| 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 | 10x 120x 10x 10x 10x 10x 10x 8x 1x 7x 3x 3x 3x 3x 3x 3x 1x 2x 2x 1x 1x 1x 1x 1x 3x 3x 3x 3x 3x | import * as vscode from 'vscode';
import { IPrefixLookupService } from '@src/services/document';
import { Store } from '@faubulous/mentor-rdf';
import { InferenceUri } from '@src/providers/inference-uri';
import { IViewRouter } from '@src/views/webviews';
import { SETTINGS_GROUPS, SettingsSectionId } from '@src/views/webviews/views/settings/sections';
/**
* Single URI handler for the extension. VS Code allows only one handler per
* extension, so all `vscode://faubulous.mentor/…` deep links are dispatched here
* by path:
*
* - `/inference?uri=<graph>` — opens the inferred-triples graph in a Turtle editor.
* - `/settings[?section=<id>]` — opens the settings panel, optionally on a section
* (e.g. `?section=query.connections`). Intended for linking from external docs.
*/
export class MentorUriHandler implements vscode.UriHandler {
readonly extensionId: string;
/** Valid settings section ids, derived from the single source of truth. */
private static readonly _sectionIds = new Set<SettingsSectionId>(
SETTINGS_GROUPS.flatMap(g => g.sections.map(s => s.id))
);
constructor(
context: vscode.ExtensionContext,
private readonly _store: Store,
private readonly _prefixLookup: IPrefixLookupService,
private readonly _router: IViewRouter
) {
// Self-register with the extension context for automatic disposal
this.extensionId = context.extension.id;
context.subscriptions.push(
vscode.window.registerUriHandler(this)
);
}
async handleUri(uri: vscode.Uri) {
if (uri.authority !== this.extensionId) {
return;
}
switch (uri.path) {
case '/inference':
return this.handleInference(uri);
case '/settings':
return this.handleSettings(uri);
}
}
private async handleInference(uri: vscode.Uri) {
try {
// Parse the query parameter directly
const query = new URLSearchParams(uri.query);
const targetUri = query.get('uri');
if (!targetUri) {
throw new Error('No URI provided in inference request');
}
// Decode the URI parameter
const inferenceUri = InferenceUri.toInferenceUri(targetUri);
if (this._store.hasGraph(inferenceUri)) {
const namespaces = this._prefixLookup.getInferencePrefixes();
const content = await this._store.serializeGraph(inferenceUri, 'text/turtle', undefined, namespaces);
const document = await vscode.workspace.openTextDocument({ content, language: 'turtle' });
await vscode.window.showTextDocument(document);
}
} catch (error) {
vscode.window.showErrorMessage(`Failed to load inference graph: ${error}`);
}
}
private async handleSettings(uri: vscode.Uri) {
try {
const requested = new URLSearchParams(uri.query).get('section');
const section = requested && MentorUriHandler._sectionIds.has(requested as SettingsSectionId)
? requested as SettingsSectionId
: undefined;
const router = this._router;
await router.open({ kind: 'settings', section }, vscode.ViewColumn.Active);
} catch (error) {
vscode.window.showErrorMessage(`Failed to open settings: ${error}`);
}
}
}
|