Skip to content

Commit

Permalink
Fix
Browse files Browse the repository at this point in the history
Signed-off-by: Anatoliy Bazko <abazko@redhat.com>
  • Loading branch information
tolusha committed Apr 26, 2019
1 parent a061b49 commit 3ddca95
Show file tree
Hide file tree
Showing 9 changed files with 127 additions and 3 deletions.
3 changes: 3 additions & 0 deletions packages/core/src/browser/frontend-application-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,7 @@ import { QuickPickService, quickPickServicePath } from '../common/quick-pick-ser
import { ContextKeyService } from './context-key-service';
import { ResourceContextKey } from './resource-context-key';
import { KeyboardLayoutService } from './keyboard/keyboard-layout-service';
import { MimeService } from './mime-service';

export const frontendApplicationModule = new ContainerModule((bind, unbind, isBound, rebind) => {
const themeService = ThemeService.get();
Expand Down Expand Up @@ -249,4 +250,6 @@ export const frontendApplicationModule = new ContainerModule((bind, unbind, isBo
);

bindCorePreferences(bind);

bind(MimeService).toSelf().inSingletonScope();
});
30 changes: 30 additions & 0 deletions packages/core/src/browser/mime-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,30 @@
/********************************************************************************
* Copyright (C) 2019 Red Hat, Inc. and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { injectable } from 'inversify';

export interface MimeAssociation {
readonly id: string;
readonly filepattern: string;
}

@injectable()
export class MimeService {
// should be overridden by an implementation
setAssociations(associations: MimeAssociation[]): void {
/* no-op by default */
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -20,9 +20,11 @@ import { MaybePromise } from '@theia/core/lib/common';
import {
FrontendApplicationContribution, ApplicationShell,
NavigatableWidget, NavigatableWidgetOptions,
Saveable, WidgetManager, StatefulWidget
Saveable, WidgetManager, StatefulWidget, FrontendApplication
} from '@theia/core/lib/browser';
import { FileSystemWatcher, FileChangeEvent, FileMoveEvent, FileChangeType } from './filesystem-watcher';
import { MimeService } from '@theia/core/lib/browser/mime-service';
import { FileSystemPreferences } from './filesystem-preferences';

@injectable()
export class FileSystemFrontendContribution implements FrontendApplicationContribution {
Expand All @@ -36,11 +38,26 @@ export class FileSystemFrontendContribution implements FrontendApplicationContri
@inject(FileSystemWatcher)
protected readonly fileSystemWatcher: FileSystemWatcher;

@inject(MimeService)
protected readonly mimeService: MimeService;

@inject(FileSystemPreferences)
protected readonly preferences: FileSystemPreferences;

initialize(): void {
this.fileSystemWatcher.onFilesChanged(event => this.run(() => this.updateWidgets(event)));
this.fileSystemWatcher.onDidMove(event => this.run(() => this.moveWidgets(event)));
}

onStart?(app: FrontendApplication): MaybePromise<void> {
this.updateAssociations();
this.preferences.onPreferenceChanged(e => {
if (e.preferenceName === 'files.associations') {
this.updateAssociations();
}
});
}

protected pendingOperation = Promise.resolve();
protected run(operation: () => MaybePromise<void>): Promise<void> {
return this.pendingOperation = this.pendingOperation.then(async () => {
Expand Down Expand Up @@ -141,4 +158,9 @@ export class FileSystemFrontendContribution implements FrontendApplicationContri
}
}

protected updateAssociations(): void {
const fileAssociations = this.preferences['files.associations'];
const mimeAssociations = Object.keys(fileAssociations).map(filepattern => ({ id: fileAssociations[filepattern], filepattern }));
this.mimeService.setAssociations(mimeAssociations);
}
}
6 changes: 6 additions & 0 deletions packages/filesystem/src/browser/filesystem-preferences.ts
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,11 @@ export const filesystemPreferenceSchema: PreferenceSchema = {
'type': 'boolean',
'default': true,
'description': 'Moves files/folders to the OS trash (recycle bin on Windows) when deleting. Disabling this will delete files/folders permanently.'
},
'files.associations': {
'type': 'object',
'description': 'Configure file associations to languages (e.g. \"*.extension\": \"html\"). \
These have precedence over the default associations of the languages installed.'
}
}
};
Expand All @@ -56,6 +61,7 @@ export interface FileSystemConfiguration {
'files.watcherExclude': { [globPattern: string]: boolean };
'files.exclude': { [key: string]: boolean };
'files.enableTrash': boolean;
'files.associations': { [filepattern: string]: string };
}

export const FileSystemPreferences = Symbol('FileSystemPreferences');
Expand Down
5 changes: 5 additions & 0 deletions packages/monaco/src/browser/monaco-frontend-module.ts
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ import { OutlineTreeDecorator } from '@theia/outline-view/lib/browser/outline-de
import { MonacoSnippetSuggestProvider } from './monaco-snippet-suggest-provider';
import { ContextKeyService } from '@theia/core/lib/browser/context-key-service';
import { MonacoContextKeyService } from './monaco-context-key-service';
import { MonacoMimeService } from './monaco-mime-service';
import { MimeService } from '@theia/core/lib/browser/mime-service';

