files.contribution.ts 17.6 KB
Newer Older
E
Erich Gamma 已提交
1 2 3 4 5 6 7 8
/*---------------------------------------------------------------------------------------------
 *  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 URI from 'vs/base/common/uri';
9
import { ViewletRegistry, Extensions as ViewletExtensions, ViewletDescriptor, ToggleViewletAction } from 'vs/workbench/browser/viewlet';
E
Erich Gamma 已提交
10
import nls = require('vs/nls');
11
import { SyncActionDescriptor } from 'vs/platform/actions/common/actions';
12
import { Registry } from 'vs/platform/registry/common/platform';
13
import { IConfigurationRegistry, Extensions as ConfigurationExtensions, ConfigurationScope } from 'vs/platform/configuration/common/configurationRegistry';
B
Benjamin Pasero 已提交
14
import { IWorkbenchActionRegistry, Extensions as ActionExtensions } from 'vs/workbench/common/actions';
15
import { IWorkbenchContributionsRegistry, Extensions as WorkbenchExtensions } from 'vs/workbench/common/contributions';
16
import { IEditorRegistry, IEditorInputFactory, EditorInput, IFileEditorInput } from 'vs/workbench/common/editor';
17
import { AutoSaveConfiguration, HotExitConfiguration, SUPPORTED_ENCODINGS } from 'vs/platform/files/common/files';
18
import { EditorDescriptor, Extensions as EditorExtensions } from 'vs/workbench/browser/parts/editor/baseEditor';
19
import { FILE_EDITOR_INPUT_ID, VIEWLET_ID, SortOrderConfiguration } from 'vs/workbench/parts/files/common/files';
20 21 22 23 24 25
import { FileEditorTracker } from 'vs/workbench/parts/files/common/editors/fileEditorTracker';
import { SaveErrorHandler } from 'vs/workbench/parts/files/browser/saveErrorHandler';
import { FileEditorInput } from 'vs/workbench/parts/files/common/editors/fileEditorInput';
import { TextFileEditor } from 'vs/workbench/parts/files/browser/editors/textFileEditor';
import { BinaryFileEditor } from 'vs/workbench/parts/files/browser/editors/binaryFileEditor';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
26
import { SyncDescriptor } from 'vs/platform/instantiation/common/descriptors';
A
Renames  
Alex Dima 已提交
27
import { IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry';
B
Benjamin Pasero 已提交
28
import { IViewletService } from 'vs/workbench/services/viewlet/browser/viewlet';
29 30
import { IWorkbenchEditorService } from 'vs/workbench/services/editor/common/editorService';
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
31
import * as platform from 'vs/base/common/platform';
32
import { DirtyFilesTracker } from 'vs/workbench/parts/files/common/dirtyFilesTracker';
B
Benjamin Pasero 已提交
33
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
E
Erich Gamma 已提交
34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50

// Viewlet Action
export class OpenExplorerViewletAction extends ToggleViewletAction {
	public static ID = VIEWLET_ID;
	public static LABEL = nls.localize('showExplorerViewlet', "Show Explorer");

	constructor(
		id: string,
		label: string,
		@IViewletService viewletService: IViewletService,
		@IWorkbenchEditorService editorService: IWorkbenchEditorService
	) {
		super(id, label, VIEWLET_ID, viewletService, editorService);
	}
}

// Register Viewlet
B
Benjamin Pasero 已提交
51
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).registerViewlet(new ViewletDescriptor(
E
Erich Gamma 已提交
52 53 54
	'vs/workbench/parts/files/browser/explorerViewlet',
	'ExplorerViewlet',
	VIEWLET_ID,
B
Benjamin Pasero 已提交
55
	nls.localize('explore', "Explorer"),
E
Erich Gamma 已提交
56 57 58 59
	'explore',
	0
));

B
Benjamin Pasero 已提交
60
Registry.as<ViewletRegistry>(ViewletExtensions.Viewlets).setDefaultViewletId(VIEWLET_ID);
E
Erich Gamma 已提交
61

B
Benjamin Pasero 已提交
62
const openViewletKb: IKeybindings = {
E
Erich Gamma 已提交
63 64 65 66
	primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_E
};

// Register Action to Open Viewlet
B
Benjamin Pasero 已提交
67
const registry = Registry.as<IWorkbenchActionRegistry>(ActionExtensions.WorkbenchActions);
68
registry.registerWorkbenchAction(
E
Erich Gamma 已提交
69
	new SyncActionDescriptor(OpenExplorerViewletAction, OpenExplorerViewletAction.ID, OpenExplorerViewletAction.LABEL, openViewletKb),
70
	'View: Show Explorer',
71
	nls.localize('view', "View")
E
Erich Gamma 已提交
72 73 74
);

// Register file editors
B
Benjamin Pasero 已提交
75
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
B
Benjamin Pasero 已提交
76
	new EditorDescriptor(
77
		TextFileEditor.ID, // explicit dependency because we don't want these editors lazy loaded
E
Erich Gamma 已提交
78 79
		nls.localize('textFileEditor', "Text File Editor"),
		'vs/workbench/parts/files/browser/editors/textFileEditor',
B
Benjamin Pasero 已提交
80
		'TextFileEditor'
E
Erich Gamma 已提交
81 82 83 84 85 86
	),
	[
		new SyncDescriptor<EditorInput>(FileEditorInput)
	]
);

B
Benjamin Pasero 已提交
87
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
B
Benjamin Pasero 已提交
88
	new EditorDescriptor(
89
		BinaryFileEditor.ID, // explicit dependency because we don't want these editors lazy loaded
E
Erich Gamma 已提交
90 91
		nls.localize('binaryFileEditor', "Binary File Editor"),
		'vs/workbench/parts/files/browser/editors/binaryFileEditor',
B
Benjamin Pasero 已提交
92
		'BinaryFileEditor'
E
Erich Gamma 已提交
93 94 95 96 97 98
	),
	[
		new SyncDescriptor<EditorInput>(FileEditorInput)
	]
);

99 100 101 102 103 104
// Register default file input factory
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerFileInputFactory({
	createFileInput: (resource, encoding, instantiationService): IFileEditorInput => {
		return instantiationService.createInstance(FileEditorInput, resource, encoding);
	}
});
E
Erich Gamma 已提交
105 106

interface ISerializedFileInput {
107
	resource: string;
B
Benjamin Pasero 已提交
108
	resourceJSON: object;
109
	encoding?: string;
E
Erich Gamma 已提交
110 111 112 113 114
}

// Register Editor Input Factory
class FileEditorInputFactory implements IEditorInputFactory {

115
	constructor(
B
Benjamin Pasero 已提交
116
		@ITextResourceConfigurationService private configurationService: ITextResourceConfigurationService
117 118
	) {
	}
E
Erich Gamma 已提交
119 120

	public serialize(editorInput: EditorInput): string {
B
Benjamin Pasero 已提交
121
		const fileEditorInput = <FileEditorInput>editorInput;
122
		const resource = fileEditorInput.getResource();
B
Benjamin Pasero 已提交
123
		const fileInput: ISerializedFileInput = {
124
			resource: resource.toString(), // Keep for backwards compatibility
125 126
			resourceJSON: resource.toJSON(),
			encoding: fileEditorInput.getEncoding()
E
Erich Gamma 已提交
127 128 129 130 131
		};

		return JSON.stringify(fileInput);
	}

132 133 134 135 136
	public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): FileEditorInput {
		return instantiationService.invokeFunction<FileEditorInput>(accessor => {
			const fileInput: ISerializedFileInput = JSON.parse(serializedEditorInput);
			const resource = !!fileInput.resourceJSON ? URI.revive(fileInput.resourceJSON) : URI.parse(fileInput.resource);
			const encoding = fileInput.encoding;
E
Erich Gamma 已提交
137

138 139
			return accessor.get(IWorkbenchEditorService).createInput({ resource, encoding }) as FileEditorInput;
		});
E
Erich Gamma 已提交
140 141 142
	}
}

B
Benjamin Pasero 已提交
143
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditorInputFactory(FILE_EDITOR_INPUT_ID, FileEditorInputFactory);
E
Erich Gamma 已提交
144

145
// Register File Editor Tracker
B
Benjamin Pasero 已提交
146
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(
147
	FileEditorTracker
E
Erich Gamma 已提交
148 149
);

B
Benjamin Pasero 已提交
150 151 152 153 154
// Register Save Error Handler
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(
	SaveErrorHandler
);

155 156 157 158 159
// Register Dirty Files Tracker
Registry.as<IWorkbenchContributionsRegistry>(WorkbenchExtensions.Workbench).registerWorkbenchContribution(
	DirtyFilesTracker
);

E
Erich Gamma 已提交
160
// Configuration
B
Benjamin Pasero 已提交
161
const configurationRegistry = Registry.as<IConfigurationRegistry>(ConfigurationExtensions.Configuration);
E
Erich Gamma 已提交
162 163 164

configurationRegistry.registerConfiguration({
	'id': 'files',
165
	'order': 9,
166
	'title': nls.localize('filesConfigurationTitle', "Files"),
E
Erich Gamma 已提交
167 168 169 170
	'type': 'object',
	'properties': {
		'files.exclude': {
			'type': 'object',
B
Benjamin Pasero 已提交
171
			'description': nls.localize('exclude', "Configure glob patterns for excluding files and folders. For example, the files explorer decides which files and folders to show or hide based on this setting."),
P
Peter V 已提交
172
			'default': { '**/.git': true, '**/.svn': true, '**/.hg': true, '**/CVS': true, '**/.DS_Store': true },
