提交 4cd0bf09 编写于 作者: B Benjamin Pasero

debt: get rid of mime in file input

上级 d1023ee9
......@@ -14,6 +14,7 @@ export let MIME_BINARY = 'application/octet-stream';
export let MIME_UNKNOWN = 'application/unknown';
export interface ITextMimeAssociation {
id: string;
mime: string;
filename?: string;
extension?: string;
......@@ -75,6 +76,7 @@ export function registerTextMime(association: ITextMimeAssociation): void {
function toTextMimeAssociationItem(association: ITextMimeAssociation): ITextMimeAssociationItem {
return {
id: association.id,
mime: association.mime,
filename: association.filename,
extension: association.extension,
......@@ -240,14 +242,14 @@ export function isUnspecific(mime: string[] | string): boolean {
return mime.length === 1 && isUnspecific(mime[0]);
}
export function suggestFilename(theMime: string, prefix: string): string {
export function suggestFilename(langId: string, prefix: string): string {
for (var i = 0; i < registeredAssociations.length; i++) {
let association = registeredAssociations[i];
if (association.userConfigured) {
continue; // only support registered ones
}
if (association.mime === theMime && association.extension) {
if (association.id === langId && association.extension) {
return prefix + association.extension;
}
}
......
......@@ -12,28 +12,28 @@ suite('Mime', () => {
var guess = guessMimeTypes('foo.monaco');
assert.deepEqual(guess, ['application/unknown']);
registerTextMime({ extension: '.monaco', mime: 'text/monaco' });
registerTextMime({ id: 'monaco', extension: '.monaco', mime: 'text/monaco' });
guess = guessMimeTypes('foo.monaco');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
guess = guessMimeTypes('.monaco');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
registerTextMime({ filename: 'Codefile', mime: 'text/code' });
registerTextMime({ id: 'codefile', filename: 'Codefile', mime: 'text/code' });
guess = guessMimeTypes('Codefile');
assert.deepEqual(guess, ['text/code', 'text/plain']);
guess = guessMimeTypes('foo.Codefile');
assert.deepEqual(guess, ['application/unknown']);
registerTextMime({ filepattern: 'Docker*', mime: 'text/docker' });
registerTextMime({ id: 'docker', filepattern: 'Docker*', mime: 'text/docker' });
guess = guessMimeTypes('Docker-debug');
assert.deepEqual(guess, ['text/docker', 'text/plain']);
guess = guessMimeTypes('docker-PROD');
assert.deepEqual(guess, ['text/docker', 'text/plain']);
registerTextMime({ mime: 'text/nice-regex', firstline: /RegexesAreNice/ });
registerTextMime({ id: 'niceregex', mime: 'text/nice-regex', firstline: /RegexesAreNice/ });
guess = guessMimeTypes('Randomfile.noregistration', 'RegexesAreNice');
assert.deepEqual(guess, ['text/nice-regex', 'text/plain']);
......@@ -45,8 +45,8 @@ suite('Mime', () => {
});
test('Mimes Priority', () => {
registerTextMime({ extension: '.monaco', mime: 'text/monaco' });
registerTextMime({ mime: 'text/foobar', firstline: /foobar/ });
registerTextMime({ id: 'monaco', extension: '.monaco', mime: 'text/monaco' });
registerTextMime({ id: 'foobar', mime: 'text/foobar', firstline: /foobar/ });
var guess = guessMimeTypes('foo.monaco');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
......@@ -54,32 +54,32 @@ suite('Mime', () => {
guess = guessMimeTypes('foo.monaco', 'foobar');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
registerTextMime({ filename: 'dockerfile', mime: 'text/winner' });
registerTextMime({ filepattern: 'dockerfile*', mime: 'text/looser' });
registerTextMime({ id: 'docker', filename: 'dockerfile', mime: 'text/winner' });
registerTextMime({ id: 'docker', filepattern: 'dockerfile*', mime: 'text/looser' });
guess = guessMimeTypes('dockerfile');
assert.deepEqual(guess, ['text/winner', 'text/plain']);
});
test('Specificity priority 1', () => {
registerTextMime({ extension: '.monaco2', mime: 'text/monaco2' });
registerTextMime({ filename: 'specific.monaco2', mime: 'text/specific-monaco2' });
registerTextMime({ id: 'monaco2', extension: '.monaco2', mime: 'text/monaco2' });
registerTextMime({ id: 'monaco2', filename: 'specific.monaco2', mime: 'text/specific-monaco2' });
assert.deepEqual(guessMimeTypes('specific.monaco2'), ['text/specific-monaco2', 'text/plain']);
assert.deepEqual(guessMimeTypes('foo.monaco2'), ['text/monaco2', 'text/plain']);
});
test('Specificity priority 2', () => {
registerTextMime({ filename: 'specific.monaco3', mime: 'text/specific-monaco3' });
registerTextMime({ extension: '.monaco3', mime: 'text/monaco3' });
registerTextMime({ id: 'monaco3', filename: 'specific.monaco3', mime: 'text/specific-monaco3' });
registerTextMime({ id: 'monaco3', extension: '.monaco3', mime: 'text/monaco3' });
assert.deepEqual(guessMimeTypes('specific.monaco3'), ['text/specific-monaco3', 'text/plain']);
assert.deepEqual(guessMimeTypes('foo.monaco3'), ['text/monaco3', 'text/plain']);
});
test('Mimes Priority - Longest Extension wins', () => {
registerTextMime({ extension: '.monaco', mime: 'text/monaco' });
registerTextMime({ extension: '.monaco.xml', mime: 'text/monaco-xml' });
registerTextMime({ extension: '.monaco.xml.build', mime: 'text/monaco-xml-build' });
registerTextMime({ id: 'monaco', extension: '.monaco', mime: 'text/monaco' });
registerTextMime({ id: 'monaco', extension: '.monaco.xml', mime: 'text/monaco-xml' });
registerTextMime({ id: 'monaco', extension: '.monaco.xml.build', mime: 'text/monaco-xml-build' });
var guess = guessMimeTypes('foo.monaco');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
......@@ -92,16 +92,16 @@ suite('Mime', () => {
});
test('Mimes Priority - User configured wins', () => {
registerTextMime({ extension: '.monaco.xnl', mime: 'text/monaco', userConfigured: true });
registerTextMime({ extension: '.monaco.xml', mime: 'text/monaco-xml' });
registerTextMime({ id: 'monaco', extension: '.monaco.xnl', mime: 'text/monaco', userConfigured: true });
registerTextMime({ id: 'monaco', extension: '.monaco.xml', mime: 'text/monaco-xml' });
var guess = guessMimeTypes('foo.monaco.xnl');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
});
test('Mimes Priority - Pattern matches on path if specified', () => {
registerTextMime({ filepattern: '**/dot.monaco.xml', mime: 'text/monaco' });
registerTextMime({ filepattern: '*ot.other.xml', mime: 'text/other' });
registerTextMime({ id: 'monaco', filepattern: '**/dot.monaco.xml', mime: 'text/monaco' });
registerTextMime({ id: 'other', filepattern: '*ot.other.xml', mime: 'text/other' });
var guess = guessMimeTypes('/some/path/dot.monaco.xml');
assert.deepEqual(guess, ['text/monaco', 'text/plain']);
......
......@@ -23,7 +23,7 @@ suite('Mime', () => {
});
test('detectMimesFromFile (PNG saved as TXT)', function (done: () => void) {
mimeCommon.registerTextMime({ mime: 'text/plain', extension: '.txt' });
mimeCommon.registerTextMime({ id: 'text', mime: 'text/plain', extension: '.txt' });
var file = require.toUrl('./fixtures/some.png.txt');
mime.detectMimesFromFile(file, (error, mimes) => {
assert.equal(error, null);
......
......@@ -123,7 +123,7 @@ export class LanguagesRegistry {
if (Array.isArray(lang.extensions)) {
this.id2Extensions[lang.id] = this.id2Extensions[lang.id] || [];
for (let extension of lang.extensions) {
mime.registerTextMime({ mime: primaryMime, extension: extension });
mime.registerTextMime({ id: lang.id, mime: primaryMime, extension: extension });
this.id2Extensions[lang.id].push(extension);
}
}
......@@ -131,14 +131,14 @@ export class LanguagesRegistry {
if (Array.isArray(lang.filenames)) {
this.id2Filenames[lang.id] = this.id2Filenames[lang.id] || [];
for (let filename of lang.filenames) {
mime.registerTextMime({ mime: primaryMime, filename: filename });
mime.registerTextMime({ id: lang.id, mime: primaryMime, filename: filename });
this.id2Filenames[lang.id].push(filename);
}
}
if (Array.isArray(lang.filenamePatterns)) {
for (let filenamePattern of lang.filenamePatterns) {
mime.registerTextMime({ mime: primaryMime, filepattern: filenamePattern });
mime.registerTextMime({ id: lang.id, mime: primaryMime, filepattern: filenamePattern });
}
}
......@@ -150,7 +150,7 @@ export class LanguagesRegistry {
try {
var firstLineRegex = new RegExp(firstLineRegexStr);
if (!strings.regExpLeadsToEndlessLoop(firstLineRegex)) {
mime.registerTextMime({ mime: primaryMime, firstline: firstLineRegex });
mime.registerTextMime({ id: lang.id, mime: primaryMime, firstline: firstLineRegex });
}
} catch (err) {
// Most likely, the regex was bad
......
......@@ -513,7 +513,7 @@ export class MainThreadModeServiceImpl extends ModeServiceImpl {
const langId = configuration.files.associations[pattern];
const mimetype = this.getMimeForMode(langId) || `text/x-${langId}`;
mime.registerTextMime({ mime: mimetype, filepattern: pattern, userConfigured: true });
mime.registerTextMime({ id: langId, mime: mimetype, filepattern: pattern, userConfigured: true });
});
}
}
......
......@@ -15,7 +15,7 @@ import {Dimension, Builder, $} from 'vs/base/browser/builder';
import {ResourceViewer} from 'vs/base/browser/ui/resourceviewer/resourceViewer';
import {DomScrollableElement} from 'vs/base/browser/ui/scrollbar/scrollableElement';
import {BaseEditor} from 'vs/workbench/browser/parts/editor/baseEditor';
import {EditorInput, EditorOptions} from 'vs/workbench/common/editor';
import {EditorInput, EditorOptions, BINARY_DIFF_EDITOR_ID} from 'vs/workbench/common/editor';
import {BinaryEditorModel} from 'vs/workbench/common/editor/binaryEditorModel';
import {DiffEditorModel} from 'vs/workbench/common/editor/diffEditorModel';
import {IWorkbenchEditorService} from 'vs/workbench/services/editor/common/editorService';
......@@ -27,7 +27,7 @@ import {ScrollbarVisibility} from 'vs/base/common/scrollable';
*/
export class BinaryResourceDiffEditor extends BaseEditor implements IVerticalSashLayoutProvider {
public static ID = 'workbench.editors.binaryResourceDiffEditor';
public static ID = BINARY_DIFF_EDITOR_ID;
private static MIN_CONTAINER_WIDTH = 100;
......
......@@ -16,7 +16,7 @@ import {Position} from 'vs/platform/editor/common/editor';
import {IDiffEditor} from 'vs/editor/browser/editorBrowser';
import {IDiffEditorOptions, IEditorOptions} from 'vs/editor/common/editorCommon';
import {BaseTextEditor} from 'vs/workbench/browser/parts/editor/textEditor';
import {TextEditorOptions, TextDiffEditorOptions, EditorModel, EditorInput, EditorOptions} from 'vs/workbench/common/editor';
import {TextEditorOptions, TextDiffEditorOptions, EditorModel, EditorInput, EditorOptions, TEXT_DIFF_EDITOR_ID} from 'vs/workbench/common/editor';
import {StringEditorInput} from 'vs/workbench/common/editor/stringEditorInput';
import {ResourceEditorInput} from 'vs/workbench/common/editor/resourceEditorInput';
import {DiffEditorInput} from 'vs/workbench/common/editor/diffEditorInput';
......@@ -44,7 +44,7 @@ export const TextCompareEditorVisible = new RawContextKey<boolean>('textCompareE
*/
export class TextDiffEditor extends BaseTextEditor {
public static ID = 'workbench.editors.textDiffEditor';
public static ID = TEXT_DIFF_EDITOR_ID;
private diffNavigator: DiffNavigator;
private nextDiffAction: NavigateAction;
......
......@@ -36,6 +36,16 @@ export const Extensions = {
Editors: 'workbench.contributions.editors'
};
/**
* Text diff editor id.
*/
export const TEXT_DIFF_EDITOR_ID = 'workbench.editors.textDiffEditor';
/**
* Binary diff editor id.
*/
export const BINARY_DIFF_EDITOR_ID = 'workbench.editors.binaryResourceDiffEditor';
export interface IEditorRegistry {
/**
......@@ -323,16 +333,6 @@ export interface IEncodingSupport {
*/
export interface IFileEditorInput extends IEditorInput, IEncodingSupport {
/**
* Gets the mime type of the file this input is about.
*/
getMime(): string;
/**
* Sets the mime type of the file this input is about.
*/
setMime(mime: string): void;
/**
* Gets the absolute file resource URI this input is about.
*/
......@@ -360,8 +360,6 @@ export abstract class UntitledEditorInput extends EditorInput implements IEncodi
abstract suggestFileName(): string;
abstract getMime(): string;
abstract getEncoding(): string;
abstract setEncoding(encoding: string, mode: EncodingMode): void;
......@@ -799,7 +797,7 @@ export function asFileEditorInput(obj: any, supportDiff?: boolean): IFileEditorI
let i = <IFileEditorInput>obj;
return i instanceof EditorInput && types.areFunctions(i.setResource, i.setMime, i.setEncoding, i.getEncoding, i.getResource, i.getMime) ? i : null;
return i instanceof EditorInput && types.areFunctions(i.setResource, i.setEncoding, i.getEncoding, i.getResource) ? i : null;
}
export interface IStacksModelChangeEvent {
......
......@@ -6,12 +6,10 @@
import nls = require('vs/nls');
import {TPromise} from 'vs/base/common/winjs.base';
import types = require('vs/base/common/types');
import {once} from 'vs/base/common/event';
import URI from 'vs/base/common/uri';
import {getPathLabel, IWorkspaceProvider} from 'vs/base/common/labels';
import {isBinaryMime} from 'vs/base/common/mime';
import {EditorModel, IFileEditorInput, EditorInput, BaseDiffEditorInput} from 'vs/workbench/common/editor';
import {EditorModel, EditorInput, BaseDiffEditorInput, TEXT_DIFF_EDITOR_ID, BINARY_DIFF_EDITOR_ID} from 'vs/workbench/common/editor';
import {BaseTextEditorModel} from 'vs/workbench/common/editor/textEditorModel';
import {DiffEditorModel} from 'vs/workbench/common/editor/diffEditorModel';
import {TextDiffEditorModel} from 'vs/workbench/common/editor/textDiffEditorModel';
......@@ -109,23 +107,7 @@ export class DiffEditorInput extends BaseDiffEditorInput {
}
public getPreferredEditorId(candidates: string[]): string {
// Find the right diff editor for the given isBinary/isText state
const useBinaryEditor = this.forceOpenAsBinary || this.isBinary(this.originalInput) || this.isBinary(this.modifiedInput);
return !useBinaryEditor ? 'workbench.editors.textDiffEditor' : 'workbench.editors.binaryResourceDiffEditor';
}
private isBinary(input: EditorInput): boolean {
let mime: string;
// Find mime by checking for IFileEditorInput implementors
const fileInput = <IFileEditorInput>(<any>input);
if (types.isFunction(fileInput.getMime)) {
mime = fileInput.getMime();
}
return mime && isBinaryMime(mime);
return this.forceOpenAsBinary ? BINARY_DIFF_EDITOR_ID : TEXT_DIFF_EDITOR_ID;
}
private createModel(refresh?: boolean): TPromise<DiffEditorModel> {
......
......@@ -63,10 +63,6 @@ export class StringEditorInput extends EditorInput {
return this.value;
}
public getMime(): string {
return this.mime;
}
/**
* Sets the textual value of this input and will also update the underlying model if this input is resolved.
*/
......
......@@ -99,10 +99,6 @@ export class StringEditorModel extends BaseTextEditorModel {
return null;
}
public getMime(): string {
return this.mime;
}
public load(): TPromise<EditorModel> {
// Create text editor model if not yet done
......
......@@ -16,6 +16,7 @@ import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {IModeService} from 'vs/editor/common/services/modeService';
import {IDisposable, dispose} from 'vs/base/common/lifecycle';
import Event, {Emitter} from 'vs/base/common/event';
import {PLAINTEXT_MODE_ID} from 'vs/editor/common/modes/modesRegistry';
import {ITextFileService} from 'vs/workbench/parts/files/common/files'; // TODO@Ben layer breaker
......@@ -98,23 +99,17 @@ export class UntitledEditorInput extends AbstractUntitledEditorInput {
public suggestFileName(): string {
if (!this.hasAssociatedFilePath) {
const mime = this.getMime();
if (mime && mime !== MIME_TEXT /* do not suggest when the mime type is simple plain text */) {
return suggestFilename(mime, this.getName());
if (this.cachedModel) {
const modeId = this.cachedModel.getModeId();
if (modeId !== PLAINTEXT_MODE_ID) { // do not suggest when the mime type is simple plain text
return suggestFilename(modeId, this.getName());
}
}
}
return this.getName();
}
public getMime(): string {
if (this.cachedModel) {
return this.modeService.getMimeForMode(this.cachedModel.getModeId());
}
return null;
}
public getEncoding(): string {
if (this.cachedModel) {
return this.cachedModel.getEncoding();
......
......@@ -8,7 +8,6 @@ import {TPromise} from 'vs/base/common/winjs.base';
import nls = require('vs/nls');
import errors = require('vs/base/common/errors');
import {toErrorMessage} from 'vs/base/common/errorMessage';
import {MIME_BINARY} from 'vs/base/common/mime';
import types = require('vs/base/common/types');
import paths = require('vs/base/common/paths');
import {IEditorViewState} from 'vs/editor/common/editorCommon';
......@@ -199,7 +198,9 @@ export class TextFileEditor extends BaseTextEditor {
}
private openAsBinary(input: FileEditorInput, options: EditorOptions): void {
const fileInputBinary = this.instantiationService.createInstance(FileEditorInput, input.getResource(), MIME_BINARY, void 0);
const fileInputBinary = this.instantiationService.createInstance(FileEditorInput, input.getResource(), void 0);
fileInputBinary.setForceOpenAsBinary();
this.editorService.openEditor(fileInputBinary, options, this.position).done(null, errors.onUnexpectedError);
}
......
......@@ -1355,8 +1355,8 @@ export class CompareResourcesAction extends Action {
this.tree.clearHighlight();
}
const leftInput = this.instantiationService.createInstance(FileEditorInput, globalResourceToCompare, void 0, void 0);
const rightInput = this.instantiationService.createInstance(FileEditorInput, this.resource, void 0, void 0);
const leftInput = this.instantiationService.createInstance(FileEditorInput, globalResourceToCompare, void 0);
const rightInput = this.instantiationService.createInstance(FileEditorInput, this.resource, void 0);
return this.editorService.openEditor(new DiffEditorInput(toDiffLabel(globalResourceToCompare, this.resource, this.contextService), null, leftInput, rightInput));
}
......
......@@ -115,7 +115,7 @@ Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerEditor(
// Note: because of service injection, the descriptor needs to have the exact count
// of arguments as the FileEditorInput constructor. Otherwise when creating an
// instance through the instantiation service he will inject the services wrong!
const descriptor = new AsyncDescriptor<IFileEditorInput>('vs/workbench/parts/files/common/editors/fileEditorInput', 'FileEditorInput', /* DO NOT REMOVE */ void 0, /* DO NOT REMOVE */ void 0, /* DO NOT REMOVE */ void 0);
const descriptor = new AsyncDescriptor<IFileEditorInput>('vs/workbench/parts/files/common/editors/fileEditorInput', 'FileEditorInput', /* DO NOT REMOVE */ void 0, /* DO NOT REMOVE */ void 0);
Registry.as<IEditorRegistry>(EditorExtensions.Editors).registerDefaultFileInput(descriptor);
interface ISerializedFileInput {
......@@ -139,7 +139,7 @@ class FileEditorInputFactory implements IEditorInputFactory {
public deserialize(instantiationService: IInstantiationService, serializedEditorInput: string): EditorInput {
const fileInput: ISerializedFileInput = JSON.parse(serializedEditorInput);
return instantiationService.createInstance(FileEditorInput, URI.parse(fileInput.resource), void 0, void 0);
return instantiationService.createInstance(FileEditorInput, URI.parse(fileInput.resource), void 0);
}
}
......
......@@ -263,7 +263,7 @@ class ResolveSaveConflictMessage implements IMessageWithAction {
if (!this.model.isDisposed()) {
const mime = guessMimeTypes(resource.fsPath).join(', ');
const originalInput = this.instantiationService.createInstance(FileOnDiskEditorInput, resource, mime, paths.basename(resource.fsPath), resource.fsPath);
const modifiedInput = this.instantiationService.createInstance(FileEditorInput, resource, mime, void 0);
const modifiedInput = this.instantiationService.createInstance(FileEditorInput, resource, void 0);
const conflictInput = this.instantiationService.createInstance(ConflictResolutionDiffEditorInput, this.model, nls.localize('saveConflictDiffLabel', "{0} (on disk) ↔ {1} (in {2})", modifiedInput.getName(), modifiedInput.getName(), product.nameLong), nls.localize('resolveSaveConflict', "Resolve save conflict"), originalInput, modifiedInput);
return this.editorService.openEditor(conflictInput).then(() => {
......
......@@ -5,18 +5,13 @@
'use strict';
import {TPromise} from 'vs/base/common/winjs.base';
import {Registry} from 'vs/platform/platform';
import types = require('vs/base/common/types');
import paths = require('vs/base/common/paths');
import {guessMimeTypes} from 'vs/base/common/mime';
import labels = require('vs/base/common/labels');
import URI from 'vs/base/common/uri';
import strings = require('vs/base/common/strings');
import assert = require('vs/base/common/assert');
import {IEditorRegistry, Extensions, EditorModel, EncodingMode, ConfirmResult, IEditorDescriptor} from 'vs/workbench/common/editor';
import {EditorModel, EncodingMode, ConfirmResult} from 'vs/workbench/common/editor';
import {BinaryEditorModel} from 'vs/workbench/common/editor/binaryEditorModel';
import {IFileOperationResult, FileOperationResult, FileChangesEvent, EventType} from 'vs/platform/files/common/files';
import {ITextFileService, BINARY_FILE_EDITOR_ID, FILE_EDITOR_INPUT_ID, FileEditorInput as CommonFileEditorInput, AutoSaveMode, ModelState, TextFileModelChangeEvent, IFileEditorDescriptor, LocalFileChangeEvent} from 'vs/workbench/parts/files/common/files';
import {ITextFileService, BINARY_FILE_EDITOR_ID, TEXT_FILE_EDITOR_ID, FILE_EDITOR_INPUT_ID, FileEditorInput as CommonFileEditorInput, AutoSaveMode, ModelState, TextFileModelChangeEvent, LocalFileChangeEvent} from 'vs/workbench/parts/files/common/files';
import {IWorkspaceContextService} from 'vs/platform/workspace/common/workspace';
import {IEventService} from 'vs/platform/event/common/event';
import {IInstantiationService} from 'vs/platform/instantiation/common/instantiation';
......@@ -28,8 +23,8 @@ import {IHistoryService} from 'vs/workbench/services/history/common/history';
*/
export class FileEditorInput extends CommonFileEditorInput {
private resource: URI;
private mime: string;
private preferredEncoding: string;
private forceOpenAsBinary: boolean;
private name: string;
private description: string;
......@@ -42,7 +37,6 @@ export class FileEditorInput extends CommonFileEditorInput {
*/
constructor(
resource: URI,
mime: string,
preferredEncoding: string,
@IInstantiationService private instantiationService: IInstantiationService,
@IWorkspaceContextService private contextService: IWorkspaceContextService,
......@@ -56,7 +50,6 @@ export class FileEditorInput extends CommonFileEditorInput {
if (resource) {
this.setResource(resource);
this.setMime(mime || guessMimeTypes(this.resource.fsPath).join(', '));
this.preferredEncoding = preferredEncoding;
}
......@@ -112,16 +105,6 @@ export class FileEditorInput extends CommonFileEditorInput {
return this.resource;
}
public getMime(): string {
return this.mime;
}
public setMime(mime: string): void {
assert.ok(mime, 'Editor input needs mime type');
this.mime = mime;
}
public setPreferredEncoding(encoding: string): void {
this.preferredEncoding = encoding;
}
......@@ -144,6 +127,10 @@ export class FileEditorInput extends CommonFileEditorInput {
}
}
public setForceOpenAsBinary(): void {
this.forceOpenAsBinary = true;
}
public getTypeId(): string {
return FILE_EDITOR_INPUT_ID;
}
......@@ -203,38 +190,7 @@ export class FileEditorInput extends CommonFileEditorInput {
}
public getPreferredEditorId(candidates: string[]): string {
const editorRegistry = (<IEditorRegistry>Registry.as(Extensions.Editors));
// Lookup Editor by Mime
let descriptor: IEditorDescriptor;
const mimes = this.mime.split(',');
for (let m = 0; m < mimes.length; m++) {
const mime = strings.trim(mimes[m]);
for (let i = 0; i < candidates.length; i++) {
descriptor = editorRegistry.getEditorById(candidates[i]);
if (types.isFunction((<IFileEditorDescriptor>descriptor).getMimeTypes)) {
const mimetypes = (<IFileEditorDescriptor>descriptor).getMimeTypes();
for (let j = 0; j < mimetypes.length; j++) {
const mimetype = mimetypes[j];
// Check for direct mime match
if (mime === mimetype) {
return descriptor.getId();
}
// Otherwise check for wildcard mime matches
if (strings.endsWith(mimetype, '/*') && strings.startsWith(mime, mimetype.substring(0, mimetype.length - 1))) {
return descriptor.getId();
}
}
}
}
}
// Otherwise use default editor
return BINARY_FILE_EDITOR_ID;
return this.forceOpenAsBinary ? BINARY_FILE_EDITOR_ID : TEXT_FILE_EDITOR_ID;
}
public resolve(refresh?: boolean): TPromise<EditorModel> {
......@@ -283,13 +239,6 @@ export class FileEditorInput extends CommonFileEditorInput {
}
if (otherInput) {
// Note that we can not test for the mime type here because we cache resolved file editor input models by resource. And
// these models have a fixed mode association that can not be changed afterwards. As such, we always treat this input
// equal if the resource is equal so that there is always just one text editor model (with undo hisotry etc.) around.
//
// !!! DO NOT CHANGE THIS ASSUMPTION !!!
//
return otherInput instanceof FileEditorInput && (<FileEditorInput>otherInput).resource.toString() === this.resource.toString();
}
......
......@@ -50,10 +50,6 @@ export abstract class FileEditorInput extends EditorInput implements IFileEditor
public abstract getResource(): URI;
public abstract setMime(mime: string): void;
public abstract getMime(): string;
public abstract setPreferredEncoding(encoding: string): void;
public abstract setEncoding(encoding: string, mode: EncodingMode): void;
......
......@@ -53,9 +53,9 @@ suite('Files - FileEditorInput', () => {
});
test('Basics', function (done) {
let input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/file.js'), 'text/javascript', void 0);
const otherInput = instantiationService.createInstance(FileEditorInput, toResource('foo/bar/otherfile.js'), 'text/javascript', void 0);
const otherInputSame = instantiationService.createInstance(FileEditorInput, toResource('foo/bar/file.js'), 'text/javascript', void 0);
let input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/file.js'), void 0);
const otherInput = instantiationService.createInstance(FileEditorInput, toResource('foo/bar/otherfile.js'), void 0);
const otherInputSame = instantiationService.createInstance(FileEditorInput, toResource('foo/bar/file.js'), void 0);
assert(input.matches(input));
assert(input.matches(otherInputSame));
......@@ -72,8 +72,8 @@ suite('Files - FileEditorInput', () => {
input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar.html'), 'text/html', void 0);
const inputToResolve: any = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/file.js'), 'text/javascript', void 0);
const sameOtherInput = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/file.js'), 'text/javascript', void 0);
const inputToResolve: any = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/file.js'), void 0);
const sameOtherInput = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/file.js'), void 0);
return accessor.editorService.resolveEditorModel(inputToResolve, true).then(resolved => {
const resolvedModelA = resolved;
......@@ -115,8 +115,8 @@ suite('Files - FileEditorInput', () => {
});
test('matches', function () {
const input1 = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), 'text/javascript', void 0);
const input2 = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), 'text/javascript', void 0);
const input1 = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), void 0);
const input2 = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), void 0);
assert.strictEqual(input1.matches(null), false);
assert.strictEqual(input1.matches(input1), true);
......@@ -124,7 +124,7 @@ suite('Files - FileEditorInput', () => {
});
test('getEncoding/setEncoding', function (done) {
const input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), 'text/javascript', void 0);
const input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), void 0);
input.setEncoding('utf16', EncodingMode.Encode);
assert.equal(input.getEncoding(), 'utf16');
......@@ -139,7 +139,7 @@ suite('Files - FileEditorInput', () => {
});
test('save', function (done) {
const input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), 'text/javascript', void 0);
const input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), void 0);
return accessor.editorService.resolveEditorModel(input, true).then((resolved: ITextFileEditorModel) => {
resolved.textEditorModel.setValue('changed');
......@@ -156,7 +156,7 @@ suite('Files - FileEditorInput', () => {
});
test('revert', function (done) {
const input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), 'text/javascript', void 0);
const input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), void 0);
return accessor.editorService.resolveEditorModel(input, true).then((resolved: ITextFileEditorModel) => {
resolved.textEditorModel.setValue('changed');
......@@ -173,7 +173,7 @@ suite('Files - FileEditorInput', () => {
});
test('resolve handles binary files', function (done) {
const input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), 'text/javascript', void 0);
const input = instantiationService.createInstance(FileEditorInput, toResource('/foo/bar/updatefile.js'), void 0);
accessor.textFileService.setResolveTextContentErrorOnce(<IFileOperationResult>{
message: 'error',
......@@ -192,14 +192,14 @@ suite('Files - FileEditorInput', () => {
test('disposes when resource gets deleted - local file changes', function () {
const parent = toResource('/foo/bar');
const resource = toResource('/foo/bar/updatefile.js');
let input = instantiationService.createInstance(FileEditorInput, resource, 'text/javascript', void 0);
let input = instantiationService.createInstance(FileEditorInput, resource, void 0);
assert.ok(!input.isDisposed());
accessor.eventService.emit('files.internal:fileChanged', new LocalFileChangeEvent(toStat(resource)));
assert.ok(input.isDisposed());
input = instantiationService.createInstance(FileEditorInput, resource, 'text/javascript', void 0);
input = instantiationService.createInstance(FileEditorInput, resource, void 0);
const other = toResource('/foo/barfoo');
......@@ -218,14 +218,14 @@ suite('Files - FileEditorInput', () => {
test('disposes when resource gets deleted - remote file changes', function () {
const parent = toResource('/foo/bar');
const resource = toResource('/foo/bar/updatefile.js');
let input = instantiationService.createInstance(FileEditorInput, resource, 'text/javascript', void 0);
let input = instantiationService.createInstance(FileEditorInput, resource, void 0);
assert.ok(!input.isDisposed());
accessor.eventService.emit(EventType.FILE_CHANGES, new FileChangesEvent([{ resource, type: FileChangeType.DELETED }]));
assert.ok(input.isDisposed());
input = instantiationService.createInstance(FileEditorInput, resource, 'text/javascript', void 0);
input = instantiationService.createInstance(FileEditorInput, resource, void 0);
const other = toResource('/foo/barfoo');
......
......@@ -238,8 +238,8 @@ suite('Files - TextFileEditorModel', () => {
});
test('save() and isDirty() - proper with check for mtimes', function (done) {
const input1 = instantiationService.createInstance(FileEditorInput, toResource('/path/index_async2.txt'), 'text/plain', 'utf8');
const input2 = instantiationService.createInstance(FileEditorInput, toResource('/path/index_async.txt'), 'text/plain', 'utf8');
const input1 = instantiationService.createInstance(FileEditorInput, toResource('/path/index_async2.txt'), 'utf8');
const input2 = instantiationService.createInstance(FileEditorInput, toResource('/path/index_async.txt'), 'utf8');
input1.resolve().then((model1: TextFileEditorModel) => {
input2.resolve().then((model2: TextFileEditorModel) => {
......
/*---------------------------------------------------------------------------------------------
* 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 {strictEqual, equal} from 'assert';
import {join} from 'vs/base/common/paths';
import URI from 'vs/base/common/uri';
import {FileEditorDescriptor} from 'vs/workbench/parts/files/browser/files';
import {Registry} from 'vs/platform/platform';
import {SyncDescriptor} from 'vs/platform/instantiation/common/descriptors';
import {FileEditorInput} from 'vs/workbench/parts/files/common/editors/fileEditorInput';
import {Extensions} from 'vs/workbench/common/editor';
import {workbenchInstantiationService} from 'vs/test/utils/servicesTestUtils';
const ExtensionId = Extensions.Editors;
suite('Files - TextFileEditor', () => {
test('TextFile Editor Registration', function () {
const d1 = new FileEditorDescriptor('ce-id1', 'name', 'vs/workbench/parts/files/browser/tests/contentEditor.test', 'MyClass', ['test-text/html', 'test-text/javascript']);
const d2 = new FileEditorDescriptor('ce-id2', 'name', 'vs/workbench/parts/files/browser/tests/contentEditor.test', 'MyOtherClass', ['test-text/css', 'test-text/javascript']);
const oldEditors = Registry.as(ExtensionId).getEditors();
Registry.as(ExtensionId).setEditors([]);
const oldEditorCnt = Registry.as(ExtensionId).getEditors().length;
const oldInputCnt = Registry.as(ExtensionId).getEditorInputs().length;
Registry.as(ExtensionId).registerEditor(d1, new SyncDescriptor(FileEditorInput));
Registry.as(ExtensionId).registerEditor(d2, new SyncDescriptor(FileEditorInput));
equal(Registry.as(ExtensionId).getEditors().length, oldEditorCnt + 2);
equal(Registry.as(ExtensionId).getEditorInputs().length, oldInputCnt + 2);
const instantiationService = workbenchInstantiationService();
strictEqual(Registry.as(ExtensionId).getEditor(instantiationService.createInstance(FileEditorInput, URI.file(join('C:\\', '/foo/bar/foobar.html')), 'test-text/html', void 0)), d1);
strictEqual(Registry.as(ExtensionId).getEditor(instantiationService.createInstance(FileEditorInput, URI.file(join('C:\\', '/foo/bar/foobar.js')), 'test-text/javascript', void 0)), d1);
strictEqual(Registry.as(ExtensionId).getEditor(instantiationService.createInstance(FileEditorInput, URI.file(join('C:\\', '/foo/bar/foobar.css')), 'test-text/css', void 0)), d2);
Registry.as(ExtensionId).setEditors(oldEditors);
});
});
\ No newline at end of file
......@@ -146,7 +146,7 @@ suite('Files - TextFileEditorModelManager', () => {
const model: TextFileEditorModel = instantiationService.createInstance(TextFileEditorModel, resource, 'utf8');
manager.add(resource, model);
const input = instantiationService.createInstance(FileEditorInput, resource, 'text/plain', void 0);
const input = instantiationService.createInstance(FileEditorInput, resource, void 0);
const stacks = accessor.editorGroupService.getStacksModel();
const group = stacks.openGroup('group', true);
......
......@@ -6,7 +6,6 @@
import {TPromise} from 'vs/base/common/winjs.base';
import URI from 'vs/base/common/uri';
import {guessMimeTypes} from 'vs/base/common/mime';
import network = require('vs/base/common/network');
import {Registry} from 'vs/platform/platform';
import {basename, dirname} from 'vs/base/common/paths';
......@@ -280,7 +279,6 @@ export class WorkbenchEditorService implements IWorkbenchEditorService {
private createFileInput(resource: URI, encoding?: string): TPromise<IFileEditorInput> {
return this.instantiationService.createInstance(this.fileInputDescriptor).then((typedFileInput) => {
typedFileInput.setResource(resource);
typedFileInput.setMime(guessMimeTypes(resource.fsPath).join(', '));
typedFileInput.setPreferredEncoding(encoding);
return typedFileInput;
......
......@@ -272,7 +272,7 @@ suite('Workbench UI Services', () => {
test('WorkbenchEditorService', function () {
let instantiationService = workbenchInstantiationService();
let activeInput: EditorInput = instantiationService.createInstance(FileEditorInput, toResource('/something.js'), 'text/javascript', void 0);
let activeInput: EditorInput = instantiationService.createInstance(FileEditorInput, toResource('/something.js'), void 0);
let testEditorPart = new TestEditorPart();
testEditorPart.setActiveEditorInput(activeInput);
......@@ -333,7 +333,7 @@ suite('Workbench UI Services', () => {
test('DelegatingWorkbenchEditorService', function () {
let instantiationService = workbenchInstantiationService();
let activeInput: EditorInput = instantiationService.createInstance(FileEditorInput, toResource('/something.js'), 'text/javascript', void 0);
let activeInput: EditorInput = instantiationService.createInstance(FileEditorInput, toResource('/something.js'), void 0);
let testEditorPart = new TestEditorPart();
testEditorPart.setActiveEditorInput(activeInput);
......
......@@ -10,10 +10,6 @@ import {EditorInput} from 'vs/workbench/common/editor';
import {DiffEditorInput} from 'vs/workbench/common/editor/diffEditorInput';
class MyEditorInput extends EditorInput {
getMime() {
return 'text/css';
}
public getTypeId(): string {
return '';
}
......
......@@ -144,9 +144,6 @@ class TestFileEditorInput extends EditorInput implements IFileEditorInput {
public setResource(r: URI): void {
}
public setMime(mime: string) {
}
public setEncoding(encoding: string) {
}
......@@ -160,10 +157,6 @@ class TestFileEditorInput extends EditorInput implements IFileEditorInput {
public getResource(): URI {
return this.resource;
}
public getMime(): string {
return null;
}
}
function input(id = String(index++), nonSerializable?: boolean, resource?: URI): EditorInput {
......
......@@ -149,7 +149,7 @@ suite('Editor - Range decorations', () => {
function mockEditorService(editorInput: IEditorInput)
function mockEditorService(resource: URI)
function mockEditorService(arg: any) {
let editorInput: IEditorInput = arg instanceof URI ? instantiationService.createInstance(FileEditorInput, arg, '', '') : arg;
let editorInput: IEditorInput = arg instanceof URI ? instantiationService.createInstance(FileEditorInput, arg, void 0) : arg;
instantiationService.stub(WorkbenchEditorService.IWorkbenchEditorService, 'getActiveEditorInput', editorInput);
}
......
Markdown is supported
0% .
You are about to add 0 people to the discussion. Proceed with caution.
先完成此消息的编辑!
想要评论请 注册