2022-11-08 17:00:59 -08:00
|
|
|
import {
|
|
|
|
|
CompletionItem,
|
|
|
|
|
createConnection,
|
|
|
|
|
Hover,
|
|
|
|
|
HoverParams,
|
|
|
|
|
InitializeParams,
|
|
|
|
|
InitializeResult,
|
|
|
|
|
ProposedFeatures,
|
|
|
|
|
TextDocumentPositionParams,
|
|
|
|
|
TextDocuments,
|
|
|
|
|
TextDocumentSyncKind,
|
|
|
|
|
} from "vscode-languageserver/node";
|
|
|
|
|
|
|
|
|
|
import { hover, validate } from "@github/actions-languageservice";
|
|
|
|
|
import { TextDocument } from "vscode-languageserver-textdocument";
|
|
|
|
|
import {
|
|
|
|
|
InitializationOptions,
|
|
|
|
|
RepositoryContext,
|
|
|
|
|
} from "./initializationOptions";
|
|
|
|
|
import { onCompletion } from "./on-completion";
|
2022-11-28 16:35:23 -05:00
|
|
|
import { TTLCache } from "./utils/cache";
|
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[] = [];
|
2022-11-28 16:35:23 -05:00
|
|
|
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;
|
|
|
|
|
|
|
|
|
|
hasWorkspaceFolderCapability = !!(
|
|
|
|
|
capabilities.workspace && !!capabilities.workspace.workspaceFolders
|
|
|
|
|
);
|
|
|
|
|
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-15 16:24:10 -08:00
|
|
|
triggerCharacters: [":", "."],
|
2022-11-08 17:00:59 -08:00
|
|
|
},
|
|
|
|
|
hoverProvider: true,
|
|
|
|
|
},
|
|
|
|
|
};
|
2022-11-15 16:24:10 -08:00
|
|
|
|
2022-11-08 17:00:59 -08:00
|
|
|
if (hasWorkspaceFolderCapability) {
|
|
|
|
|
result.capabilities.workspace = {
|
|
|
|
|
workspaceFolders: {
|
|
|
|
|
supported: true,
|
|
|
|
|
},
|
|
|
|
|
};
|
|
|
|
|
}
|
2022-11-15 16:24:10 -08:00
|
|
|
|
2022-11-08 17:00:59 -08:00
|
|
|
return result;
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
connection.onInitialized(() => {
|
|
|
|
|
if (hasWorkspaceFolderCapability) {
|
|
|
|
|
connection.workspace.onDidChangeWorkspaceFolders((_event) => {
|
|
|
|
|
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.
|
|
|
|
|
documents.onDidChangeContent((change) => {
|
|
|
|
|
validateTextDocument(change.document);
|
|
|
|
|
});
|
|
|
|
|
|
|
|
|
|
async function validateTextDocument(textDocument: TextDocument): Promise<void> {
|
|
|
|
|
const result = await validate(textDocument);
|
|
|
|
|
|
|
|
|
|
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: result });
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
connection.onDidChangeWatchedFiles((_change) => {
|
|
|
|
|
// 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.
|
|
|
|
|
connection.onCompletion(
|
|
|
|
|
async ({
|
|
|
|
|
position,
|
|
|
|
|
textDocument,
|
|
|
|
|
}: TextDocumentPositionParams): Promise<CompletionItem[]> => {
|
|
|
|
|
return await onCompletion(
|
|
|
|
|
position,
|
|
|
|
|
documents.get(textDocument.uri)!,
|
|
|
|
|
sessionToken,
|
2022-11-28 16:35:23 -05:00
|
|
|
repos.find((repo) => textDocument.uri.startsWith(repo.workspaceUri)),
|
|
|
|
|
cache,
|
2022-11-08 17:00:59 -08:00
|
|
|
);
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
connection.onHover(
|
|
|
|
|
async ({ position, textDocument }: HoverParams): Promise<Hover | null> => {
|
|
|
|
|
const r = await hover(documents.get(textDocument.uri)!, position);
|
|
|
|
|
return r;
|
|
|
|
|
}
|
|
|
|
|
);
|
|
|
|
|
|
|
|
|
|
// 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();
|