Change:
VSCode Version: 1.2.1 OS Version: Windows 10 64x Steps to Reproduce: create new file, before save file with '.js' extension and the manual language selection, need to have option to default language e.g. JavaScript, not plaintext as default
We would need to introduce a workbench configuration such that there is a default language mode for new files opened. Such that it is being picked up before a user manuly chooses a mode or sets the file extension.
I would think this could also be done nicely from an extension.
This is one of my key uses from PowerShell ISE that is hard to convert over to VS Code. I use the Untitled page often to construct commands and scripts rather than doing it in terminal because its much easier to edit and I'm not wanting to save it just yet. The trick though is this is Visual Studio Code and versatile so sometimes I will want the default to be different based on the language I'm focusing on in a given period. The two ways to handle this would be: Command Line option to select default language on startup. File New --Language menu options The first option allows me to create a shortcut focused on my language. VS Code PowerShell and VS Code C#. It would also make it easier for extensions to configure the environment more for their use if they knew someone was starting it up as their language. The second option should not be defaults, but rather configurations for me to add my own list to the File menu. I like both approaches but if I had to choose one, the first I think could be more useful.
I just looked into making an extension for this but there doesn't seem to be an API to change the language ID of a TextDocument. I tried passing the language ID as a parameter to but it always displays the quick pick dialog. Any ideas?
I think this can be done via a new command using the new API:
That doesn't work for new files that the user creates using "File -New", "Files: New File" or double-clicking in the tab area. Though maybe I should just send a PR to VS Code to add an official setting for default language mode :)
Oh yeah, but I would start with an extension first to see how it works. You can easily map it to Ctrl+N for "New File" by default.
All in all, also not opposed to seeing a PR on this, e.g. could be something like editor.defaultLanguage or file.defaultMode.
maybe? Not sure that most users know what a "mode" is.
I'm going to work on this today!
Verify: a new setting allows to configure the default language mode a new untitled file should get you can still change the mode from the picker and the untitled file will keep this association even between restarts

Discussion:
return this.provideExcludeCompletionItems(location, range); } <ins> // files.defaultLanguage if (location.path[0] === 'files.defaultLanguage') { return this.provideLanguageCompletionItems(location, range); } </ins> return this.provideLanguageOverridesCompletionItems(location, position); }

