Files
languageservices/actions-languageserver/src/index.ts
T

127 lines
3.9 KiB
TypeScript
Raw Normal View History

2022-11-08 17:00:59 -08:00
import {
CompletionItem,
createConnection,
Hover,
HoverParams,
InitializeParams,
InitializeResult,
ProposedFeatures,
TextDocumentPositionParams,
TextDocuments,
2022-11-29 17:41:48 -05:00
TextDocumentSyncKind
2022-11-08 17:00:59 -08:00
} from "vscode-languageserver/node";
2022-11-29 17:41:48 -05:00
import {hover, validate} from "@github/actions-languageservice";
import {TextDocument} from "vscode-languageserver-textdocument";
2022-11-29 17:17:04 -08:00
import {contextProviders} from "./context-providers";
2022-11-29 17:41:48 -05:00
import {InitializationOptions, RepositoryContext} from "./initializationOptions";
import {onCompletion} from "./on-completion";
import {TTLCache} from "./utils/cache";
import {valueProviders} from "./value-providers";
2022-11-08 17:00:59 -08:00
// Create a connection for the server, using Node's IPC as a transport.
// Also include all preview / proposed LSP features.
const connection = createConnection(ProposedFeatures.all);
// Create a simple text document manager.
const documents: TextDocuments<TextDocument> = new TextDocuments(TextDocument);
let sessionToken: string | undefined;
let repos: RepositoryContext[] = [];
const cache = new TTLCache();
2022-11-08 17:00:59 -08:00
let hasConfigurationCapability = false;
let hasWorkspaceFolderCapability = false;
let hasDiagnosticRelatedInformationCapability = false;
connection.onInitialize((params: InitializeParams) => {
const capabilities = params.capabilities;
2022-11-29 17:41:48 -05:00
hasWorkspaceFolderCapability = !!(capabilities.workspace && !!capabilities.workspace.workspaceFolders);
2022-11-08 17:00:59 -08:00
hasDiagnosticRelatedInformationCapability = !!(
capabilities.textDocument &&
capabilities.textDocument.publishDiagnostics &&
capabilities.textDocument.publishDiagnostics.relatedInformation
);
const options: InitializationOptions = params.initializationOptions;
sessionToken = options.sessionToken;
if (options.repos) {
repos = options.repos;
}
const result: InitializeResult = {
capabilities: {
2022-11-15 16:24:10 -08:00
textDocumentSync: TextDocumentSyncKind.Full,
2022-11-08 17:00:59 -08:00
completionProvider: {
resolveProvider: false,
2022-11-29 17:41:48 -05:00
triggerCharacters: [":", "."]
2022-11-08 17:00:59 -08:00
},
2022-11-29 17:41:48 -05:00
hoverProvider: true
}
2022-11-08 17:00:59 -08:00
};
2022-11-15 16:24:10 -08:00
2022-11-08 17:00:59 -08:00
if (hasWorkspaceFolderCapability) {
result.capabilities.workspace = {
workspaceFolders: {
2022-11-29 17:41:48 -05:00
supported: true
}
2022-11-08 17:00:59 -08:00
};
}
2022-11-15 16:24:10 -08:00
2022-11-08 17:00:59 -08:00
return result;
});
connection.onInitialized(() => {
if (hasWorkspaceFolderCapability) {
2022-11-29 17:41:48 -05:00
connection.workspace.onDidChangeWorkspaceFolders(_event => {
2022-11-08 17:00:59 -08:00
connection.console.log("Workspace folder change event received.");
});
}
});
// The content of a text document has changed. This event is emitted
// when the text document first opened or when its content has changed.
2022-11-29 17:41:48 -05:00
documents.onDidChangeContent(change => {
2022-11-08 17:00:59 -08:00
validateTextDocument(change.document);
});
async function validateTextDocument(textDocument: TextDocument): Promise<void> {
2022-11-29 17:17:04 -08:00
const repoContext = repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri));
2022-11-28 15:47:05 -08:00
const result = await validate(
textDocument,
2022-11-29 17:17:04 -08:00
valueProviders(sessionToken, repoContext, cache),
contextProviders(sessionToken, repoContext, cache)
2022-11-28 15:47:05 -08:00
);
2022-11-08 17:00:59 -08:00
2022-11-29 17:41:48 -05:00
connection.sendDiagnostics({uri: textDocument.uri, diagnostics: result});
2022-11-08 17:00:59 -08:00
}
2022-11-29 17:41:48 -05:00
connection.onDidChangeWatchedFiles(_change => {
2022-11-08 17:00:59 -08:00
// Monitored files have change in VSCode
connection.console.log("We received an file change event");
});
// This handler provides the initial list of the completion items.
2022-11-29 17:41:48 -05:00
connection.onCompletion(async ({position, textDocument}: TextDocumentPositionParams): Promise<CompletionItem[]> => {
return await onCompletion(
2022-11-08 17:00:59 -08:00
position,
2022-11-29 17:41:48 -05:00
documents.get(textDocument.uri)!,
sessionToken,
repos.find(repo => textDocument.uri.startsWith(repo.workspaceUri)),
cache
);
});
2022-11-08 17:00:59 -08:00
2022-11-29 17:41:48 -05:00
connection.onHover(async ({position, textDocument}: HoverParams): Promise<Hover | null> => {
const r = await hover(documents.get(textDocument.uri)!, position);
return r;
});
2022-11-08 17:00:59 -08:00
// Make the text document manager listen on the connection
// for open, change and close text document events
documents.listen(connection);
// Listen on the connection
connection.listen();