diff --git a/README.md b/README.md index f455c86..5ed2cfd 100644 --- a/README.md +++ b/README.md @@ -1,7 +1,7 @@ # IDE-TypeScript package [![macOS Build Status](https://travis-ci.org/atom/ide-typescript.svg?branch=master)](https://travis-ci.org/atom/ide-typescript) [![Windows Build Status](https://ci.appveyor.com/api/projects/status/o1csvdbqau6m7awm?svg=true)](https://ci.appveyor.com/project/Atom/ide-typescript/branch/master) [![Dependency Status](https://david-dm.org/atom/ide-typescript.svg)](https://david-dm.org/atom/ide-typescript) -TypeScript and JavaScript language support for Atom-IDE, powered by the [Sourcegraph TypeScript Language Server](https://github.com/sourcegraph/javascript-typescript-langserver). +TypeScript and JavaScript language support for Atom-IDE, powered by the [Theia TypeScript Language Server](https://github.com/theia-ide/typescript-language-server). ![Screen shot of IDE-TypeScript](https://user-images.githubusercontent.com/118951/30306800-37e3c506-972f-11e7-805c-ba5a45a6bc3c.png) @@ -18,6 +18,7 @@ This package is currently an early access release. You should also install the * Go to definition * Hover * Signature help +* Format code ## Contributing Always feel free to help out! Whether it's [filing bugs and feature requests](https://github.com/atom/languageserver-typescript/issues/new) or working on some of the [open issues](https://github.com/atom/languageserver-typescript/issues), Atom's [contributing guide](https://github.com/atom/atom/blob/master/CONTRIBUTING.md) will help get you started while the [guide for contributing to packages](https://github.com/atom/atom/blob/master/docs/contributing-to-packages.md) has some extra information. diff --git a/lib/main.js b/lib/main.js index 389de78..4fbbaca 100644 --- a/lib/main.js +++ b/lib/main.js @@ -14,16 +14,15 @@ class TypeScriptLanguageClient extends AutoLanguageClient { return atom.config.get('ide-typescript.javascriptSupport') ? allScopes : tsScopes } getLanguageName () { return 'TypeScript' } - getServerName () { return 'SourceGraph' } + getServerName () { return 'Theia' } startServerProcess () { this.supportedExtensions = atom.config.get('ide-typescript.javascriptSupport') ? allExtensions : tsExtensions - const args = [ 'node_modules/javascript-typescript-langserver/lib/language-server-stdio' ] - return super.spawnChildNode(args, { cwd: path.join(__dirname, '..') }) - } - - preInitialization (connection) { - connection.onCustom('$/partialResult', () => {}) // Suppress partialResult until the language server honors 'streaming' detection + return super.spawnChildNode([ + 'node_modules/typescript-language-server/lib/cli', + '--stdio', + '--tsserver-path', atom.config.get('ide-typescript.typeScriptServer.path') + ] , { cwd: path.join(__dirname, '..') }) } consumeLinterV2() { @@ -45,12 +44,36 @@ class TypeScriptLanguageClient extends AutoLanguageClient { shouldStartForEditor(editor) { if (atom.config.get('ide-typescript.ignoreFlow') === true) { - const flowConfigPath = path.join(this.getProjectPath(editor.getURI() || ''), '.flowconfig'); - if (fs.existsSync(flowConfigPath)) return false; + const flowConfigPath = path.join(this.getProjectPath(editor.getURI() || ''), '.flowconfig') + if (fs.existsSync(flowConfigPath)) return false } + + if (!this.validateTypeScriptServerPath()) return false + return super.shouldStartForEditor(editor); } + validateTypeScriptServerPath() { + const tsSpecifiedPath = atom.config.get('ide-typescript.typeScriptServer.path') + const isAbsolutelySpecified = path.isAbsolute(tsSpecifiedPath) + const tsAbsolutePath = isAbsolutelySpecified ? tsSpecifiedPath : path.join(__dirname, '..', tsSpecifiedPath) + + if (fs.existsSync(tsAbsolutePath)) return true + + atom.notifications.addError('ide-typescript could not locate the TypeScript server', { + dismissable: true, + buttons: [ + { text: 'Set TypeScript server path', onDidClick: () => this.openPackageSettings() }, + ], + description: + `No TypeScript server could be found at ${tsAbsolutePath}` + }) + } + + openPackageSettings() { + atom.workspace.open('atom://config/packages/ide-typescript') + } + getProjectPath(filePath) { const projectPath = atom.project.getDirectories().find(d => filePath.startsWith(d.path)) return projectPath != null ? projectPath.path : '' @@ -62,7 +85,7 @@ class TypeScriptLanguageClient extends AutoLanguageClient { cancel = true; }) - return new Promise((resolve, reject) => { + return new Promise((resolve, _reject) => { let timeout = setTimeout(() => { clearTimeout(timeout) @@ -83,9 +106,17 @@ class TypeScriptLanguageClient extends AutoLanguageClient { return provided } - onDidConvertAutocomplete(completionItem, suggestion, request) { - if (suggestion.rightLabel == null || suggestion.displayText == null) return + onDidConvertAutocomplete(_completionItem, suggestion, _request) { + TypeScriptLanguageClient.setLeftAndRightLabels(suggestion) + + // Theia language server sets snippets to '' leading to ambiguity between using that and text + if (suggestion.snippet === '' && suggestion.text != null && suggestion.text !== '') { + suggestion.snippet = undefined + } + } + static setLeftAndRightLabels(suggestion) { + if (suggestion.rightLabel == null || suggestion.displayText == null) return const nameIndex = suggestion.rightLabel.indexOf(suggestion.displayText) if (nameIndex >= 0) { const signature = suggestion.rightLabel.substr(nameIndex + suggestion.displayText.length).trim() @@ -93,8 +124,8 @@ class TypeScriptLanguageClient extends AutoLanguageClient { let paramsEnd = -1 let returnStart = -1 let bracesDepth = 0 - for(let i = 0; i < signature.length; i++) { - switch(signature[i]) { + for (let i = 0; i < signature.length; i++) { + switch (signature[i]) { case '(': { if (bracesDepth++ === 0 && paramsStart === -1) { paramsStart = i; @@ -115,6 +146,7 @@ class TypeScriptLanguageClient extends AutoLanguageClient { } } } + if (atom.config.get('ide-typescript.returnTypeInAutocomplete') === 'left') { if (paramsStart > -1) { suggestion.rightLabel = signature.substring(paramsStart, paramsEnd + 1).trim() diff --git a/package.json b/package.json index 2241a58..7028a3a 100644 --- a/package.json +++ b/package.json @@ -14,6 +14,18 @@ "default": true, "description": "Use the TypeScript language server to provide diagnostics and warnings." }, + "typeScriptServer": { + "title": "TypeScript server", + "type": "object", + "properties": { + "path": { + "title": "TypeScript server path", + "type": "string", + "default": "node_modules/typescript/lib/tsserver.js", + "description": "Path to a TypeScript `tsserver.js` the language server will use to process TypeScript. Defaults to the bundled version." + } + } + }, "javascriptSupport": { "type": "boolean", "title": "JavaScript support", @@ -49,8 +61,9 @@ } }, "dependencies": { - "atom-languageclient": "0.9.7", - "javascript-typescript-langserver": "^2.7.0" + "atom-languageclient": "0.9.8", + "typescript": "~3.1.6", + "typescript-language-server": "0.3.7" }, "enhancedScopes": [ "source.ts",