return Promise.resolve(completions); } <del> private provideLanguageCompletionItems(location: Location, range: vscode.Range, stringify: boolean = true): vscode.ProviderResult<vscode.CompletionItem[]> { </del> <ins> private provideLanguageCompletionItems(location: Location, range: vscode.Range, formatFunc: (string) => string = (l) => JSON.stringify(l)): vscode.ProviderResult<vscode.CompletionItem[]> { </ins> return vscode.languages.getLanguages().then(languages => { return languages.map(l => { <del> return this.newSimpleCompletionItem(stringify ? JSON.stringify(l) : l, range); </del> <ins> return this.newSimpleCompletionItem(formatFunc(l), range); </ins> }); }); }

} if (location.path.length === 1 && location.previousNode && typeof location.previousNode.value === 'string' && location.previousNode.value.startsWith('[')) { <del> // Suggestion model word matching includes starting quote and open sqaure bracket // Hence exclude them from the proposal range range = new vscode.Range(new vscode.Position(range.start.line, range.start.character + 2), range.end); return vscode.languages.getLanguages().then(languages => { return languages.map(l => { // Suggestion model word matching includes closed sqaure bracket and ending quote // Hence include them in the proposal to replace return this.newSimpleCompletionItem(l, range, '', l + ']"'); }); }); </del> <ins> // Suggestion model word matching includes closed sqaure bracket and ending quote // Hence include them in the proposal to replace return this.provideLanguageCompletionItems(location, range, language => `"[${language}]"`); </ins> } return Promise.resolve([]); }

exclude: glob.IExpression; watcherExclude: { [filepattern: string]: boolean }; encoding: string; <ins> defaultLanguage: string; </ins> trimTrailingWhitespace: boolean; autoSave: string; autoSaveDelay: number;

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 pallete, 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.reopenFolders" to "all".') ], '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) <ins> }, 'files.defaultLanguage': { 'type': 'string', 'description': nls.localize('defaultLanguage', "The default language mode that is assigned to new files.") </ins> } } });

import { createDecorator, IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; import arrays = require('vs/base/common/arrays'); import { UntitledEditorInput } from 'vs/workbench/common/editor/untitledEditorInput'; <ins> import { IFilesConfiguration } from 'vs/platform/files/common/files'; import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; </ins> import Event, { Emitter, once } from 'vs/base/common/event'; export const IUntitledEditorService = createDecorator<IUntitledEditorService>('untitledEditorService');

private _onDidDisposeModel: Emitter<URI>; constructor( <del> @IInstantiationService private instantiationService: IInstantiationService </del> <ins> @IInstantiationService private instantiationService: IInstantiationService, @IConfigurationService private configurationService: IConfigurationService </ins> ) { this._onDidChangeContent = new Emitter<URI>(); this._onDidChangeDirty = new Emitter<URI>();

} while (Object.keys(UntitledEditorService.CACHE).indexOf(resource.toString()) >= 0); } <ins> const configuration = this.configurationService.getConfiguration<IFilesConfiguration>(); if (!modeId && configuration.files && configuration.files.defaultLanguage) { modeId = configuration.files.defaultLanguage; } </ins> const input = this.instantiationService.createInstance(UntitledEditorInput, resource, hasAssociatedFilePath, modeId, initialValue); const contentListener = input.onDidModelChangeContent(() => {

import { TPromise } from 'vs/base/common/winjs.base'; import { join } from 'vs/base/common/paths'; import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation'; <ins> import { TestInstantiationService } from 'vs/platform/instantiation/test/common/instantiationServiceMock'; </ins> import { IUntitledEditorService, UntitledEditorService } from 'vs/workbench/services/untitled/common/untitledEditorService'; <ins> import { IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService'; </ins> import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices'; import { UntitledEditorModel } from 'vs/workbench/common/editor/untitledEditorModel'; <ins> import { IModeService } from 'vs/editor/common/services/modeService'; import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl'; </ins> class ServiceAccessor { <del> constructor( @IUntitledEditorService public untitledEditorService: UntitledEditorService) { </del> <ins> constructor( @IUntitledEditorService public untitledEditorService: UntitledEditorService, @IModeService public modeService: ModeServiceImpl, @IConfigurationService public testConfigurationService: TestConfigurationService) { </ins> } }

}); }); <ins> test('Untitled created with files.defaultLanguage setting', function (done) { const defaultLanguage = 'javascript'; const config = accessor.testConfigurationService; config.setUserConfiguration('files', { 'defaultLanguage': defaultLanguage }); const service = accessor.untitledEditorService; const input = service.createOrGet(); input.resolve().then((model: UntitledEditorModel) => { assert.equal(model.getModeId(), defaultLanguage); config.setUserConfiguration('files', { 'defaultLanguage': undefined }); input.dispose(); done(); }); }); test('Untitled created with modeId overrides files.defaultLanguage setting', function (done) { const modeId = 'typescript'; const defaultLanguage = 'javascript'; const config = accessor.testConfigurationService; config.setUserConfiguration('files', { 'defaultLanguage': defaultLanguage }); const service = accessor.untitledEditorService; const input = service.createOrGet(null, modeId); input.resolve().then((model: UntitledEditorModel) => { assert.equal(model.getModeId(), modeId); config.setUserConfiguration('files', { 'defaultLanguage': undefined }); input.dispose(); done(); }); }); </ins> test('encoding change event', function (done) { const service = accessor.untitledEditorService; const input = service.createOrGet();