Add Command to Go To / Create project configuration for an active js or ts file (#20362)

* Add Command to Go To / Create project configuration for an active js or ts file

Part of #20356

Adds a new command that opens the jsconfig or tsconfig project configuration file for the currently active file. If one does not exist, displays a quick pick that allows users to learn more and create a config file at the root of their project

* Add messages for error cases

* Work around ts error
This commit is contained in:
Matt Bierner
2017-02-13 12:58:40 -08:00
committed by GitHub
parent d3cbe86479
commit 5db8fd0f55
3 changed files with 116 additions and 9 deletions

View File

@@ -9,12 +9,13 @@
* ------------------------------------------------------------------------------------------ */
'use strict';
import { env, languages, commands, workspace, window, ExtensionContext, Memento, IndentAction, Diagnostic, DiagnosticCollection, Range, DocumentFilter, Disposable, Uri } from 'vscode';
import { env, languages, commands, workspace, window, ExtensionContext, Memento, IndentAction, Diagnostic, DiagnosticCollection, Range, DocumentFilter, Disposable, Uri, MessageItem, TextEditor } from 'vscode';
// This must be the first statement otherwise modules might got loaded with
// the wrong locale.
import * as nls from 'vscode-nls';
nls.config({ locale: env.language });
const localize = nls.loadMessageBundle();
import * as path from 'path';
@@ -52,6 +53,16 @@ interface LanguageDescription {
configFile: string;
}
enum ProjectConfigAction {
None,
CreateConfig,
LearnMore
}
interface ProjectConfigMessageItem extends MessageItem {
id: ProjectConfigAction;
}
export function activate(context: ExtensionContext): void {
const MODE_ID_TS = 'typescript';
const MODE_ID_TSX = 'typescriptreact';
@@ -89,6 +100,15 @@ export function activate(context: ExtensionContext): void {
client.onVersionStatusClicked();
}));
const goToProjectConfig = (isTypeScript: boolean) => {
const editor = window.activeTextEditor;
if (editor) {
clientHost.goToProjectConfig(isTypeScript, editor.document.uri, editor.document.languageId);
}
};
context.subscriptions.push(commands.registerCommand('typescript.goToProjectConfig', goToProjectConfig.bind(null, true)));
context.subscriptions.push(commands.registerCommand('javascript.goToProjectConfig', goToProjectConfig.bind(null, false)));
window.onDidChangeActiveTextEditor(VersionStatus.showHideStatus, null, context.subscriptions);
client.onReady().then(() => {
context.subscriptions.push(ProjectStatus.create(client,
@@ -378,6 +398,76 @@ class TypeScriptServiceClientHost implements ITypescriptServiceClientHost {
return !!this.findLanguage(file);
}
public goToProjectConfig(
isTypeScriptProject: boolean,
resource: Uri,
languageId: string
): Thenable<TextEditor> | undefined {
const rootPath = workspace.rootPath;
if (!rootPath) {
window.showInformationMessage(
localize(
'typescript.projectConfigNoWorkspace',
'Please open a folder in VS Code to use a TypeScript or JavaScript project'));
return;
}
const file = this.client.normalizePath(resource);
// TODO: TSServer errors when 'projectInfo' is invoked on a non js/ts file
if (!file || !this.languagePerId[languageId]) {
window.showWarningMessage(
localize(
'typescript.projectConfigUnsupportedFile',
'Could not determine TypeScript or JavaScript project. Unsupported file type'));
return;
}
return this.client.execute('projectInfo', { file, needFileNameList: false }).then(res => {
if (!res || !res.body) {
return window.showWarningMessage(localize('typescript.projectConfigCouldNotGetInfo', 'Could not determine TypeScript or JavaScript project'));
}
const { configFileName } = res.body;
if (configFileName && configFileName.indexOf('/dev/null/') !== 0) {
return workspace.openTextDocument(configFileName)
.then(window.showTextDocument);
}
return window.showInformationMessage<ProjectConfigMessageItem>(
(isTypeScriptProject
? localize('typescript.noTypeScriptProjectConfig', 'File is not part of a TypeScript project')
: localize('typescript.noJavaScriptProjectConfig', 'File is not part of a JavaScript project')
), {
title: isTypeScriptProject
? localize('typescript.configureTsconfigQuickPick', 'Configure tsconfig.json')
: localize('typescript.configureJsconfigQuickPick', 'Configure jsconfig.json'),
id: ProjectConfigAction.CreateConfig
}, {
title: localize('typescript.projectConfigLearnMore', 'Learn More'),
id: ProjectConfigAction.LearnMore
}).then(selected => {
switch (selected && selected.id) {
case ProjectConfigAction.CreateConfig:
const configFile = Uri.file(path.join(rootPath, isTypeScriptProject ? 'tsconfig.json' : 'jsconfig.json'));
return workspace.openTextDocument(configFile)
.then(undefined, _ => workspace.openTextDocument(configFile.with({ scheme: 'untitled' })))
.then(window.showTextDocument);
case ProjectConfigAction.LearnMore:
if (isTypeScriptProject) {
commands.executeCommand('vscode.open', Uri.parse('https://go.microsoft.com/fwlink/?linkid=841896'));
} else {
commands.executeCommand('vscode.open', Uri.parse('https://go.microsoft.com/fwlink/?linkid=759670'));
}
return;
default:
return Promise.resolve(undefined);
}
});
});
}
private findLanguage(file: string): LanguageProvider | null {
for (let i = 0; i < this.languages.length; i++) {
let language = this.languages[i];