From 2b8ba1cd62ebbec166a245653d48e58f853b335f Mon Sep 17 00:00:00 2001 From: Johannes Rieken Date: Thu, 10 Mar 2016 16:06:39 +0100 Subject: [PATCH] salsa project status, first cut, #3901 --- extensions/typescript/src/typescriptMain.ts | 4 + .../typescript/src/utils/projectStatus.ts | 128 ++++++++++++++++++ 2 files changed, 132 insertions(+) create mode 100644 extensions/typescript/src/utils/projectStatus.ts diff --git a/extensions/typescript/src/typescriptMain.ts b/extensions/typescript/src/typescriptMain.ts index 2debf09f08d..01a57e3f4c2 100644 --- a/extensions/typescript/src/typescriptMain.ts +++ b/extensions/typescript/src/typescriptMain.ts @@ -30,6 +30,7 @@ import CompletionItemProvider from './features/completionItemProvider'; import WorkspaceSymbolProvider from './features/workspaceSymbolProvider'; import * as VersionStatus from './utils/versionStatus'; +import * as ProjectStatus from './utils/projectStatus'; import * as nls from 'vscode-nls'; @@ -71,6 +72,9 @@ export function activate(context: ExtensionContext): void { // Register the supports for both TS and TSX so that we can have separate grammars but share the mode client.onReady().then(() => { + + context.subscriptions.push(ProjectStatus.create(client)); + registerSupports(MODE_ID_TS, clientHost, client); registerSupports(MODE_ID_TSX, clientHost, client); registerSupports(MODE_ID_JS, clientHost, client); diff --git a/extensions/typescript/src/utils/projectStatus.ts b/extensions/typescript/src/utils/projectStatus.ts new file mode 100644 index 00000000000..9d5784ba9f9 --- /dev/null +++ b/extensions/typescript/src/utils/projectStatus.ts @@ -0,0 +1,128 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +'use strict'; + +import * as vscode from 'vscode'; +import {ITypescriptServiceClient} from '../typescriptService'; +import {loadMessageBundle} from 'vscode-nls'; + +const localize = loadMessageBundle(); +const selector = ['javascript', 'javascriptreact']; + +interface Option extends vscode.MessageItem { + execute(): void; +} + +interface Hint { + message: string; + option: Option; +} + +export function create(client: ITypescriptServiceClient) { + + const fileLimit = 10; + const toDispose: vscode.Disposable[] = []; + const projectHinted = new Set(); + + let currentHint: Hint; + let item = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Right, Number.MIN_VALUE); + item.command = 'js.projectStatus.command'; + toDispose.push(vscode.commands.registerCommand('js.projectStatus.command', () => { + let {message, option} = currentHint; + return vscode.window.showInformationMessage(message, option).then(selection => { + if (selection === option) { + return selection.execute(); + } + }); + })); + + toDispose.push(vscode.workspace.onDidChangeTextDocument(e => { + projectHinted.delete(e.document.fileName); + })); + + function onEditor(editor: vscode.TextEditor): void { + if (!editor || !vscode.languages.match(selector, editor.document)) { + item.hide(); + return; + } + + const file = client.asAbsolutePath(editor.document.uri); + client.execute('open', { file }, false); // tsserver will fail if document isn't open + client.execute('projectInfo', { file, needFileNameList: true }).then(res => { + + let {configFileName, fileNames} = res.body; + + if (projectHinted.has(configFileName)) { + return; + } + + if (!configFileName) { + currentHint = { + message: localize('hintCreate', "Create a project and experience better IntelliSense and code navigation."), + option: { + title: localize('cmdCreate', "Create jsconfig.json-file..."), + execute: () => { + projectHinted.add(configFileName); + item.hide(); + + return vscode.workspace.openTextDocument(vscode.Uri.parse('untitled://' + vscode.workspace.rootPath + '/jsconfig.json')) + .then(vscode.window.showTextDocument) + .then(editor => editor.edit(builder => builder.insert(new vscode.Position(0, 0), defaultConfig))); + } + } + }; + item.text = '$(light-bulb)'; + item.tooltip = localize('hint.tooltip', "Create a project and have better IntelliSense, better symbol search, and much more."); + item.color = 'lime'; + item.show(); + + } else if (fileNames.length > fileLimit) { + currentHint = { + message: localize('hintExclude', "'{0}' is a large project. For better performance exclude library files like 'node_modules'.", vscode.workspace.asRelativePath(configFileName)), + option: { + title: localize('open', "Edit excludes..."), + execute: () => { + projectHinted.add(configFileName); + item.hide(); + + return vscode.workspace.openTextDocument(configFileName) + .then(vscode.window.showTextDocument); + } + } + }; + item.tooltip = currentHint.message; + item.text = localize('large.label', "+{0} files", fileLimit); + item.tooltip = localize('large.tooltip', "Too many files in a project might result in bad performance. Exclude library files like 'node_modules'."); + item.color = 'orange'; + item.show(); + + } else { + item.hide(); + } + }).catch(err => { + console.log(err); + }); + } + + toDispose.push(vscode.window.onDidChangeActiveTextEditor(onEditor)); + onEditor(vscode.window.activeTextEditor); + + return vscode.Disposable.from(...toDispose); +} + +const defaultConfig = `{ + "compilerOptions": { + "module": "commonjs" + }, + "exclude": [ + "node_modules", + "bower_components", + "jspm_packages", + "tmp", + "temp" + ] +} +`; -- GitLab