projectStatus.ts 4.0 KB
Newer Older
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25
/*---------------------------------------------------------------------------------------------
 *  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) {

J
Johannes Rieken 已提交
26
	const fileLimit = 1000;
27
	const toDispose: vscode.Disposable[] = [];
J
Johannes Rieken 已提交
28
	const projectHinted: { [k: string]:any} = Object.create(null);
29 30 31 32 33 34 35 36 37 38 39 40 41 42

	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 => {
J
Johannes Rieken 已提交
43
		delete projectHinted[e.document.fileName];
44 45 46 47 48 49 50 51 52 53 54 55 56 57
	}));

	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;

J
Johannes Rieken 已提交
58
			if (projectHinted[configFileName] === true) {
59 60 61 62 63 64 65 66 67
				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: () => {
J
Johannes Rieken 已提交
68
							projectHinted[configFileName] = true;
69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87
							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: () => {
J
Johannes Rieken 已提交
88
							projectHinted[configFileName] = true;
89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128
							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"
	]
}
`;