S
Sandeep Somavarapu 已提交
173
			'scope': ConfigurationScope.RESOURCE,
E
Erich Gamma 已提交
174 175 176 177 178 179 180 181 182 183 184 185 186
			'additionalProperties': {
				'anyOf': [
					{
						'type': 'boolean',
						'description': nls.localize('files.exclude.boolean', "The glob pattern to match file paths against. Set to true or false to enable or disable the pattern."),
					},
					{
						'type': 'object',
						'properties': {
							'when': {
								'type': 'string', // expression ({ "**/*.js": { "when": "$(basename).js" } })
								'pattern': '\\w*\\$\\(basename\\)\\w*',
								'default': '$(basename).ext',
B
Benjamin Pasero 已提交
187
								'description': nls.localize('files.exclude.when', "Additional check on the siblings of a matching file. Use $(basename) as variable for the matching file name.")
E
Erich Gamma 已提交
188 189 190 191 192 193
							}
						}
					}
				]
			}
		},
B
Benjamin Pasero 已提交
194
		'files.associations': {
195
			'type': 'object',
B
Benjamin Pasero 已提交
196
			'description': nls.localize('associations', "Configure file associations to languages (e.g. \"*.extension\": \"html\"). These have precedence over the default associations of the languages installed."),
197
		},
