argv.ts 6.3 KB
Newer Older
J
Joao Moreno 已提交
1 2 3 4 5
/*---------------------------------------------------------------------------------------------
 *  Copyright (c) Microsoft Corporation. All rights reserved.
 *  Licensed under the MIT License. See License.txt in the project root for license information.
 *--------------------------------------------------------------------------------------------*/

J
Joao Moreno 已提交
6
import * as os from 'os';
J
Joao Moreno 已提交
7
import * as minimist from 'minimist';
J
Joao Moreno 已提交
8
import * as assert from 'assert';
J
Joao Moreno 已提交
9
import { firstIndex } from 'vs/base/common/arrays';
J
Joao Moreno 已提交
10
import { localize } from 'vs/nls';
J
Joao Moreno 已提交
11 12

export interface ParsedArgs extends minimist.ParsedArgs {
13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33
	help?: boolean;
	version?: boolean;
	wait?: boolean;
	diff?: boolean;
	goto?: boolean;
	'new-window'?: boolean;
	'reuse-window'?: boolean;
	locale?: string;
	'user-data-dir'?: string;
	performance?: boolean;
	verbose?: boolean;
	logExtensionHostCommunication?: boolean;
	'disable-extensions'?: boolean;
	extensionHomePath?: string;
	extensionDevelopmentPath?: string;
	extensionTestsPath?: string;
	debugBrkPluginHost?: string;
	debugPluginHost?: string;
	'list-extensions'?: boolean;
	'install-extension'?: string | string[];
	'uninstall-extension'?: string | string[];
J
Joao Moreno 已提交
34
	'open-url'?: string | string[];
J
Joao Moreno 已提交
35 36
}

J
Joao Moreno 已提交
37
const options: minimist.Opts = {
38 39
	string: [
		'locale',
J
Joao Moreno 已提交
40 41 42 43
		'user-data-dir',
		'extensionHomePath',
		'extensionDevelopmentPath',
		'extensionTestsPath',
J
Joao Moreno 已提交
44
		'install-extension',
45 46
		'uninstall-extension',
		'debugBrkPluginHost',
J
Joao Moreno 已提交
47 48
		'debugPluginHost',
		'open-url'
49 50 51 52 53 54 55 56
	],
	boolean: [
		'help',
		'version',
		'wait',
		'diff',
		'goto',
		'new-window',
J
Joao Moreno 已提交
57 58 59 60
		'reuse-window',
		'performance',
		'verbose',
		'logExtensionHostCommunication',
J
Joao Moreno 已提交
61 62
		'disable-extensions',
		'list-extensions'
63
	],
J
Joao Moreno 已提交
64 65 66
	alias: {
		help: 'h',
		version: 'v',
67 68 69 70
		wait: 'w',
		diff: 'd',
		goto: 'g',
		'new-window': 'n',
J
Joao Moreno 已提交
71 72 73
		'reuse-window': 'r',
		performance: 'p',
		'disable-extensions': 'disableExtensions'
J
Joao Moreno 已提交
74
	}
J
Joao Moreno 已提交
75
};
J
Joao Moreno 已提交
76

J
Joao Moreno 已提交
77 78
function validate(args: ParsedArgs): ParsedArgs {
	if (args.goto) {
J
Joao Moreno 已提交
79
		args._.forEach(arg => assert(/^(\w:)?[^:]+(:\d*){0,2}$/.test(arg), localize('gotoValidation', "Arguments in `--goto` mode should be in the format of `FILE(:LINE(:COLUMN))`.")));
J
Joao Moreno 已提交
80 81 82 83 84 85 86 87 88 89 90 91 92
	}

	return args;
}

function stripAppPath(argv: string[]): string[] {
	const index = firstIndex(argv, a => !/^-/.test(a));

	if (index > -1) {
		return [...argv.slice(0, index), ...argv.slice(index + 1)];
	}
}

J
Joao Moreno 已提交
93 94 95 96
/**
 * Use this to parse raw code process.argv such as: `Electron . --verbose --wait`
 */
export function parseMainProcessArgv(processArgv: string[]): ParsedArgs {
J
Joao Moreno 已提交
97
	let [, ...args] = processArgv;
J
Joao Moreno 已提交
98 99 100

	// If dev, remove the first non-option argument: it's the app location
	if (process.env['VSCODE_DEV']) {
J
Joao Moreno 已提交
101 102 103 104 105
		args = stripAppPath(args);
	}

	return validate(parseArgs(args));
}
J
Joao Moreno 已提交
106

J
Joao Moreno 已提交
107 108 109 110 111 112 113 114
/**
 * Use this to parse raw code CLI process.argv such as: `Electron cli.js . --verbose --wait`
 */
export function parseCLIProcessArgv(processArgv: string[]): ParsedArgs {
	let [,, ...args] = processArgv;

	if (process.env['VSCODE_DEV']) {
		args = stripAppPath(args);
J
Joao Moreno 已提交
115 116
	}

J
Joao Moreno 已提交
117
	return validate(parseArgs(args));
J
Joao Moreno 已提交
118 119 120 121 122
}

