diff --git a/src/tsconfig.strictNullChecks.json b/src/tsconfig.strictNullChecks.json
index 7af6120a787..fbb819f0fbc 100644
--- a/src/tsconfig.strictNullChecks.json
+++ b/src/tsconfig.strictNullChecks.json
@@ -62,6 +62,7 @@
"./vs/base/common/idGenerator.ts",
"./vs/base/common/iterator.ts",
"./vs/base/common/jsonSchema.ts",
+ "./vs/base/common/keybindingLabels.ts",
"./vs/base/common/keybindingParser.ts",
"./vs/base/common/keyCodes.ts",
"./vs/base/common/labels.ts",
@@ -270,10 +271,15 @@
"./vs/editor/contrib/caretOperations/transpose.ts",
"./vs/editor/contrib/clipboard/clipboard.ts",
"./vs/editor/contrib/codeAction/codeActionTrigger.ts",
+ "./vs/editor/contrib/colorPicker/color.ts",
"./vs/editor/contrib/colorPicker/colorPickerModel.ts",
"./vs/editor/contrib/comment/blockCommentCommand.ts",
+ "./vs/editor/contrib/comment/comment.ts",
+ "./vs/editor/contrib/comment/lineCommentCommand.ts",
"./vs/editor/contrib/cursorUndo/cursorUndo.ts",
"./vs/editor/contrib/dnd/dragAndDropCommand.ts",
+ "./vs/editor/contrib/find/findDecorations.ts",
+ "./vs/editor/contrib/find/findModel.ts",
"./vs/editor/contrib/find/findState.ts",
"./vs/editor/contrib/find/replaceAllCommand.ts",
"./vs/editor/contrib/find/replacePattern.ts",
@@ -288,12 +294,19 @@
"./vs/editor/contrib/linesOperations/deleteLinesCommand.ts",
"./vs/editor/contrib/linesOperations/sortLinesCommand.ts",
"./vs/editor/contrib/links/getLinks.ts",
+ "./vs/editor/contrib/links/links.ts",
"./vs/editor/contrib/quickOpen/quickOpen.ts",
"./vs/editor/contrib/toggleTabFocusMode/toggleTabFocusMode.ts",
+ "./vs/editor/contrib/wordHighlighter/wordHighlighter.ts",
"./vs/editor/contrib/wordOperations/wordOperations.ts",
+ "./vs/editor/contrib/wordPartOperations/wordPartOperations.ts",
"./vs/editor/editor.worker.ts",
+ "./vs/editor/standalone/browser/colorizer.ts",
+ "./vs/editor/standalone/browser/inspectTokens/inspectTokens.ts",
"./vs/editor/standalone/browser/iPadShowKeyboard/iPadShowKeyboard.ts",
"./vs/editor/standalone/browser/standaloneCodeServiceImpl.ts",
+ "./vs/editor/standalone/browser/standaloneThemeServiceImpl.ts",
+ "./vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.ts",
"./vs/editor/standalone/common/monarch/monarchCommon.ts",
"./vs/editor/standalone/common/monarch/monarchCompile.ts",
"./vs/editor/standalone/common/monarch/monarchTypes.ts",
@@ -334,6 +347,7 @@
"./vs/platform/instantiation/common/serviceCollection.ts",
"./vs/platform/integrity/common/integrity.ts",
"./vs/platform/jsonschemas/common/jsonContributionRegistry.ts",
+ "./vs/platform/keybinding/common/keybinding.ts",
"./vs/platform/keybinding/common/keybindingResolver.ts",
"./vs/platform/keybinding/common/keybindingsRegistry.ts",
"./vs/platform/keybinding/common/resolvedKeybindingItem.ts",
diff --git a/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts b/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts
index 3cff751c75d..44036154809 100644
--- a/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts
+++ b/src/vs/base/browser/ui/keybindingLabel/keybindingLabel.ts
@@ -71,23 +71,23 @@ export class KeybindingLabel implements IDisposable {
this.didEverRender = true;
}
- private renderPart(parent: HTMLElement, part: ResolvedKeybindingPart, match: PartMatches) {
+ private renderPart(parent: HTMLElement, part: ResolvedKeybindingPart, match: PartMatches | null) {
const modifierLabels = UILabelProvider.modifierLabels[this.os];
if (part.ctrlKey) {
- this.renderKey(parent, modifierLabels.ctrlKey, match && match.ctrlKey, modifierLabels.separator);
+ this.renderKey(parent, modifierLabels.ctrlKey, Boolean(match && match.ctrlKey), modifierLabels.separator);
}
if (part.shiftKey) {
- this.renderKey(parent, modifierLabels.shiftKey, match && match.shiftKey, modifierLabels.separator);
+ this.renderKey(parent, modifierLabels.shiftKey, Boolean(match && match.shiftKey), modifierLabels.separator);
}
if (part.altKey) {
- this.renderKey(parent, modifierLabels.altKey, match && match.altKey, modifierLabels.separator);
+ this.renderKey(parent, modifierLabels.altKey, Boolean(match && match.altKey), modifierLabels.separator);
}
if (part.metaKey) {
- this.renderKey(parent, modifierLabels.metaKey, match && match.metaKey, modifierLabels.separator);
+ this.renderKey(parent, modifierLabels.metaKey, Boolean(match && match.metaKey), modifierLabels.separator);
}
const keyLabel = part.keyLabel;
if (keyLabel) {
- this.renderKey(parent, keyLabel, match && match.keyCode, '');
+ this.renderKey(parent, keyLabel, Boolean(match && match.keyCode), '');
}
}
@@ -99,7 +99,6 @@ export class KeybindingLabel implements IDisposable {
}
dispose() {
- this.keybinding = null;
}
private static areSame(a: Matches, b: Matches): boolean {
diff --git a/src/vs/base/common/keybindingLabels.ts b/src/vs/base/common/keybindingLabels.ts
index 36afbab6a05..9c5955b6569 100644
--- a/src/vs/base/common/keybindingLabels.ts
+++ b/src/vs/base/common/keybindingLabels.ts
@@ -26,13 +26,13 @@ export class ModifierLabelProvider {
public readonly modifierLabels: ModifierLabels[];
constructor(mac: ModifierLabels, windows: ModifierLabels, linux: ModifierLabels = windows) {
- this.modifierLabels = [null];
+ this.modifierLabels = [null!]; // index 0 will never me accessed.
this.modifierLabels[OperatingSystem.Macintosh] = mac;
this.modifierLabels[OperatingSystem.Windows] = windows;
this.modifierLabels[OperatingSystem.Linux] = linux;
}
- public toLabel(firstPartMod: Modifiers, firstPartKey: string, chordPartMod: Modifiers, chordPartKey: string, OS: OperatingSystem): string {
+ public toLabel(firstPartMod: Modifiers, firstPartKey: string, chordPartMod: Modifiers, chordPartKey: string, OS: OperatingSystem): string | null {
if (firstPartKey === null && chordPartKey === null) {
return null;
}
diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts
index 9f53afd1eca..651d1bf9fec 100644
--- a/src/vs/editor/browser/editorBrowser.ts
+++ b/src/vs/editor/browser/editorBrowser.ts
@@ -803,14 +803,6 @@ export interface IActiveCodeEditor extends ICodeEditor {
*/
getDomNode(): HTMLElement;
- /**
- * Get the hit test target at coordinates `clientX` and `clientY`.
- * The coordinates are relative to the top-left of the viewport.
- *
- * @returns Hit test target or null if the coordinates fall outside the editor or the editor has no model.
- */
- getTargetAtClientPoint(clientX: number, clientY: number): IMouseTarget;
-
/**
* Get the visible position for `position`.
* The result position takes scrolling into account and is relative to the top left corner of the editor.
diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts
index 0ac94b2b5e4..22842cb2cdf 100644
--- a/src/vs/editor/browser/widget/codeEditorWidget.ts
+++ b/src/vs/editor/browser/widget/codeEditorWidget.ts
@@ -201,17 +201,16 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
public readonly isSimpleWidget: boolean;
private readonly _telemetryData: object | null;
- private readonly domElement: HTMLElement;
- private readonly id: number;
+ private readonly _domElement: HTMLElement;
+ private readonly _id: number;
private readonly _configuration: editorCommon.IConfiguration;
- protected _contributions: { [key: string]: editorCommon.IEditorContribution; };
- protected _actions: { [key: string]: editorCommon.IEditorAction; };
+ protected readonly _contributions: { [key: string]: editorCommon.IEditorContribution; };
+ protected readonly _actions: { [key: string]: editorCommon.IEditorAction; };
// --- Members logically associated to a model
protected _modelData: ModelData | null;
-
protected readonly _instantiationService: IInstantiationService;
protected readonly _contextKeyService: IContextKeyService;
private readonly _notificationService: INotificationService;
@@ -219,10 +218,10 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
private readonly _commandService: ICommandService;
private readonly _themeService: IThemeService;
- private _focusTracker: CodeEditorWidgetFocusTracker;
+ private readonly _focusTracker: CodeEditorWidgetFocusTracker;
- private contentWidgets: { [key: string]: IContentWidgetData; };
- private overlayWidgets: { [key: string]: IOverlayWidgetData; };
+ private readonly _contentWidgets: { [key: string]: IContentWidgetData; };
+ private readonly _overlayWidgets: { [key: string]: IOverlayWidgetData; };
/**
* map from "parent" decoration type to live decoration ids.
@@ -242,8 +241,8 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
@INotificationService notificationService: INotificationService
) {
super();
- this.domElement = domElement;
- this.id = (++EDITOR_ID);
+ this._domElement = domElement;
+ this._id = (++EDITOR_ID);
this._decorationTypeKeysToIds = {};
this._decorationTypeSubtypes = {};
this.isSimpleWidget = codeEditorWidgetOptions.isSimpleWidget || false;
@@ -258,13 +257,13 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
this._onDidLayoutChange.fire(this._configuration.editor.layoutInfo);
}
if (this._configuration.editor.showUnused) {
- this.domElement.classList.add(SHOW_UNUSED_ENABLED_CLASS);
+ this._domElement.classList.add(SHOW_UNUSED_ENABLED_CLASS);
} else {
- this.domElement.classList.remove(SHOW_UNUSED_ENABLED_CLASS);
+ this._domElement.classList.remove(SHOW_UNUSED_ENABLED_CLASS);
}
}));
- this._contextKeyService = this._register(contextKeyService.createScoped(this.domElement));
+ this._contextKeyService = this._register(contextKeyService.createScoped(this._domElement));
this._notificationService = notificationService;
this._codeEditorService = codeEditorService;
this._commandService = commandService;
@@ -284,8 +283,8 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
this._editorWidgetFocus.setValue(this._focusTracker.hasFocus());
});
- this.contentWidgets = {};
- this.overlayWidgets = {};
+ this._contentWidgets = {};
+ this._overlayWidgets = {};
mark('editor/start/contrib');
let contributions: IEditorContributionCtor[];
@@ -325,11 +324,11 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
}
protected _createConfiguration(options: editorOptions.IEditorOptions): editorCommon.IConfiguration {
- return new Configuration(options, this.domElement);
+ return new Configuration(options, this._domElement);
}
public getId(): string {
- return this.getEditorType() + ':' + this.id;
+ return this.getEditorType() + ':' + this._id;
}
public getEditorType(): string {
@@ -339,9 +338,6 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
public dispose(): void {
this._codeEditorService.removeCodeEditor(this);
- this.contentWidgets = {};
- this.overlayWidgets = {};
-
this._focusTracker.dispose();
let keys = Object.keys(this._contributions);
@@ -349,10 +345,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
let contributionId = keys[i];
this._contributions[contributionId].dispose();
}
- this._contributions = {};
- // editor actions don't need to be disposed
- this._actions = {};
this._removeDecorationTypes();
this._postDetachModelCleanup(this._detachModel());
@@ -1026,14 +1019,14 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
// callback will not be called
return null;
}
- return this._modelData.model.changeDecorations(callback, this.id);
+ return this._modelData.model.changeDecorations(callback, this._id);
}
public getLineDecorations(lineNumber: number): IModelDecoration[] | null {
if (!this._modelData) {
return null;
}
- return this._modelData.model.getLineDecorations(lineNumber, this.id, this._configuration.editor.readOnly);
+ return this._modelData.model.getLineDecorations(lineNumber, this._id, this._configuration.editor.readOnly);
}
public deltaDecorations(oldDecorations: string[], newDecorations: IModelDeltaDecoration[]): string[] {
@@ -1045,7 +1038,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
return oldDecorations;
}
- return this._modelData.model.deltaDecorations(oldDecorations, newDecorations, this.id);
+ return this._modelData.model.deltaDecorations(oldDecorations, newDecorations, this._id);
}
public setDecorations(decorationTypeKey: string, decorationOptions: editorCommon.IDecorationOptions[]): void {
@@ -1178,11 +1171,11 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
position: widget.getPosition()
};
- if (this.contentWidgets.hasOwnProperty(widget.getId())) {
+ if (this._contentWidgets.hasOwnProperty(widget.getId())) {
console.warn('Overwriting a content widget with the same id.');
}
- this.contentWidgets[widget.getId()] = widgetData;
+ this._contentWidgets[widget.getId()] = widgetData;
if (this._modelData && this._modelData.hasRealView) {
this._modelData.view.addContentWidget(widgetData);
@@ -1191,8 +1184,8 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
public layoutContentWidget(widget: editorBrowser.IContentWidget): void {
let widgetId = widget.getId();
- if (this.contentWidgets.hasOwnProperty(widgetId)) {
- let widgetData = this.contentWidgets[widgetId];
+ if (this._contentWidgets.hasOwnProperty(widgetId)) {
+ let widgetData = this._contentWidgets[widgetId];
widgetData.position = widget.getPosition();
if (this._modelData && this._modelData.hasRealView) {
this._modelData.view.layoutContentWidget(widgetData);
@@ -1202,9 +1195,9 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
public removeContentWidget(widget: editorBrowser.IContentWidget): void {
let widgetId = widget.getId();
- if (this.contentWidgets.hasOwnProperty(widgetId)) {
- let widgetData = this.contentWidgets[widgetId];
- delete this.contentWidgets[widgetId];
+ if (this._contentWidgets.hasOwnProperty(widgetId)) {
+ let widgetData = this._contentWidgets[widgetId];
+ delete this._contentWidgets[widgetId];
if (this._modelData && this._modelData.hasRealView) {
this._modelData.view.removeContentWidget(widgetData);
}
@@ -1217,11 +1210,11 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
position: widget.getPosition()
};
- if (this.overlayWidgets.hasOwnProperty(widget.getId())) {
+ if (this._overlayWidgets.hasOwnProperty(widget.getId())) {
console.warn('Overwriting an overlay widget with the same id.');
}
- this.overlayWidgets[widget.getId()] = widgetData;
+ this._overlayWidgets[widget.getId()] = widgetData;
if (this._modelData && this._modelData.hasRealView) {
this._modelData.view.addOverlayWidget(widgetData);
@@ -1230,8 +1223,8 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
public layoutOverlayWidget(widget: editorBrowser.IOverlayWidget): void {
let widgetId = widget.getId();
- if (this.overlayWidgets.hasOwnProperty(widgetId)) {
- let widgetData = this.overlayWidgets[widgetId];
+ if (this._overlayWidgets.hasOwnProperty(widgetId)) {
+ let widgetData = this._overlayWidgets[widgetId];
widgetData.position = widget.getPosition();
if (this._modelData && this._modelData.hasRealView) {
this._modelData.view.layoutOverlayWidget(widgetData);
@@ -1241,9 +1234,9 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
public removeOverlayWidget(widget: editorBrowser.IOverlayWidget): void {
let widgetId = widget.getId();
- if (this.overlayWidgets.hasOwnProperty(widgetId)) {
- let widgetData = this.overlayWidgets[widgetId];
- delete this.overlayWidgets[widgetId];
+ if (this._overlayWidgets.hasOwnProperty(widgetId)) {
+ let widgetData = this._overlayWidgets[widgetId];
+ delete this._overlayWidgets[widgetId];
if (this._modelData && this._modelData.hasRealView) {
this._modelData.view.removeOverlayWidget(widgetData);
}
@@ -1311,17 +1304,17 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
const listenersToRemove: IDisposable[] = [];
- this.domElement.setAttribute('data-mode-id', model.getLanguageIdentifier().language);
+ this._domElement.setAttribute('data-mode-id', model.getLanguageIdentifier().language);
this._configuration.setIsDominatedByLongLines(model.isDominatedByLongLines());
this._configuration.setMaxLineNumber(model.getLineCount());
model.onBeforeAttached();
- const viewModel = new ViewModel(this.id, this._configuration, model, (callback) => dom.scheduleAtNextAnimationFrame(callback));
+ const viewModel = new ViewModel(this._id, this._configuration, model, (callback) => dom.scheduleAtNextAnimationFrame(callback));
listenersToRemove.push(model.onDidChangeDecorations((e) => this._onDidChangeModelDecorations.fire(e)));
listenersToRemove.push(model.onDidChangeLanguage((e) => {
- this.domElement.setAttribute('data-mode-id', model.getLanguageIdentifier().language);
+ this._domElement.setAttribute('data-mode-id', model.getLanguageIdentifier().language);
this._onDidChangeModelLanguage.fire(e);
}));
listenersToRemove.push(model.onDidChangeLanguageConfiguration((e) => this._onDidChangeModelLanguageConfiguration.fire(e)));
@@ -1365,18 +1358,18 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
const [view, hasRealView] = this._createView(viewModel, cursor);
if (hasRealView) {
- this.domElement.appendChild(view.domNode.domNode);
+ this._domElement.appendChild(view.domNode.domNode);
- let keys = Object.keys(this.contentWidgets);
+ let keys = Object.keys(this._contentWidgets);
for (let i = 0, len = keys.length; i < len; i++) {
let widgetId = keys[i];
- view.addContentWidget(this.contentWidgets[widgetId]);
+ view.addContentWidget(this._contentWidgets[widgetId]);
}
- keys = Object.keys(this.overlayWidgets);
+ keys = Object.keys(this._overlayWidgets);
for (let i = 0, len = keys.length; i < len; i++) {
let widgetId = keys[i];
- view.addOverlayWidget(this.overlayWidgets[widgetId]);
+ view.addOverlayWidget(this._overlayWidgets[widgetId]);
}
view.render(false, true);
@@ -1479,7 +1472,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
protected _postDetachModelCleanup(detachedModel: ITextModel | null): void {
if (detachedModel) {
- detachedModel.removeAllDecorationsWithOwnerId(this.id);
+ detachedModel.removeAllDecorationsWithOwnerId(this._id);
}
}
@@ -1493,9 +1486,9 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
this._modelData.dispose();
this._modelData = null;
- this.domElement.removeAttribute('data-mode-id');
+ this._domElement.removeAttribute('data-mode-id');
if (removeDomNode) {
- this.domElement.removeChild(removeDomNode);
+ this._domElement.removeChild(removeDomNode);
}
return model;
diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts
index 585dfea30e2..80622c9e094 100644
--- a/src/vs/editor/browser/widget/diffEditorWidget.ts
+++ b/src/vs/editor/browser/widget/diffEditorWidget.ts
@@ -1231,8 +1231,13 @@ abstract class DiffEditorWidgetStyle extends Disposable implements IDiffEditorWi
public abstract layout(): number;
}
-interface IMyViewZone extends editorBrowser.IViewZone {
+interface IMyViewZone {
shouldNotShrink?: boolean;
+ afterLineNumber: number;
+ heightInLines: number;
+ minWidthInPx?: number;
+ domNode: HTMLElement | null;
+ marginDomNode?: HTMLElement | null;
}
class ForeignViewZonesIterator {
@@ -1270,7 +1275,7 @@ abstract class ViewZonesComputer {
}
public getViewZones(): IEditorsZones {
- let result: IEditorsZones = {
+ let result: { original: IMyViewZone[]; modified: IMyViewZone[]; } = {
original: [],
modified: []
};
@@ -1286,7 +1291,7 @@ abstract class ViewZonesComputer {
return a.afterLineNumber - b.afterLineNumber;
};
- let addAndCombineIfPossible = (destination: editorBrowser.IViewZone[], item: IMyViewZone) => {
+ let addAndCombineIfPossible = (destination: IMyViewZone[], item: IMyViewZone) => {
if (item.domNode === null && destination.length > 0) {
let lastItem = destination[destination.length - 1];
if (lastItem.afterLineNumber === item.afterLineNumber && lastItem.domNode === null) {
diff --git a/src/vs/editor/common/core/range.ts b/src/vs/editor/common/core/range.ts
index d010a6bd55a..46cec746b26 100644
--- a/src/vs/editor/common/core/range.ts
+++ b/src/vs/editor/common/core/range.ts
@@ -354,28 +354,33 @@ export class Range {
* A function that compares ranges, useful for sorting ranges
* It will first compare ranges on the startPosition and then on the endPosition
*/
- public static compareRangesUsingStarts(a: IRange, b: IRange): number {
- let aStartLineNumber = a.startLineNumber | 0;
- let bStartLineNumber = b.startLineNumber | 0;
+ public static compareRangesUsingStarts(a: IRange | null | undefined, b: IRange | null | undefined): number {
+ if (a && b) {
+ const aStartLineNumber = a.startLineNumber | 0;
+ const bStartLineNumber = b.startLineNumber | 0;
- if (aStartLineNumber === bStartLineNumber) {
- let aStartColumn = a.startColumn | 0;
- let bStartColumn = b.startColumn | 0;
+ if (aStartLineNumber === bStartLineNumber) {
+ const aStartColumn = a.startColumn | 0;
+ const bStartColumn = b.startColumn | 0;
- if (aStartColumn === bStartColumn) {
- let aEndLineNumber = a.endLineNumber | 0;
- let bEndLineNumber = b.endLineNumber | 0;
+ if (aStartColumn === bStartColumn) {
+ const aEndLineNumber = a.endLineNumber | 0;
+ const bEndLineNumber = b.endLineNumber | 0;
- if (aEndLineNumber === bEndLineNumber) {
- let aEndColumn = a.endColumn | 0;
- let bEndColumn = b.endColumn | 0;
- return aEndColumn - bEndColumn;
+ if (aEndLineNumber === bEndLineNumber) {
+ const aEndColumn = a.endColumn | 0;
+ const bEndColumn = b.endColumn | 0;
+ return aEndColumn - bEndColumn;
+ }
+ return aEndLineNumber - bEndLineNumber;
}
- return aEndLineNumber - bEndLineNumber;
+ return aStartColumn - bStartColumn;
}
- return aStartColumn - bStartColumn;
+ return aStartLineNumber - bStartLineNumber;
}
- return aStartLineNumber - bStartLineNumber;
+ const aExists = (a ? 1 : 0);
+ const bExists = (b ? 1 : 0);
+ return aExists - bExists;
}
/**
diff --git a/src/vs/editor/common/model/textModelSearch.ts b/src/vs/editor/common/model/textModelSearch.ts
index d523c8de262..cb4c3128f10 100644
--- a/src/vs/editor/common/model/textModelSearch.ts
+++ b/src/vs/editor/common/model/textModelSearch.ts
@@ -17,9 +17,9 @@ export class SearchParams {
public readonly searchString: string;
public readonly isRegex: boolean;
public readonly matchCase: boolean;
- public readonly wordSeparators: string;
+ public readonly wordSeparators: string | null;
- constructor(searchString: string, isRegex: boolean, matchCase: boolean, wordSeparators: string) {
+ constructor(searchString: string, isRegex: boolean, matchCase: boolean, wordSeparators: string | null) {
this.searchString = searchString;
this.isRegex = isRegex;
this.matchCase = matchCase;
diff --git a/src/vs/editor/common/modes.ts b/src/vs/editor/common/modes.ts
index 92d30766481..a1d1c0f7222 100644
--- a/src/vs/editor/common/modes.ts
+++ b/src/vs/editor/common/modes.ts
@@ -200,7 +200,7 @@ export interface ITokenizationSupport {
getInitialState(): IState;
// add offsetDelta to each of the returned indices
- tokenize?(line: string, state: IState, offsetDelta: number): TokenizationResult;
+ tokenize(line: string, state: IState, offsetDelta: number): TokenizationResult;
tokenize2(line: string, state: IState, offsetDelta: number): TokenizationResult2;
}
diff --git a/src/vs/editor/common/modes/languageConfiguration.ts b/src/vs/editor/common/modes/languageConfiguration.ts
index 6d5645cef2f..d12a89f0c69 100644
--- a/src/vs/editor/common/modes/languageConfiguration.ts
+++ b/src/vs/editor/common/modes/languageConfiguration.ts
@@ -12,11 +12,11 @@ export interface CommentRule {
/**
* The line comment token, like `// this is a comment`
*/
- lineComment?: string;
+ lineComment?: string | null;
/**
* The block comment character pair, like `/* block comment */`
*/
- blockComment?: CharacterPair;
+ blockComment?: CharacterPair | null;
}
/**
diff --git a/src/vs/editor/common/modes/textToHtmlTokenizer.ts b/src/vs/editor/common/modes/textToHtmlTokenizer.ts
index d932f8d0e44..88a888c06d7 100644
--- a/src/vs/editor/common/modes/textToHtmlTokenizer.ts
+++ b/src/vs/editor/common/modes/textToHtmlTokenizer.ts
@@ -4,18 +4,23 @@
*--------------------------------------------------------------------------------------------*/
import * as strings from 'vs/base/common/strings';
-import { ITokenizationSupport, IState, LanguageId } from 'vs/editor/common/modes';
+import { IState, LanguageId } from 'vs/editor/common/modes';
import { LineTokens, IViewLineTokens } from 'vs/editor/common/core/lineTokens';
import { CharCode } from 'vs/base/common/charCode';
import { NULL_STATE, nullTokenize2 } from 'vs/editor/common/modes/nullMode';
+import { TokenizationResult2 } from 'vs/editor/common/core/token';
-const fallback: ITokenizationSupport = {
+export interface IReducedTokenizationSupport {
+ getInitialState(): IState;
+ tokenize2(line: string, state: IState, offsetDelta: number): TokenizationResult2;
+}
+
+const fallback: IReducedTokenizationSupport = {
getInitialState: () => NULL_STATE,
- tokenize: undefined,
tokenize2: (buffer: string, state: IState, deltaOffset: number) => nullTokenize2(LanguageId.Null, buffer, state, deltaOffset)
};
-export function tokenizeToString(text: string, tokenizationSupport: ITokenizationSupport = fallback): string {
+export function tokenizeToString(text: string, tokenizationSupport: IReducedTokenizationSupport = fallback): string {
return _tokenizeToString(text, tokenizationSupport || fallback);
}
@@ -88,7 +93,7 @@ export function tokenizeLineToHTML(text: string, viewLineTokens: IViewLineTokens
return result;
}
-function _tokenizeToString(text: string, tokenizationSupport: ITokenizationSupport): string {
+function _tokenizeToString(text: string, tokenizationSupport: IReducedTokenizationSupport): string {
let result = `
`;
let lines = text.split(/\r\n|\r|\n/);
let currentState = tokenizationSupport.getInitialState();
diff --git a/src/vs/editor/contrib/colorPicker/color.ts b/src/vs/editor/contrib/colorPicker/color.ts
index 5dc35f511e3..18a48205012 100644
--- a/src/vs/editor/contrib/colorPicker/color.ts
+++ b/src/vs/editor/contrib/colorPicker/color.ts
@@ -32,7 +32,7 @@ export function getColors(model: ITextModel, token: CancellationToken): Promise<
return Promise.all(promises).then(() => colors);
}
-export function getColorPresentations(model: ITextModel, colorInfo: IColorInformation, provider: DocumentColorProvider, token: CancellationToken): Promise {
+export function getColorPresentations(model: ITextModel, colorInfo: IColorInformation, provider: DocumentColorProvider, token: CancellationToken): Promise {
return Promise.resolve(provider.provideColorPresentations(model, colorInfo, token));
}
diff --git a/src/vs/editor/contrib/comment/comment.ts b/src/vs/editor/contrib/comment/comment.ts
index d0cd2682560..5792573e3bc 100644
--- a/src/vs/editor/contrib/comment/comment.ts
+++ b/src/vs/editor/contrib/comment/comment.ts
@@ -24,11 +24,11 @@ abstract class CommentLineAction extends EditorAction {
}
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
- let model = editor.getModel();
- if (!model) {
+ if (!editor.hasModel()) {
return;
}
+ let model = editor.getModel();
let commands: ICommand[] = [];
let selections = editor.getSelections();
let opts = model.getOptions();
@@ -122,9 +122,12 @@ class BlockCommentAction extends EditorAction {
}
public run(accessor: ServicesAccessor, editor: ICodeEditor): void {
+ if (!editor.hasModel()) {
+ return;
+ }
+
let commands: ICommand[] = [];
let selections = editor.getSelections();
-
for (let i = 0; i < selections.length; i++) {
commands.push(new BlockCommentCommand(selections[i]));
}
diff --git a/src/vs/editor/contrib/comment/lineCommentCommand.ts b/src/vs/editor/contrib/comment/lineCommentCommand.ts
index ec591640e3e..b442b4d402c 100644
--- a/src/vs/editor/contrib/comment/lineCommentCommand.ts
+++ b/src/vs/editor/contrib/comment/lineCommentCommand.ts
@@ -26,11 +26,15 @@ export interface ILinePreflightData {
commentStrLength: number;
}
-export interface IPreflightData {
- supported: boolean;
+export interface IPreflightDataSupported {
+ supported: true;
shouldRemoveComments: boolean;
lines: ILinePreflightData[];
}
+export interface IPreflightDataUnsupported {
+ supported: false;
+}
+export type IPreflightData = IPreflightDataSupported | IPreflightDataUnsupported;
export interface ISimpleModel {
getLineContent(lineNumber: number): string;
@@ -62,7 +66,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
* Do an initial pass over the lines and gather info about the line comment string.
* Returns null if any of the lines doesn't support a line comment string.
*/
- public static _gatherPreflightCommentStrings(model: ITextModel, startLineNumber: number, endLineNumber: number): ILinePreflightData[] {
+ public static _gatherPreflightCommentStrings(model: ITextModel, startLineNumber: number, endLineNumber: number): ILinePreflightData[] | null {
model.tokenizeIfCheap(startLineNumber);
const languageId = model.getLanguageIdAtPosition(startLineNumber, 1);
@@ -170,9 +174,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
const lines = LineCommentCommand._gatherPreflightCommentStrings(model, startLineNumber, endLineNumber);
if (lines === null) {
return {
- supported: false,
- shouldRemoveComments: false,
- lines: null
+ supported: false
};
}
@@ -182,7 +184,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
/**
* Given a successful analysis, execute either insert line comments, either remove line comments
*/
- private _executeLineComments(model: ISimpleModel, builder: editorCommon.IEditOperationBuilder, data: IPreflightData, s: Selection): void {
+ private _executeLineComments(model: ISimpleModel, builder: editorCommon.IEditOperationBuilder, data: IPreflightDataSupported, s: Selection): void {
let ops: IIdentifiedSingleEditOperation[];
@@ -200,7 +202,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
if (ops[i].range.isEmpty() && ops[i].range.getStartPosition().equals(cursorPosition)) {
const lineContent = model.getLineContent(cursorPosition.lineNumber);
if (lineContent.length + 1 === cursorPosition.column) {
- this._deltaColumn = ops[i].text.length;
+ this._deltaColumn = (ops[i].text || '').length;
}
}
}
@@ -208,7 +210,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
this._selectionId = builder.trackSelection(s);
}
- private _attemptRemoveBlockComment(model: ITextModel, s: Selection, startToken: string, endToken: string): IIdentifiedSingleEditOperation[] {
+ private _attemptRemoveBlockComment(model: ITextModel, s: Selection, startToken: string, endToken: string): IIdentifiedSingleEditOperation[] | null {
let startLineNumber = s.startLineNumber;
let endLineNumber = s.endLineNumber;
diff --git a/src/vs/editor/contrib/comment/test/lineCommentCommand.test.ts b/src/vs/editor/contrib/comment/test/lineCommentCommand.test.ts
index c415a3a9689..2fdd2f5f173 100644
--- a/src/vs/editor/contrib/comment/test/lineCommentCommand.test.ts
+++ b/src/vs/editor/contrib/comment/test/lineCommentCommand.test.ts
@@ -91,6 +91,9 @@ suite('Editor Contrib - Line Comment Command', () => {
' c',
'\t\td'
]), createBasicLinePreflightData(['//', 'rem', '!@#', '!@#']), 1);
+ if (!r.supported) {
+ throw new Error(`unexpected`);
+ }
assert.equal(r.shouldRemoveComments, false);
@@ -119,6 +122,9 @@ suite('Editor Contrib - Line Comment Command', () => {
' !@# c',
'\t\t!@#d'
]), createBasicLinePreflightData(['//', 'rem', '!@#', '!@#']), 1);
+ if (!r.supported) {
+ throw new Error(`unexpected`);
+ }
assert.equal(r.shouldRemoveComments, true);
diff --git a/src/vs/editor/contrib/find/findDecorations.ts b/src/vs/editor/contrib/find/findDecorations.ts
index 5ab9a026a9b..e36236e6b3f 100644
--- a/src/vs/editor/contrib/find/findDecorations.ts
+++ b/src/vs/editor/contrib/find/findDecorations.ts
@@ -9,12 +9,12 @@ import { Range } from 'vs/editor/common/core/range';
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
import { overviewRulerFindMatchForeground } from 'vs/platform/theme/common/colorRegistry';
import { themeColorFromId } from 'vs/platform/theme/common/themeService';
-import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
+import { IActiveCodeEditor } from 'vs/editor/browser/editorBrowser';
import { IModelDecorationsChangeAccessor, FindMatch, IModelDeltaDecoration, TrackedRangeStickiness, OverviewRulerLane } from 'vs/editor/common/model';
export class FindDecorations implements IDisposable {
- private _editor: ICodeEditor;
+ private _editor: IActiveCodeEditor;
private _decorations: string[];
private _overviewRulerApproximateDecorations: string[];
private _findScopeDecorationId: string | null;
@@ -22,7 +22,7 @@ export class FindDecorations implements IDisposable {
private _highlightedDecorationId: string | null;
private _startPosition: Position;
- constructor(editor: ICodeEditor) {
+ constructor(editor: IActiveCodeEditor) {
this._editor = editor;
this._decorations = [];
this._overviewRulerApproximateDecorations = [];
@@ -35,13 +35,11 @@ export class FindDecorations implements IDisposable {
public dispose(): void {
this._editor.deltaDecorations(this._allDecorations(), []);
- this._editor = null;
this._decorations = [];
this._overviewRulerApproximateDecorations = [];
this._findScopeDecorationId = null;
this._rangeHighlightDecorationId = null;
this._highlightedDecorationId = null;
- this._startPosition = null;
}
public reset(): void {
@@ -56,7 +54,7 @@ export class FindDecorations implements IDisposable {
return this._decorations.length;
}
- public getFindScope(): Range {
+ public getFindScope(): Range | null {
if (this._findScopeDecorationId) {
return this._editor.getModel().getDecorationRange(this._findScopeDecorationId);
}
@@ -92,7 +90,7 @@ export class FindDecorations implements IDisposable {
return 1;
}
- public setCurrentFindMatch(nextMatch: Range): number {
+ public setCurrentFindMatch(nextMatch: Range | null): number {
let newCurrentDecorationId: string | null = null;
let matchPosition = 0;
if (nextMatch) {
@@ -121,7 +119,7 @@ export class FindDecorations implements IDisposable {
this._rangeHighlightDecorationId = null;
}
if (newCurrentDecorationId !== null) {
- let rng = this._editor.getModel().getDecorationRange(newCurrentDecorationId);
+ let rng = this._editor.getModel().getDecorationRange(newCurrentDecorationId)!;
if (rng.startLineNumber !== rng.endLineNumber && rng.endColumn === 1) {
let lineBeforeEnd = rng.endLineNumber - 1;
let lineBeforeEndMaxColumn = this._editor.getModel().getLineMaxColumn(lineBeforeEnd);
@@ -135,7 +133,7 @@ export class FindDecorations implements IDisposable {
return matchPosition;
}
- public set(findMatches: FindMatch[], findScope: Range): void {
+ public set(findMatches: FindMatch[], findScope: Range | null): void {
this._editor.changeDecorations((accessor) => {
let findMatchesOptions: ModelDecorationOptions = FindDecorations._FIND_MATCH_DECORATION;
@@ -207,7 +205,7 @@ export class FindDecorations implements IDisposable {
});
}
- public matchBeforePosition(position: Position): Range {
+ public matchBeforePosition(position: Position): Range | null {
if (this._decorations.length === 0) {
return null;
}
@@ -229,7 +227,7 @@ export class FindDecorations implements IDisposable {
return this._editor.getModel().getDecorationRange(this._decorations[this._decorations.length - 1]);
}
- public matchAfterPosition(position: Position): Range {
+ public matchAfterPosition(position: Position): Range | null {
if (this._decorations.length === 0) {
return null;
}
diff --git a/src/vs/editor/contrib/find/findModel.ts b/src/vs/editor/contrib/find/findModel.ts
index 146d28ad3d8..b5b4102a821 100644
--- a/src/vs/editor/contrib/find/findModel.ts
+++ b/src/vs/editor/contrib/find/findModel.ts
@@ -20,7 +20,7 @@ import { SearchParams } from 'vs/editor/common/model/textModelSearch';
import { IKeybindings } from 'vs/platform/keybinding/common/keybindingsRegistry';
import { CursorChangeReason, ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents';
import { RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
-import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
+import { IActiveCodeEditor } from 'vs/editor/browser/editorBrowser';
import { ITextModel, FindMatch, EndOfLinePreference } from 'vs/editor/common/model';
export const CONTEXT_FIND_WIDGET_VISIBLE = new RawContextKey('findWidgetVisible', false);
@@ -69,7 +69,7 @@ const RESEARCH_DELAY = 240;
export class FindModelBoundToEditorModel {
- private _editor: ICodeEditor;
+ private _editor: IActiveCodeEditor;
private _state: FindReplaceState;
private _toDispose: IDisposable[];
private _decorations: FindDecorations;
@@ -79,7 +79,7 @@ export class FindModelBoundToEditorModel {
private _updateDecorationsScheduler: RunOnceScheduler;
private _isDisposed: boolean;
- constructor(editor: ICodeEditor, state: FindReplaceState) {
+ constructor(editor: IActiveCodeEditor, state: FindReplaceState) {
this._editor = editor;
this._state = state;
this._toDispose = [];
@@ -158,18 +158,16 @@ export class FindModelBoundToEditorModel {
}
}
- private static _getSearchRange(model: ITextModel, findScope: Range): Range {
- let searchRange = model.getFullModelRange();
-
+ private static _getSearchRange(model: ITextModel, findScope: Range | null): Range {
// If we have set now or before a find scope, use it for computing the search range
if (findScope) {
- searchRange = searchRange.intersectRanges(findScope);
+ return findScope;
}
- return searchRange;
+ return model.getFullModelRange();
}
- private research(moveCursor: boolean, newFindScope?: Range): void {
+ private research(moveCursor: boolean, newFindScope?: Range | null): void {
let findScope: Range | null = null;
if (typeof newFindScope !== 'undefined') {
findScope = newFindScope;
@@ -299,7 +297,7 @@ export class FindModelBoundToEditorModel {
if (!prevMatch) {
// there is precisely one match and selection is on top of it
- return null;
+ return;
}
if (!isRecursed && !searchRange.containsRange(prevMatch.range)) {
@@ -358,7 +356,7 @@ export class FindModelBoundToEditorModel {
}
}
- private _getNextMatch(after: Position, captureMatches: boolean, forceMove: boolean, isRecursed: boolean = false): FindMatch {
+ private _getNextMatch(after: Position, captureMatches: boolean, forceMove: boolean, isRecursed: boolean = false): FindMatch | null {
if (this._cannotFind()) {
return null;
}
@@ -438,7 +436,7 @@ export class FindModelBoundToEditorModel {
}
}
- private _findMatches(findScope: Range, captureMatches: boolean, limitResultCount: number): FindMatch[] {
+ private _findMatches(findScope: Range | null, captureMatches: boolean, limitResultCount: number): FindMatch[] {
let searchRange = FindModelBoundToEditorModel._getSearchRange(this._editor.getModel(), findScope);
return this._editor.getModel().findMatches(this._state.searchString, searchRange, this._state.isRegex, this._state.matchCase, this._state.wholeWord ? this._editor.getConfiguration().wordSeparators : null, captureMatches, limitResultCount);
}
@@ -497,7 +495,7 @@ export class FindModelBoundToEditorModel {
this._executeEditorCommand('replaceAll', command);
}
- private _regularReplaceAll(findScope: Range): void {
+ private _regularReplaceAll(findScope: Range | null): void {
const replacePattern = this._getReplacePattern();
// Get all the ranges (even more than the highlighted ones)
let matches = this._findMatches(findScope, replacePattern.hasReplacementPatterns, Constants.MAX_SAFE_SMALL_INTEGER);
diff --git a/src/vs/editor/contrib/find/findState.ts b/src/vs/editor/contrib/find/findState.ts
index fdd0b9093ba..35ff1e4dbf5 100644
--- a/src/vs/editor/contrib/find/findState.ts
+++ b/src/vs/editor/contrib/find/findState.ts
@@ -110,7 +110,7 @@ export class FindReplaceState implements IDisposable {
public dispose(): void {
}
- public changeMatchInfo(matchesPosition: number, matchesCount: number, currentMatch: Range): void {
+ public changeMatchInfo(matchesPosition: number, matchesCount: number, currentMatch: Range | undefined): void {
let changeEvent: FindReplaceStateChangedEvent = {
moveCursor: false,
updateHistory: false,
diff --git a/src/vs/editor/contrib/find/replacePattern.ts b/src/vs/editor/contrib/find/replacePattern.ts
index a4ee990ea20..3bd09a78e2d 100644
--- a/src/vs/editor/contrib/find/replacePattern.ts
+++ b/src/vs/editor/contrib/find/replacePattern.ts
@@ -48,7 +48,7 @@ export class ReplacePattern {
}
}
- public buildReplaceString(matches: string[]): string {
+ public buildReplaceString(matches: string[] | null): string {
if (this._state.kind === ReplacePatternKind.StaticValue) {
return this._state.staticValue;
}
@@ -69,7 +69,10 @@ export class ReplacePattern {
return result;
}
- private static _substitute(matchIndex: number, matches: string[]): string {
+ private static _substitute(matchIndex: number, matches: string[] | null): string {
+ if (matches === null) {
+ return '';
+ }
if (matchIndex === 0) {
return matches[0];
}
diff --git a/src/vs/editor/contrib/links/links.ts b/src/vs/editor/contrib/links/links.ts
index 56797d59cc0..17ffc1ed5b2 100644
--- a/src/vs/editor/contrib/links/links.ts
+++ b/src/vs/editor/contrib/links/links.ts
@@ -111,7 +111,7 @@ class LinkOccurrence {
}
private static _getOptions(link: Link, useMetaKey: boolean, isActive: boolean): ModelDecorationOptions {
- if (/^command:/i.test(link.url)) {
+ if (link.url && /^command:/i.test(link.url)) {
if (useMetaKey) {
return (isActive ? decoration.metaCommandActive : decoration.metaCommand);
} else {
@@ -157,8 +157,8 @@ class LinkDetector implements editorCommon.IEditorContribution {
private enabled: boolean;
private listenersToRemove: IDisposable[];
private timeout: async.TimeoutTimer;
- private computePromise: async.CancelablePromise;
- private activeLinkDecorationId: string;
+ private computePromise: async.CancelablePromise | null;
+ private activeLinkDecorationId: string | null;
private openerService: IOpenerService;
private notificationService: INotificationService;
private currentOccurrences: { [decorationId: string]: LinkOccurrence; };
@@ -236,15 +236,17 @@ class LinkDetector implements editorCommon.IEditorContribution {
}
private async beginCompute(): Promise {
- if (!this.editor.getModel() || !this.enabled) {
+ if (!this.editor.hasModel() || !this.enabled) {
return;
}
- if (!LinkProviderRegistry.has(this.editor.getModel())) {
+ const model = this.editor.getModel();
+
+ if (!LinkProviderRegistry.has(model)) {
return;
}
- this.computePromise = async.createCancelablePromise(token => getLinks(this.editor.getModel(), token));
+ this.computePromise = async.createCancelablePromise(token => getLinks(model, token));
try {
const links = await this.computePromise;
this.updateDecorations(links);
@@ -283,11 +285,11 @@ class LinkDetector implements editorCommon.IEditorContribution {
}
}
- private _onEditorMouseMove(mouseEvent: ClickLinkMouseEvent, withKey?: ClickLinkKeyboardEvent): void {
+ private _onEditorMouseMove(mouseEvent: ClickLinkMouseEvent, withKey: ClickLinkKeyboardEvent | null): void {
const useMetaKey = (this.editor.getConfiguration().multiCursorModifier === 'altKey');
if (this.isEnabled(mouseEvent, withKey)) {
this.cleanUpActiveLinkDecoration(); // always remove previous link decoration as their can only be one
- const occurrence = this.getLinkOccurrence(mouseEvent.target.position);
+ const occurrence = this.getLinkOccurrence(mouseEvent.target!.position);
if (occurrence) {
this.editor.changeDecorations((changeAccessor) => {
occurrence.activate(changeAccessor, useMetaKey);
@@ -317,7 +319,7 @@ class LinkDetector implements editorCommon.IEditorContribution {
if (!this.isEnabled(mouseEvent)) {
return;
}
- const occurrence = this.getLinkOccurrence(mouseEvent.target.position);
+ const occurrence = this.getLinkOccurrence(mouseEvent.target!.position);
if (!occurrence) {
return;
}
@@ -348,7 +350,10 @@ class LinkDetector implements editorCommon.IEditorContribution {
});
}
- public getLinkOccurrence(position: Position): LinkOccurrence {
+ public getLinkOccurrence(position: Position | null): LinkOccurrence | null {
+ if (!this.editor.hasModel() || !position) {
+ return null;
+ }
const decorations = this.editor.getModel().getDecorationsInRange({
startLineNumber: position.lineNumber,
startColumn: position.column,
@@ -367,9 +372,9 @@ class LinkDetector implements editorCommon.IEditorContribution {
return null;
}
- private isEnabled(mouseEvent: ClickLinkMouseEvent, withKey?: ClickLinkKeyboardEvent): boolean {
- return (
- mouseEvent.target.type === MouseTargetType.CONTENT_TEXT
+ private isEnabled(mouseEvent: ClickLinkMouseEvent, withKey?: ClickLinkKeyboardEvent | null): boolean {
+ return Boolean(
+ (mouseEvent.target && mouseEvent.target.type === MouseTargetType.CONTENT_TEXT)
&& (mouseEvent.hasTriggerModifier || (withKey && withKey.keyCodeIsTriggerKey))
);
}
@@ -405,6 +410,9 @@ class OpenLinkAction extends EditorAction {
if (!linkDetector) {
return;
}
+ if (!editor.hasModel()) {
+ return;
+ }
let selections = editor.getSelections();
diff --git a/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts b/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts
index 4fcd25fbd03..1c720f23753 100644
--- a/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts
+++ b/src/vs/editor/contrib/wordHighlighter/wordHighlighter.ts
@@ -9,9 +9,10 @@ import { first, createCancelablePromise, CancelablePromise, timeout } from 'vs/b
import { onUnexpectedExternalError, onUnexpectedError } from 'vs/base/common/errors';
import { Range } from 'vs/editor/common/core/range';
import * as editorCommon from 'vs/editor/common/editorCommon';
+import * as arrays from 'vs/base/common/arrays';
import { registerEditorContribution, EditorAction, IActionOptions, registerEditorAction, registerDefaultLanguageCommand } from 'vs/editor/browser/editorExtensions';
import { DocumentHighlight, DocumentHighlightKind, DocumentHighlightProviderRegistry } from 'vs/editor/common/modes';
-import { IDisposable, dispose } from 'vs/base/common/lifecycle';
+import { IDisposable, dispose, Disposable } from 'vs/base/common/lifecycle';
import { Position } from 'vs/editor/common/core/position';
import { Selection } from 'vs/editor/common/core/selection';
import { registerColor, editorSelectionHighlight, overviewRulerSelectionHighlightForeground, activeContrastBorder, editorSelectionHighlightBorder } from 'vs/platform/theme/common/colorRegistry';
@@ -22,8 +23,7 @@ import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/cont
import { KeyCode, KeyMod } from 'vs/base/common/keyCodes';
import { ServicesAccessor } from 'vs/platform/instantiation/common/instantiation';
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
-import { firstIndex, isFalsyOrEmpty } from 'vs/base/common/arrays';
-import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
+import { ICodeEditor, IActiveCodeEditor } from 'vs/editor/browser/editorBrowser';
import { ITextModel, TrackedRangeStickiness, OverviewRulerLane, IModelDeltaDecoration } from 'vs/editor/common/model';
import { CancellationToken } from 'vs/base/common/cancellation';
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
@@ -38,17 +38,17 @@ export const overviewRulerWordHighlightStrongForeground = registerColor('editorO
export const ctxHasWordHighlights = new RawContextKey('hasWordHighlights', false);
-export function getOccurrencesAtPosition(model: ITextModel, position: Position, token: CancellationToken): Promise {
+export function getOccurrencesAtPosition(model: ITextModel, position: Position, token: CancellationToken): Promise {
const orderedByScore = DocumentHighlightProviderRegistry.ordered(model);
// in order of score ask the occurrences provider
// until someone response with a good result
// (good = none empty array)
- return first(orderedByScore.map(provider => () => {
+ return first(orderedByScore.map(provider => () => {
return Promise.resolve(provider.provideDocumentHighlights(model, position, token))
.then(undefined, onUnexpectedExternalError);
- }), result => !isFalsyOrEmpty(result));
+ }), result => !arrays.isFalsyOrEmpty(result));
}
interface IOccurenceAtPositionRequest {
@@ -59,7 +59,7 @@ interface IOccurenceAtPositionRequest {
abstract class OccurenceAtPositionRequest implements IOccurenceAtPositionRequest {
- private readonly _wordRange: Range;
+ private readonly _wordRange: Range | null;
public readonly result: CancelablePromise;
constructor(model: ITextModel, selection: Selection, wordSeparators: string) {
@@ -69,7 +69,7 @@ abstract class OccurenceAtPositionRequest implements IOccurenceAtPositionRequest
protected abstract _compute(model: ITextModel, selection: Selection, wordSeparators: string, token: CancellationToken): Thenable;
- private _getCurrentWordRange(model: ITextModel, selection: Selection): Range {
+ private _getCurrentWordRange(model: ITextModel, selection: Selection): Range | null {
const word = model.getWordAtPosition(selection.getPosition());
if (word) {
return new Range(selection.startLineNumber, word.startColumn, selection.startLineNumber, word.endColumn);
@@ -84,7 +84,7 @@ abstract class OccurenceAtPositionRequest implements IOccurenceAtPositionRequest
const endColumn = selection.endColumn;
const currentWordRange = this._getCurrentWordRange(model, selection);
- let requestIsValid = (this._wordRange && this._wordRange.equalsRange(currentWordRange));
+ let requestIsValid = Boolean(this._wordRange && this._wordRange.equalsRange(currentWordRange));
// Even if we are on a different word, if that word is in the decorations ranges, the request is still valid
// (Same symbol)
@@ -161,14 +161,14 @@ registerDefaultLanguageCommand('_executeDocumentHighlights', (model, position) =
class WordHighlighter {
- private editor: ICodeEditor;
+ private editor: IActiveCodeEditor;
private occurrencesHighlight: boolean;
private model: ITextModel;
private _decorationIds: string[];
private toUnhook: IDisposable[];
private workerRequestTokenId: number = 0;
- private workerRequest: IOccurenceAtPositionRequest;
+ private workerRequest: IOccurenceAtPositionRequest | null;
private workerRequestCompleted: boolean = false;
private workerRequestValue: DocumentHighlight[] = [];
@@ -178,7 +178,7 @@ class WordHighlighter {
private _hasWordHighlights: IContextKey;
private _ignorePositionChangeEvent: boolean;
- constructor(editor: ICodeEditor, contextKeyService: IContextKeyService) {
+ constructor(editor: IActiveCodeEditor, contextKeyService: IContextKeyService) {
this.editor = editor;
this._hasWordHighlights = ctxHasWordHighlights.bindTo(contextKeyService);
this._ignorePositionChangeEvent = false;
@@ -200,10 +200,6 @@ class WordHighlighter {
this._onPositionChanged(e);
}));
- this.toUnhook.push(editor.onDidChangeModel((e) => {
- this._stopAll();
- this.model = this.editor.getModel();
- }));
this.toUnhook.push(editor.onDidChangeModelContent((e) => {
this._stopAll();
}));
@@ -236,14 +232,16 @@ class WordHighlighter {
}
private _getSortedHighlights(): Range[] {
- return this._decorationIds
- .map((id) => this.model.getDecorationRange(id))
- .sort(Range.compareRangesUsingStarts);
+ return arrays.coalesce(
+ this._decorationIds
+ .map((id) => this.model.getDecorationRange(id))
+ .sort(Range.compareRangesUsingStarts)
+ );
}
public moveNext() {
let highlights = this._getSortedHighlights();
- let index = firstIndex(highlights, (range) => range.containsPosition(this.editor.getPosition()));
+ let index = arrays.firstIndex(highlights, (range) => range.containsPosition(this.editor.getPosition()));
let newIndex = ((index + 1) % highlights.length);
let dest = highlights[newIndex];
try {
@@ -257,7 +255,7 @@ class WordHighlighter {
public moveBack() {
let highlights = this._getSortedHighlights();
- let index = firstIndex(highlights, (range) => range.containsPosition(this.editor.getPosition()));
+ let index = arrays.firstIndex(highlights, (range) => range.containsPosition(this.editor.getPosition()));
let newIndex = ((index - 1 + highlights.length) % highlights.length);
let dest = highlights[newIndex];
try {
@@ -461,7 +459,7 @@ class WordHighlighter {
}
}
-class WordHighlighterContribution implements editorCommon.IEditorContribution {
+class WordHighlighterContribution extends Disposable implements editorCommon.IEditorContribution {
private static readonly ID = 'editor.contrib.wordHighlighter';
@@ -469,10 +467,23 @@ class WordHighlighterContribution implements editorCommon.IEditorContribution {
return editor.getContribution(WordHighlighterContribution.ID);
}
- private wordHighligher: WordHighlighter;
+ private wordHighligher: WordHighlighter | null;
constructor(editor: ICodeEditor, @IContextKeyService contextKeyService: IContextKeyService) {
- this.wordHighligher = new WordHighlighter(editor, contextKeyService);
+ super();
+ const createWordHighlighterIfPossible = () => {
+ if (editor.hasModel()) {
+ this.wordHighligher = new WordHighlighter(editor, contextKeyService);
+ }
+ };
+ this._register(editor.onDidChangeModel((e) => {
+ if (this.wordHighligher) {
+ this.wordHighligher.dispose();
+ this.wordHighligher = null;
+ }
+ createWordHighlighterIfPossible();
+ }));
+ createWordHighlighterIfPossible();
}
public getId(): string {
@@ -480,28 +491,36 @@ class WordHighlighterContribution implements editorCommon.IEditorContribution {
}
public saveViewState(): boolean {
- if (this.wordHighligher.hasDecorations()) {
+ if (this.wordHighligher && this.wordHighligher.hasDecorations()) {
return true;
}
return false;
}
public moveNext() {
- this.wordHighligher.moveNext();
+ if (this.wordHighligher) {
+ this.wordHighligher.moveNext();
+ }
}
public moveBack() {
- this.wordHighligher.moveBack();
+ if (this.wordHighligher) {
+ this.wordHighligher.moveBack();
+ }
}
public restoreViewState(state: boolean | undefined): void {
- if (state) {
+ if (this.wordHighligher && state) {
this.wordHighligher.restore();
}
}
public dispose(): void {
- this.wordHighligher.dispose();
+ if (this.wordHighligher) {
+ this.wordHighligher.dispose();
+ this.wordHighligher = null;
+ }
+ super.dispose();
}
}
diff --git a/src/vs/editor/standalone/browser/colorizer.ts b/src/vs/editor/standalone/browser/colorizer.ts
index 47a2bc4aa05..245b4559fef 100644
--- a/src/vs/editor/standalone/browser/colorizer.ts
+++ b/src/vs/editor/standalone/browser/colorizer.ts
@@ -31,29 +31,32 @@ export class Colorizer {
let mimeType = options.mimeType || domNode.getAttribute('lang') || domNode.getAttribute('data-lang');
if (!mimeType) {
console.error('Mode not detected');
- return undefined;
+ return Promise.resolve();
}
themeService.setTheme(theme);
- let text = domNode.firstChild.nodeValue;
+ let text = domNode.firstChild ? domNode.firstChild.nodeValue : '';
domNode.className += ' ' + theme;
let render = (str: string) => {
domNode.innerHTML = str;
};
- return this.colorize(modeService, text, mimeType, options).then(render, (err) => console.error(err));
+ return this.colorize(modeService, text || '', mimeType, options).then(render, (err) => console.error(err));
}
- public static colorize(modeService: IModeService, text: string, mimeType: string, options: IColorizerOptions): Promise {
+ public static colorize(modeService: IModeService, text: string, mimeType: string, options: IColorizerOptions | null | undefined): Promise {
+ let tabSize = 4;
+ if (options && typeof options.tabSize === 'number') {
+ tabSize = options.tabSize;
+ }
+
if (strings.startsWithUTF8BOM(text)) {
text = text.substr(1);
}
let lines = text.split(/\r\n|\r|\n/);
let language = modeService.getModeId(mimeType);
-
- options = options || {};
- if (typeof options.tabSize === 'undefined') {
- options.tabSize = 4;
+ if (!language) {
+ return Promise.resolve(_fakeColorize(lines, tabSize));
}
// Send out the event to create the mode
@@ -61,7 +64,7 @@ export class Colorizer {
let tokenizationSupport = TokenizationRegistry.get(language);
if (tokenizationSupport) {
- return Promise.resolve(_colorize(lines, options.tabSize, tokenizationSupport));
+ return Promise.resolve(_colorize(lines, tabSize, tokenizationSupport));
}
return new Promise((resolve, reject) => {
@@ -77,18 +80,18 @@ export class Colorizer {
timeout.dispose();
timeout = null;
}
- const tokenizationSupport = TokenizationRegistry.get(language);
+ const tokenizationSupport = TokenizationRegistry.get(language!);
if (tokenizationSupport) {
- return resolve(_colorize(lines, options.tabSize, tokenizationSupport));
+ return resolve(_colorize(lines, tabSize, tokenizationSupport));
}
- return resolve(_fakeColorize(lines, options.tabSize));
+ return resolve(_fakeColorize(lines, tabSize));
};
// wait 500ms for mode to load, then give up
timeout = new TimeoutTimer();
timeout.cancelAndSet(execute, 500);
listener = TokenizationRegistry.onDidChange((e) => {
- if (e.changedLanguages.indexOf(language) >= 0) {
+ if (e.changedLanguages.indexOf(language!) >= 0) {
execute();
}
});
diff --git a/src/vs/editor/standalone/browser/inspectTokens/inspectTokens.ts b/src/vs/editor/standalone/browser/inspectTokens/inspectTokens.ts
index f8c84e50ead..9372dbd7e58 100644
--- a/src/vs/editor/standalone/browser/inspectTokens/inspectTokens.ts
+++ b/src/vs/editor/standalone/browser/inspectTokens/inspectTokens.ts
@@ -11,7 +11,7 @@ import { Position } from 'vs/editor/common/core/position';
import { IEditorContribution } from 'vs/editor/common/editorCommon';
import { ITextModel } from 'vs/editor/common/model';
import { registerEditorAction, registerEditorContribution, EditorAction, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
-import { ICodeEditor, ContentWidgetPositionPreference, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser';
+import { ICodeEditor, ContentWidgetPositionPreference, IContentWidget, IContentWidgetPosition, IActiveCodeEditor } from 'vs/editor/browser/editorBrowser';
import { IModeService } from 'vs/editor/common/services/modeService';
import { TokenizationRegistry, LanguageIdentifier, FontStyle, StandardTokenType, ITokenizationSupport, IState, TokenMetadata } from 'vs/editor/common/modes';
import { CharCode } from 'vs/base/common/charCode';
@@ -32,7 +32,6 @@ class InspectTokensController extends Disposable implements IEditorContribution
}
private _editor: ICodeEditor;
- private _standaloneThemeService: IStandaloneThemeService;
private _modeService: IModeService;
private _widget: InspectTokensWidget | null;
@@ -43,7 +42,6 @@ class InspectTokensController extends Disposable implements IEditorContribution
) {
super();
this._editor = editor;
- this._standaloneThemeService = standaloneColorService;
this._modeService = modeService;
this._widget = null;
@@ -68,7 +66,7 @@ class InspectTokensController extends Disposable implements IEditorContribution
if (!this._editor.hasModel()) {
return;
}
- this._widget = new InspectTokensWidget(this._editor, this._standaloneThemeService, this._modeService);
+ this._widget = new InspectTokensWidget(this._editor, this._modeService);
}
public stop(): void {
@@ -164,15 +162,14 @@ class InspectTokensWidget extends Disposable implements IContentWidget {
// Editor.IContentWidget.allowEditorOverflow
public allowEditorOverflow = true;
- private _editor: ICodeEditor;
+ private _editor: IActiveCodeEditor;
private _modeService: IModeService;
private _tokenizationSupport: ITokenizationSupport;
private _model: ITextModel;
private _domNode: HTMLElement;
constructor(
- editor: ICodeEditor,
- standaloneThemeService: IStandaloneThemeService,
+ editor: IActiveCodeEditor,
modeService: IModeService
) {
super();
@@ -249,14 +246,14 @@ class InspectTokensWidget extends Disposable implements IContentWidget {
}
private _decodeMetadata(metadata: number): IDecodedMetadata {
- let colorMap = TokenizationRegistry.getColorMap();
+ let colorMap = TokenizationRegistry.getColorMap()!;
let languageId = TokenMetadata.getLanguageId(metadata);
let tokenType = TokenMetadata.getTokenType(metadata);
let fontStyle = TokenMetadata.getFontStyle(metadata);
let foreground = TokenMetadata.getForeground(metadata);
let background = TokenMetadata.getBackground(metadata);
return {
- languageIdentifier: this._modeService.getLanguageIdentifier(languageId),
+ languageIdentifier: this._modeService.getLanguageIdentifier(languageId)!,
tokenType: tokenType,
fontStyle: fontStyle,
foreground: colorMap[foreground],
diff --git a/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts b/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts
index 35235073a96..f25911aa714 100644
--- a/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts
+++ b/src/vs/editor/standalone/browser/standaloneThemeServiceImpl.ts
@@ -27,9 +27,9 @@ class StandaloneTheme implements IStandaloneTheme {
public readonly themeName: string;
private themeData: IStandaloneThemeData;
- private colors: { [colorId: string]: Color };
- private defaultColors: { [colorId: string]: Color };
- private _tokenTheme: TokenTheme;
+ private colors: { [colorId: string]: Color } | null;
+ private defaultColors: { [colorId: string]: Color | null; };
+ private _tokenTheme: TokenTheme | null;
constructor(name: string, standaloneThemeData: IStandaloneThemeData) {
this.themeData = standaloneThemeData;
@@ -77,7 +77,7 @@ class StandaloneTheme implements IStandaloneTheme {
return this.colors;
}
- public getColor(colorId: ColorIdentifier, useDefault?: boolean): Color {
+ public getColor(colorId: ColorIdentifier, useDefault?: boolean): Color | null {
const color = this.getColors()[colorId];
if (color) {
return color;
@@ -88,7 +88,7 @@ class StandaloneTheme implements IStandaloneTheme {
return null;
}
- private getDefault(colorId: ColorIdentifier): Color {
+ private getDefault(colorId: ColorIdentifier): Color | null {
let color = this.defaultColors[colorId];
if (color) {
return color;
@@ -113,7 +113,7 @@ class StandaloneTheme implements IStandaloneTheme {
public get tokenTheme(): TokenTheme {
if (!this._tokenTheme) {
let rules: ITokenThemeRule[] = [];
- let encodedTokensColors = [];
+ let encodedTokensColors: string[] = [];
if (this.themeData.inherit) {
let baseData = getBuiltinRules(this.themeData.base);
rules = baseData.rules;
diff --git a/src/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.ts b/src/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.ts
index fbb0790bae1..0b59bc960a6 100644
--- a/src/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.ts
+++ b/src/vs/editor/standalone/browser/toggleHighContrast/toggleHighContrast.ts
@@ -10,7 +10,7 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
class ToggleHighContrast extends EditorAction {
- private _originalThemeName: string;
+ private _originalThemeName: string | null;
constructor() {
super({
diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts
index 8c1006e4bea..6ecfcd74608 100644
--- a/src/vs/monaco.d.ts
+++ b/src/vs/monaco.d.ts
@@ -675,7 +675,7 @@ declare namespace monaco {
* A function that compares ranges, useful for sorting ranges
* It will first compare ranges on the startPosition and then on the endPosition
*/
- static compareRangesUsingStarts(a: IRange, b: IRange): number;
+ static compareRangesUsingStarts(a: IRange | null | undefined, b: IRange | null | undefined): number;
/**
* A function that compares ranges, useful for sorting ranges
* It will first compare ranges on the endPosition and then on the startPosition
@@ -4403,11 +4403,11 @@ declare namespace monaco.languages {
/**
* The line comment token, like `// this is a comment`
*/
- lineComment?: string;
+ lineComment?: string | null;
/**
* The block comment character pair, like `/* block comment */`
*/
- blockComment?: CharacterPair;
+ blockComment?: CharacterPair | null;
}
/**
diff --git a/src/vs/platform/theme/common/themeService.ts b/src/vs/platform/theme/common/themeService.ts
index a06dafa5d90..a719d8647dd 100644
--- a/src/vs/platform/theme/common/themeService.ts
+++ b/src/vs/platform/theme/common/themeService.ts
@@ -52,7 +52,7 @@ export interface ITheme {
* @param color the id of the color
* @param useDefault specifies if the default color should be used. If not set, the default is used.
*/
- getColor(color: ColorIdentifier, useDefault?: boolean): Color;
+ getColor(color: ColorIdentifier, useDefault?: boolean): Color | null;
/**
* Returns wheter the theme defines a value for the color. If not, that means the