E
Erich Gamma 已提交
198 199
		'files.encoding': {
			'type': 'string',
200
			'overridable': true,
E
Erich Gamma 已提交
201 202
			'enum': Object.keys(SUPPORTED_ENCODINGS),
			'default': 'utf8',
203
			'description': nls.localize('encoding', "The default character set encoding to use when reading and writing files. This setting can be configured per language too."),
204 205
			'scope': ConfigurationScope.RESOURCE,
			'enumDescriptions': Object.keys(SUPPORTED_ENCODINGS).map(key => SUPPORTED_ENCODINGS[key].labelLong)
E
Erich Gamma 已提交
206
		},
207
		'files.autoGuessEncoding': {
208
			'type': 'boolean',
209
			'overridable': true,
210
			'default': false,
211
			'description': nls.localize('autoGuessEncoding', "When enabled, will attempt to guess the character set encoding when opening files. This setting can be configured per language too."),
S
Sandeep Somavarapu 已提交
212
			'scope': ConfigurationScope.RESOURCE
213
		},
214 215 216 217 218 219 220
		'files.eol': {
			'type': 'string',
			'enum': [
				'\n',
				'\r\n'
			],
			'default': (platform.isLinux || platform.isMacintosh) ? '\n' : '\r\n',
221
			'description': nls.localize('eol', "The default end of line character. Use \\n for LF and \\r\\n for CRLF."),
222
			'scope': ConfigurationScope.RESOURCE
223
		},
E
Erich Gamma 已提交
224 225 226
		'files.trimTrailingWhitespace': {
			'type': 'boolean',
			'default': false,
227
			'description': nls.localize('trimTrailingWhitespace', "When enabled, will trim trailing whitespace when saving a file."),
S
Sandeep Somavarapu 已提交
228
			'overridable': true,
S
Sandeep Somavarapu 已提交
229
			'scope': ConfigurationScope.RESOURCE
230 231 232 233
		},
		'files.insertFinalNewline': {
			'type': 'boolean',
			'default': false,
234
			'description': nls.localize('insertFinalNewline', "When enabled, insert a final new line at the end of the file when saving it."),
S
Sandeep Somavarapu 已提交
235
			'overridable': true,
S
Sandeep Somavarapu 已提交
236
			'scope': ConfigurationScope.RESOURCE
237
		},
