Skip to content

Commit

Permalink
feat: add support for tasks and test code lens (#436)
Browse files Browse the repository at this point in the history
  • Loading branch information
kitsonk committed Jun 7, 2021
1 parent bb5f058 commit 007b5f3
Show file tree
Hide file tree
Showing 15 changed files with 525 additions and 131 deletions.
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

0 comments on commit 007b5f3

Please sign in to comment.