Skip to content
Merged
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
15 changes: 3 additions & 12 deletions src/client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@ import {
TestItem,
TestMessage,
TestController,
OutputChannel,
CancellationToken,
TestRunRequest,
} from 'vscode';
Expand Down Expand Up @@ -101,19 +100,14 @@ function getLspCommand(uri: Uri) {
}

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

constructor(uri: Uri, workspaceFolder?: WorkspaceFolder) {
const outputChannel = window.createOutputChannel(extensionName, languageId);

constructor(uri: Uri, workspaceFolder?: WorkspaceFolder, file?: string) {
const [command, args] = getLspCommand(uri);

const documentSelector: TextDocumentFilter[] = [];
Expand All @@ -139,23 +133,20 @@ export default class Client extends LanguageClient {
const clientOptions: LanguageClientOptions = {
documentSelector,
workspaceFolder,
outputChannel,
initializationOptions: {
enableCodeLens,
},
outputChannelName: file ? `${extensionName} (${file})` : `${extensionName}`,
traceOutputChannel: file ? null : window.createOutputChannel(`${extensionName} Trace`),
};

const serverOptions: ServerOptions = {
command,
args,
};

super(languageId, extensionName, serverOptions, clientOptions);

this.#uri = uri;
this.#command = command;
this.#args = args;
this.#output = outputChannel;

// TODO: Figure out how to do type-safe onNotification
this.onNotification('nargo/tests/update', (testData: NargoTests) => {
Expand Down
55 changes: 50 additions & 5 deletions src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -240,7 +240,7 @@ async function addFileClient(uri: Uri) {
const file = uri.toString();
if (!lspClients.has(file)) {
// Start the client. This will also launch the server
const client = new Client(uri);
const client = new Client(uri, undefined, file);
lspClients.set(file, client);
await client.start();
}
Expand Down Expand Up @@ -290,8 +290,13 @@ async function runNargoExpand() {
if (!editor) return 'Not available';

const document = editor.document;
const workspaceFolder = workspace.getWorkspaceFolder(document.uri).uri.toString();
const client = lspClients.get(workspaceFolder);
const workspaceFolder = workspace.getWorkspaceFolder(document.uri);
let client: Client;
if (workspaceFolder) {
client = lspClients.get(workspaceFolder.uri.toString());
} else {
client = lspClients.get(document.uri.toString());
}
if (!client) return 'Not available';

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

// Each file outside of a workspace gets it's own client
await addFileClient(uri);

if (uri.scheme === 'noir-std') {
return Disposable.from();
}

registerFileCommands(uri);

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

async function didCloseTextDocument(document: TextDocument): Promise<Disposable> {
// We are only interested in language mode text
if (document.languageId !== languageId) {
return Disposable.from();
}

const uri = document.uri;
if (uri.scheme === 'noir-std') {
await removeFileClient(uri);
}
}

async function didChangeWorkspaceFolders(event: WorkspaceFoldersChangeEvent) {
// Reset the workspace folders so it'll sort them again
workspaceFolders = [];
Expand All @@ -415,12 +437,21 @@ async function didChangeWorkspaceFolders(event: WorkspaceFoldersChangeEvent) {
}

export async function activate(context: ExtensionContext): Promise<void> {
registerNoirStdContentProvider();

const didOpenTextDocument$ = workspace.onDidOpenTextDocument(didOpenTextDocument);
const didCloseTextDocument$ = workspace.onDidCloseTextDocument(didCloseTextDocument);
const didChangeWorkspaceFolders$ = workspace.onDidChangeWorkspaceFolders(didChangeWorkspaceFolders);
const restart$ = commands.registerCommand('noir.restart', restartAllClients);
const expand$ = commands.registerCommand('nargo.expand', runNargoExpand);

context.subscriptions.push(didOpenTextDocument$, didChangeWorkspaceFolders$, restart$, expand$);
context.subscriptions.push(
didOpenTextDocument$,
didCloseTextDocument$,
didChangeWorkspaceFolders$,
restart$,
expand$,
);

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

await commands.executeCommand('setContext', NOIR_PROJECT_CONTEXT_NAME, undefined);
}

function registerNoirStdContentProvider() {
const noir_std_provider = new (class implements TextDocumentContentProvider {
async provideTextDocumentContent(uri: Uri): Promise<string> {
if (lspClients.size == 0) {
return 'Not available';
}
// Any client can answer this request
const client: Client = lspClients.values().next().value;
return await client.sendRequest<string>('nargo/std-source-code', { uri: uri.toString() });
}
})();
workspace.registerTextDocumentContentProvider('noir-std', noir_std_provider);
}