238 239
		'files.autoSave': {
			'type': 'string',
S
Sandeep Somavarapu 已提交
240
			'enum': [AutoSaveConfiguration.OFF, AutoSaveConfiguration.AFTER_DELAY, AutoSaveConfiguration.ON_FOCUS_CHANGE, , AutoSaveConfiguration.ON_WINDOW_CHANGE],
241
			'enumDescriptions': [
242 243 244 245
				nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'files.autoSave.off' }, "A dirty file is never automatically saved."),
				nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'files.autoSave.afterDelay' }, "A dirty file is automatically saved after the configured 'files.autoSaveDelay'."),
				nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'files.autoSave.onFocusChange' }, "A dirty file is automatically saved when the editor loses focus."),
				nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'files.autoSave.onWindowChange' }, "A dirty file is automatically saved when the window loses focus.")
246
			],
247
			'default': AutoSaveConfiguration.OFF,
B
Benjamin Pasero 已提交
248
			'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'autoSave' }, "Controls auto save of dirty files. Accepted values:  '{0}', '{1}', '{2}' (editor loses focus), '{3}' (window loses focus). If set to '{4}', you can configure the delay in 'files.autoSaveDelay'.", AutoSaveConfiguration.OFF, AutoSaveConfiguration.AFTER_DELAY, AutoSaveConfiguration.ON_FOCUS_CHANGE, AutoSaveConfiguration.ON_WINDOW_CHANGE, AutoSaveConfiguration.AFTER_DELAY)
249
		},
250
		'files.autoSaveDelay': {
251
			'type': 'number',
252
			'default': 1000,
B
Benjamin Pasero 已提交
253
			'description': nls.localize({ comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'], key: 'autoSaveDelay' }, "Controls the delay in ms after which a dirty file is saved automatically. Only applies when 'files.autoSave' is set to '{0}'", AutoSaveConfiguration.AFTER_DELAY)
254 255
		},
		'files.watcherExclude': {
256
			'type': 'object',
257
			'default': platform.isWindows /* https://github.com/Microsoft/vscode/issues/23954 */ ? { '**/.git/objects/**': true, '**/.git/subtree-cache/**': true, '**/node_modules/*/**': true } : { '**/.git/objects/**': true, '**/.git/subtree-cache/**': true, '**/node_modules/**': true },
B
Benjamin Pasero 已提交
258
			'description': nls.localize('watcherExclude', "Configure glob patterns of file paths to exclude from file watching. Patterns must match on absolute paths (i.e. prefix with ** or the full path to match properly). Changing this setting requires a restart. When you experience Code consuming lots of cpu time on startup, you can exclude large folders to reduce the initial load."),
S
Sandeep Somavarapu 已提交
259
			'scope': ConfigurationScope.RESOURCE
D
Daniel Imms 已提交
260 261
		},
		'files.hotExit': {
262
			'type': 'string',
D
Daniel Imms 已提交
263 264
			'enum': [HotExitConfiguration.OFF, HotExitConfiguration.ON_EXIT, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE],
			'default': HotExitConfiguration.ON_EXIT,
D
Daniel Imms 已提交
265 266
			'enumDescriptions': [
				nls.localize('hotExit.off', 'Disable hot exit.'),
B
Benjamin Pasero 已提交
267
				nls.localize('hotExit.onExit', 'Hot exit will be triggered when the application is closed, that is when the last window is closed on Windows/Linux or when the workbench.action.quit command is triggered (command palette, keybinding, menu). All windows with backups will be restored upon next launch.'),
268
				nls.localize('hotExit.onExitAndWindowClose', 'Hot exit will be triggered when the application is closed, that is when the last window is closed on Windows/Linux or when the workbench.action.quit command is triggered (command palette, keybinding, menu), and also for any window with a folder opened regardless of whether it\'s the last window. All windows without folders opened will be restored upon next launch. To restore folder windows as they were before shutdown set "window.restoreWindows" to "all".')
D
Daniel Imms 已提交
269 270
			],
			'description': nls.localize('hotExit', "Controls whether unsaved files are remembered between sessions, allowing the save prompt when exiting the editor to be skipped.", HotExitConfiguration.ON_EXIT, HotExitConfiguration.ON_EXIT_AND_WINDOW_CLOSE)
271
		},
272
		'files.useExperimentalFileWatcher': {
273 274
			'type': 'boolean',
			'default': false,
275
			'description': nls.localize('useExperimentalFileWatcher', "Use the new experimental file watcher.")
276
		},
277 278 279
		'files.defaultLanguage': {
			'type': 'string',
			'description': nls.localize('defaultLanguage', "The default language mode that is assigned to new files.")
280 281 282 283 284 285
		}
	}
});

