mirror of
https://github.com/Microsoft/vscode
synced 2024-08-27 21:09:43 +00:00
Allow to configure "files.defaultLanguage" to use current language (fix #78903)
This commit is contained in:
parent
0bce136f24
commit
0fd2883856
|
@ -34,7 +34,11 @@ export class SettingsDocument {
|
|||
|
||||
// files.defaultLanguage
|
||||
if (location.path[0] === 'files.defaultLanguage') {
|
||||
return this.provideLanguageCompletionItems(location, range);
|
||||
return this.provideLanguageCompletionItems(location, range).then(items => {
|
||||
|
||||
// Add special item 'active-editor'
|
||||
return [this.newSimpleCompletionItem(JSON.stringify('active-editor'), range, localize('activeEditor', "Use the language mode of the currently active text editor if any")), ...items];
|
||||
});
|
||||
}
|
||||
|
||||
return this.provideLanguageOverridesCompletionItems(location, position);
|
||||
|
@ -153,7 +157,7 @@ export class SettingsDocument {
|
|||
return Promise.resolve(completions);
|
||||
}
|
||||
|
||||
private provideLanguageCompletionItems(_location: Location, range: vscode.Range, formatFunc: (string: string) => string = (l) => JSON.stringify(l)): vscode.ProviderResult<vscode.CompletionItem[]> {
|
||||
private provideLanguageCompletionItems(_location: Location, range: vscode.Range, formatFunc: (string: string) => string = (l) => JSON.stringify(l)): Thenable<vscode.CompletionItem[]> {
|
||||
return vscode.languages.getLanguages().then(languages => {
|
||||
const completionItems = [];
|
||||
const configuration = vscode.workspace.getConfiguration();
|
||||
|
|
|
@ -115,7 +115,7 @@ class RenameController implements IEditorContribution {
|
|||
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
|
||||
@IThemeService private readonly _themeService: IThemeService,
|
||||
) {
|
||||
this._renameInputField = new IdleValue(() => this._dispoableStore.add(new RenameInputField(this.editor, this._themeService, this._contextKeyService)));
|
||||
this._renameInputField = this._dispoableStore.add(new IdleValue(() => this._dispoableStore.add(new RenameInputField(this.editor, this._themeService, this._contextKeyService))));
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
|
|
|
@ -121,7 +121,7 @@ export class SuggestController implements IEditorContribution {
|
|||
this.editor = editor;
|
||||
this.model = new SuggestModel(this.editor, editorWorker);
|
||||
|
||||
this.widget = new IdleValue(() => {
|
||||
this.widget = this._toDispose.add(new IdleValue(() => {
|
||||
|
||||
const widget = this._instantiationService.createInstance(SuggestWidget, this.editor);
|
||||
|
||||
|
@ -168,11 +168,11 @@ export class SuggestController implements IEditorContribution {
|
|||
|
||||
|
||||
return widget;
|
||||
});
|
||||
}));
|
||||
|
||||
this._alternatives = new IdleValue(() => {
|
||||
this._alternatives = this._toDispose.add(new IdleValue(() => {
|
||||
return this._toDispose.add(new SuggestAlternatives(this.editor, this._contextKeyService));
|
||||
});
|
||||
}));
|
||||
|
||||
this._toDispose.add(_instantiationService.createInstance(WordContextKey, editor));
|
||||
|
||||
|
|
|
@ -28,19 +28,21 @@ export class UntitledTextEditorInput extends TextEditorInput implements IEncodin
|
|||
|
||||
private static readonly MEMOIZER = createMemoizer();
|
||||
|
||||
private cachedModel: UntitledTextEditorModel | null = null;
|
||||
private modelResolve: Promise<UntitledTextEditorModel & IResolvedTextEditorModel> | null = null;
|
||||
|
||||
private readonly _onDidModelChangeContent = this._register(new Emitter<void>());
|
||||
readonly onDidModelChangeContent = this._onDidModelChangeContent.event;
|
||||
|
||||
private readonly _onDidModelChangeEncoding = this._register(new Emitter<void>());
|
||||
readonly onDidModelChangeEncoding = this._onDidModelChangeEncoding.event;
|
||||
|
||||
private cachedModel: UntitledTextEditorModel | null = null;
|
||||
private modelResolve: Promise<UntitledTextEditorModel & IResolvedTextEditorModel> | null = null;
|
||||
|
||||
private preferredMode: string | undefined;
|
||||
|
||||
constructor(
|
||||
resource: URI,
|
||||
private readonly _hasAssociatedFilePath: boolean,
|
||||
private preferredMode: string | undefined,
|
||||
preferredMode: string | undefined,
|
||||
private readonly initialValue: string | undefined,
|
||||
private preferredEncoding: string | undefined,
|
||||
@IInstantiationService private readonly instantiationService: IInstantiationService,
|
||||
|
@ -52,6 +54,10 @@ export class UntitledTextEditorInput extends TextEditorInput implements IEncodin
|
|||
) {
|
||||
super(resource, editorService, editorGroupService, textFileService);
|
||||
|
||||
if (preferredMode) {
|
||||
this.setMode(preferredMode);
|
||||
}
|
||||
|
||||
this.registerListeners();
|
||||
}
|
||||
|
||||
|
@ -225,10 +231,20 @@ export class UntitledTextEditorInput extends TextEditorInput implements IEncodin
|
|||
}
|
||||
|
||||
setMode(mode: string): void {
|
||||
this.preferredMode = mode;
|
||||
let actualMode: string | undefined = undefined;
|
||||
if (mode === 'active-editor') {
|
||||
// support the special 'active-editor' mode by
|
||||
// looking up the language mode from the currently
|
||||
// active text editor if any
|
||||
actualMode = this.editorService.activeTextEditorMode;
|
||||
} else {
|
||||
actualMode = mode;
|
||||
}
|
||||
|
||||
if (this.cachedModel) {
|
||||
this.cachedModel.setMode(mode);
|
||||
this.preferredMode = actualMode;
|
||||
|
||||
if (this.preferredMode && this.cachedModel) {
|
||||
this.cachedModel.setMode(this.preferredMode);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -314,7 +314,7 @@ configurationRegistry.registerConfiguration({
|
|||
'files.hotExit': hotExitConfiguration,
|
||||
'files.defaultLanguage': {
|
||||
'type': 'string',
|
||||
'description': nls.localize('defaultLanguage', "The default language mode that is assigned to new files.")
|
||||
'description': nls.localize('defaultLanguage', "The default language mode that is assigned to new files. If configured to `active-editor`, will use the language mode of the currently active text editor if any.")
|
||||
},
|
||||
'files.maxMemoryForLargeFilesMB': {
|
||||
'type': 'number',
|
||||
|
|
|
@ -186,6 +186,19 @@ export class EditorService extends Disposable implements EditorServiceImpl {
|
|||
return undefined;
|
||||
}
|
||||
|
||||
get activeTextEditorMode(): string | undefined {
|
||||
let activeCodeEditor: ICodeEditor | undefined = undefined;
|
||||
|
||||
const activeTextEditorWidget = this.activeTextEditorWidget;
|
||||
if (isDiffEditor(activeTextEditorWidget)) {
|
||||
activeCodeEditor = activeTextEditorWidget.getModifiedEditor();
|
||||
} else {
|
||||
activeCodeEditor = activeTextEditorWidget;
|
||||
}
|
||||
|
||||
return activeCodeEditor?.getModel()?.getLanguageIdentifier().language;
|
||||
}
|
||||
|
||||
get count(): number {
|
||||
return this.editorsObserver.count;
|
||||
}
|
||||
|
@ -839,6 +852,7 @@ export class DelegatingEditorService implements IEditorService {
|
|||
get activeEditor(): IEditorInput | undefined { return this.editorService.activeEditor; }
|
||||
get activeControl(): IVisibleEditor | undefined { return this.editorService.activeControl; }
|
||||
get activeTextEditorWidget(): ICodeEditor | IDiffEditor | undefined { return this.editorService.activeTextEditorWidget; }
|
||||
get activeTextEditorMode(): string | undefined { return this.editorService.activeTextEditorMode; }
|
||||
get visibleEditors(): ReadonlyArray<IEditorInput> { return this.editorService.visibleEditors; }
|
||||
get visibleControls(): ReadonlyArray<IVisibleEditor> { return this.editorService.visibleControls; }
|
||||
get visibleTextEditorWidgets(): ReadonlyArray<ICodeEditor | IDiffEditor> { return this.editorService.visibleTextEditorWidgets; }
|
||||
|
|
|
@ -105,6 +105,13 @@ export interface IEditorService {
|
|||
*/
|
||||
readonly activeTextEditorWidget: ICodeEditor | IDiffEditor | undefined;
|
||||
|
||||
/**
|
||||
* The currently active text editor mode or `undefined` if there is currently no active
|
||||
* editor or the active editor widget is neither a text nor a diff editor. If the active
|
||||
* editor is a diff editor, the modified side's mode will be taken.
|
||||
*/
|
||||
readonly activeTextEditorMode: string | undefined;
|
||||
|
||||
/**
|
||||
* All editors that are currently visible. An editor is visible when it is opened in an
|
||||
* editor group and active in that group. Multiple editor groups can be opened at the same time.
|
||||
|
|
|
@ -31,7 +31,7 @@ import { UntitledTextEditorModel } from 'vs/workbench/common/editor/untitledText
|
|||
import { NullFileSystemProvider } from 'vs/platform/files/test/common/nullFileSystemProvider';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { NullTelemetryService } from 'vs/platform/telemetry/common/telemetryUtils';
|
||||
import { CancellationToken } from 'vscode';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
|
||||
const TEST_EDITOR_ID = 'MyTestEditorForEditorService';
|
||||
const TEST_EDITOR_INPUT_ID = 'testEditorInputForEditorService';
|
||||
|
@ -163,6 +163,7 @@ suite('EditorService', () => {
|
|||
assert.equal(service.visibleControls.length, 1);
|
||||
assert.equal(service.visibleControls[0], editor);
|
||||
assert.ok(!service.activeTextEditorWidget);
|
||||
assert.ok(!service.activeTextEditorMode);
|
||||
assert.equal(service.visibleTextEditorWidgets.length, 0);
|
||||
assert.equal(service.isOpen(input), true);
|
||||
assert.equal(service.getOpened({ resource: input.getResource() }), input);
|
||||
|
|
|
@ -9,7 +9,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
|||
import { IUntitledTextEditorService, UntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { TestConfigurationService } from 'vs/platform/configuration/test/common/testConfigurationService';
|
||||
import { workbenchInstantiationService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { workbenchInstantiationService, TestEditorService } from 'vs/workbench/test/workbenchTestServices';
|
||||
import { UntitledTextEditorModel } from 'vs/workbench/common/editor/untitledTextEditorModel';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { ModeServiceImpl } from 'vs/editor/common/services/modeServiceImpl';
|
||||
|
@ -18,6 +18,7 @@ import { timeout } from 'vs/base/common/async';
|
|||
import { snapshotToString } from 'vs/workbench/services/textfile/common/textfiles';
|
||||
import { ModesRegistry, PLAINTEXT_MODE_ID } from 'vs/editor/common/modes/modesRegistry';
|
||||
import { IWorkingCopyService, IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService';
|
||||
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
|
||||
|
||||
export class TestUntitledTextEditorService extends UntitledTextEditorService {
|
||||
get(resource: URI) { return super.get(resource); }
|
||||
|
@ -27,10 +28,11 @@ export class TestUntitledTextEditorService extends UntitledTextEditorService {
|
|||
class ServiceAccessor {
|
||||
constructor(
|
||||
@IUntitledTextEditorService public readonly untitledTextEditorService: TestUntitledTextEditorService,
|
||||
@IEditorService public readonly editorService: TestEditorService,
|
||||
@IWorkingCopyService public readonly workingCopyService: IWorkingCopyService,
|
||||
@IModeService public readonly modeService: ModeServiceImpl,
|
||||
@IConfigurationService public readonly testConfigurationService: TestConfigurationService) {
|
||||
}
|
||||
@IConfigurationService public readonly testConfigurationService: TestConfigurationService
|
||||
) { }
|
||||
}
|
||||
|
||||
suite('Workbench untitled text editors', () => {
|
||||
|
@ -234,6 +236,23 @@ suite('Workbench untitled text editors', () => {
|
|||
input.dispose();
|
||||
});
|
||||
|
||||
test('Untitled created with files.defaultLanguage setting (active-editor)', () => {
|
||||
const config = accessor.testConfigurationService;
|
||||
config.setUserConfiguration('files', { 'defaultLanguage': 'active-editor' });
|
||||
|
||||
accessor.editorService.activeTextEditorMode = 'typescript';
|
||||
|
||||
const service = accessor.untitledTextEditorService;
|
||||
const input = service.createOrGet();
|
||||
|
||||
assert.equal(input.getMode(), 'typescript');
|
||||
|
||||
config.setUserConfiguration('files', { 'defaultLanguage': undefined });
|
||||
accessor.editorService.activeTextEditorMode = undefined;
|
||||
|
||||
input.dispose();
|
||||
});
|
||||
|
||||
test('Untitled created with mode overrides files.defaultLanguage setting', () => {
|
||||
const mode = 'typescript';
|
||||
const defaultLanguage = 'javascript';
|
||||
|
|
|
@ -905,6 +905,7 @@ export class TestEditorService implements EditorServiceImpl {
|
|||
|
||||
activeControl!: IVisibleEditor;
|
||||
activeTextEditorWidget: any;
|
||||
activeTextEditorMode: any;
|
||||
activeEditor!: IEditorInput;
|
||||
editors: ReadonlyArray<IEditorInput> = [];
|
||||
mostRecentlyActiveEditors: ReadonlyArray<IEditorIdentifier> = [];
|
||||
|
|
Loading…
Reference in a new issue