Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

feat: add support for tasks and test code lens #436

Merged
merged 4 commits into from
Jun 7, 2021
Merged
Show file tree
Hide file tree
Changes from 3 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
9 changes: 8 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,7 +12,7 @@
This extension adds support for using [Deno](https://deno.land/) with Visual
Studio Code, powered by the Deno language server.

> ⚠️ **Important:** You need to have a version of Deno CLI installed (v1.7 or
> ⚠️ **Important:** You need to have a version of Deno CLI installed (v1.10.3 or
> later). The extension requires the executable and by default will use the
> environment path. You can explicitly set the path to the executable in Visual
> Studio Code Settings for `deno.path`.
Expand All @@ -36,6 +36,8 @@ Studio Code, powered by the Deno language server.
used with the Deno CLI.
- [Auto completion for imports](./docs/ImportCompletions.md).
- [Workspace folder configuration](./docs/workspaceFolders.md).
- [Testing Code Lens](./docs/testing.md).
- [Provides Tasks for the Deno CLI](./docs/tasks.md).

## Usage

Expand Down Expand Up @@ -107,6 +109,11 @@ extension has the following configuration options:
- `deno.codeLens.referencesAllFunctions`: Enables or disables the display of
code lens information for all functions in the code. Requires
`deno.codeLens.references` to be enabled as well. _boolean, default `false`_
- `deno.codeLens.test`: Enables or disables the display of test code lens on
Deno tests. _boolean, default `true`_.
- `deno.codeLens.testArgs`: Provides additional arguments that should be set
when invoking the Deno CLI test from a code lens. _array of strings, default
`[ "--allow-all" ]`_.
- `deno.config`: The file path to a `tsconfig.json` file. This is the equivalent
to using `--config` on the command line. The path can be either be relative to
the workspace, or an absolute path. _string, default `null`, examples:
Expand Down
97 changes: 68 additions & 29 deletions client/src/commands.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,21 +10,16 @@ import {
LANGUAGE_CLIENT_NAME,
} from "./constants";
import { pickInitWorkspace } from "./initialize_project";
import type { DenoExtensionContext } from "./interfaces";
import {
cache as cacheReq,
reloadImportRegistries as reloadImportRegistriesReq,
} from "./lsp_extensions";
import * as tasks from "./tasks";
import type { DenoExtensionContext } from "./types";
import { WelcomePanel } from "./welcome";
import { assert } from "./util";

import {
commands,
ExtensionContext,
ProgressLocation,
Uri,
window,
workspace,
} from "vscode";
import * as vscode from "vscode";
import { LanguageClient } from "vscode-languageclient/node";
import type {
DocumentUri,
Expand All @@ -35,23 +30,23 @@ import type {
// deno-lint-ignore no-explicit-any
export type Callback = (...args: any[]) => unknown;
export type Factory = (
context: ExtensionContext,
context: vscode.ExtensionContext,
extensionContext: DenoExtensionContext,
) => Callback;

/** For the current document active in the editor tell the Deno LSP to cache
* the file and all of its dependencies in the local cache. */
export function cache(
_context: ExtensionContext,
_context: vscode.ExtensionContext,
extensionContext: DenoExtensionContext,
): Callback {
return (uris: DocumentUri[] = []) => {
const activeEditor = window.activeTextEditor;
const activeEditor = vscode.window.activeTextEditor;
if (!activeEditor) {
return;
}
return window.withProgress({
location: ProgressLocation.Window,
return vscode.window.withProgress({
location: vscode.ProgressLocation.Window,
title: "caching",
}, () => {
return extensionContext.client.sendRequest(
Expand All @@ -68,43 +63,43 @@ export function cache(
}

export function initializeWorkspace(
_context: ExtensionContext,
_context: vscode.ExtensionContext,
_extensionContext: DenoExtensionContext,
): Callback {
return async () => {
try {
const settings = await pickInitWorkspace();
const config = workspace.getConfiguration(EXTENSION_NS);
const config = vscode.workspace.getConfiguration(EXTENSION_NS);
await config.update("enable", true);
await config.update("lint", settings.lint);
await config.update("unstable", settings.unstable);
await window.showInformationMessage(
await vscode.window.showInformationMessage(
"Deno is now setup in this workspace.",
);
} catch {
window.showErrorMessage("Deno project initialization failed.");
vscode.window.showErrorMessage("Deno project initialization failed.");
}
};
}

export function reloadImportRegistries(
_context: ExtensionContext,
_context: vscode.ExtensionContext,
{ client }: DenoExtensionContext,
): Callback {
return () => client.sendRequest(reloadImportRegistriesReq);
}

/** Start (or restart) the Deno Language Server */
export function startLanguageServer(
context: ExtensionContext,
context: vscode.ExtensionContext,
extensionContext: DenoExtensionContext,
): Callback {
return async () => {
const { statusBarItem } = extensionContext;
if (extensionContext.client) {
await extensionContext.client.stop();
statusBarItem.hide();
commands.executeCommand("setContext", ENABLEMENT_FLAG, false);
vscode.commands.executeCommand("setContext", ENABLEMENT_FLAG, false);
}
const client = extensionContext.client = new LanguageClient(
LANGUAGE_CLIENT_ID,
Expand All @@ -114,7 +109,7 @@ export function startLanguageServer(
);
context.subscriptions.push(client.start());
await client.onReady();
commands.executeCommand("setContext", ENABLEMENT_FLAG, true);
vscode.commands.executeCommand("setContext", ENABLEMENT_FLAG, true);
const serverVersion = extensionContext.serverVersion =
(client.initializeResult?.serverInfo?.version ?? "")
.split(
Expand All @@ -128,13 +123,13 @@ export function startLanguageServer(
}

export function showReferences(
_content: ExtensionContext,
_content: vscode.ExtensionContext,
extensionContext: DenoExtensionContext,
): Callback {
return (uri: string, position: Position, locations: Location[]) => {
commands.executeCommand(
vscode.commands.executeCommand(
"editor.action.showReferences",
Uri.parse(uri),
vscode.Uri.parse(uri),
extensionContext.client.protocol2CodeConverter.asPosition(position),
locations.map(extensionContext.client.protocol2CodeConverter.asLocation),
);
Expand All @@ -144,17 +139,61 @@ export function showReferences(
/** Open and display the "virtual document" which provides the status of the
* Deno Language Server. */
export function status(
_context: ExtensionContext,
_context: vscode.ExtensionContext,
_extensionContext: DenoExtensionContext,
): Callback {
return () => {
const uri = Uri.parse("deno:/status.md");
return commands.executeCommand("markdown.showPreviewToSide", uri);
const uri = vscode.Uri.parse("deno:/status.md");
return vscode.commands.executeCommand("markdown.showPreviewToSide", uri);
};
}

export function test(
_context: vscode.ExtensionContext,
_extensionContext: DenoExtensionContext,
): Callback {
return async (uriStr: string, name: string) => {
const uri = vscode.Uri.parse(uriStr, true);
const path = uri.fsPath;
const config = vscode.workspace.getConfiguration(EXTENSION_NS, uri);
const testArgs: string[] = [
...(config.get<string[]>("codeLens.testArgs") ?? []),
];
if (config.get("unstable")) {
testArgs.push("--unstable");
}
const args = ["test", ...testArgs, "--filter", name, path];

const definition: tasks.DenoTaskDefinition = {
type: tasks.TASK_TYPE,
command: "test",
args,
cwd: ".",
};

assert(vscode.workspace.workspaceFolders);
const target = vscode.workspace.workspaceFolders[0];
const task = await tasks.buildDenoTask(
target,
definition,
`test "${name}"`,
args,
["$deno-test"],
);

task.presentationOptions = {
reveal: vscode.TaskRevealKind.Always,
panel: vscode.TaskPanelKind.Dedicated,
clear: true,
};
task.group = vscode.TaskGroup.Test;

return vscode.tasks.executeTask(task);
};
}

export function welcome(
context: ExtensionContext,
context: vscode.ExtensionContext,
_extensionContext: DenoExtensionContext,
): Callback {
return () => {
Expand Down
2 changes: 1 addition & 1 deletion client/src/content_provider.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.

import type { DenoExtensionContext } from "./interfaces";
import { virtualTextDocument } from "./lsp_extensions";
import type { DenoExtensionContext } from "./types";

import type {
CancellationToken,
Expand Down
4 changes: 3 additions & 1 deletion client/src/debug_config_provider.ts
Original file line number Diff line number Diff line change
@@ -1,5 +1,7 @@
// Copyright 2018-2021 the Deno authors. All rights reserved. MIT license.

import type { Settings } from "./types";
import * as vscode from "vscode";
import type { Settings } from "./interfaces";

export class DenoDebugConfigurationProvider
implements vscode.DebugConfigurationProvider {
Expand Down
Loading