const deepmerge: (args: object[]) => object = require('deepmerge').default.all;

Expand Down Expand Up @@ -119,6 +121,9 @@ export default new ContainerModule((bind, unbind, isBound, rebind) => {

bind(MonacoOutlineDecorator).toSelf().inSingletonScope();
bind(OutlineTreeDecorator).toService(MonacoOutlineDecorator);

bind(MonacoMimeService).toSelf().inSingletonScope();
rebind(MimeService).toService(MonacoMimeService);
});

export const MonacoConfigurationService = Symbol('MonacoConfigurationService');
Expand Down
4 changes: 3 additions & 1 deletion packages/monaco/src/browser/monaco-loader.ts
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ export function loadMonaco(vsRequire: any): Promise<void> {
'vs/platform/keybinding/common/usLayoutResolvedKeybinding',
'vs/base/common/keybindingLabels',
'vs/base/common/keyCodes',
'vs/base/common/mime',
'vs/editor/browser/editorExtensions',
'vs/editor/standalone/browser/simpleServices',
'vs/editor/standalone/browser/standaloneServices',
Expand All @@ -76,7 +77,7 @@ export function loadMonaco(vsRequire: any): Promise<void> {
'vs/platform/contextkey/browser/contextKeyService'
], (css: any, html: any, commands: any, actions: any,
keybindingsRegistry: any, keybindingResolver: any, resolvedKeybinding: any, keybindingLabels: any,
keyCodes: any, editorExtensions: any, simpleServices: any, standaloneServices: any, quickOpen: any, quickOpenWidget: any, quickOpenModel: any,
keyCodes: any, mime: any, editorExtensions: any, simpleServices: any, standaloneServices: any, quickOpen: any, quickOpenWidget: any, quickOpenModel: any,
filters: any, styler: any, platform: any, modes: any, suggest: any, suggestController: any, findController: any, rename: any, snippetParser: any,
configuration: any, configurationModels: any,
codeEditorService: any, codeEditorServiceImpl: any,
Expand All @@ -99,6 +100,7 @@ export function loadMonaco(vsRequire: any): Promise<void> {
global.monaco.snippetParser = snippetParser;
global.monaco.contextkey = contextKey;
global.monaco.contextKeyService = contextKeyService;
global.monaco.mime = mime;
resolve();
});
});
Expand Down
41 changes: 41 additions & 0 deletions packages/monaco/src/browser/monaco-mime-service.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,41 @@
/********************************************************************************
* Copyright (C) 2019 Red Hat, Inc. and others.
*
* This program and the accompanying materials are made available under the
* terms of the Eclipse Public License v. 2.0 which is available at
* http://www.eclipse.org/legal/epl-2.0.
*
* This Source Code may also be made available under the following Secondary
* Licenses when the conditions for such availability set forth in the Eclipse
* Public License v. 2.0 are satisfied: GNU General Public License, version 2
* with the GNU Classpath Exception which is available at
* https://www.gnu.org/software/classpath/license.html.
*
* SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
********************************************************************************/

import { MimeAssociation, MimeService } from '@theia/core/lib/browser/mime-service';
import { injectable } from 'inversify';

@injectable()
export class MonacoMimeService extends MimeService {

setAssociations(associations: MimeAssociation[]): void {
monaco.mime.clearTextMimes(true);

for (const association of associations) {
const mimetype = this.getMimeForMode(association.id) || `text/x-${association.id}`;
monaco.mime.registerTextMime({ id: association.id, mime: mimetype, filepattern: association.filepattern, userConfigured: true }, false);
}
}

protected getMimeForMode(langId: string): string | undefined {
for (const language of monaco.languages.getLanguages()) {
if (language.id === langId && language.mimetypes) {
return language.mimetypes[0];
}
}

return undefined;
}
}
16 changes: 16 additions & 0 deletions packages/monaco/src/typings/monaco/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1112,3 +1112,19 @@ declare module monaco.contextkey {
static deserialize(when: string): ContextKeyExpr;
}
}

declare module monaco.mime {
export interface ITextMimeAssociation {
readonly id: string;
readonly mime: string;
readonly filename?: string;
readonly extension?: string;
readonly filepattern?: string;
readonly firstline?: RegExp;
readonly userConfigured?: boolean;
}

export function registerTextMime(association: monaco.mime.ITextMimeAssociation, warnOnOverwrite: boolean): void

export function clearTextMimes(onlyUserConfigured?: boolean): void;
}
1 change: 0 additions & 1 deletion packages/plugin-ext/src/plugin/preference-registry.ts
Original file line number Diff line number Diff line change
Expand Up @@ -80,7 +80,6 @@ export class PreferenceRegistryExtImpl implements PreferenceRegistryExt {
}

init(data: PreferenceData): void {
data[PreferenceScope.Default]['files.associations'] = {};
this._preferences = this.parse(data);
}

Expand Down

0 comments on commit 3ddca95

Please sign in to comment.