diff --git a/src/extension.ts b/src/extension.ts index 838513d..e731cf5 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -3,14 +3,13 @@ import * as path from 'path'; import GDScriptClient from './gdscript/client'; import { workspace, Disposable, ExtensionContext } from 'vscode'; +import * as vscode from "vscode"; + import { LanguageClient } from 'vscode-languageclient'; -let gdscript_client = null; +let gdclient: GDScriptClient = null; export function activate(context: ExtensionContext) { - - gdscript_client = new GDScriptClient(context); - - // Create the language client and start the client. - let disposable = new LanguageClient('GDScriptLanguage', gdscript_client.server_options, gdscript_client.client_options).start(); + gdclient = new GDScriptClient(context); + let disposable = gdclient.createLanguageClient().start(); context.subscriptions.push(disposable); } diff --git a/src/gdscript/client.ts b/src/gdscript/client.ts index 28f27fa..1c130ec 100644 --- a/src/gdscript/client.ts +++ b/src/gdscript/client.ts @@ -1,37 +1,67 @@ import * as path from 'path'; -import * as LanguageClient from 'vscode-languageclient'; -import { workspace , ExtensionContext } from 'vscode'; +import { + LanguageClientOptions, + ServerOptions, + LanguageClient, + TransportKind, + NotificationType, + NotificationHandler +} from 'vscode-languageclient'; +import { + workspace, + ExtensionContext +} from 'vscode'; /** * GDScriptClient */ class GDScriptClient { - public client_options: LanguageClient.LanguageClientOptions; - public server_options: LanguageClient.ServerOptions; - - constructor(context: ExtensionContext) { - this.client_options = { - // Register the server for gdscript documents - documentSelector: ['gdscript'], - synchronize: { - // Synchronize the setting section 'languageServerExample' to the server - configurationSection: 'GDScriptServer', - // Notify the server about file changes to *.gd files contain in the workspace - fileEvents: workspace.createFileSystemWatcher('*.gd') - } - }; + private client_options: LanguageClientOptions; + private server_options: ServerOptions; + private context: ExtensionContext; + + constructor(context: ExtensionContext) { + this.context = context; + this.client_options = { + // Register the server for gdscript documents + documentSelector: ['gdscript'], + synchronize: { + // Synchronize the setting section 'languageServerExample' to the server + configurationSection: 'GDScriptServer', + // Notify the server about file changes to *.gd files contain in the workspace + fileEvents: workspace.createFileSystemWatcher('*.gd') + } + }; // The server is implemented in node let serverModule = context.asAbsolutePath(path.join('server', 'server.js')); // The debug options for the server - let debugOptions = { execArgv: ["--nolazy", "--debug=6980"] }; - this.server_options = { - run : { module: serverModule, transport: LanguageClient.TransportKind.ipc }, - debug: { module: serverModule, transport: LanguageClient.TransportKind.ipc, options: debugOptions } + let debugOptions = { + execArgv: ["--nolazy", "--debug=6980"] }; + this.server_options = { + run: { + module: serverModule, + transport: TransportKind.ipc + }, + debug: { + module: serverModule, + transport: TransportKind.ipc, + options: debugOptions + } + }; + } - } + public createLanguageClient(): LanguageClient { + const lc = new LanguageClient('GDScriptLanguage', this.server_options, this.client_options); + lc.onNotification < string > ({method:"notify"}, this.onNotification.bind(this)); + return lc; + } + + public onNotification(param: any) { + console.log(param); + } } -export default GDScriptClient; +export default GDScriptClient; \ No newline at end of file diff --git a/src/gdscript/server/src/server.ts b/src/gdscript/server/src/server.ts index 79b8a20..98beb47 100644 --- a/src/gdscript/server/src/server.ts +++ b/src/gdscript/server/src/server.ts @@ -8,6 +8,12 @@ import { CompletionItem, CompletionItemKind } from 'vscode-languageserver'; +import request from "./request"; +import validate from "./actions/gd_validate"; +import CodeCompleter from './actions/gd_codecomplete'; + +let completer: CodeCompleter = null; + // Create a connection for the server. The connection uses Node's IPC as a transport let connection: IConnection = createConnection(new IPCMessageReader(process), new IPCMessageWriter(process)); @@ -22,69 +28,66 @@ documents.listen(connection); let workspaceRoot: string; connection.onInitialize((params): InitializeResult => { workspaceRoot = params.rootPath; + completer = new CodeCompleter(); return { capabilities: { // Tell the client that the server works in FULL text document sync mode textDocumentSync: documents.syncKind, // Tell the client that the server support code complete completionProvider: { - resolveProvider: true + resolveProvider: true, + triggerCharacters: [ '.', 'a', 'b', 'c', 'd', 'e', 'f', 'g','h','i','j','k','l','m','n','o','p','q','r','s','t','u','v','w','x','y','z','(', + '_', 'A', 'B', 'C','D','E','F','G','H','I','J','K','L','M','N','O','P','Q','R','S','T','U','V','W','X','Y','Z','\'','\"' + ] } } } }); +let doc = null; // 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); + doc = change.document; + validateTextDocument(doc); +}); + +// This handler provides the initial list of the completion items. +connection.onCompletion((textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => { + let cursor = {row: textDocumentPosition.position.line+1, column:textDocumentPosition.position.character}; + let items = [...completer.getItems()]; + completer.query(doc.getText(), doc.uri, cursor); + return items; }); // The settings interface describe the server relevant settings part interface Settings { GDScriptServer: ExampleSettings; + } // These are the example settings we defined in the client's package.json // file interface ExampleSettings { maxNumberOfProblems: number; + editorServerPort: number; } // hold the maxNumberOfProblems setting let maxNumberOfProblems: number; +let editorServerPort: number; + // The settings have changed. Is send on server activation // as well. connection.onDidChangeConfiguration((change) => { let settings = change.settings; maxNumberOfProblems = settings.GDScriptServer.maxNumberOfProblems || 10; - // Revalidate any open text documents + // editorServerPort: settings.GDScriptServer.editorServerPort || 6996; documents.all().forEach(validateTextDocument); }); function validateTextDocument(textDocument: TextDocument): void { - console.log(textDocument.uri); - let diagnostics: Diagnostic[] = []; - let lines = textDocument.getText().split(/\r?\n/g); - let problems = 0; - for (var i = 0; i < lines.length && problems < maxNumberOfProblems; i++) { - let line = lines[i]; - let index = line.indexOf('typescript'); - if (index >= 0) { - problems++; - diagnostics.push({ - severity: DiagnosticSeverity.Warning, - range: { - start: { line: i, character: index}, - end: { line: i, character: index + 10 } - }, - message: `${line.substr(index, 10)} should be spelled TypeScript`, - source: 'ex' - }); - } - } - // Send the computed diagnostics to VSCode. - connection.sendDiagnostics({ uri: textDocument.uri, diagnostics }); + validate(textDocument.getText(), textDocument.uri, connection); } connection.onDidChangeWatchedFiles((change) => { @@ -93,59 +96,41 @@ connection.onDidChangeWatchedFiles((change) => { }); -// This handler provides the initial list of the completion items. -connection.onCompletion((textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => { - // The pass parameter contains the position of the text document in - // which code complete got requested. For the example we ignore this - // info and always provide the same completion items. - return [ - { - label: 'TypeScript', - kind: CompletionItemKind.Text, - data: 1 - }, - { - label: 'JavaScript', - kind: CompletionItemKind.Text, - data: 2 - } - ] -}); - // This handler resolve additional information for the item selected in // the completion list. connection.onCompletionResolve((item: CompletionItem): CompletionItem => { - if (item.data === 1) { - item.detail = 'TypeScript details', - item.documentation = 'TypeScript documentation' - } else if (item.data === 2) { - item.detail = 'JavaScript details', - item.documentation = 'JavaScript documentation' - } + // if (item.data === 1) { + // item.detail = 'TypeScript details', + // item.documentation = 'TypeScript documentation' + // } else if (item.data === 2) { + // item.detail = 'JavaScript details', + // item.documentation = 'JavaScript documentation' + // } return item; }); -/* -connection.onDidOpenTextDocument((params) => { - // A text document got opened in VSCode. - // params.uri uniquely identifies the document. For documents store on disk this is a file URI. - // params.text the initial full content of the document. - connection.console.log(`${params.uri} opened.`); -}); -connection.onDidChangeTextDocument((params) => { - // The content of a text document did change in VSCode. - // params.uri uniquely identifies the document. - // params.contentChanges describe the content changes to the document. - connection.console.log(`${params.uri} changed: ${JSON.stringify(params.contentChanges)}`); -}); +// connection.onDidOpenTextDocument((params) => { +// // A text document got opened in VSCode. +// // params.uri uniquely identifies the document. For documents store on disk this is a file URI. +// // params.text the initial full content of the document. +// connection.console.log(`${params.uri} opened.`); +// }); + +// connection.onDidChangeTextDocument((params) => { +// // The content of a text document did change in VSCode. +// // params.uri uniquely identifies the document. +// // params.contentChanges describe the content changes to the document. +// params.contentChanges +// connection.console.log(`${params.uri} changed: ${JSON.stringify(params.contentChanges)}`); +// }); + +// connection.onDidCloseTextDocument((params) => { +// // A text document got closed in VSCode. +// // params.uri uniquely identifies the document. +// connection.console.log(`${params.uri} closed.`); +// }); -connection.onDidCloseTextDocument((params) => { - // A text document got closed in VSCode. - // params.uri uniquely identifies the document. - connection.console.log(`${params.uri} closed.`); -}); -*/ // Listen on the connection connection.listen(); \ No newline at end of file