configurationRegistry.registerConfiguration({
	id: 'editor',
286 287
	order: 5,
	title: nls.localize('editorConfigurationTitle', "Editor"),
288 289
	type: 'object',
	properties: {
290 291 292
		'editor.formatOnSave': {
			'type': 'boolean',
			'default': false,
293 294
			'description': nls.localize('formatOnSave', "Format a file on save. A formatter must be available, the file must not be auto-saved, and editor must not be shutting down."),
			'overridable': true
E
Erich Gamma 已提交
295 296 297 298 299 300
		}
	}
});

configurationRegistry.registerConfiguration({
	'id': 'explorer',
301
	'order': 10,
302
	'title': nls.localize('explorerConfigurationTitle', "File Explorer"),
E
Erich Gamma 已提交
303 304
	'type': 'object',
	'properties': {
305
		'explorer.openEditors.visible': {
E
Erich Gamma 已提交
306
			'type': 'number',
I
isidor 已提交
307
			'description': nls.localize({ key: 'openEditorsVisible', comment: ['Open is an adjective'] }, "Number of editors shown in the Open Editors pane. Set it to 0 to hide the pane."),
E
Erich Gamma 已提交
308 309
			'default': 9
		},
310
		'explorer.openEditors.dynamicHeight': {
E
Erich Gamma 已提交
311
			'type': 'boolean',
I
isidor 已提交
312
			'description': nls.localize({ key: 'dynamicHeight', comment: ['Open is an adjective'] }, "Controls if the height of the open editors section should adapt dynamically to the number of elements or not."),
E
Erich Gamma 已提交
313
			'default': true
314 315 316
		},
		'explorer.autoReveal': {
			'type': 'boolean',
317
			'description': nls.localize('autoReveal', "Controls if the explorer should automatically reveal and select files when opening them."),
318
			'default': true
319 320 321 322 323
		},
		'explorer.enableDragAndDrop': {
			'type': 'boolean',
			'description': nls.localize('enableDragAndDrop', "Controls if the explorer should allow to move files and folders via drag and drop."),
			'default': true
324 325 326 327 328 329
		},
		'explorer.sortOrder': {
			'type': 'string',
			'enum': [SortOrderConfiguration.DEFAULT, SortOrderConfiguration.MIXED, SortOrderConfiguration.FILES_FIRST, SortOrderConfiguration.TYPE, SortOrderConfiguration.MODIFIED],
			'default': SortOrderConfiguration.DEFAULT,
			'enumDescriptions': [
B
Benjamin Pasero 已提交
330 331 332 333 334
				nls.localize('sortOrder.default', 'Files and folders are sorted by their names, in alphabetical order. Folders are displayed before files.'),
				nls.localize('sortOrder.mixed', 'Files and folders are sorted by their names, in alphabetical order. Files are interwoven with folders.'),
				nls.localize('sortOrder.filesFirst', 'Files and folders are sorted by their names, in alphabetical order. Files are displayed before folders.'),
				nls.localize('sortOrder.type', 'Files and folders are sorted by their extensions, in alphabetical order. Folders are displayed before files.'),
				nls.localize('sortOrder.modified', 'Files and folders are sorted by last modified date, in descending order. Folders are displayed before files.')
335
			],
336
			'description': nls.localize({ key: 'sortOrder', comment: ['This is the description for a setting. Values surrounded by single quotes are not to be translated.'] }, "Controls sorting order of files and folders in the explorer. In addition to the default sorting, you can set the order to 'mixed' (files and folders sorted combined), 'type' (by file type), 'modified' (by last modified date) or 'filesFirst' (sort files before folders).")
E
Erich Gamma 已提交
337 338
		}
	}
B
Benjamin Pasero 已提交
339
});