Skip to content

Commit

Permalink
add input auto completion
Browse files Browse the repository at this point in the history
  • Loading branch information
Cammisuli committed Sep 14, 2022
1 parent 980fb9e commit 9b62926
Show file tree
Hide file tree
Showing 14 changed files with 157 additions and 19 deletions.
11 changes: 6 additions & 5 deletions apps/nxls/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -23,14 +23,15 @@ import {
createConnection,
InitializeResult,
ProposedFeatures,
RequestType,
ResponseError,
TextDocuments,
TextDocumentSyncKind,
} from 'vscode-languageserver/node';
import { URI, Utils } from 'vscode-uri';
import {
NxWorkspace,
NxWorkspaceRefresh,
NxWorkspaceRequest,
NxWorkspaceRefreshNotification,
} from '@nx-console/language-server/types';

let WORKING_PATH: string | undefined = undefined;
Expand Down Expand Up @@ -192,17 +193,17 @@ connection.onShutdown(() => {
jsonDocumentMapper.dispose();
});

connection.onRequest(NxWorkspace.type, async () => {
connection.onRequest(NxWorkspaceRequest, async () => {
if (!WORKING_PATH) {
return new ResponseError(1000, 'Unable to get Nx info: no workspace path');
}

const workspace = await nxWorkspace(WORKING_PATH, lspLogger);

return workspace.workspace.projects;
return workspace.workspace;
});

connection.onNotification(NxWorkspaceRefresh.type, async () => {
connection.onNotification(NxWorkspaceRefreshNotification, async () => {
if (!WORKING_PATH) {
return new ResponseError(1000, 'Unable to get Nx info: no workspace path');
}
Expand Down
4 changes: 2 additions & 2 deletions apps/vscode/src/commands/refresh-workspace.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { NxWorkspaceRefresh } from '@nx-console/language-server/types';
import { NxWorkspaceRefreshNotification } from '@nx-console/language-server/types';
import { sendNotification } from '@nx-console/vscode/lsp-client';
import { getWorkspacePath, outputLogger } from '@nx-console/vscode/utils';
import { debounceTime, Subject } from 'rxjs';
Expand All @@ -11,7 +11,7 @@ const refresh = new Subject();
refresh.pipe(debounceTime(150)).subscribe(async () => {
const { nxWorkspace } = await import('@nx-console/workspace');
await nxWorkspace(getWorkspacePath(), outputLogger, true);
sendNotification(NxWorkspaceRefresh.type);
sendNotification(NxWorkspaceRefreshNotification);
commands.executeCommand('nxConsole.refreshNxProjectsTree');
commands.executeCommand('nxConsole.refreshRunTargetTree');
commands.executeCommand('nx.graph.refresh');
Expand Down
5 changes: 3 additions & 2 deletions libs/json-schema/src/lib/common-json-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,12 +18,13 @@ export const outputs: JSONSchema = {
};

export const inputs: JSONSchema[] = [
{ type: 'string' },
{ type: 'string', 'x-completion-type': CompletionType.inputNameWithDeps },
{
type: 'object',
properties: {
input: {
type: 'string',
'x-completion-type': CompletionType.inputName,
},
projects: {
type: 'string',
Expand Down Expand Up @@ -88,7 +89,7 @@ export const targets = (executors?: JSONSchema[]): JSONSchema => {
oneOf: [
{
type: 'string',
'x-completion-type': CompletionType.targets,
'x-completion-type': CompletionType.targetsWithDeps,
},
{
type: 'object',
Expand Down
3 changes: 3 additions & 0 deletions libs/json-schema/src/lib/completion-type.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,10 @@ export enum CompletionType {
projectTarget = 'projectTarget',
project = 'project',
targets = 'targets',
targetsWithDeps = 'targetsWithDeps',
tags = 'tags',
inputName = 'inputName',
inputNameWithDeps = 'inputNameWithDeps',
}

export function hasCompletionType(
Expand Down
3 changes: 3 additions & 0 deletions libs/json-schema/src/lib/package-json-schema.ts
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,9 @@ function createJsonSchema(): EnhancedJsonSchema {
nx: {
type: 'object',
properties: {
ignore: {
type: 'boolean',
},
namedInputs,
tags,
implicitDependencies,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,13 +10,15 @@ export function createCompletionItem(
path: string,
node: ASTNode,
document: TextDocument,
kind: CompletionItemKind
kind: CompletionItemKind,
documentation?: string
): CompletionItem {
const startPosition = document.positionAt(node.offset);
const endPosition = document.positionAt(node.offset + node.length);
label = `"${label}"`;
return {
label,
documentation,
kind,
insertText: label,
insertTextFormat: 2,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,12 @@ import {
Position,
TextDocument,
} from 'vscode-json-languageservice';
import { inputNameCompletion } from './input-name-completion';
import { pathCompletion } from './path-completion';
import { projectCompletion } from './project-completion';
import { projectTargetCompletion } from './project-target-completion';
import { tagsCompletion } from './tags-completion';
import { targetsCompletion } from './targets-completion';

export async function getCompletionItems(
workingPath: string | undefined,
Expand Down Expand Up @@ -93,6 +95,18 @@ function completionItems(
case CompletionType.tags: {
return tagsCompletion(workingPath, node, document);
}
case CompletionType.targets: {
return targetsCompletion(workingPath, node, document);
}
case CompletionType.targetsWithDeps: {
return targetsCompletion(workingPath, node, document, true);
}
case CompletionType.inputName: {
return inputNameCompletion(workingPath, node, document);
}
case CompletionType.inputNameWithDeps: {
return inputNameCompletion(workingPath, node, document, true);
}
default: {
return [];
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
import { nxWorkspace } from '@nx-console/workspace';
import {
ASTNode,
CompletionItem,
CompletionItemKind,
TextDocument,
} from 'vscode-json-languageservice';
import { createCompletionItem } from './create-completion-path-item';

export async function inputNameCompletion(
workingPath: string | undefined,
node: ASTNode,
document: TextDocument,
hasDependencyHat = false
): Promise<CompletionItem[]> {
if (!workingPath) {
return [];
}

const inputNameCompletion: CompletionItem[] = [];

const { workspace } = await nxWorkspace(workingPath);

for (const inputName of Object.keys(workspace.namedInputs ?? {})) {
if (hasDependencyHat) {
inputNameCompletion.push(
createCompletionItem(
`^${inputName}`,
'',
node,
document,
CompletionItemKind.Property,
`Base "${inputName}" on this project's dependencies`
)
);
}
inputNameCompletion.push(
createCompletionItem(
inputName,
'',
node,
document,
CompletionItemKind.Property
)
);
}

return inputNameCompletion;
}
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,8 @@ export async function projectCompletion(
'',
node,
document,
CompletionItemKind.Struct
CompletionItemKind.Struct,
`Exclude "${projectName}" from this project's dependencies`
)
);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { isArrayNode, lspLogger } from '@nx-console/language-server/utils';
import { isArrayNode } from '@nx-console/language-server/utils';
import { nxWorkspace } from '@nx-console/workspace';
import {
ASTNode,
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
import { nxWorkspace } from '@nx-console/workspace';
import {
ASTNode,
CompletionItem,
CompletionItemKind,
TextDocument,
} from 'vscode-json-languageservice';
import { createCompletionItem } from './create-completion-path-item';

export async function targetsCompletion(
workingPath: string | undefined,
node: ASTNode,
document: TextDocument,
hasDependencyHat = false
): Promise<CompletionItem[]> {
if (!workingPath) {
return [];
}

const targetsCompletion: CompletionItem[] = [];
const { workspace } = await nxWorkspace(workingPath);

const targetNames = new Set<string>();
for (const project of Object.values(workspace.projects)) {
for (const targetName of Object.keys(project.targets ?? {})) {
targetNames.add(targetName);
}
}

for (const targetName of targetNames) {
if (hasDependencyHat) {
targetsCompletion.push(
createCompletionItem(
`^${targetName}`,
'',
node,
document,
CompletionItemKind.Field,
`Run all dependencies that have "${targetName}" as a target before this one`
)
);
}
targetsCompletion.push(
createCompletionItem(
targetName,
'',
node,
document,
CompletionItemKind.Field,
`Run the "${targetName}" target before this one`
)
);
}

return targetsCompletion;
}
16 changes: 10 additions & 6 deletions libs/language-server/types/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,7 +1,11 @@
export class NxWorkspaceRefresh {
static type: 'nx/refreshWorkspace';
}
import { RequestType, NotificationType } from 'vscode-languageserver/node';
import type { NxWorkspaceConfiguration } from '@nx-console/workspace';

export class NxWorkspace {
static type: 'nx/workspace';
}
export const NxWorkspaceRefreshNotification: NotificationType<void> =
new NotificationType('nx/refreshWorkspace');

export const NxWorkspaceRequest: RequestType<
void,
NxWorkspaceConfiguration,
unknown
> = new RequestType('nx/workspace');
5 changes: 4 additions & 1 deletion libs/vscode/lsp-client/src/lib/configure-lsp-client.ts
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,9 @@ import { Disposable, ExtensionContext } from 'vscode';
import {
LanguageClient,
LanguageClientOptions,
NotificationType,
ProtocolNotificationType,
RequestType,
ServerOptions,
TransportKind,
} from 'vscode-languageclient/node';
Expand Down Expand Up @@ -68,6 +71,6 @@ export async function configureLspClient(
};
}

export function sendNotification(notificationType: string) {
export function sendNotification<P>(notificationType: NotificationType<P>) {
client.sendNotification(notificationType);
}
1 change: 1 addition & 0 deletions libs/workspace/src/index.ts
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
export * from './lib/workspace';
export * from './lib/find-project-with-path';
export type { NxWorkspaceConfiguration } from './lib/get-nx-workspace-config';

0 comments on commit 9b62926

Please sign in to comment.