diff --git a/.vscode/launch.json b/.vscode/launch.json index febcbae..846d7c2 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -15,7 +15,7 @@ "outFiles": [ "${workspaceRoot}/client/out/**/*.js" ], - "preLaunchTask": "watch:client" + "preLaunchTask": "compile" }, { "name": "Attach to Server", diff --git a/client/server/package-lock.json b/client/server/package-lock.json new file mode 100644 index 0000000..2ba2eb0 --- /dev/null +++ b/client/server/package-lock.json @@ -0,0 +1,41 @@ +{ + "name": "vscode-mc-shader-server", + "version": "0.0.1", + "lockfileVersion": 1, + "requires": true, + "dependencies": { + "vscode-jsonrpc": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-3.5.0.tgz", + "integrity": "sha1-hyOdnhZrLXNSJFuKgTWXgEwdY6o=" + }, + "vscode-languageserver": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-3.5.1.tgz", + "integrity": "sha512-RYUKn0DgHTFcS8kS4VaNCjNMaQXYqiXdN9bKrFjXzu5RPKfjIYcoh47oVWwZj4L3R/DPB0Se7HPaDatvYY2XgQ==", + "requires": { + "vscode-languageserver-protocol": "3.5.1", + "vscode-uri": "^1.0.1" + } + }, + "vscode-languageserver-protocol": { + "version": "3.5.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.1.tgz", + "integrity": "sha512-1fPDIwsAv1difCV+8daOrJEGunClNJWqnUHq/ncWrjhitKWXgGmRCjlwZ3gDUTt54yRcvXz1PXJDaRNvNH6pYA==", + "requires": { + "vscode-jsonrpc": "3.5.0", + "vscode-languageserver-types": "3.5.0" + } + }, + "vscode-languageserver-types": { + "version": "3.5.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0.tgz", + "integrity": "sha1-5I15li8LjgLelV4/UkkI4rGcA3Q=" + }, + "vscode-uri": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.3.tgz", + "integrity": "sha1-Yxvb9xbcyrDmUpGo3CXCMjIIWlI=" + } + } +} diff --git a/client/server/package.json b/client/server/package.json new file mode 100644 index 0000000..6785c02 --- /dev/null +++ b/client/server/package.json @@ -0,0 +1,27 @@ +{ + "name": "vscode-mc-shader-server", + "description": "A Visual Studio Code extension for linting/etc Minecraft GLSL Shaders", + "version": "0.0.1", + "author": "Noah Santschi-Cooney (Strum355)", + "license": "MIT", + "engines": { + "node": "*" + }, + "repository": { + "type": "git", + "url": "https://dl.continuum.graphics/nova-group/bedrock-verifier.git" + }, + "devDependencies": { + "@types/node": "^7.0.43", + "tslint": "^5.8.0", + "typescript": "^2.6.1" + }, + "dependencies": { + "vscode-languageserver": "^3.4.2" + }, + "scripts": { + "installServer": "installServerIntoExtension ../client ./package.json ./tsconfig.json", + "compile": "installServerIntoExtension ../client ./package.json ./tsconfig.json && tsc -p .", + "watch": "installServerIntoExtension ../client ./package.json ./tsconfig.json && tsc -w -p ." + } +} diff --git a/client/server/server.js b/client/server/server.js new file mode 100644 index 0000000..360428b --- /dev/null +++ b/client/server/server.js @@ -0,0 +1,113 @@ +"use strict"; +Object.defineProperty(exports, "__esModule", { value: true }); +const vscode_languageserver_1 = require("vscode-languageserver"); +// Create a connection for the server. The connection uses Node's IPC as a transport +const connection = vscode_languageserver_1.createConnection(new vscode_languageserver_1.IPCMessageReader(process), new vscode_languageserver_1.IPCMessageWriter(process)); +// Create a simple text document manager. The text document manager +// supports full document sync only +const documents = new vscode_languageserver_1.TextDocuments(); +// Make the text document manager listen on the connection +// for open, change and close text document events +documents.listen(connection); +// After the server has started, the client sends an initialize request. The server receives +// in the passed params, the rootPath of the workspace plus the client capabilities. +connection.onInitialize((params) => { + return { + capabilities: { + // Tell the client that the server works in FULL text document sync mode + textDocumentSync: documents.syncKind, + // Tell the client that the server supports code completion + completionProvider: { + resolveProvider: true + } + } + }; +}); +// The content of a text document has changed. This event is emitted +// when the text document is first opened or when its content has changed. +documents.onDidChangeContent((change) => { + validateTextDocument(change.document); +}); +// The settings have changed. It is sent on server activation +// as well. +connection.onDidChangeConfiguration((change) => { + documents.all().forEach(validateTextDocument); +}); +function validateTextDocument(textDocument) { + const diagnostics = []; + const lines = textDocument.getText().split(/\r?\n/g); + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const index = line.indexOf('typescript'); + if (index >= 0) { + diagnostics.push({ + severity: vscode_languageserver_1.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 VS Code. + connection.sendDiagnostics({ uri: textDocument.uri, diagnostics }); +} +connection.onDidChangeWatchedFiles((change) => { + // Monitored files have changed in VS Code + connection.console.log('We received a file change event'); +}); +// This handler provides the initial list of the completion items. +connection.onCompletion((textDocumentPosition) => { + // The passed parameter contains the position in the text document in + // which code completion was requested. For this example, we ignore this + // information and always provide the same completion items. + return [ + { + label: 'TypeScript', + kind: vscode_languageserver_1.CompletionItemKind.Text, + data: 1 + }, + { + label: 'JavaScript', + kind: vscode_languageserver_1.CompletionItemKind.Text, + data: 2 + } + ]; +}); +// This handler resolves additional information for the item selected in +// the completion list. +connection.onCompletionResolve((item) => { + 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 was opened in VS Code. + // params.uri uniquely identifies the document. For documents stored on disk, this is a file URI. + // params.text the initial full content of the document. + connection.console.log(`${params.textDocument.uri} opened.`); +}); +connection.onDidChangeTextDocument((params) => { + // The content of a text document has changed in VS Code. + // params.uri uniquely identifies the document. + // params.contentChanges describe the content changes to the document. + connection.console.log(`${params.textDocument.uri} changed: ${JSON.stringify(params.contentChanges)}`); +}); +connection.onDidCloseTextDocument((params) => { + // A text document was closed in VS Code. + // params.uri uniquely identifies the document. + connection.console.log(`${params.textDocument.uri} closed.`); +}); +*/ +// Listen on the connection +connection.listen(); +//# sourceMappingURL=server.js.map \ No newline at end of file diff --git a/client/server/server.js.map b/client/server/server.js.map new file mode 100644 index 0000000..3ade12a --- /dev/null +++ b/client/server/server.js.map @@ -0,0 +1 @@ +{"version":3,"file":"server.js","sourceRoot":"","sources":["../../server/src/server.ts"],"names":[],"mappings":"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"} \ No newline at end of file diff --git a/server/package.json b/server/package.json index 6785c02..e96cd64 100644 --- a/server/package.json +++ b/server/package.json @@ -22,6 +22,7 @@ "scripts": { "installServer": "installServerIntoExtension ../client ./package.json ./tsconfig.json", "compile": "installServerIntoExtension ../client ./package.json ./tsconfig.json && tsc -p .", - "watch": "installServerIntoExtension ../client ./package.json ./tsconfig.json && tsc -w -p ." + "watch": "installServerIntoExtension ../client ./package.json ./tsconfig.json && tsc -w -p .", + "lint": "tslint -c tslint.json 'src/**/*.ts'" } } diff --git a/server/src/server.ts b/server/src/server.ts index 51bb0a6..7a0b5c7 100644 --- a/server/src/server.ts +++ b/server/src/server.ts @@ -1,3 +1,122 @@ -import * as vscodeLang from 'vscode-languageserver' -import { exec } from 'child_process' +import { IPCMessageReader, IPCMessageWriter, createConnection, IConnection, + TextDocuments, TextDocument, Diagnostic, DiagnosticSeverity, InitializeResult, TextDocumentPositionParams, CompletionItem, CompletionItemKind +} from 'vscode-languageserver'; +// Create a connection for the server. The connection uses Node's IPC as a transport +const connection: IConnection = createConnection(new IPCMessageReader(process), new IPCMessageWriter(process)); + +// Create a simple text document manager. The text document manager +// supports full document sync only +const documents: TextDocuments = new TextDocuments(); +// Make the text document manager listen on the connection +// for open, change and close text document events +documents.listen(connection); + +// After the server has started, the client sends an initialize request. The server receives +// in the passed params, the rootPath of the workspace plus the client capabilities. +connection.onInitialize((params): InitializeResult => { + return { + capabilities: { + // Tell the client that the server works in FULL text document sync mode + textDocumentSync: documents.syncKind, + // Tell the client that the server supports code completion + completionProvider: { + resolveProvider: true + } + } + }; +}); + +// The content of a text document has changed. This event is emitted +// when the text document is first opened or when its content has changed. +documents.onDidChangeContent((change) => { + validateTextDocument(change.document); +}); + +// The settings have changed. It is sent on server activation +// as well. +connection.onDidChangeConfiguration((change) => { + documents.all().forEach(validateTextDocument); +}); + +function validateTextDocument(textDocument: TextDocument): void { + const diagnostics: Diagnostic[] = []; + const lines = textDocument.getText().split(/\r?\n/g); + for (let i = 0; i < lines.length; i++) { + const line = lines[i]; + const index = line.indexOf('typescript'); + if (index >= 0) { + 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 VS Code. + connection.sendDiagnostics({ uri: textDocument.uri, diagnostics }); +} + +connection.onDidChangeWatchedFiles((change) => { + // Monitored files have changed in VS Code + connection.console.log('We received a file change event'); +}); + +// This handler provides the initial list of the completion items. +connection.onCompletion((textDocumentPosition: TextDocumentPositionParams): CompletionItem[] => { + // The passed parameter contains the position in the text document in + // which code completion was requested. For this example, we ignore this + // information and always provide the same completion items. + return [ + { + label: 'TypeScript', + kind: CompletionItemKind.Text, + data: 1 + }, + { + label: 'JavaScript', + kind: CompletionItemKind.Text, + data: 2 + } + ]; +}); + +// This handler resolves 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' + } + return item; +}); + +/* +connection.onDidOpenTextDocument((params) => { + // A text document was opened in VS Code. + // params.uri uniquely identifies the document. For documents stored on disk, this is a file URI. + // params.text the initial full content of the document. + connection.console.log(`${params.textDocument.uri} opened.`); +}); +connection.onDidChangeTextDocument((params) => { + // The content of a text document has changed in VS Code. + // params.uri uniquely identifies the document. + // params.contentChanges describe the content changes to the document. + connection.console.log(`${params.textDocument.uri} changed: ${JSON.stringify(params.contentChanges)}`); +}); +connection.onDidCloseTextDocument((params) => { + // A text document was closed in VS Code. + // params.uri uniquely identifies the document. + connection.console.log(`${params.textDocument.uri} closed.`); +}); +*/ + +// Listen on the connection +connection.listen(); \ No newline at end of file diff --git a/server/tsconfig.json b/server/tsconfig.json index 51ae0d6..bc06053 100644 --- a/server/tsconfig.json +++ b/server/tsconfig.json @@ -2,7 +2,7 @@ "compilerOptions": { "module": "commonjs", "target": "esnext", - "outDir": "out", + "outDir": "../client/server", "lib": [ "es6" ], @@ -10,7 +10,7 @@ "rootDir": "src", "strict": true, "noUnusedLocals": true, - "noImplicitReturns": true, + "noImplicitReturns": true }, "exclude": [ "node_modules",