/**
 * Use this to parse code arguments such as `--verbose --wait`
 */
B
Benjamin Pasero 已提交
123
export function parseArgs(args: string[]): ParsedArgs {
124
	return minimist(args, options) as ParsedArgs;
J
Joao Moreno 已提交
125 126
}

J
Joao Moreno 已提交
127 128 129
export const optionsHelp: { [name: string]: string; } = {
	'-d, --diff': localize('diff', "Open a diff editor. Requires to pass two file paths as arguments."),
	'-g, --goto': localize('goto', "Open the file at path at the line and column (add :line[:column] to path)."),
130
	'--locale <locale>': localize('locale', "The locale to use (e.g. en-US or zh-TW)."),
J
Joao Moreno 已提交
131
	'-n, --new-window': localize('newWindow', "Force a new instance of Code."),
D
Daniel Imms 已提交
132
	'-p, --performance': localize('performance', "Start with the 'Developer: Startup Performance' command enabled."),
J
Joao Moreno 已提交
133 134 135 136
	'-r, --reuse-window': localize('reuseWindow', "Force opening a file or folder in the last active window."),
	'--user-data-dir <dir>': localize('userDataDir', "Specifies the directory that user data is kept in, useful when running as root."),
	'--verbose': localize('verbose', "Print verbose output (implies --wait)."),
	'-w, --wait': localize('wait', "Wait for the window to be closed before returning."),
J
Joao Moreno 已提交
137
	'--extensionHomePath': localize('extensionHomePath', "Set the root path for extensions."),
J
Joao Moreno 已提交
138
	'--list-extensions': localize('listExtensions', "List the installed extensions."),
D
Daniel Imms 已提交
139 140
	'--install-extension <ext>': localize('installExtension', "Installs an extension."),
	'--uninstall-extension <ext>': localize('uninstallExtension', "Uninstalls an extension."),
J
Joao Moreno 已提交
141
	'--disable-extensions': localize('disableExtensions', "Disable all installed extensions."),
J
Joao Moreno 已提交
142 143 144 145
	'-v, --version': localize('version', "Print version."),
	'-h, --help': localize('help', "Print usage.")
};

D
Daniel Imms 已提交
146 147 148 149 150 151 152 153 154 155 156
export function formatOptions(options: { [name: string]: string; }, columns: number): string {
	let keys = Object.keys(options);
	let argLength = Math.max.apply(null, keys.map(k => k.length)) + 2/*left padding*/ + 1/*right padding*/;
	if (columns - argLength < 25) {
		// Use a condensed version on narrow terminals
		return keys.reduce((r, key) => r.concat([`  ${ key }`, `      ${ options[key] }`]), []).join('\n');
	}
	let descriptionColumns = columns - argLength - 1;
	let result = '';
	keys.forEach(k => {
		let wrappedDescription = wrapText(options[k], descriptionColumns);
D
Daniel Imms 已提交
157 158 159 160 161
		let keyPadding = (<any>' ').repeat(argLength - k.length - 2/*left padding*/);
		if (result.length > 0) {
			result += '\n';
		}
		result += '  ' + k + keyPadding + wrappedDescription[0];
D
Daniel Imms 已提交
162
		for (var i = 1; i < wrappedDescription.length; i++) {
D
Daniel Imms 已提交
163
			result += '\n' + (<any>' ').repeat(argLength) + wrappedDescription[i];
D
Daniel Imms 已提交
164 165 166
		}
	});
	return result;
J
Joao Moreno 已提交
167 168
}

D
Daniel Imms 已提交
169 170 171 172
function wrapText(text: string, columns: number) : string[] {
	let lines = [];
	while (text.length) {
		let index = text.length < columns ? text.length : text.lastIndexOf(' ', columns);
D
Daniel Imms 已提交
173
		let line = text.slice(0, index).trim();
D
Daniel Imms 已提交
174 175 176 177 178 179
		text = text.slice(index);
		lines.push(line);
	}
	return lines;
}

J
Joao Moreno 已提交
180 181 182
export function buildHelpMessage(fullName: string, name: string, version: string): string {
	const columns = (<any>process.stdout).isTTY ? (<any>process.stdout).columns : 80;
	const executable = `${ name }${ os.platform() === 'win32' ? '.exe' : '' }`;
D
Daniel Imms 已提交
183

J
Joao Moreno 已提交
184
	return `${ fullName } ${ version }
J
Joao Moreno 已提交
185

J
Joao Moreno 已提交
186
${ localize('usage', "Usage") }: ${ executable } [${ localize('options', "options") }] [${ localize('paths', 'paths') }...]
J
Joao Moreno 已提交
187

J
Joao Moreno 已提交
188
${ localize('optionsUpperCase', "Options") }:
D
Daniel Imms 已提交
189
${formatOptions(optionsHelp, columns)}`;
190
}