mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-15 02:48:30 -05:00
Merge VS Code 1.31.1 (#4283)
This commit is contained in:
@@ -26,7 +26,7 @@ export interface IEditorWorkerService {
|
||||
canComputeDirtyDiff(original: URI, modified: URI): boolean;
|
||||
computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise<IChange[] | null>;
|
||||
|
||||
computeMoreMinimalEdits(resource: URI, edits: TextEdit[]): Promise<TextEdit[]>;
|
||||
computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined): Promise<TextEdit[] | null | undefined>;
|
||||
|
||||
canComputeWordRanges(resource: URI): boolean;
|
||||
computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] } | null>;
|
||||
|
||||
@@ -19,6 +19,7 @@ import { EditorSimpleWorkerImpl } from 'vs/editor/common/services/editorSimpleWo
|
||||
import { IDiffComputationResult, IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
|
||||
import { regExpFlags } from 'vs/base/common/strings';
|
||||
|
||||
/**
|
||||
* Stop syncing a model to the worker if it was not needed for 1 min.
|
||||
@@ -87,7 +88,7 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
|
||||
return this._workerManager.withWorker().then(client => client.computeDirtyDiff(original, modified, ignoreTrimWhitespace));
|
||||
}
|
||||
|
||||
public computeMoreMinimalEdits(resource: URI, edits: modes.TextEdit[]): Promise<modes.TextEdit[]> {
|
||||
public computeMoreMinimalEdits(resource: URI, edits: modes.TextEdit[] | null | undefined): Promise<modes.TextEdit[] | null | undefined> {
|
||||
if (!Array.isArray(edits) || edits.length === 0) {
|
||||
return Promise.resolve(edits);
|
||||
} else {
|
||||
@@ -237,8 +238,7 @@ class EditorModelManager extends Disposable {
|
||||
}
|
||||
|
||||
public esureSyncedResources(resources: URI[]): void {
|
||||
for (let i = 0; i < resources.length; i++) {
|
||||
let resource = resources[i];
|
||||
for (const resource of resources) {
|
||||
let resourceStr = resource.toString();
|
||||
|
||||
if (!this._syncedModels[resourceStr]) {
|
||||
@@ -261,8 +261,8 @@ class EditorModelManager extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
for (let i = 0; i < toRemove.length; i++) {
|
||||
this._stopModelSync(toRemove[i]);
|
||||
for (const e of toRemove) {
|
||||
this._stopModelSync(e);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -360,7 +360,7 @@ export class EditorWorkerClient extends Disposable {
|
||||
}
|
||||
|
||||
protected _getProxy(): Promise<EditorSimpleWorkerImpl> {
|
||||
return this._getOrCreateWorker().getProxyObject().then(null, (err) => {
|
||||
return this._getOrCreateWorker().getProxyObject().then(undefined, (err) => {
|
||||
logOnceWebWorkerWarning(err);
|
||||
this._worker = new SynchronousWorkerClient(new EditorSimpleWorkerImpl(null));
|
||||
return this._getOrCreateWorker().getProxyObject();
|
||||
@@ -413,7 +413,7 @@ export class EditorWorkerClient extends Disposable {
|
||||
}
|
||||
let wordDefRegExp = LanguageConfigurationRegistry.getWordDefinition(model.getLanguageIdentifier().id);
|
||||
let wordDef = wordDefRegExp.source;
|
||||
let wordDefFlags = (wordDefRegExp.global ? 'g' : '') + (wordDefRegExp.ignoreCase ? 'i' : '') + (wordDefRegExp.multiline ? 'm' : '');
|
||||
let wordDefFlags = regExpFlags(wordDefRegExp);
|
||||
return proxy.textualSuggest(resource.toString(), position, wordDef, wordDefFlags);
|
||||
});
|
||||
}
|
||||
@@ -426,7 +426,7 @@ export class EditorWorkerClient extends Disposable {
|
||||
}
|
||||
let wordDefRegExp = LanguageConfigurationRegistry.getWordDefinition(model.getLanguageIdentifier().id);
|
||||
let wordDef = wordDefRegExp.source;
|
||||
let wordDefFlags = (wordDefRegExp.global ? 'g' : '') + (wordDefRegExp.ignoreCase ? 'i' : '') + (wordDefRegExp.multiline ? 'm' : '');
|
||||
let wordDefFlags = regExpFlags(wordDefRegExp);
|
||||
return proxy.computeWordRanges(resource.toString(), range, wordDef, wordDefFlags);
|
||||
});
|
||||
}
|
||||
@@ -439,7 +439,7 @@ export class EditorWorkerClient extends Disposable {
|
||||
}
|
||||
let wordDefRegExp = LanguageConfigurationRegistry.getWordDefinition(model.getLanguageIdentifier().id);
|
||||
let wordDef = wordDefRegExp.source;
|
||||
let wordDefFlags = (wordDefRegExp.global ? 'g' : '') + (wordDefRegExp.ignoreCase ? 'i' : '') + (wordDefRegExp.multiline ? 'm' : '');
|
||||
let wordDefFlags = regExpFlags(wordDefRegExp);
|
||||
return proxy.navigateValueSet(resource.toString(), range, up, wordDef, wordDefFlags);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -11,13 +11,13 @@ import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { FileKind } from 'vs/platform/files/common/files';
|
||||
|
||||
export function getIconClasses(modelService: IModelService, modeService: IModeService, resource: uri, fileKind?: FileKind): string[] {
|
||||
export function getIconClasses(modelService: IModelService, modeService: IModeService, resource: uri | undefined, fileKind?: FileKind): string[] {
|
||||
// we always set these base classes even if we do not have a path
|
||||
const classes = fileKind === FileKind.ROOT_FOLDER ? ['rootfolder-icon'] : fileKind === FileKind.FOLDER ? ['folder-icon'] : ['file-icon'];
|
||||
if (resource) {
|
||||
// Get the path and name of the resource. For data-URIs, we need to parse specially
|
||||
let name: string;
|
||||
let path: string;
|
||||
let name: string | undefined;
|
||||
let path: string | undefined;
|
||||
if (resource.scheme === Schemas.data) {
|
||||
const metadata = DataUri.parseMetaData(resource);
|
||||
name = metadata.get(DataUri.META_DATA_LABEL);
|
||||
@@ -44,7 +44,7 @@ export function getIconClasses(modelService: IModelService, modeService: IModeSe
|
||||
}
|
||||
// Configured Language
|
||||
let configuredLangId: string | null = getConfiguredLangId(modelService, resource);
|
||||
configuredLangId = configuredLangId || modeService.getModeIdByFilepathOrFirstLine(path);
|
||||
configuredLangId = configuredLangId || (path ? modeService.getModeIdByFilepathOrFirstLine(path) : null);
|
||||
if (configuredLangId) {
|
||||
classes.push(`${cssEscape(configuredLangId)}-lang-file-icon`);
|
||||
}
|
||||
|
||||
@@ -33,39 +33,51 @@ export class LanguagesRegistry extends Disposable {
|
||||
private readonly _onDidChange: Emitter<void> = this._register(new Emitter<void>());
|
||||
public readonly onDidChange: Event<void> = this._onDidChange.event;
|
||||
|
||||
private _nextLanguageId: number;
|
||||
private _languages: { [id: string]: IResolvedLanguage; };
|
||||
private _languageIds: string[];
|
||||
private readonly _warnOnOverwrite: boolean;
|
||||
|
||||
private _nextLanguageId2: number;
|
||||
private _languageIdToLanguage: string[];
|
||||
private _languageToLanguageId: { [id: string]: number; };
|
||||
|
||||
private _languages: { [id: string]: IResolvedLanguage; };
|
||||
private _mimeTypesMap: { [mimeType: string]: LanguageIdentifier; };
|
||||
private _nameMap: { [name: string]: LanguageIdentifier; };
|
||||
private _lowercaseNameMap: { [name: string]: LanguageIdentifier; };
|
||||
|
||||
private _warnOnOverwrite: boolean;
|
||||
|
||||
constructor(useModesRegistry = true, warnOnOverwrite = false) {
|
||||
super();
|
||||
this._nextLanguageId = 1;
|
||||
|
||||
this._warnOnOverwrite = warnOnOverwrite;
|
||||
|
||||
this._nextLanguageId2 = 1;
|
||||
this._languageIdToLanguage = [];
|
||||
this._languageToLanguageId = Object.create(null);
|
||||
|
||||
this._languages = {};
|
||||
this._mimeTypesMap = {};
|
||||
this._nameMap = {};
|
||||
this._lowercaseNameMap = {};
|
||||
this._languageIds = [];
|
||||
this._warnOnOverwrite = warnOnOverwrite;
|
||||
|
||||
if (useModesRegistry) {
|
||||
this._registerLanguages(ModesRegistry.getLanguages());
|
||||
this._register(ModesRegistry.onDidAddLanguages((m) => this._registerLanguages(m)));
|
||||
this._initializeFromRegistry();
|
||||
this._register(ModesRegistry.onDidChangeLanguages((m) => this._initializeFromRegistry()));
|
||||
}
|
||||
}
|
||||
|
||||
_registerLanguages(desc: ILanguageExtensionPoint[]): void {
|
||||
if (desc.length === 0) {
|
||||
return;
|
||||
}
|
||||
private _initializeFromRegistry(): void {
|
||||
this._languages = {};
|
||||
this._mimeTypesMap = {};
|
||||
this._nameMap = {};
|
||||
this._lowercaseNameMap = {};
|
||||
|
||||
for (let i = 0; i < desc.length; i++) {
|
||||
this._registerLanguage(desc[i]);
|
||||
const desc = ModesRegistry.getLanguages();
|
||||
this._registerLanguages(desc);
|
||||
}
|
||||
|
||||
_registerLanguages(desc: ILanguageExtensionPoint[]): void {
|
||||
|
||||
for (const d of desc) {
|
||||
this._registerLanguage(d);
|
||||
}
|
||||
|
||||
// Rebuild fast path maps
|
||||
@@ -90,6 +102,18 @@ export class LanguagesRegistry extends Disposable {
|
||||
this._onDidChange.fire();
|
||||
}
|
||||
|
||||
private _getLanguageId(language: string): number {
|
||||
if (this._languageToLanguageId[language]) {
|
||||
return this._languageToLanguageId[language];
|
||||
}
|
||||
|
||||
const languageId = this._nextLanguageId2++;
|
||||
this._languageIdToLanguage[languageId] = language;
|
||||
this._languageToLanguageId[language] = languageId;
|
||||
|
||||
return languageId;
|
||||
}
|
||||
|
||||
private _registerLanguage(lang: ILanguageExtensionPoint): void {
|
||||
const langId = lang.id;
|
||||
|
||||
@@ -97,7 +121,7 @@ export class LanguagesRegistry extends Disposable {
|
||||
if (hasOwnProperty.call(this._languages, langId)) {
|
||||
resolvedLanguage = this._languages[langId];
|
||||
} else {
|
||||
let languageId = this._nextLanguageId++;
|
||||
const languageId = this._getLanguageId(langId);
|
||||
resolvedLanguage = {
|
||||
identifier: new LanguageIdentifier(langId, languageId),
|
||||
name: null,
|
||||
@@ -107,7 +131,6 @@ export class LanguagesRegistry extends Disposable {
|
||||
filenames: [],
|
||||
configurationFiles: []
|
||||
};
|
||||
this._languageIds[languageId] = langId;
|
||||
this._languages[langId] = resolvedLanguage;
|
||||
}
|
||||
|
||||
@@ -170,7 +193,7 @@ export class LanguagesRegistry extends Disposable {
|
||||
|
||||
resolvedLanguage.aliases.push(langId);
|
||||
|
||||
let langAliases: (string | null)[] | null = null;
|
||||
let langAliases: Array<string | null> | null = null;
|
||||
if (typeof lang.aliases !== 'undefined' && Array.isArray(lang.aliases)) {
|
||||
if (lang.aliases.length === 0) {
|
||||
// signal that this language should not get a name
|
||||
@@ -181,8 +204,7 @@ export class LanguagesRegistry extends Disposable {
|
||||
}
|
||||
|
||||
if (langAliases !== null) {
|
||||
for (let i = 0; i < langAliases.length; i++) {
|
||||
const langAlias = langAliases[i];
|
||||
for (const langAlias of langAliases) {
|
||||
if (!langAlias || langAlias.length === 0) {
|
||||
continue;
|
||||
}
|
||||
@@ -281,7 +303,7 @@ export class LanguagesRegistry extends Disposable {
|
||||
if (typeof _modeId === 'string') {
|
||||
modeId = _modeId;
|
||||
} else {
|
||||
modeId = this._languageIds[_modeId];
|
||||
modeId = this._languageIdToLanguage[_modeId];
|
||||
if (!modeId) {
|
||||
return null;
|
||||
}
|
||||
@@ -303,7 +325,7 @@ export class LanguagesRegistry extends Disposable {
|
||||
return [];
|
||||
}
|
||||
|
||||
public getModeIdsFromFilepathOrFirstLine(filepath: string, firstLine?: string): string[] {
|
||||
public getModeIdsFromFilepathOrFirstLine(filepath: string | null, firstLine?: string): string[] {
|
||||
if (!filepath && !firstLine) {
|
||||
return [];
|
||||
}
|
||||
|
||||
210
src/vs/editor/common/services/markerDecorationsServiceImpl.ts
Normal file
210
src/vs/editor/common/services/markerDecorationsServiceImpl.ts
Normal file
@@ -0,0 +1,210 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IMarkerService, IMarker, MarkerSeverity, MarkerTag } from 'vs/platform/markers/common/markers';
|
||||
import { Disposable, toDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IModelDeltaDecoration, ITextModel, IModelDecorationOptions, TrackedRangeStickiness, OverviewRulerLane, IModelDecoration } from 'vs/editor/common/model';
|
||||
import { ClassName } from 'vs/editor/common/model/intervalTree';
|
||||
import { themeColorFromId, ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
import { overviewRulerWarning, overviewRulerInfo, overviewRulerError } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { keys } from 'vs/base/common/map';
|
||||
import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
|
||||
function MODEL_ID(resource: URI): string {
|
||||
return resource.toString();
|
||||
}
|
||||
|
||||
class MarkerDecorations extends Disposable {
|
||||
|
||||
private readonly _markersData: Map<string, IMarker> = new Map<string, IMarker>();
|
||||
|
||||
constructor(
|
||||
readonly model: ITextModel
|
||||
) {
|
||||
super();
|
||||
this._register(toDisposable(() => {
|
||||
this.model.deltaDecorations(keys(this._markersData), []);
|
||||
this._markersData.clear();
|
||||
}));
|
||||
}
|
||||
|
||||
public update(markers: IMarker[], newDecorations: IModelDeltaDecoration[]): void {
|
||||
const ids = this.model.deltaDecorations(keys(this._markersData), newDecorations);
|
||||
for (let index = 0; index < ids.length; index++) {
|
||||
this._markersData.set(ids[index], markers[index]);
|
||||
}
|
||||
}
|
||||
|
||||
getMarker(decoration: IModelDecoration): IMarker | undefined {
|
||||
return this._markersData.get(decoration.id);
|
||||
}
|
||||
}
|
||||
|
||||
export class MarkerDecorationsService extends Disposable implements IMarkerDecorationsService {
|
||||
|
||||
_serviceBrand: any;
|
||||
|
||||
private readonly _markerDecorations: Map<string, MarkerDecorations> = new Map<string, MarkerDecorations>();
|
||||
|
||||
constructor(
|
||||
@IModelService modelService: IModelService,
|
||||
@IMarkerService private readonly _markerService: IMarkerService
|
||||
) {
|
||||
super();
|
||||
modelService.getModels().forEach(model => this._onModelAdded(model));
|
||||
this._register(modelService.onModelAdded(this._onModelAdded, this));
|
||||
this._register(modelService.onModelRemoved(this._onModelRemoved, this));
|
||||
this._register(this._markerService.onMarkerChanged(this._handleMarkerChange, this));
|
||||
}
|
||||
|
||||
getMarker(model: ITextModel, decoration: IModelDecoration): IMarker | null {
|
||||
const markerDecorations = this._markerDecorations.get(MODEL_ID(model.uri));
|
||||
return markerDecorations ? markerDecorations.getMarker(decoration) || null : null;
|
||||
}
|
||||
|
||||
private _handleMarkerChange(changedResources: URI[]): void {
|
||||
changedResources.forEach((resource) => {
|
||||
const markerDecorations = this._markerDecorations.get(MODEL_ID(resource));
|
||||
if (markerDecorations) {
|
||||
this.updateDecorations(markerDecorations);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
private _onModelAdded(model: ITextModel): void {
|
||||
const markerDecorations = new MarkerDecorations(model);
|
||||
this._markerDecorations.set(MODEL_ID(model.uri), markerDecorations);
|
||||
this.updateDecorations(markerDecorations);
|
||||
}
|
||||
|
||||
private _onModelRemoved(model: ITextModel): void {
|
||||
const markerDecorations = this._markerDecorations.get(MODEL_ID(model.uri));
|
||||
if (markerDecorations) {
|
||||
markerDecorations.dispose();
|
||||
this._markerDecorations.delete(MODEL_ID(model.uri));
|
||||
}
|
||||
|
||||
// clean up markers for internal, transient models
|
||||
if (model.uri.scheme === Schemas.inMemory
|
||||
|| model.uri.scheme === Schemas.internal
|
||||
|| model.uri.scheme === Schemas.vscode) {
|
||||
if (this._markerService) {
|
||||
this._markerService.read({ resource: model.uri }).map(marker => marker.owner).forEach(owner => this._markerService.remove(owner, [model.uri]));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private updateDecorations(markerDecorations: MarkerDecorations): void {
|
||||
// Limit to the first 500 errors/warnings
|
||||
const markers = this._markerService.read({ resource: markerDecorations.model.uri, take: 500 });
|
||||
let newModelDecorations: IModelDeltaDecoration[] = markers.map((marker) => {
|
||||
return {
|
||||
range: this._createDecorationRange(markerDecorations.model, marker),
|
||||
options: this._createDecorationOption(marker)
|
||||
};
|
||||
});
|
||||
markerDecorations.update(markers, newModelDecorations);
|
||||
}
|
||||
|
||||
private _createDecorationRange(model: ITextModel, rawMarker: IMarker): Range {
|
||||
|
||||
let ret = Range.lift(rawMarker);
|
||||
|
||||
if (rawMarker.severity === MarkerSeverity.Hint) {
|
||||
if (!rawMarker.tags || rawMarker.tags.indexOf(MarkerTag.Unnecessary) === -1) {
|
||||
// * never render hints on multiple lines
|
||||
// * make enough space for three dots
|
||||
ret = ret.setEndPosition(ret.startLineNumber, ret.startColumn + 2);
|
||||
}
|
||||
}
|
||||
|
||||
ret = model.validateRange(ret);
|
||||
|
||||
if (ret.isEmpty()) {
|
||||
let word = model.getWordAtPosition(ret.getStartPosition());
|
||||
if (word) {
|
||||
ret = new Range(ret.startLineNumber, word.startColumn, ret.endLineNumber, word.endColumn);
|
||||
} else {
|
||||
let maxColumn = model.getLineLastNonWhitespaceColumn(ret.startLineNumber) ||
|
||||
model.getLineMaxColumn(ret.startLineNumber);
|
||||
|
||||
if (maxColumn === 1) {
|
||||
// empty line
|
||||
// console.warn('marker on empty line:', marker);
|
||||
} else if (ret.endColumn >= maxColumn) {
|
||||
// behind eol
|
||||
ret = new Range(ret.startLineNumber, maxColumn - 1, ret.endLineNumber, maxColumn);
|
||||
} else {
|
||||
// extend marker to width = 1
|
||||
ret = new Range(ret.startLineNumber, ret.startColumn, ret.endLineNumber, ret.endColumn + 1);
|
||||
}
|
||||
}
|
||||
} else if (rawMarker.endColumn === Number.MAX_VALUE && rawMarker.startColumn === 1 && ret.startLineNumber === ret.endLineNumber) {
|
||||
let minColumn = model.getLineFirstNonWhitespaceColumn(rawMarker.startLineNumber);
|
||||
if (minColumn < ret.endColumn) {
|
||||
ret = new Range(ret.startLineNumber, minColumn, ret.endLineNumber, ret.endColumn);
|
||||
rawMarker.startColumn = minColumn;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private _createDecorationOption(marker: IMarker): IModelDecorationOptions {
|
||||
|
||||
let className: string;
|
||||
let color: ThemeColor | undefined = undefined;
|
||||
let zIndex: number;
|
||||
let inlineClassName: string | undefined = undefined;
|
||||
|
||||
switch (marker.severity) {
|
||||
case MarkerSeverity.Hint:
|
||||
if (marker.tags && marker.tags.indexOf(MarkerTag.Unnecessary) >= 0) {
|
||||
className = ClassName.EditorUnnecessaryDecoration;
|
||||
} else {
|
||||
className = ClassName.EditorHintDecoration;
|
||||
}
|
||||
zIndex = 0;
|
||||
break;
|
||||
case MarkerSeverity.Warning:
|
||||
className = ClassName.EditorWarningDecoration;
|
||||
color = themeColorFromId(overviewRulerWarning);
|
||||
zIndex = 20;
|
||||
break;
|
||||
case MarkerSeverity.Info:
|
||||
className = ClassName.EditorInfoDecoration;
|
||||
color = themeColorFromId(overviewRulerInfo);
|
||||
zIndex = 10;
|
||||
break;
|
||||
case MarkerSeverity.Error:
|
||||
default:
|
||||
className = ClassName.EditorErrorDecoration;
|
||||
color = themeColorFromId(overviewRulerError);
|
||||
zIndex = 30;
|
||||
break;
|
||||
}
|
||||
|
||||
if (marker.tags) {
|
||||
if (marker.tags.indexOf(MarkerTag.Unnecessary) !== -1) {
|
||||
inlineClassName = ClassName.EditorUnnecessaryInlineDecoration;
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
|
||||
className,
|
||||
showIfCollapsed: true,
|
||||
overviewRuler: {
|
||||
color,
|
||||
position: OverviewRulerLane.Right
|
||||
},
|
||||
zIndex,
|
||||
inlineClassName,
|
||||
};
|
||||
}
|
||||
}
|
||||
16
src/vs/editor/common/services/markersDecorationService.ts
Normal file
16
src/vs/editor/common/services/markersDecorationService.ts
Normal file
@@ -0,0 +1,16 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { ITextModel, IModelDecoration } from 'vs/editor/common/model';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IMarker } from 'vs/platform/markers/common/markers';
|
||||
|
||||
export const IMarkerDecorationsService = createDecorator<IMarkerDecorationsService>('markerDecorationsService');
|
||||
|
||||
export interface IMarkerDecorationsService {
|
||||
_serviceBrand: any;
|
||||
|
||||
getMarker(model: ITextModel, decoration: IModelDecoration): IMarker | null;
|
||||
}
|
||||
@@ -49,7 +49,7 @@ export interface IModeService {
|
||||
// --- instantiation
|
||||
create(commaSeparatedMimetypesOrCommaSeparatedIds: string): ILanguageSelection;
|
||||
createByLanguageName(languageName: string): ILanguageSelection;
|
||||
createByFilepathOrFirstLine(filepath: string, firstLine?: string): ILanguageSelection;
|
||||
createByFilepathOrFirstLine(filepath: string | null, firstLine?: string): ILanguageSelection;
|
||||
|
||||
triggerMode(commaSeparatedMimetypesOrCommaSeparatedIds: string): void;
|
||||
}
|
||||
|
||||
@@ -45,10 +45,10 @@ export class ModeServiceImpl implements IModeService {
|
||||
private readonly _instantiatedModes: { [modeId: string]: IMode; };
|
||||
private readonly _registry: LanguagesRegistry;
|
||||
|
||||
private readonly _onDidCreateMode: Emitter<IMode> = new Emitter<IMode>();
|
||||
private readonly _onDidCreateMode = new Emitter<IMode>();
|
||||
public readonly onDidCreateMode: Event<IMode> = this._onDidCreateMode.event;
|
||||
|
||||
protected readonly _onLanguagesMaybeChanged: Emitter<void> = new Emitter<void>();
|
||||
protected readonly _onLanguagesMaybeChanged = new Emitter<void>();
|
||||
private readonly onLanguagesMaybeChanged: Event<void> = this._onLanguagesMaybeChanged.event;
|
||||
|
||||
constructor(warnOnOverwrite = false) {
|
||||
@@ -94,7 +94,7 @@ export class ModeServiceImpl implements IModeService {
|
||||
return this._registry.getModeIdForLanguageNameLowercase(alias);
|
||||
}
|
||||
|
||||
public getModeIdByFilepathOrFirstLine(filepath: string, firstLine?: string): string | null {
|
||||
public getModeIdByFilepathOrFirstLine(filepath: string | null, firstLine?: string): string | null {
|
||||
const modeIds = this._registry.getModeIdsFromFilepathOrFirstLine(filepath, firstLine);
|
||||
|
||||
if (modeIds.length > 0) {
|
||||
@@ -138,7 +138,7 @@ export class ModeServiceImpl implements IModeService {
|
||||
});
|
||||
}
|
||||
|
||||
public createByFilepathOrFirstLine(filepath: string, firstLine?: string): ILanguageSelection {
|
||||
public createByFilepathOrFirstLine(filepath: string | null, firstLine?: string): ILanguageSelection {
|
||||
return new LanguageSelection(this.onLanguagesMaybeChanged, () => {
|
||||
const modeId = this.getModeIdByFilepathOrFirstLine(filepath, firstLine);
|
||||
return this._createModeAndGetLanguageIdentifier(modeId);
|
||||
|
||||
@@ -14,7 +14,7 @@ export const IModelService = createDecorator<IModelService>('modelService');
|
||||
export interface IModelService {
|
||||
_serviceBrand: any;
|
||||
|
||||
createModel(value: string | ITextBufferFactory, languageSelection: ILanguageSelection | null, resource: URI, isForSimpleWidget?: boolean): ITextModel;
|
||||
createModel(value: string | ITextBufferFactory, languageSelection: ILanguageSelection | null, resource: URI | undefined, isForSimpleWidget?: boolean): ITextModel;
|
||||
|
||||
updateModel(model: ITextModel, value: string | ITextBufferFactory): void;
|
||||
|
||||
|
||||
@@ -3,20 +3,14 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { MarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { escape } from 'vs/base/common/strings';
|
||||
import { Disposable, IDisposable, dispose } from 'vs/base/common/lifecycle';
|
||||
import * as network from 'vs/base/common/network';
|
||||
import { basename } from 'vs/base/common/paths';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { EDITOR_MODEL_DEFAULTS } from 'vs/editor/common/config/editorOptions';
|
||||
import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { DefaultEndOfLine, EndOfLinePreference, EndOfLineSequence, IIdentifiedSingleEditOperation, IModelDecorationOptions, IModelDeltaDecoration, ITextBuffer, ITextBufferFactory, ITextModel, ITextModelCreationOptions, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model';
|
||||
import { ClassName } from 'vs/editor/common/model/intervalTree';
|
||||
import { DefaultEndOfLine, EndOfLinePreference, EndOfLineSequence, IIdentifiedSingleEditOperation, ITextBuffer, ITextBufferFactory, ITextModel, ITextModelCreationOptions } from 'vs/editor/common/model';
|
||||
import { TextModel, createTextBuffer } from 'vs/editor/common/model/textModel';
|
||||
import { IModelLanguageChangedEvent } from 'vs/editor/common/model/textModelEvents';
|
||||
import { LanguageIdentifier } from 'vs/editor/common/modes';
|
||||
@@ -24,10 +18,7 @@ import { PLAINTEXT_LANGUAGE_IDENTIFIER } from 'vs/editor/common/modes/modesRegis
|
||||
import { ILanguageSelection } from 'vs/editor/common/services/modeService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ITextResourcePropertiesService } from 'vs/editor/common/services/resourceConfiguration';
|
||||
import { overviewRulerError, overviewRulerInfo, overviewRulerWarning } from 'vs/editor/common/view/editorColorRegistry';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IMarker, IMarkerService, MarkerSeverity, MarkerTag } from 'vs/platform/markers/common/markers';
|
||||
import { ThemeColor, themeColorFromId } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
function MODEL_ID(resource: URI): string {
|
||||
return resource.toString();
|
||||
@@ -39,7 +30,6 @@ class ModelData implements IDisposable {
|
||||
private _languageSelection: ILanguageSelection | null;
|
||||
private _languageSelectionListener: IDisposable | null;
|
||||
|
||||
private _markerDecorations: string[];
|
||||
private _modelEventListeners: IDisposable[];
|
||||
|
||||
constructor(
|
||||
@@ -52,8 +42,6 @@ class ModelData implements IDisposable {
|
||||
this._languageSelection = null;
|
||||
this._languageSelectionListener = null;
|
||||
|
||||
this._markerDecorations = [];
|
||||
|
||||
this._modelEventListeners = [];
|
||||
this._modelEventListeners.push(model.onWillDispose(() => onWillDispose(model)));
|
||||
this._modelEventListeners.push(model.onDidChangeLanguage((e) => onDidChangeLanguage(model, e)));
|
||||
@@ -71,15 +59,10 @@ class ModelData implements IDisposable {
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._markerDecorations = this.model.deltaDecorations(this._markerDecorations, []);
|
||||
this._modelEventListeners = dispose(this._modelEventListeners);
|
||||
this._disposeLanguageSelection();
|
||||
}
|
||||
|
||||
public acceptMarkerDecorations(newDecorations: IModelDeltaDecoration[]): void {
|
||||
this._markerDecorations = this.model.deltaDecorations(this._markerDecorations, newDecorations);
|
||||
}
|
||||
|
||||
public setLanguage(languageSelection: ILanguageSelection): void {
|
||||
this._disposeLanguageSelection();
|
||||
this._languageSelection = languageSelection;
|
||||
@@ -88,155 +71,6 @@ class ModelData implements IDisposable {
|
||||
}
|
||||
}
|
||||
|
||||
class ModelMarkerHandler {
|
||||
|
||||
public static setMarkers(modelData: ModelData, markerService: IMarkerService): void {
|
||||
|
||||
// Limit to the first 500 errors/warnings
|
||||
const markers = markerService.read({ resource: modelData.model.uri, take: 500 });
|
||||
|
||||
let newModelDecorations: IModelDeltaDecoration[] = markers.map((marker) => {
|
||||
return {
|
||||
range: ModelMarkerHandler._createDecorationRange(modelData.model, marker),
|
||||
options: ModelMarkerHandler._createDecorationOption(marker)
|
||||
};
|
||||
});
|
||||
|
||||
modelData.acceptMarkerDecorations(newModelDecorations);
|
||||
}
|
||||
|
||||
private static _createDecorationRange(model: ITextModel, rawMarker: IMarker): Range {
|
||||
|
||||
let ret = Range.lift(rawMarker);
|
||||
|
||||
if (rawMarker.severity === MarkerSeverity.Hint) {
|
||||
if (!rawMarker.tags || rawMarker.tags.indexOf(MarkerTag.Unnecessary) === -1) {
|
||||
// * never render hints on multiple lines
|
||||
// * make enough space for three dots
|
||||
ret = ret.setEndPosition(ret.startLineNumber, ret.startColumn + 2);
|
||||
}
|
||||
}
|
||||
|
||||
ret = model.validateRange(ret);
|
||||
|
||||
if (ret.isEmpty()) {
|
||||
let word = model.getWordAtPosition(ret.getStartPosition());
|
||||
if (word) {
|
||||
ret = new Range(ret.startLineNumber, word.startColumn, ret.endLineNumber, word.endColumn);
|
||||
} else {
|
||||
let maxColumn = model.getLineLastNonWhitespaceColumn(ret.startLineNumber) ||
|
||||
model.getLineMaxColumn(ret.startLineNumber);
|
||||
|
||||
if (maxColumn === 1) {
|
||||
// empty line
|
||||
// console.warn('marker on empty line:', marker);
|
||||
} else if (ret.endColumn >= maxColumn) {
|
||||
// behind eol
|
||||
ret = new Range(ret.startLineNumber, maxColumn - 1, ret.endLineNumber, maxColumn);
|
||||
} else {
|
||||
// extend marker to width = 1
|
||||
ret = new Range(ret.startLineNumber, ret.startColumn, ret.endLineNumber, ret.endColumn + 1);
|
||||
}
|
||||
}
|
||||
} else if (rawMarker.endColumn === Number.MAX_VALUE && rawMarker.startColumn === 1 && ret.startLineNumber === ret.endLineNumber) {
|
||||
let minColumn = model.getLineFirstNonWhitespaceColumn(rawMarker.startLineNumber);
|
||||
if (minColumn < ret.endColumn) {
|
||||
ret = new Range(ret.startLineNumber, minColumn, ret.endLineNumber, ret.endColumn);
|
||||
rawMarker.startColumn = minColumn;
|
||||
}
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
private static _createDecorationOption(marker: IMarker): IModelDecorationOptions {
|
||||
|
||||
let className: string;
|
||||
let color: ThemeColor | undefined = undefined;
|
||||
let zIndex: number;
|
||||
let inlineClassName: string | undefined = undefined;
|
||||
|
||||
switch (marker.severity) {
|
||||
case MarkerSeverity.Hint:
|
||||
if (marker.tags && marker.tags.indexOf(MarkerTag.Unnecessary) >= 0) {
|
||||
className = ClassName.EditorUnnecessaryDecoration;
|
||||
} else {
|
||||
className = ClassName.EditorHintDecoration;
|
||||
}
|
||||
zIndex = 0;
|
||||
break;
|
||||
case MarkerSeverity.Warning:
|
||||
className = ClassName.EditorWarningDecoration;
|
||||
color = themeColorFromId(overviewRulerWarning);
|
||||
zIndex = 20;
|
||||
break;
|
||||
case MarkerSeverity.Info:
|
||||
className = ClassName.EditorInfoDecoration;
|
||||
color = themeColorFromId(overviewRulerInfo);
|
||||
zIndex = 10;
|
||||
break;
|
||||
case MarkerSeverity.Error:
|
||||
default:
|
||||
className = ClassName.EditorErrorDecoration;
|
||||
color = themeColorFromId(overviewRulerError);
|
||||
zIndex = 30;
|
||||
break;
|
||||
}
|
||||
|
||||
if (marker.tags) {
|
||||
if (marker.tags.indexOf(MarkerTag.Unnecessary) !== -1) {
|
||||
inlineClassName = ClassName.EditorUnnecessaryInlineDecoration;
|
||||
}
|
||||
}
|
||||
|
||||
let hoverMessage: MarkdownString | null = null;
|
||||
let { message, source, relatedInformation, code } = marker;
|
||||
|
||||
if (typeof message === 'string') {
|
||||
|
||||
hoverMessage = new MarkdownString();
|
||||
// Disable markdown renderer sanitize to allow html
|
||||
// Hence, escape all input strings
|
||||
hoverMessage.sanitize = false;
|
||||
|
||||
hoverMessage.appendMarkdown(`<div>`);
|
||||
hoverMessage.appendMarkdown(`<span style='font-family: Monaco, Menlo, Consolas, "Droid Sans Mono", "Inconsolata", "Courier New", monospace, "Droid Sans Fallback"; white-space: pre-wrap;'>${escape(message.trim())}</span>`);
|
||||
if (source) {
|
||||
hoverMessage.appendMarkdown(`<span style='opacity: 0.6; padding-left:6px;'>${escape(source)}</span>`);
|
||||
if (code) {
|
||||
hoverMessage.appendMarkdown(`<span style='opacity: 0.6; padding-left:2px;'>(${escape(code)})</span>`);
|
||||
}
|
||||
} else if (code) {
|
||||
hoverMessage.appendMarkdown(`<span style='opacity: 0.6; padding-left:6px;'>(${escape(code)})</span>`);
|
||||
}
|
||||
hoverMessage.appendMarkdown(`</div>`);
|
||||
|
||||
if (isNonEmptyArray(relatedInformation)) {
|
||||
hoverMessage.appendMarkdown(`<ul>`);
|
||||
for (const { message, resource, startLineNumber, startColumn } of relatedInformation) {
|
||||
hoverMessage.appendMarkdown(`<li>`);
|
||||
hoverMessage.appendMarkdown(`<a href='#' data-href='${resource.toString(false)}#${startLineNumber},${startColumn}'>${escape(basename(resource.path))}(${startLineNumber}, ${startColumn})</a>`);
|
||||
hoverMessage.appendMarkdown(`<span>: ${escape(message)}</span>`);
|
||||
hoverMessage.appendMarkdown(`</li>`);
|
||||
}
|
||||
hoverMessage.appendMarkdown(`</ul>`);
|
||||
}
|
||||
}
|
||||
|
||||
return {
|
||||
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
|
||||
className,
|
||||
hoverMessage,
|
||||
showIfCollapsed: true,
|
||||
overviewRuler: {
|
||||
color,
|
||||
position: OverviewRulerLane.Right
|
||||
},
|
||||
zIndex,
|
||||
inlineClassName,
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
interface IRawEditorConfig {
|
||||
tabSize?: any;
|
||||
insertSpaces?: any;
|
||||
@@ -256,8 +90,6 @@ const DEFAULT_EOL = (platform.isLinux || platform.isMacintosh) ? DefaultEndOfLin
|
||||
export class ModelServiceImpl extends Disposable implements IModelService {
|
||||
public _serviceBrand: any;
|
||||
|
||||
private _markerService: IMarkerService;
|
||||
private _markerServiceSubscription: IDisposable;
|
||||
private _configurationService: IConfigurationService;
|
||||
private _configurationServiceSubscription: IDisposable;
|
||||
private _resourcePropertiesService: ITextResourcePropertiesService;
|
||||
@@ -268,7 +100,7 @@ export class ModelServiceImpl extends Disposable implements IModelService {
|
||||
private readonly _onModelRemoved: Emitter<ITextModel> = this._register(new Emitter<ITextModel>());
|
||||
public readonly onModelRemoved: Event<ITextModel> = this._onModelRemoved.event;
|
||||
|
||||
private readonly _onModelModeChanged: Emitter<{ model: ITextModel; oldModeId: string; }> = this._register(new Emitter<{ model: ITextModel; oldModeId: string; }>({ leakWarningThreshold: 500 }));
|
||||
private readonly _onModelModeChanged: Emitter<{ model: ITextModel; oldModeId: string; }> = this._register(new Emitter<{ model: ITextModel; oldModeId: string; }>());
|
||||
public readonly onModelModeChanged: Event<{ model: ITextModel; oldModeId: string; }> = this._onModelModeChanged.event;
|
||||
|
||||
private _modelCreationOptionsByLanguageAndResource: {
|
||||
@@ -281,21 +113,15 @@ export class ModelServiceImpl extends Disposable implements IModelService {
|
||||
private _models: { [modelId: string]: ModelData; };
|
||||
|
||||
constructor(
|
||||
@IMarkerService markerService: IMarkerService,
|
||||
@IConfigurationService configurationService: IConfigurationService,
|
||||
@ITextResourcePropertiesService resourcePropertiesService: ITextResourcePropertiesService,
|
||||
@ITextResourcePropertiesService resourcePropertiesService: ITextResourcePropertiesService
|
||||
) {
|
||||
super();
|
||||
this._markerService = markerService;
|
||||
this._configurationService = configurationService;
|
||||
this._resourcePropertiesService = resourcePropertiesService;
|
||||
this._models = {};
|
||||
this._modelCreationOptionsByLanguageAndResource = Object.create(null);
|
||||
|
||||
if (this._markerService) {
|
||||
this._markerServiceSubscription = this._markerService.onMarkerChanged(this._handleMarkerChange, this);
|
||||
}
|
||||
|
||||
this._configurationServiceSubscription = this._configurationService.onDidChangeConfiguration(e => this._updateModelOptions());
|
||||
this._updateModelOptions();
|
||||
}
|
||||
@@ -351,7 +177,7 @@ export class ModelServiceImpl extends Disposable implements IModelService {
|
||||
};
|
||||
}
|
||||
|
||||
public getCreationOptions(language: string, resource: URI, isForSimpleWidget: boolean): ITextModelCreationOptions {
|
||||
public getCreationOptions(language: string, resource: URI | null | undefined, isForSimpleWidget: boolean): ITextModelCreationOptions {
|
||||
let creationOptions = this._modelCreationOptionsByLanguageAndResource[language + resource];
|
||||
if (!creationOptions) {
|
||||
const editor = this._configurationService.getValue<IRawEditorConfig>('editor', { overrideIdentifier: language, resource });
|
||||
@@ -405,41 +231,13 @@ export class ModelServiceImpl extends Disposable implements IModelService {
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
if (this._markerServiceSubscription) {
|
||||
this._markerServiceSubscription.dispose();
|
||||
}
|
||||
this._configurationServiceSubscription.dispose();
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
private _handleMarkerChange(changedResources: URI[]): void {
|
||||
changedResources.forEach((resource) => {
|
||||
let modelId = MODEL_ID(resource);
|
||||
let modelData = this._models[modelId];
|
||||
if (!modelData) {
|
||||
return;
|
||||
}
|
||||
ModelMarkerHandler.setMarkers(modelData, this._markerService);
|
||||
});
|
||||
}
|
||||
|
||||
private _cleanUp(model: ITextModel): void {
|
||||
// clean up markers for internal, transient models
|
||||
if (model.uri.scheme === network.Schemas.inMemory
|
||||
|| model.uri.scheme === network.Schemas.internal
|
||||
|| model.uri.scheme === network.Schemas.vscode) {
|
||||
if (this._markerService) {
|
||||
this._markerService.read({ resource: model.uri }).map(marker => marker.owner).forEach(owner => this._markerService.remove(owner, [model.uri]));
|
||||
}
|
||||
}
|
||||
|
||||
// clean up cache
|
||||
delete this._modelCreationOptionsByLanguageAndResource[model.getLanguageIdentifier().language + model.uri];
|
||||
}
|
||||
|
||||
// --- begin IModelService
|
||||
|
||||
private _createModelData(value: string | ITextBufferFactory, languageIdentifier: LanguageIdentifier, resource: URI, isForSimpleWidget: boolean): ModelData {
|
||||
private _createModelData(value: string | ITextBufferFactory, languageIdentifier: LanguageIdentifier, resource: URI | null | undefined, isForSimpleWidget: boolean): ModelData {
|
||||
// create & save the model
|
||||
const options = this.getCreationOptions(languageIdentifier.language, resource, isForSimpleWidget);
|
||||
const model: TextModel = new TextModel(value, options, languageIdentifier, resource);
|
||||
@@ -530,7 +328,7 @@ export class ModelServiceImpl extends Disposable implements IModelService {
|
||||
return [EditOperation.replaceMove(oldRange, textBuffer.getValueInRange(newRange, EndOfLinePreference.TextDefined))];
|
||||
}
|
||||
|
||||
public createModel(value: string | ITextBufferFactory, languageSelection: ILanguageSelection | null, resource: URI, isForSimpleWidget: boolean = false): ITextModel {
|
||||
public createModel(value: string | ITextBufferFactory, languageSelection: ILanguageSelection | null, resource: URI | null | undefined, isForSimpleWidget: boolean = false): ITextModel {
|
||||
let modelData: ModelData;
|
||||
|
||||
if (languageSelection) {
|
||||
@@ -540,11 +338,6 @@ export class ModelServiceImpl extends Disposable implements IModelService {
|
||||
modelData = this._createModelData(value, PLAINTEXT_LANGUAGE_IDENTIFIER, resource, isForSimpleWidget);
|
||||
}
|
||||
|
||||
// handle markers (marker service => model)
|
||||
if (this._markerService) {
|
||||
ModelMarkerHandler.setMarkers(modelData, this._markerService);
|
||||
}
|
||||
|
||||
this._onModelAdded.fire(modelData.model);
|
||||
|
||||
return modelData.model;
|
||||
@@ -600,7 +393,9 @@ export class ModelServiceImpl extends Disposable implements IModelService {
|
||||
delete this._models[modelId];
|
||||
modelData.dispose();
|
||||
|
||||
this._cleanUp(model);
|
||||
// clean up cache
|
||||
delete this._modelCreationOptionsByLanguageAndResource[model.getLanguageIdentifier().language + model.uri];
|
||||
|
||||
this._onModelRemoved.fire(model);
|
||||
}
|
||||
|
||||
|
||||
@@ -5,7 +5,6 @@
|
||||
|
||||
import { IDisposable, IReference } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TPromise } from 'vs/base/common/winjs.base';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { IEditorModel } from 'vs/platform/editor/common/editor';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -19,12 +18,17 @@ export interface ITextModelService {
|
||||
* Provided a resource URI, it will return a model reference
|
||||
* which should be disposed once not needed anymore.
|
||||
*/
|
||||
createModelReference(resource: URI): TPromise<IReference<ITextEditorModel>>;
|
||||
createModelReference(resource: URI): Promise<IReference<ITextEditorModel>>;
|
||||
|
||||
/**
|
||||
* Registers a specific `scheme` content provider.
|
||||
*/
|
||||
registerTextModelContentProvider(scheme: string, provider: ITextModelContentProvider): IDisposable;
|
||||
|
||||
/**
|
||||
* Check if a provider for the given `scheme` exists
|
||||
*/
|
||||
hasTextModelContentProvider(scheme: string): boolean;
|
||||
}
|
||||
|
||||
export interface ITextModelContentProvider {
|
||||
@@ -32,7 +36,7 @@ export interface ITextModelContentProvider {
|
||||
/**
|
||||
* Given a resource, return the content of the resource as `ITextModel`.
|
||||
*/
|
||||
provideTextContent(resource: URI): Thenable<ITextModel>;
|
||||
provideTextContent(resource: URI): Promise<ITextModel> | null;
|
||||
}
|
||||
|
||||
export interface ITextEditorModel extends IEditorModel {
|
||||
@@ -40,7 +44,7 @@ export interface ITextEditorModel extends IEditorModel {
|
||||
/**
|
||||
* Provides access to the underlying `ITextModel`.
|
||||
*/
|
||||
textEditorModel: ITextModel;
|
||||
readonly textEditorModel: ITextModel;
|
||||
|
||||
isReadonly(): boolean;
|
||||
}
|
||||
|
||||
@@ -43,5 +43,5 @@ export interface ITextResourcePropertiesService {
|
||||
/**
|
||||
* Returns the End of Line characters for the given resource
|
||||
*/
|
||||
getEOL(resource: URI, language?: string): string;
|
||||
getEOL(resource: URI | null | undefined, language?: string): string;
|
||||
}
|
||||
@@ -20,9 +20,9 @@ export class TextResourceConfigurationService extends Disposable implements ITex
|
||||
public readonly onDidChangeConfiguration: Event<IConfigurationChangeEvent> = this._onDidChangeConfiguration.event;
|
||||
|
||||
constructor(
|
||||
@IConfigurationService private configurationService: IConfigurationService,
|
||||
@IModelService private modelService: IModelService,
|
||||
@IModeService private modeService: IModeService,
|
||||
@IConfigurationService private readonly configurationService: IConfigurationService,
|
||||
@IModelService private readonly modelService: IModelService,
|
||||
@IModeService private readonly modeService: IModeService,
|
||||
) {
|
||||
super();
|
||||
this._register(this.configurationService.onDidChangeConfiguration(e => this._onDidChangeConfiguration.fire(e)));
|
||||
@@ -38,7 +38,7 @@ export class TextResourceConfigurationService extends Disposable implements ITex
|
||||
}
|
||||
|
||||
private _getValue<T>(resource: URI, position: IPosition | null, section: string | undefined): T {
|
||||
const language = resource ? this.getLanguage(resource, position) : void 0;
|
||||
const language = resource ? this.getLanguage(resource, position) : undefined;
|
||||
if (typeof section === 'undefined') {
|
||||
return this.configurationService.getValue<T>({ resource, overrideIdentifier: language });
|
||||
}
|
||||
|
||||
@@ -69,20 +69,20 @@ class MonacoWebWorkerImpl<T> extends EditorWorkerClient implements MonacoWebWork
|
||||
return proxy.loadForeignModule(this._foreignModuleId, this._foreignModuleCreateData).then((foreignMethods) => {
|
||||
this._foreignModuleCreateData = null;
|
||||
|
||||
let proxyMethodRequest = (method: string, args: any[]): Promise<any> => {
|
||||
const proxyMethodRequest = (method: string, args: any[]): Promise<any> => {
|
||||
return proxy.fmr(method, args);
|
||||
};
|
||||
|
||||
let createProxyMethod = (method: string, proxyMethodRequest: (method: string, args: any[]) => Promise<any>): Function => {
|
||||
const createProxyMethod = (method: string, proxyMethodRequest: (method: string, args: any[]) => Promise<any>): () => Promise<any> => {
|
||||
return function () {
|
||||
let args = Array.prototype.slice.call(arguments, 0);
|
||||
const args = Array.prototype.slice.call(arguments, 0);
|
||||
return proxyMethodRequest(method, args);
|
||||
};
|
||||
};
|
||||
|
||||
let foreignProxy = {} as T;
|
||||
for (let i = 0; i < foreignMethods.length; i++) {
|
||||
(<any>foreignProxy)[foreignMethods[i]] = createProxyMethod(foreignMethods[i], proxyMethodRequest);
|
||||
for (const foreignMethod of foreignMethods) {
|
||||
(<any>foreignProxy)[foreignMethod] = createProxyMethod(foreignMethod, proxyMethodRequest);
|
||||
}
|
||||
|
||||
return foreignProxy;
|
||||
|
||||
Reference in New Issue
Block a user