Skip to content

Commit e0a6481

Browse files
authored
feat: allow opening noir stdlib files (#108)
1 parent 3c2b82e commit e0a6481

File tree

2 files changed

+53
-17
lines changed

2 files changed

+53
-17
lines changed

src/client.ts

Lines changed: 3 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import {
99
TestItem,
1010
TestMessage,
1111
TestController,
12-
OutputChannel,
1312
CancellationToken,
1413
TestRunRequest,
1514
} from 'vscode';
@@ -101,19 +100,14 @@ function getLspCommand(uri: Uri) {
101100
}
102101

103102
export default class Client extends LanguageClient {
104-
#uri: Uri;
105103
#command: string;
106-
#args: string[];
107-
#output: OutputChannel;
108104
profileRunResult: NargoProfileRunResult;
109105
// This function wasn't added until vscode 1.81.0 so fake the type
110106
#testController: TestController & {
111107
invalidateTestResults?: (item: TestItem) => void;
112108
};
113109

114-
constructor(uri: Uri, workspaceFolder?: WorkspaceFolder) {
115-
const outputChannel = window.createOutputChannel(extensionName, languageId);
116-
110+
constructor(uri: Uri, workspaceFolder?: WorkspaceFolder, file?: string) {
117111
const [command, args] = getLspCommand(uri);
118112

119113
const documentSelector: TextDocumentFilter[] = [];
@@ -139,23 +133,20 @@ export default class Client extends LanguageClient {
139133
const clientOptions: LanguageClientOptions = {
140134
documentSelector,
141135
workspaceFolder,
142-
outputChannel,
143136
initializationOptions: {
144137
enableCodeLens,
145138
},
139+
outputChannelName: file ? `${extensionName} (${file})` : `${extensionName}`,
140+
traceOutputChannel: file ? null : window.createOutputChannel(`${extensionName} Trace`),
146141
};
147-
148142
const serverOptions: ServerOptions = {
149143
command,
150144
args,
151145
};
152146

153147
super(languageId, extensionName, serverOptions, clientOptions);
154148

155-
this.#uri = uri;
156149
this.#command = command;
157-
this.#args = args;
158-
this.#output = outputChannel;
159150

160151
// TODO: Figure out how to do type-safe onNotification
161152
this.onNotification('nargo/tests/update', (testData: NargoTests) => {

src/extension.ts

Lines changed: 50 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -240,7 +240,7 @@ async function addFileClient(uri: Uri) {
240240
const file = uri.toString();
241241
if (!lspClients.has(file)) {
242242
// Start the client. This will also launch the server
243-
const client = new Client(uri);
243+
const client = new Client(uri, undefined, file);
244244
lspClients.set(file, client);
245245
await client.start();
246246
}
@@ -290,8 +290,13 @@ async function runNargoExpand() {
290290
if (!editor) return 'Not available';
291291

292292
const document = editor.document;
293-
const workspaceFolder = workspace.getWorkspaceFolder(document.uri).uri.toString();
294-
const client = lspClients.get(workspaceFolder);
293+
const workspaceFolder = workspace.getWorkspaceFolder(document.uri);
294+
let client: Client;
295+
if (workspaceFolder) {
296+
client = lspClients.get(workspaceFolder.uri.toString());
297+
} else {
298+
client = lspClients.get(document.uri.toString());
299+
}
295300
if (!client) return 'Not available';
296301

297302
const position = editor.selection.active;
@@ -365,12 +370,17 @@ async function didOpenTextDocument(document: TextDocument): Promise<Disposable>
365370
} else {
366371
// We only want to handle `file:` and `untitled:` schemes because
367372
// vscode sends `output:` schemes for markdown responses from our LSP
368-
if (uri.scheme !== 'file' && uri.scheme !== 'untitled') {
373+
if (uri.scheme !== 'file' && uri.scheme !== 'untitled' && uri.scheme !== 'noir-std') {
369374
return Disposable.from();
370375
}
371376

372377
// Each file outside of a workspace gets it's own client
373378
await addFileClient(uri);
379+
380+
if (uri.scheme === 'noir-std') {
381+
return Disposable.from();
382+
}
383+
374384
registerFileCommands(uri);
375385

376386
configHandler = mutex(uri.toString(), async (e: ConfigurationChangeEvent) => {
@@ -401,6 +411,18 @@ async function didOpenTextDocument(document: TextDocument): Promise<Disposable>
401411
}
402412
}
403413

414+
async function didCloseTextDocument(document: TextDocument): Promise<Disposable> {
415+
// We are only interested in language mode text
416+
if (document.languageId !== languageId) {
417+
return Disposable.from();
418+
}
419+
420+
const uri = document.uri;
421+
if (uri.scheme === 'noir-std') {
422+
await removeFileClient(uri);
423+
}
424+
}
425+
404426
async function didChangeWorkspaceFolders(event: WorkspaceFoldersChangeEvent) {
405427
// Reset the workspace folders so it'll sort them again
406428
workspaceFolders = [];
@@ -415,12 +437,21 @@ async function didChangeWorkspaceFolders(event: WorkspaceFoldersChangeEvent) {
415437
}
416438

417439
export async function activate(context: ExtensionContext): Promise<void> {
440+
registerNoirStdContentProvider();
441+
418442
const didOpenTextDocument$ = workspace.onDidOpenTextDocument(didOpenTextDocument);
443+
const didCloseTextDocument$ = workspace.onDidCloseTextDocument(didCloseTextDocument);
419444
const didChangeWorkspaceFolders$ = workspace.onDidChangeWorkspaceFolders(didChangeWorkspaceFolders);
420445
const restart$ = commands.registerCommand('noir.restart', restartAllClients);
421446
const expand$ = commands.registerCommand('nargo.expand', runNargoExpand);
422447

423-
context.subscriptions.push(didOpenTextDocument$, didChangeWorkspaceFolders$, restart$, expand$);
448+
context.subscriptions.push(
449+
didOpenTextDocument$,
450+
didCloseTextDocument$,
451+
didChangeWorkspaceFolders$,
452+
restart$,
453+
expand$,
454+
);
424455

425456
for (const doc of workspace.textDocuments) {
426457
const disposable = await didOpenTextDocument(doc);
@@ -439,3 +470,17 @@ export async function deactivate(): Promise<void> {
439470

440471
await commands.executeCommand('setContext', NOIR_PROJECT_CONTEXT_NAME, undefined);
441472
}
473+
474+
function registerNoirStdContentProvider() {
475+
const noir_std_provider = new (class implements TextDocumentContentProvider {
476+
async provideTextDocumentContent(uri: Uri): Promise<string> {
477+
if (lspClients.size == 0) {
478+
return 'Not available';
479+
}
480+
// Any client can answer this request
481+
const client: Client = lspClients.values().next().value;
482+
return await client.sendRequest<string>('nargo/std-source-code', { uri: uri.toString() });
483+
}
484+
})();
485+
workspace.registerTextDocumentContentProvider('noir-std', noir_std_provider);
486+
}

0 commit comments

Comments
 (0)