diff --git a/build/lib/tslint/noUnexternalizedStringsRule.js b/build/lib/tslint/noUnexternalizedStringsRule.js index 18a90c0f9c1..a1183ce68e7 100644 --- a/build/lib/tslint/noUnexternalizedStringsRule.js +++ b/build/lib/tslint/noUnexternalizedStringsRule.js @@ -11,6 +11,9 @@ const Lint = require("tslint"); */ class Rule extends Lint.Rules.AbstractRule { apply(sourceFile) { + if (/\.d.ts$/.test(sourceFile.fileName)) { + return []; + } return this.applyWithWalker(new NoUnexternalizedStringsRuleWalker(sourceFile, this.getOptions())); } } diff --git a/build/lib/tslint/noUnexternalizedStringsRule.ts b/build/lib/tslint/noUnexternalizedStringsRule.ts index e8c0e98ec15..d896e4fabe2 100644 --- a/build/lib/tslint/noUnexternalizedStringsRule.ts +++ b/build/lib/tslint/noUnexternalizedStringsRule.ts @@ -11,6 +11,9 @@ import * as Lint from 'tslint'; */ export class Rule extends Lint.Rules.AbstractRule { public apply(sourceFile: ts.SourceFile): Lint.RuleFailure[] { + if (/\.d.ts$/.test(sourceFile.fileName)) { + return []; + } return this.applyWithWalker(new NoUnexternalizedStringsRuleWalker(sourceFile, this.getOptions())); } } diff --git a/build/monaco/api.js b/build/monaco/api.js index 5cd0be82039..93fea1558b9 100644 --- a/build/monaco/api.js +++ b/build/monaco/api.js @@ -148,8 +148,9 @@ function getMassagedTopLevelDeclarationText(sourceFile, declaration, importName, } }); } - result = result.replace(/export default/g, 'export'); - result = result.replace(/export declare/g, 'export'); + result = result.replace(/export default /g, 'export '); + result = result.replace(/export declare /g, 'export '); + result = result.replace(/declare /g, ''); if (declaration.kind === ts.SyntaxKind.EnumDeclaration) { result = result.replace(/const enum/, 'enum'); enums.push(result); diff --git a/build/monaco/api.ts b/build/monaco/api.ts index ef9c9a584dc..1cd4e49b733 100644 --- a/build/monaco/api.ts +++ b/build/monaco/api.ts @@ -178,8 +178,9 @@ function getMassagedTopLevelDeclarationText(sourceFile: ts.SourceFile, declarati } }); } - result = result.replace(/export default/g, 'export'); - result = result.replace(/export declare/g, 'export'); + result = result.replace(/export default /g, 'export '); + result = result.replace(/export declare /g, 'export '); + result = result.replace(/declare /g, ''); if (declaration.kind === ts.SyntaxKind.EnumDeclaration) { result = result.replace(/const enum/, 'enum'); diff --git a/build/monaco/monaco.d.ts.recipe b/build/monaco/monaco.d.ts.recipe index afba093b25c..4a80dae41aa 100644 --- a/build/monaco/monaco.d.ts.recipe +++ b/build/monaco/monaco.d.ts.recipe @@ -62,6 +62,7 @@ export interface ICommandHandler { #includeAll(vs/editor/common/editorCommon;editorOptions.=>): IScrollEvent #includeAll(vs/editor/common/model/textModelEvents): #includeAll(vs/editor/common/controller/cursorEvents): +#include(vs/platform/accessibility/common/accessibility): AccessibilitySupport #includeAll(vs/editor/common/config/editorOptions): #includeAll(vs/editor/browser/editorBrowser;editorCommon.=>;editorOptions.=>): #include(vs/editor/common/config/fontInfo): FontInfo, BareFontInfo diff --git a/src/vs/editor/browser/controller/mouseHandler.ts b/src/vs/editor/browser/controller/mouseHandler.ts index ccd54250d89..ce65849c418 100644 --- a/src/vs/editor/browser/controller/mouseHandler.ts +++ b/src/vs/editor/browser/controller/mouseHandler.ts @@ -217,7 +217,7 @@ export class MouseHandler extends ViewEventHandler { const targetIsContent = (t.type === editorBrowser.MouseTargetType.CONTENT_TEXT || t.type === editorBrowser.MouseTargetType.CONTENT_EMPTY); const targetIsGutter = (t.type === editorBrowser.MouseTargetType.GUTTER_GLYPH_MARGIN || t.type === editorBrowser.MouseTargetType.GUTTER_LINE_NUMBERS || t.type === editorBrowser.MouseTargetType.GUTTER_LINE_DECORATIONS); const targetIsLineNumbers = (t.type === editorBrowser.MouseTargetType.GUTTER_LINE_NUMBERS); - const selectOnLineNumbers = this._context.configuration.getOption(EditorOptionId.selectOnLineNumbers); + const selectOnLineNumbers = this._context.configuration.options.get(EditorOptionId.selectOnLineNumbers); const targetIsViewZone = (t.type === editorBrowser.MouseTargetType.CONTENT_VIEW_ZONE || t.type === editorBrowser.MouseTargetType.GUTTER_VIEW_ZONE); const targetIsWidget = (t.type === editorBrowser.MouseTargetType.CONTENT_WIDGET); diff --git a/src/vs/editor/browser/controller/mouseTarget.ts b/src/vs/editor/browser/controller/mouseTarget.ts index f510e0f6f82..58948e740aa 100644 --- a/src/vs/editor/browser/controller/mouseTarget.ts +++ b/src/vs/editor/browser/controller/mouseTarget.ts @@ -10,7 +10,7 @@ import { ClientCoordinates, EditorMouseEvent, EditorPagePosition, PageCoordinate import { PartFingerprint, PartFingerprints } from 'vs/editor/browser/view/viewPart'; import { ViewLine } from 'vs/editor/browser/viewParts/lines/viewLine'; import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor'; -import { EditorLayoutInfo } from 'vs/editor/common/config/editorOptions'; +import { EditorLayoutInfo, EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; import { Position } from 'vs/editor/common/core/position'; import { Range as EditorRange } from 'vs/editor/common/core/range'; import { HorizontalRange } from 'vs/editor/common/view/renderingContext'; @@ -239,7 +239,8 @@ export class HitTestContext { constructor(context: ViewContext, viewHelper: IPointerHandlerHelper, lastViewCursorsRenderData: IViewCursorRenderData[]) { this.model = context.model; - this.layoutInfo = context.configuration.editor.layoutInfo; + const options = context.configuration.options; + this.layoutInfo = options.get(EditorOptionId.layoutInfo); this.viewDomNode = viewHelper.viewDomNode; this.lineHeight = context.configuration.editor.lineHeight; this.typicalHalfwidthCharacterWidth = context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth; @@ -713,7 +714,8 @@ export class MouseTargetFactory { } public getMouseColumn(editorPos: EditorPagePosition, pos: PageCoordinates): number { - const layoutInfo = this._context.configuration.editor.layoutInfo; + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); const mouseContentHorizontalOffset = this._context.viewLayout.getCurrentScrollLeft() + pos.x - editorPos.x - layoutInfo.contentLeft; return MouseTargetFactory._getMouseColumn(mouseContentHorizontalOffset, this._context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth); } diff --git a/src/vs/editor/browser/controller/textAreaHandler.ts b/src/vs/editor/browser/controller/textAreaHandler.ts index c1a41a4981f..bfefbfff922 100644 --- a/src/vs/editor/browser/controller/textAreaHandler.ts +++ b/src/vs/editor/browser/controller/textAreaHandler.ts @@ -16,7 +16,7 @@ import { ViewController } from 'vs/editor/browser/view/viewController'; import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/view/viewPart'; import { LineNumbersOverlay } from 'vs/editor/browser/viewParts/lineNumbers/lineNumbers'; import { Margin } from 'vs/editor/browser/viewParts/margin/margin'; -import { RenderLineNumbersType } from 'vs/editor/common/config/editorOptions'; +import { RenderLineNumbersType, EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; import { BareFontInfo } from 'vs/editor/common/config/fontInfo'; import { WordCharacterClass, getMapForWordSeparators } from 'vs/editor/common/controller/wordCharacterClassifier'; import { Position } from 'vs/editor/common/core/position'; @@ -119,11 +119,13 @@ export class TextAreaHandler extends ViewPart { this._viewHelper = viewHelper; const conf = this._context.configuration.editor; + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); this._accessibilitySupport = conf.accessibilitySupport; - this._contentLeft = conf.layoutInfo.contentLeft; - this._contentWidth = conf.layoutInfo.contentWidth; - this._contentHeight = conf.layoutInfo.contentHeight; + this._contentLeft = layoutInfo.contentLeft; + this._contentWidth = layoutInfo.contentWidth; + this._contentHeight = layoutInfo.contentHeight; this._scrollLeft = 0; this._scrollTop = 0; this._fontInfo = conf.fontInfo; @@ -143,7 +145,7 @@ export class TextAreaHandler extends ViewPart { this.textArea.setAttribute('autocapitalize', 'off'); this.textArea.setAttribute('autocomplete', 'off'); this.textArea.setAttribute('spellcheck', 'false'); - this.textArea.setAttribute('aria-label', conf.viewInfo.ariaLabel); + this.textArea.setAttribute('aria-label', options.get(EditorOptionId.ariaLabel)); this.textArea.setAttribute('role', 'textbox'); this.textArea.setAttribute('aria-multiline', 'true'); this.textArea.setAttribute('aria-haspopup', 'false'); @@ -371,22 +373,24 @@ export class TextAreaHandler extends ViewPart { public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { const conf = this._context.configuration.editor; + const options = this._context.configuration.options; if (e.fontInfo) { this._fontInfo = conf.fontInfo; } if (e.viewInfo) { - this.textArea.setAttribute('aria-label', conf.viewInfo.ariaLabel); + this.textArea.setAttribute('aria-label', options.get(EditorOptionId.ariaLabel)); } - if (e.layoutInfo) { - this._contentLeft = conf.layoutInfo.contentLeft; - this._contentWidth = conf.layoutInfo.contentWidth; - this._contentHeight = conf.layoutInfo.contentHeight; + if (e.hasChanged(EditorOptionId.layoutInfo)) { + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._contentLeft = layoutInfo.contentLeft; + this._contentWidth = layoutInfo.contentWidth; + this._contentHeight = layoutInfo.contentHeight; } if (e.lineHeight) { this._lineHeight = conf.lineHeight; } - if (e.accessibilitySupport) { + if (e.hasChanged(EditorOptionId.accessibilitySupport)) { this._accessibilitySupport = conf.accessibilitySupport; this._textAreaInput.writeScreenReaderContent('strategy changed'); } @@ -544,10 +548,13 @@ export class TextAreaHandler extends ViewPart { tac.setWidth(1); tac.setHeight(1); + const options = this._context.configuration.options; + if (this._context.configuration.editor.viewInfo.glyphMargin) { tac.setClassName('monaco-editor-background textAreaCover ' + Margin.OUTER_CLASS_NAME); } else { - if (this._context.configuration.editor.viewInfo.renderLineNumbers !== RenderLineNumbersType.Off) { + const renderLineNumbers = options.get(EditorOptionId.renderLineNumbers); + if (renderLineNumbers.renderType !== RenderLineNumbersType.Off) { tac.setClassName('monaco-editor-background textAreaCover ' + LineNumbersOverlay.CLASS_NAME); } else { tac.setClassName('monaco-editor-background textAreaCover'); diff --git a/src/vs/editor/browser/editorBrowser.ts b/src/vs/editor/browser/editorBrowser.ts index d1efe4ddd52..de7dcc54683 100644 --- a/src/vs/editor/browser/editorBrowser.ts +++ b/src/vs/editor/browser/editorBrowser.ts @@ -536,6 +536,8 @@ export interface ICodeEditor extends editorCommon.IEditor { */ getConfiguration(): editorOptions.InternalEditorOptions; + getOptions(): editorOptions.IComputedEditorOptions; + getOption>(id: editorOptions.EditorOptionId): editorOptions.ComputedEditorOptionValue; /** diff --git a/src/vs/editor/browser/view/viewImpl.ts b/src/vs/editor/browser/view/viewImpl.ts index 45c711cecef..67fca037793 100644 --- a/src/vs/editor/browser/view/viewImpl.ts +++ b/src/vs/editor/browser/view/viewImpl.ts @@ -48,6 +48,7 @@ import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData' import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler'; import { IViewModel } from 'vs/editor/common/viewModel/viewModel'; import { IThemeService, getThemeTypeSelector } from 'vs/platform/theme/common/themeService'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; export interface IContentWidgetData { widget: editorBrowser.IContentWidget; @@ -281,7 +282,8 @@ export class View extends ViewEventHandler { } private _setLayout(): void { - const layoutInfo = this._context.configuration.editor.layoutInfo; + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); this.domNode.setWidth(layoutInfo.width); this.domNode.setHeight(layoutInfo.height); @@ -304,7 +306,7 @@ export class View extends ViewEventHandler { if (e.editorClassName) { this.domNode.setClassName(this.getEditorClassName()); } - if (e.layoutInfo) { + if (e.hasChanged(EditorOptionId.layoutInfo)) { this._setLayout(); } return false; diff --git a/src/vs/editor/browser/view/viewLayer.ts b/src/vs/editor/browser/view/viewLayer.ts index ecdd665be73..c5624ce9c83 100644 --- a/src/vs/editor/browser/view/viewLayer.ts +++ b/src/vs/editor/browser/view/viewLayer.ts @@ -7,6 +7,7 @@ import { FastDomNode, createFastDomNode } from 'vs/base/browser/fastDomNode'; import { IStringBuilder, createStringBuilder } from 'vs/editor/common/core/stringBuilder'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData'; +import { EditorOptionId } from 'vs/editor/common/config/editorOptions'; /** * Represents a visible line @@ -269,7 +270,10 @@ export class VisibleLinesCollection { // ---- begin view event handlers public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { - return e.layoutInfo; + if (e.hasChanged(EditorOptionId.layoutInfo)) { + return true; + } + return false; } public onFlushed(e: viewEvents.ViewFlushedEvent): boolean { diff --git a/src/vs/editor/browser/view/viewOverlays.ts b/src/vs/editor/browser/view/viewOverlays.ts index bc75a6b4cef..5182408db5a 100644 --- a/src/vs/editor/browser/view/viewOverlays.ts +++ b/src/vs/editor/browser/view/viewOverlays.ts @@ -14,6 +14,7 @@ import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/v import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; export class ViewOverlays extends ViewPart implements IVisibleLinesHost { @@ -215,8 +216,9 @@ export class ContentViewOverlays extends ViewOverlays { constructor(context: ViewContext) { super(context); - - this._contentWidth = this._context.configuration.editor.layoutInfo.contentWidth; + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._contentWidth = layoutInfo.contentWidth; this.domNode.setHeight(0); } @@ -224,8 +226,10 @@ export class ContentViewOverlays extends ViewOverlays { // --- begin event handlers public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { - if (e.layoutInfo) { - this._contentWidth = this._context.configuration.editor.layoutInfo.contentWidth; + if (e.hasChanged(EditorOptionId.layoutInfo)) { + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._contentWidth = layoutInfo.contentWidth; } return super.onConfigurationChanged(e); } @@ -249,7 +253,9 @@ export class MarginViewOverlays extends ViewOverlays { constructor(context: ViewContext) { super(context); - this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._contentLeft = layoutInfo.contentLeft; this.domNode.setClassName('margin-view-overlays'); this.domNode.setWidth(1); @@ -263,8 +269,10 @@ export class MarginViewOverlays extends ViewOverlays { Configuration.applyFontInfo(this.domNode, this._context.configuration.editor.fontInfo); shouldRender = true; } - if (e.layoutInfo) { - this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; + if (e.hasChanged(EditorOptionId.layoutInfo)) { + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._contentLeft = layoutInfo.contentLeft; shouldRender = true; } return super.onConfigurationChanged(e) || shouldRender; diff --git a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts index cae3be1ed16..9c7998b7427 100644 --- a/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts +++ b/src/vs/editor/browser/viewParts/contentWidgets/contentWidgets.ts @@ -14,6 +14,7 @@ import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/v import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; class Coordinate { _coordinateBrand: void; @@ -207,9 +208,12 @@ class Widget { this.allowEditorOverflow = this._actual.allowEditorOverflow || false; this.suppressMouseDown = this._actual.suppressMouseDown || false; + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._fixedOverflowWidgets = this._context.configuration.editor.viewInfo.fixedOverflowWidgets; - this._contentWidth = this._context.configuration.editor.layoutInfo.contentWidth; - this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; + this._contentWidth = layoutInfo.contentWidth; + this._contentLeft = layoutInfo.contentLeft; this._lineHeight = this._context.configuration.editor.lineHeight; this._position = null; @@ -233,9 +237,11 @@ class Widget { if (e.lineHeight) { this._lineHeight = this._context.configuration.editor.lineHeight; } - if (e.layoutInfo) { - this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; - this._contentWidth = this._context.configuration.editor.layoutInfo.contentWidth; + if (e.hasChanged(EditorOptionId.layoutInfo)) { + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._contentLeft = layoutInfo.contentLeft; + this._contentWidth = layoutInfo.contentWidth; this._maxWidth = this._getMaxWidth(); } } diff --git a/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts b/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts index d707bbad7c5..65343ec07eb 100644 --- a/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts +++ b/src/vs/editor/browser/viewParts/currentLineHighlight/currentLineHighlight.ts @@ -10,6 +10,7 @@ import { RenderingContext } from 'vs/editor/common/view/renderingContext'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; export class CurrentLineHighlightOverlay extends DynamicViewOverlay { private readonly _context: ViewContext; @@ -23,13 +24,17 @@ export class CurrentLineHighlightOverlay extends DynamicViewOverlay { constructor(context: ViewContext) { super(); this._context = context; + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._lineHeight = this._context.configuration.editor.lineHeight; this._renderLineHighlight = this._context.configuration.editor.viewInfo.renderLineHighlight; this._selectionIsEmpty = true; this._primaryCursorLineNumber = 1; this._scrollWidth = 0; - this._contentWidth = this._context.configuration.editor.layoutInfo.contentWidth; + + this._contentWidth = layoutInfo.contentWidth; this._context.addEventHandler(this); } @@ -48,8 +53,10 @@ export class CurrentLineHighlightOverlay extends DynamicViewOverlay { if (e.viewInfo) { this._renderLineHighlight = this._context.configuration.editor.viewInfo.renderLineHighlight; } - if (e.layoutInfo) { - this._contentWidth = this._context.configuration.editor.layoutInfo.contentWidth; + if (e.hasChanged(EditorOptionId.layoutInfo)) { + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._contentWidth = layoutInfo.contentWidth; } return true; } diff --git a/src/vs/editor/browser/viewParts/currentLineMarginHighlight/currentLineMarginHighlight.ts b/src/vs/editor/browser/viewParts/currentLineMarginHighlight/currentLineMarginHighlight.ts index 55145073655..1389ed0e1b0 100644 --- a/src/vs/editor/browser/viewParts/currentLineMarginHighlight/currentLineMarginHighlight.ts +++ b/src/vs/editor/browser/viewParts/currentLineMarginHighlight/currentLineMarginHighlight.ts @@ -10,6 +10,7 @@ import { RenderingContext } from 'vs/editor/common/view/renderingContext'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay { private readonly _context: ViewContext; @@ -22,12 +23,14 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay { constructor(context: ViewContext) { super(); this._context = context; + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); this._lineHeight = this._context.configuration.editor.lineHeight; this._renderLineHighlight = this._context.configuration.editor.viewInfo.renderLineHighlight; this._selectionIsEmpty = true; this._primaryCursorLineNumber = 1; - this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; + this._contentLeft = layoutInfo.contentLeft; this._context.addEventHandler(this); } @@ -46,8 +49,10 @@ export class CurrentLineMarginHighlightOverlay extends DynamicViewOverlay { if (e.viewInfo) { this._renderLineHighlight = this._context.configuration.editor.viewInfo.renderLineHighlight; } - if (e.layoutInfo) { - this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; + if (e.hasChanged(EditorOptionId.layoutInfo)) { + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._contentLeft = layoutInfo.contentLeft; } return true; } diff --git a/src/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts b/src/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts index d9b8c4dfd8f..24185fbc1c5 100644 --- a/src/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts +++ b/src/vs/editor/browser/viewParts/editorScrollbar/editorScrollbar.ts @@ -14,6 +14,7 @@ import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/v import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { getThemeTypeSelector } from 'vs/platform/theme/common/themeService'; +import { EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; export class EditorScrollbar extends ViewPart { @@ -28,8 +29,11 @@ export class EditorScrollbar extends ViewPart { ) { super(context); - const editor = this._context.configuration.editor; - const configScrollbarOpts = editor.viewInfo.scrollbar; + + const options = this._context.configuration.options; + const scrollbar = options.get(EditorOptionId.scrollbar); + const mouseWheelScrollSensitivity = options.get(EditorOptionId.mouseWheelScrollSensitivity); + const fastScrollSensitivity = options.get(EditorOptionId.fastScrollSensitivity); const scrollbarOptions: ScrollableElementCreationOptions = { listenOnDomNode: viewDomNode.domNode, @@ -37,18 +41,18 @@ export class EditorScrollbar extends ViewPart { useShadows: false, lazyRender: true, - vertical: configScrollbarOpts.vertical, - horizontal: configScrollbarOpts.horizontal, - verticalHasArrows: configScrollbarOpts.verticalHasArrows, - horizontalHasArrows: configScrollbarOpts.horizontalHasArrows, - verticalScrollbarSize: configScrollbarOpts.verticalScrollbarSize, - verticalSliderSize: configScrollbarOpts.verticalSliderSize, - horizontalScrollbarSize: configScrollbarOpts.horizontalScrollbarSize, - horizontalSliderSize: configScrollbarOpts.horizontalSliderSize, - handleMouseWheel: configScrollbarOpts.handleMouseWheel, - arrowSize: configScrollbarOpts.arrowSize, - mouseWheelScrollSensitivity: configScrollbarOpts.mouseWheelScrollSensitivity, - fastScrollSensitivity: configScrollbarOpts.fastScrollSensitivity, + vertical: scrollbar.vertical, + horizontal: scrollbar.horizontal, + verticalHasArrows: scrollbar.verticalHasArrows, + horizontalHasArrows: scrollbar.horizontalHasArrows, + verticalScrollbarSize: scrollbar.verticalScrollbarSize, + verticalSliderSize: scrollbar.verticalSliderSize, + horizontalScrollbarSize: scrollbar.horizontalScrollbarSize, + horizontalSliderSize: scrollbar.horizontalSliderSize, + handleMouseWheel: scrollbar.handleMouseWheel, + arrowSize: scrollbar.arrowSize, + mouseWheelScrollSensitivity: mouseWheelScrollSensitivity, + fastScrollSensitivity: fastScrollSensitivity, }; this.scrollbar = this._register(new SmoothScrollableElement(linesContent.domNode, scrollbarOptions, this._context.viewLayout.scrollable)); @@ -96,11 +100,13 @@ export class EditorScrollbar extends ViewPart { } private _setLayout(): void { - const layoutInfo = this._context.configuration.editor.layoutInfo; + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); this.scrollbarDomNode.setLeft(layoutInfo.contentLeft); - const side = this._context.configuration.editor.viewInfo.minimap.side; + const minimap = options.get(EditorOptionId.minimap); + const side = minimap.side; if (side === 'right') { this.scrollbarDomNode.setWidth(layoutInfo.contentWidth + layoutInfo.minimapWidth); } else { @@ -124,16 +130,23 @@ export class EditorScrollbar extends ViewPart { // --- begin event handlers public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { - if (e.viewInfo) { - const editor = this._context.configuration.editor; + if ( + e.hasChanged(EditorOptionId.scrollbar) + || e.hasChanged(EditorOptionId.mouseWheelScrollSensitivity) + || e.hasChanged(EditorOptionId.fastScrollSensitivity) + ) { + const options = this._context.configuration.options; + const scrollbar = options.get(EditorOptionId.scrollbar); + const mouseWheelScrollSensitivity = options.get(EditorOptionId.mouseWheelScrollSensitivity); + const fastScrollSensitivity = options.get(EditorOptionId.fastScrollSensitivity); const newOpts: ScrollableElementChangeOptions = { - handleMouseWheel: editor.viewInfo.scrollbar.handleMouseWheel, - mouseWheelScrollSensitivity: editor.viewInfo.scrollbar.mouseWheelScrollSensitivity, - fastScrollSensitivity: editor.viewInfo.scrollbar.fastScrollSensitivity + handleMouseWheel: scrollbar.handleMouseWheel, + mouseWheelScrollSensitivity: mouseWheelScrollSensitivity, + fastScrollSensitivity: fastScrollSensitivity }; this.scrollbar.updateOptions(newOpts); } - if (e.layoutInfo) { + if (e.hasChanged(EditorOptionId.layoutInfo)) { this._setLayout(); } return true; diff --git a/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts b/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts index 60c18790d0c..c063c668071 100644 --- a/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts +++ b/src/vs/editor/browser/viewParts/glyphMargin/glyphMargin.ts @@ -8,6 +8,7 @@ import { DynamicViewOverlay } from 'vs/editor/browser/view/dynamicViewOverlay'; import { RenderingContext } from 'vs/editor/common/view/renderingContext'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; export class DecorationToRender { _decorationToRenderBrand: void; @@ -84,10 +85,12 @@ export class GlyphMarginOverlay extends DedupOverlay { constructor(context: ViewContext) { super(); this._context = context; + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); this._lineHeight = this._context.configuration.editor.lineHeight; this._glyphMargin = this._context.configuration.editor.viewInfo.glyphMargin; - this._glyphMarginLeft = this._context.configuration.editor.layoutInfo.glyphMarginLeft; - this._glyphMarginWidth = this._context.configuration.editor.layoutInfo.glyphMarginWidth; + this._glyphMarginLeft = layoutInfo.glyphMarginLeft; + this._glyphMarginWidth = layoutInfo.glyphMarginWidth; this._renderResult = null; this._context.addEventHandler(this); } @@ -101,15 +104,18 @@ export class GlyphMarginOverlay extends DedupOverlay { // --- begin event handlers public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { + const options = this._context.configuration.options; + if (e.lineHeight) { this._lineHeight = this._context.configuration.editor.lineHeight; } if (e.viewInfo) { this._glyphMargin = this._context.configuration.editor.viewInfo.glyphMargin; } - if (e.layoutInfo) { - this._glyphMarginLeft = this._context.configuration.editor.layoutInfo.glyphMarginLeft; - this._glyphMarginWidth = this._context.configuration.editor.layoutInfo.glyphMarginWidth; + if (e.hasChanged(EditorOptionId.layoutInfo)) { + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._glyphMarginLeft = layoutInfo.glyphMarginLeft; + this._glyphMarginWidth = layoutInfo.glyphMarginWidth; } return true; } diff --git a/src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts b/src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts index ea713746e0d..a8ba2a3936a 100644 --- a/src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts +++ b/src/vs/editor/browser/viewParts/indentGuides/indentGuides.ts @@ -11,6 +11,7 @@ import { RenderingContext } from 'vs/editor/common/view/renderingContext'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; export class IndentGuidesOverlay extends DynamicViewOverlay { @@ -27,11 +28,13 @@ export class IndentGuidesOverlay extends DynamicViewOverlay { super(); this._context = context; this._primaryLineNumber = 0; + const options = this._context.configuration.options; this._lineHeight = this._context.configuration.editor.lineHeight; this._spaceWidth = this._context.configuration.editor.fontInfo.spaceWidth; this._enabled = this._context.configuration.editor.viewInfo.renderIndentGuides; this._activeIndentEnabled = this._context.configuration.editor.viewInfo.highlightActiveIndentGuide; - const wrappingColumn = this._context.configuration.editor.wrappingInfo.wrappingColumn; + const wrappingInfo = options.get(EditorOptionId.wrappingInfo); + const wrappingColumn = wrappingInfo.wrappingColumn; this._maxIndentLeft = wrappingColumn === -1 ? -1 : (wrappingColumn * this._context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth); this._renderResult = null; @@ -48,6 +51,7 @@ export class IndentGuidesOverlay extends DynamicViewOverlay { // --- begin event handlers public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { + const options = this._context.configuration.options; if (e.lineHeight) { this._lineHeight = this._context.configuration.editor.lineHeight; } @@ -58,8 +62,9 @@ export class IndentGuidesOverlay extends DynamicViewOverlay { this._enabled = this._context.configuration.editor.viewInfo.renderIndentGuides; this._activeIndentEnabled = this._context.configuration.editor.viewInfo.highlightActiveIndentGuide; } - if (e.wrappingInfo || e.fontInfo) { - const wrappingColumn = this._context.configuration.editor.wrappingInfo.wrappingColumn; + if (e.hasChanged(EditorOptionId.wrappingInfo) || e.fontInfo) { + const wrappingInfo = options.get(EditorOptionId.wrappingInfo); + const wrappingColumn = wrappingInfo.wrappingColumn; this._maxIndentLeft = wrappingColumn === -1 ? -1 : (wrappingColumn * this._context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth); } return true; diff --git a/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts b/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts index 2067c4d3878..d07bbdc92ae 100644 --- a/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts +++ b/src/vs/editor/browser/viewParts/lineNumbers/lineNumbers.ts @@ -41,13 +41,16 @@ export class LineNumbersOverlay extends DynamicViewOverlay { } private _readConfig(): void { + const options = this._context.configuration.options; const config = this._context.configuration.editor; this._lineHeight = config.lineHeight; - this._renderLineNumbers = config.viewInfo.renderLineNumbers; - this._renderCustomLineNumbers = config.viewInfo.renderCustomLineNumbers; - this._renderFinalNewline = this._context.configuration.getOption(EditorOptionId.renderFinalNewline); - this._lineNumbersLeft = config.layoutInfo.lineNumbersLeft; - this._lineNumbersWidth = config.layoutInfo.lineNumbersWidth; + const renderLineNumbers = options.get(EditorOptionId.renderLineNumbers); + this._renderLineNumbers = renderLineNumbers.renderType; + this._renderCustomLineNumbers = renderLineNumbers.renderFn; + this._renderFinalNewline = options.get(EditorOptionId.renderFinalNewline); + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._lineNumbersLeft = layoutInfo.lineNumbersLeft; + this._lineNumbersWidth = layoutInfo.lineNumbersWidth; } public dispose(): void { diff --git a/src/vs/editor/browser/viewParts/lines/viewLines.ts b/src/vs/editor/browser/viewParts/lines/viewLines.ts index 580311d7691..2e64c0c8056 100644 --- a/src/vs/editor/browser/viewParts/lines/viewLines.ts +++ b/src/vs/editor/browser/viewParts/lines/viewLines.ts @@ -18,6 +18,7 @@ import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { ViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData'; import { Viewport } from 'vs/editor/common/viewModel/viewModel'; +import { EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; class LastRenderedData { @@ -90,10 +91,12 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, this.domNode = this._visibleLines.domNode; const conf = this._context.configuration; + const options = this._context.configuration.options; + const wrappingInfo = options.get(EditorOptionId.wrappingInfo); this._lineHeight = conf.editor.lineHeight; this._typicalHalfwidthCharacterWidth = conf.editor.fontInfo.typicalHalfwidthCharacterWidth; - this._isViewportWrapping = conf.editor.wrappingInfo.isViewportWrapping; + this._isViewportWrapping = wrappingInfo.isViewportWrapping; this._revealHorizontalRightPadding = conf.editor.viewInfo.revealHorizontalRightPadding; this._scrollOff = conf.editor.viewInfo.cursorSurroundingLines; this._canUseLayerHinting = conf.editor.canUseLayerHinting; @@ -135,11 +138,12 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { this._visibleLines.onConfigurationChanged(e); - if (e.wrappingInfo) { + if (e.hasChanged(EditorOptionId.wrappingInfo)) { this._maxLineWidth = 0; } const conf = this._context.configuration; + const options = this._context.configuration.options; if (e.lineHeight) { this._lineHeight = conf.editor.lineHeight; @@ -147,8 +151,9 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, if (e.fontInfo) { this._typicalHalfwidthCharacterWidth = conf.editor.fontInfo.typicalHalfwidthCharacterWidth; } - if (e.wrappingInfo) { - this._isViewportWrapping = conf.editor.wrappingInfo.isViewportWrapping; + if (e.hasChanged(EditorOptionId.wrappingInfo)) { + const wrappingInfo = options.get(EditorOptionId.wrappingInfo); + this._isViewportWrapping = wrappingInfo.isViewportWrapping; } if (e.viewInfo) { this._revealHorizontalRightPadding = conf.editor.viewInfo.revealHorizontalRightPadding; @@ -163,7 +168,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost, this._onOptionsMaybeChanged(); - if (e.layoutInfo) { + if (e.hasChanged(EditorOptionId.layoutInfo)) { this._maxLineWidth = 0; } diff --git a/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts b/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts index fe764290bad..1d709f5b917 100644 --- a/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts +++ b/src/vs/editor/browser/viewParts/linesDecorations/linesDecorations.ts @@ -8,6 +8,7 @@ import { DecorationToRender, DedupOverlay } from 'vs/editor/browser/viewParts/gl import { RenderingContext } from 'vs/editor/common/view/renderingContext'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; export class LinesDecorationsOverlay extends DedupOverlay { @@ -20,8 +21,10 @@ export class LinesDecorationsOverlay extends DedupOverlay { constructor(context: ViewContext) { super(); this._context = context; - this._decorationsLeft = this._context.configuration.editor.layoutInfo.decorationsLeft; - this._decorationsWidth = this._context.configuration.editor.layoutInfo.decorationsWidth; + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._decorationsLeft = layoutInfo.decorationsLeft; + this._decorationsWidth = layoutInfo.decorationsWidth; this._renderResult = null; this._context.addEventHandler(this); } @@ -35,9 +38,11 @@ export class LinesDecorationsOverlay extends DedupOverlay { // --- begin event handlers public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { - if (e.layoutInfo) { - this._decorationsLeft = this._context.configuration.editor.layoutInfo.decorationsLeft; - this._decorationsWidth = this._context.configuration.editor.layoutInfo.decorationsWidth; + const options = this._context.configuration.options; + if (e.hasChanged(EditorOptionId.layoutInfo)) { + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._decorationsLeft = layoutInfo.decorationsLeft; + this._decorationsWidth = layoutInfo.decorationsWidth; } return true; } @@ -107,4 +112,4 @@ export class LinesDecorationsOverlay extends DedupOverlay { } return this._renderResult[lineNumber - startLineNumber]; } -} \ No newline at end of file +} diff --git a/src/vs/editor/browser/viewParts/margin/margin.ts b/src/vs/editor/browser/viewParts/margin/margin.ts index ab4f24c7bf3..f49a24845e7 100644 --- a/src/vs/editor/browser/viewParts/margin/margin.ts +++ b/src/vs/editor/browser/viewParts/margin/margin.ts @@ -8,6 +8,7 @@ import { ViewPart } from 'vs/editor/browser/view/viewPart'; import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; export class Margin extends ViewPart { @@ -23,10 +24,13 @@ export class Margin extends ViewPart { constructor(context: ViewContext) { super(context); + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._canUseLayerHinting = this._context.configuration.editor.canUseLayerHinting; - this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; - this._glyphMarginLeft = this._context.configuration.editor.layoutInfo.glyphMarginLeft; - this._glyphMarginWidth = this._context.configuration.editor.layoutInfo.glyphMarginWidth; + this._contentLeft = layoutInfo.contentLeft; + this._glyphMarginLeft = layoutInfo.glyphMarginLeft; + this._glyphMarginWidth = layoutInfo.glyphMarginWidth; this._domNode = createFastDomNode(document.createElement('div')); this._domNode.setClassName(Margin.OUTER_CLASS_NAME); @@ -51,14 +55,17 @@ export class Margin extends ViewPart { // --- begin event handlers public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { + const options = this._context.configuration.options; + if (e.canUseLayerHinting) { this._canUseLayerHinting = this._context.configuration.editor.canUseLayerHinting; } - if (e.layoutInfo) { - this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; - this._glyphMarginLeft = this._context.configuration.editor.layoutInfo.glyphMarginLeft; - this._glyphMarginWidth = this._context.configuration.editor.layoutInfo.glyphMarginWidth; + if (e.hasChanged(EditorOptionId.layoutInfo)) { + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._contentLeft = layoutInfo.contentLeft; + this._glyphMarginLeft = layoutInfo.glyphMarginLeft; + this._glyphMarginWidth = layoutInfo.glyphMarginWidth; } return true; diff --git a/src/vs/editor/browser/viewParts/minimap/minimap.ts b/src/vs/editor/browser/viewParts/minimap/minimap.ts index 1182f2ee8ab..747ef261830 100644 --- a/src/vs/editor/browser/viewParts/minimap/minimap.ts +++ b/src/vs/editor/browser/viewParts/minimap/minimap.ts @@ -13,7 +13,7 @@ import * as platform from 'vs/base/common/platform'; import * as strings from 'vs/base/common/strings'; import { ILine, RenderedLinesCollection } from 'vs/editor/browser/view/viewLayer'; import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/view/viewPart'; -import { RenderMinimap } from 'vs/editor/common/config/editorOptions'; +import { RenderMinimap, EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; import { Range } from 'vs/editor/common/core/range'; import { RGBA8 } from 'vs/editor/common/core/rgba'; import { IConfiguration, ScrollType } from 'vs/editor/common/editorCommon'; @@ -107,14 +107,16 @@ class MinimapOptions { public readonly canvasOuterHeight: number; constructor(configuration: IConfiguration) { + const options = configuration.options; const pixelRatio = configuration.editor.pixelRatio; - const layoutInfo = configuration.editor.layoutInfo; + const layoutInfo = options.get(EditorOptionId.layoutInfo); const viewInfo = configuration.editor.viewInfo; const fontInfo = configuration.editor.fontInfo; this.renderMinimap = layoutInfo.renderMinimap | 0; this.scrollBeyondLastLine = viewInfo.scrollBeyondLastLine; - this.showSlider = viewInfo.minimap.showSlider; + const minimapOpts = options.get(EditorOptionId.minimap); + this.showSlider = minimapOpts.showSlider; this.pixelRatio = pixelRatio; this.typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth; this.lineHeight = configuration.editor.lineHeight; diff --git a/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts b/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts index 87a35ca24f2..0fa9087323d 100644 --- a/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts +++ b/src/vs/editor/browser/viewParts/overlayWidgets/overlayWidgets.ts @@ -10,6 +10,7 @@ import { PartFingerprint, PartFingerprints, ViewPart } from 'vs/editor/browser/v import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/view/renderingContext'; import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; interface IWidgetData { widget: IOverlayWidget; @@ -35,12 +36,15 @@ export class ViewOverlayWidgets extends ViewPart { constructor(context: ViewContext) { super(context); + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._widgets = {}; - this._verticalScrollbarWidth = this._context.configuration.editor.layoutInfo.verticalScrollbarWidth; - this._minimapWidth = this._context.configuration.editor.layoutInfo.minimapWidth; - this._horizontalScrollbarHeight = this._context.configuration.editor.layoutInfo.horizontalScrollbarHeight; - this._editorHeight = this._context.configuration.editor.layoutInfo.height; - this._editorWidth = this._context.configuration.editor.layoutInfo.width; + this._verticalScrollbarWidth = layoutInfo.verticalScrollbarWidth; + this._minimapWidth = layoutInfo.minimapWidth; + this._horizontalScrollbarHeight = layoutInfo.horizontalScrollbarHeight; + this._editorHeight = layoutInfo.height; + this._editorWidth = layoutInfo.width; this._domNode = createFastDomNode(document.createElement('div')); PartFingerprints.write(this._domNode, PartFingerprint.OverlayWidgets); @@ -59,12 +63,15 @@ export class ViewOverlayWidgets extends ViewPart { // ---- begin view event handlers public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { - if (e.layoutInfo) { - this._verticalScrollbarWidth = this._context.configuration.editor.layoutInfo.verticalScrollbarWidth; - this._minimapWidth = this._context.configuration.editor.layoutInfo.minimapWidth; - this._horizontalScrollbarHeight = this._context.configuration.editor.layoutInfo.horizontalScrollbarHeight; - this._editorHeight = this._context.configuration.editor.layoutInfo.height; - this._editorWidth = this._context.configuration.editor.layoutInfo.width; + const options = this._context.configuration.options; + + if (e.hasChanged(EditorOptionId.layoutInfo)) { + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._verticalScrollbarWidth = layoutInfo.verticalScrollbarWidth; + this._minimapWidth = layoutInfo.minimapWidth; + this._horizontalScrollbarHeight = layoutInfo.horizontalScrollbarHeight; + this._editorHeight = layoutInfo.height; + this._editorWidth = layoutInfo.width; return true; } return false; diff --git a/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts b/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts index c186568ad8f..b620c0ed4ea 100644 --- a/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts +++ b/src/vs/editor/browser/viewParts/overviewRuler/decorationsOverviewRuler.ts @@ -15,6 +15,7 @@ import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/v import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { ITheme } from 'vs/platform/theme/common/themeService'; +import { EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; class Settings { @@ -42,6 +43,7 @@ class Settings { public readonly w: number[]; constructor(config: IConfiguration, theme: ITheme) { + const options = config.options; this.lineHeight = config.editor.lineHeight; this.pixelRatio = config.editor.pixelRatio; this.overviewRulerLanes = config.editor.viewInfo.overviewRulerLanes; @@ -56,8 +58,9 @@ class Settings { this.themeType = theme.type; - const minimapEnabled = config.editor.viewInfo.minimap.enabled; - const minimapSide = config.editor.viewInfo.minimap.side; + const minimapOpts = options.get(EditorOptionId.minimap); + const minimapEnabled = minimapOpts.enabled; + const minimapSide = minimapOpts.side; const backgroundColor = (minimapEnabled ? TokenizationRegistry.getDefaultBackground() : null); if (backgroundColor === null || minimapSide === 'left') { this.backgroundColor = null; @@ -65,7 +68,8 @@ class Settings { this.backgroundColor = Color.Format.CSS.formatHex(backgroundColor); } - const position = config.editor.layoutInfo.overviewRuler; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + const position = layoutInfo.overviewRuler; this.top = position.top; this.right = position.right; this.domWidth = position.width; diff --git a/src/vs/editor/browser/viewParts/rulers/rulers.ts b/src/vs/editor/browser/viewParts/rulers/rulers.ts index 7d4d402d24e..ceb396185fd 100644 --- a/src/vs/editor/browser/viewParts/rulers/rulers.ts +++ b/src/vs/editor/browser/viewParts/rulers/rulers.ts @@ -11,6 +11,7 @@ import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/v import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { EditorOptionId } from 'vs/editor/common/config/editorOptions'; export class Rulers extends ViewPart { @@ -37,7 +38,10 @@ export class Rulers extends ViewPart { // --- begin event handlers public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { - if (e.viewInfo || e.layoutInfo || e.fontInfo) { + if (e.viewInfo + || e.hasChanged(EditorOptionId.layoutInfo) + || e.fontInfo + ) { this._rulers = this._context.configuration.editor.viewInfo.rulers; this._typicalHalfwidthCharacterWidth = this._context.configuration.editor.fontInfo.typicalHalfwidthCharacterWidth; return true; diff --git a/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts b/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts index 2ae336437e4..d3b4ae392cd 100644 --- a/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts +++ b/src/vs/editor/browser/viewParts/scrollDecoration/scrollDecoration.ts @@ -11,6 +11,7 @@ import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { scrollbarShadow } from 'vs/platform/theme/common/colorRegistry'; import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; export class ScrollDecorationViewPart extends ViewPart { @@ -27,7 +28,9 @@ export class ScrollDecorationViewPart extends ViewPart { this._width = 0; this._updateWidth(); this._shouldShow = false; - this._useShadows = this._context.configuration.editor.viewInfo.scrollbar.useShadows; + const options = this._context.configuration.options; + const scrollbar = options.get(EditorOptionId.scrollbar); + this._useShadows = scrollbar.useShadows; this._domNode = createFastDomNode(document.createElement('div')); this._domNode.setAttribute('role', 'presentation'); this._domNode.setAttribute('aria-hidden', 'true'); @@ -51,7 +54,8 @@ export class ScrollDecorationViewPart extends ViewPart { } private _updateWidth(): boolean { - const layoutInfo = this._context.configuration.editor.layoutInfo; + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); let newWidth = 0; if (layoutInfo.renderMinimap === 0 || (layoutInfo.minimapWidth > 0 && layoutInfo.minimapLeft === 0)) { newWidth = layoutInfo.width; @@ -69,10 +73,12 @@ export class ScrollDecorationViewPart extends ViewPart { public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { let shouldRender = false; - if (e.viewInfo) { - this._useShadows = this._context.configuration.editor.viewInfo.scrollbar.useShadows; + if (e.hasChanged(EditorOptionId.scrollbar)) { + const options = this._context.configuration.options; + const scrollbar = options.get(EditorOptionId.scrollbar); + this._useShadows = scrollbar.useShadows; } - if (e.layoutInfo) { + if (e.hasChanged(EditorOptionId.layoutInfo)) { shouldRender = this._updateWidth(); } return this._updateShouldShow() || shouldRender; @@ -99,4 +105,4 @@ registerThemingParticipant((theme, collector) => { if (shadow) { collector.addRule(`.monaco-editor .scroll-decoration { box-shadow: ${shadow} 0 6px 6px -6px inset; }`); } -}); \ No newline at end of file +}); diff --git a/src/vs/editor/browser/viewParts/viewZones/viewZones.ts b/src/vs/editor/browser/viewParts/viewZones/viewZones.ts index 6c01df4e0b6..3e0f58f5475 100644 --- a/src/vs/editor/browser/viewParts/viewZones/viewZones.ts +++ b/src/vs/editor/browser/viewParts/viewZones/viewZones.ts @@ -12,6 +12,7 @@ import { RenderingContext, RestrictedRenderingContext } from 'vs/editor/common/v import { ViewContext } from 'vs/editor/common/view/viewContext'; import * as viewEvents from 'vs/editor/common/view/viewEvents'; import { IViewWhitespaceViewportData } from 'vs/editor/common/viewModel/viewModel'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; export interface IMyViewZone { whitespaceId: string; @@ -40,9 +41,12 @@ export class ViewZones extends ViewPart { constructor(context: ViewContext) { super(context); + const options = this._context.configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._lineHeight = this._context.configuration.editor.lineHeight; - this._contentWidth = this._context.configuration.editor.layoutInfo.contentWidth; - this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; + this._contentWidth = layoutInfo.contentWidth; + this._contentLeft = layoutInfo.contentLeft; this.domNode = createFastDomNode(document.createElement('div')); this.domNode.setClassName('view-zones'); @@ -84,15 +88,17 @@ export class ViewZones extends ViewPart { } public onConfigurationChanged(e: viewEvents.ViewConfigurationChangedEvent): boolean { + const options = this._context.configuration.options; if (e.lineHeight) { this._lineHeight = this._context.configuration.editor.lineHeight; return this._recomputeWhitespacesProps(); } - if (e.layoutInfo) { - this._contentWidth = this._context.configuration.editor.layoutInfo.contentWidth; - this._contentLeft = this._context.configuration.editor.layoutInfo.contentLeft; + if (e.hasChanged(EditorOptionId.layoutInfo)) { + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._contentWidth = layoutInfo.contentWidth; + this._contentLeft = layoutInfo.contentLeft; } return true; diff --git a/src/vs/editor/browser/widget/codeEditorWidget.ts b/src/vs/editor/browser/widget/codeEditorWidget.ts index 3860def914f..ca2133d8ab2 100644 --- a/src/vs/editor/browser/widget/codeEditorWidget.ts +++ b/src/vs/editor/browser/widget/codeEditorWidget.ts @@ -259,8 +259,10 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE this._register(this._configuration.onDidChange((e) => { this._onDidChangeConfiguration.fire(e); - if (e.layoutInfo) { - this._onDidLayoutChange.fire(this._configuration.editor.layoutInfo); + if (e.hasChanged(editorOptions.EditorOptionId.layoutInfo)) { + const options = this._configuration.options; + const layoutInfo = options.get(editorOptions.EditorOptionId.layoutInfo); + this._onDidLayoutChange.fire(layoutInfo); } if (this._configuration.editor.showUnused) { this._domElement.classList.add(SHOW_UNUSED_ENABLED_CLASS); @@ -370,8 +372,12 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE return this._configuration.editor; } + public getOptions(): editorOptions.IComputedEditorOptions { + return this._configuration.options; + } + public getOption>(id: editorOptions.EditorOptionId): editorOptions.ComputedEditorOptionValue { - return this._configuration.getOption(id); + return this._configuration.options.get(id); } public getRawConfiguration(): editorOptions.IEditorOptions { @@ -1124,7 +1130,9 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE } public getLayoutInfo(): editorOptions.EditorLayoutInfo { - return this._configuration.editor.layoutInfo; + const options = this._configuration.options; + const layoutInfo = options.get(editorOptions.EditorOptionId.layoutInfo); + return layoutInfo; } public createOverviewRuler(cssClassName: string): editorBrowser.IOverviewRuler | null { @@ -1272,7 +1280,8 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE } const position = this._modelData.model.validatePosition(rawPosition); - const layoutInfo = this._configuration.editor.layoutInfo; + const options = this._configuration.options; + const layoutInfo = options.get(editorOptions.EditorOptionId.layoutInfo); const top = CodeEditorWidget._getVerticalOffsetForPosition(this._modelData, position.lineNumber, position.column) - this.getScrollTop(); const left = this._modelData.view.getOffsetForColumn(position.lineNumber, position.column) + layoutInfo.glyphMarginWidth + layoutInfo.lineNumbersWidth + layoutInfo.decorationsWidth - this.getScrollLeft(); diff --git a/src/vs/editor/browser/widget/diffEditorWidget.ts b/src/vs/editor/browser/widget/diffEditorWidget.ts index fa0e688d696..da9e1ddf553 100644 --- a/src/vs/editor/browser/widget/diffEditorWidget.ts +++ b/src/vs/editor/browser/widget/diffEditorWidget.ts @@ -1947,6 +1947,7 @@ class InlineViewZonesComputer extends ViewZonesComputer { private readonly originalModel: ITextModel; private readonly modifiedEditorConfiguration: editorOptions.InternalEditorOptions; + private readonly modifiedEditorOptions: editorOptions.IComputedEditorOptions; private readonly modifiedEditorTabSize: number; private readonly renderIndicators: boolean; @@ -1954,6 +1955,7 @@ class InlineViewZonesComputer extends ViewZonesComputer { super(lineChanges, originalForeignVZ, modifiedForeignVZ); this.originalModel = originalEditor.getModel()!; this.modifiedEditorConfiguration = modifiedEditor.getConfiguration(); + this.modifiedEditorOptions = modifiedEditor.getOptions(); this.modifiedEditorTabSize = modifiedEditor.getModel()!.getOptions().tabSize; this.renderIndicators = renderIndicators; } @@ -1993,7 +1995,9 @@ class InlineViewZonesComputer extends ViewZonesComputer { let sb = createStringBuilder(10000); let marginHTML: string[] = []; - let lineDecorationsWidth = this.modifiedEditorConfiguration.layoutInfo.decorationsWidth; + const layoutInfo = this.modifiedEditorOptions.get(editorOptions.EditorOptionId.layoutInfo); + const lineDecorationsWidth = layoutInfo.decorationsWidth; + let lineHeight = this.modifiedEditorConfiguration.lineHeight; const typicalHalfwidthCharacterWidth = this.modifiedEditorConfiguration.fontInfo.typicalHalfwidthCharacterWidth; let maxCharsPerLine = 0; diff --git a/src/vs/editor/browser/widget/diffReview.ts b/src/vs/editor/browser/widget/diffReview.ts index 037883dd530..f6ab9ce2f14 100644 --- a/src/vs/editor/browser/widget/diffReview.ts +++ b/src/vs/editor/browser/widget/diffReview.ts @@ -525,7 +525,9 @@ export class DiffReview extends Disposable { private _render(): void { const originalOpts = this._diffEditor.getOriginalEditor().getConfiguration(); + const originalOptions = this._diffEditor.getOriginalEditor().getOptions(); const modifiedOpts = this._diffEditor.getModifiedEditor().getConfiguration(); + const modifiedOptions = this._diffEditor.getModifiedEditor().getOptions(); const originalModel = this._diffEditor.getOriginalEditor().getModel(); const modifiedModel = this._diffEditor.getModifiedEditor().getModel(); @@ -620,7 +622,7 @@ export class DiffReview extends Disposable { let modLine = minModifiedLine; for (let i = 0, len = diffs.length; i < len; i++) { const diffEntry = diffs[i]; - DiffReview._renderSection(container, diffEntry, modLine, this._width, originalOpts, originalModel, originalModelOpts, modifiedOpts, modifiedModel, modifiedModelOpts); + DiffReview._renderSection(container, diffEntry, modLine, this._width, originalOpts, originalOptions, originalModel, originalModelOpts, modifiedOpts, modifiedOptions, modifiedModel, modifiedModelOpts); if (diffEntry.modifiedLineStart !== 0) { modLine = diffEntry.modifiedLineEnd; } @@ -633,8 +635,8 @@ export class DiffReview extends Disposable { private static _renderSection( dest: HTMLElement, diffEntry: DiffEntry, modLine: number, width: number, - originalOpts: editorOptions.InternalEditorOptions, originalModel: ITextModel, originalModelOpts: TextModelResolvedOptions, - modifiedOpts: editorOptions.InternalEditorOptions, modifiedModel: ITextModel, modifiedModelOpts: TextModelResolvedOptions + originalOpts: editorOptions.InternalEditorOptions, originalOptions: editorOptions.IComputedEditorOptions, originalModel: ITextModel, originalModelOpts: TextModelResolvedOptions, + modifiedOpts: editorOptions.InternalEditorOptions, modifiedOptions: editorOptions.IComputedEditorOptions, modifiedModel: ITextModel, modifiedModelOpts: TextModelResolvedOptions ): void { const type = diffEntry.getType(); @@ -665,8 +667,11 @@ export class DiffReview extends Disposable { originalLineEnd - originalLineStart ); - const originalLineNumbersWidth = originalOpts.layoutInfo.glyphMarginWidth + originalOpts.layoutInfo.lineNumbersWidth; - const modifiedLineNumbersWidth = 10 + modifiedOpts.layoutInfo.glyphMarginWidth + modifiedOpts.layoutInfo.lineNumbersWidth; + const originalLayoutInfo = originalOptions.get(editorOptions.EditorOptionId.layoutInfo); + const originalLineNumbersWidth = originalLayoutInfo.glyphMarginWidth + originalLayoutInfo.lineNumbersWidth; + + const modifiedLayoutInfo = modifiedOptions.get(editorOptions.EditorOptionId.layoutInfo); + const modifiedLineNumbersWidth = 10 + modifiedLayoutInfo.glyphMarginWidth + modifiedLayoutInfo.lineNumbersWidth; for (let i = 0; i <= cnt; i++) { const originalLine = (originalLineStart === 0 ? 0 : originalLineStart + i); diff --git a/src/vs/editor/common/config/commonEditorConfig.ts b/src/vs/editor/common/config/commonEditorConfig.ts index 10fff300995..a5dc25319e2 100644 --- a/src/vs/editor/common/config/commonEditorConfig.ts +++ b/src/vs/editor/common/config/commonEditorConfig.ts @@ -95,7 +95,7 @@ export class EditorConfiguration2 { // console.log(`computeOptions`, options, env); const result = new editorOptions.ComputedEditorOptions(); for (const editorOption of editorOptions.editorOptionsRegistry) { - result._write(editorOption.id, editorOption.compute(options._read(editorOption.id))); + result._write(editorOption.id, editorOption.compute(env, result, options._read(editorOption.id))); } return result; } @@ -105,9 +105,9 @@ export class EditorConfiguration2 { const result = new editorOptions.ChangedEditorOptions(); let somethingChanged = false; for (const editorOption of editorOptions.editorOptionsRegistry) { - const equals = editorOption.equals(a._read(editorOption.id), b._read(editorOption.id)); - result._write(editorOption.id, equals); - if (!equals) { + const changed = !editorOption.equals(a._read(editorOption.id), b._read(editorOption.id)); + result._write(editorOption.id, changed); + if (changed) { somethingChanged = true; } } @@ -115,6 +115,25 @@ export class EditorConfiguration2 { } } +/** + * Compatibility with old options + */ +function migrateOptions(options: editorOptions.IEditorOptions): void { + let wordWrap = options.wordWrap; + if (wordWrap === true) { + options.wordWrap = 'on'; + } else if (wordWrap === false) { + options.wordWrap = 'off'; + } + + let lineNumbers = options.lineNumbers; + if (lineNumbers === true) { + options.lineNumbers = 'on'; + } else if (lineNumbers === false) { + options.lineNumbers = 'off'; + } +} + export abstract class CommonEditorConfiguration extends Disposable implements editorCommon.IConfiguration { public readonly isSimpleWidget: boolean; @@ -133,6 +152,7 @@ export abstract class CommonEditorConfiguration extends Disposable implements ed constructor(isSimpleWidget: boolean, options: editorOptions.IEditorOptions) { super(); + migrateOptions(options); this.isSimpleWidget = isSimpleWidget; @@ -156,10 +176,6 @@ export abstract class CommonEditorConfiguration extends Disposable implements ed this._register(TabFocus.onDidChangeTabFocus(_ => this._recomputeOptions())); } - public getOption>(id: editorOptions.EditorOptionId): editorOptions.ComputedEditorOptionValue { - return this.options._read(id); - } - public observeReferenceElement(dimension?: editorCommon.IDimension): void { } @@ -255,6 +271,7 @@ export abstract class CommonEditorConfiguration extends Disposable implements ed if (typeof newOptions === 'undefined') { return; } + migrateOptions(newOptions); if (CommonEditorConfiguration._subsetEquals(this._rawOptions, newOptions)) { return; } @@ -417,29 +434,29 @@ const editorConfiguration: IConfigurationNode = { }, 'editor.minimap.enabled': { 'type': 'boolean', - 'default': EDITOR_DEFAULTS.viewInfo.minimap.enabled, + 'default': editorOptions.EditorOption.minimap.defaultValue.enabled, 'description': nls.localize('minimap.enabled', "Controls whether the minimap is shown.") }, 'editor.minimap.side': { 'type': 'string', 'enum': ['left', 'right'], - 'default': EDITOR_DEFAULTS.viewInfo.minimap.side, + 'default': editorOptions.EditorOption.minimap.defaultValue.side, 'description': nls.localize('minimap.side', "Controls the side where to render the minimap.") }, 'editor.minimap.showSlider': { 'type': 'string', 'enum': ['always', 'mouseover'], - 'default': EDITOR_DEFAULTS.viewInfo.minimap.showSlider, + 'default': editorOptions.EditorOption.minimap.defaultValue.showSlider, 'description': nls.localize('minimap.showSlider', "Controls whether the minimap slider is automatically hidden.") }, 'editor.minimap.renderCharacters': { 'type': 'boolean', - 'default': EDITOR_DEFAULTS.viewInfo.minimap.renderCharacters, + 'default': editorOptions.EditorOption.minimap.defaultValue.renderCharacters, 'description': nls.localize('minimap.renderCharacters', "Render the actual characters on a line as opposed to color blocks.") }, 'editor.minimap.maxColumn': { 'type': 'number', - 'default': EDITOR_DEFAULTS.viewInfo.minimap.maxColumn, + 'default': editorOptions.EditorOption.minimap.defaultValue.maxColumn, 'description': nls.localize('minimap.maxColumn', "Limit the width of the minimap to render at most a certain number of columns.") }, 'editor.hover.enabled': { @@ -498,7 +515,7 @@ const editorConfiguration: IConfigurationNode = { ] }, "Lines will wrap at the minimum of viewport and `#editor.wordWrapColumn#`."), ], - 'default': EDITOR_DEFAULTS.wordWrap, + 'default': editorOptions.EditorOption.wordWrap.defaultValue, 'description': nls.localize({ key: 'wordWrap', comment: [ @@ -509,7 +526,7 @@ const editorConfiguration: IConfigurationNode = { }, 'editor.wordWrapColumn': { 'type': 'integer', - 'default': EDITOR_DEFAULTS.wordWrapColumn, + 'default': editorOptions.EditorOption.wordWrapColumn.defaultValue, 'minimum': 1, 'markdownDescription': nls.localize({ key: 'wordWrapColumn', @@ -533,12 +550,12 @@ const editorConfiguration: IConfigurationNode = { }, 'editor.mouseWheelScrollSensitivity': { 'type': 'number', - 'default': EDITOR_DEFAULTS.viewInfo.scrollbar.mouseWheelScrollSensitivity, + 'default': editorOptions.EditorOption.mouseWheelScrollSensitivity.defaultValue, 'markdownDescription': nls.localize('mouseWheelScrollSensitivity', "A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events.") }, 'editor.fastScrollSensitivity': { 'type': 'number', - 'default': EDITOR_DEFAULTS.viewInfo.scrollbar.fastScrollSensitivity, + 'default': editorOptions.EditorOption.fastScrollSensitivity.defaultValue, 'markdownDescription': nls.localize('fastScrollSensitivity', "Scrolling speed multiplier when pressing `Alt`.") }, 'editor.multiCursorModifier': { @@ -1035,7 +1052,7 @@ const editorConfiguration: IConfigurationNode = { }, 'editor.folding': { 'type': 'boolean', - 'default': EDITOR_DEFAULTS.contribInfo.folding, + 'default': editorOptions.EditorOption.folding.defaultValue, 'description': nls.localize('folding', "Controls whether the editor has code folding enabled.") }, 'editor.foldingStrategy': { @@ -1088,7 +1105,7 @@ const editorConfiguration: IConfigurationNode = { nls.localize('accessibilitySupport.on', "The editor will be permanently optimized for usage with a Screen Reader."), nls.localize('accessibilitySupport.off', "The editor will never be optimized for usage with a Screen Reader."), ], - 'default': EDITOR_DEFAULTS.accessibilitySupport, + 'default': editorOptions.EditorOption.accessibilitySupport.defaultValue, 'description': nls.localize('accessibilitySupport', "Controls whether the editor should run in a mode where it is optimized for screen readers.") }, 'editor.showUnused': { diff --git a/src/vs/editor/common/config/editorOptions.ts b/src/vs/editor/common/config/editorOptions.ts index 45bef3115da..dc915f4f80b 100644 --- a/src/vs/editor/common/config/editorOptions.ts +++ b/src/vs/editor/common/config/editorOptions.ts @@ -4,6 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; +import * as assert from 'vs/base/common/assert'; import * as arrays from 'vs/base/common/arrays'; import * as objects from 'vs/base/common/objects'; import * as platform from 'vs/base/common/platform'; @@ -272,7 +273,7 @@ export interface IEditorOptions { * Otherwise, line numbers will not be rendered. * Defaults to true. */ - lineNumbers?: 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string); + lineNumbers?: LineNumbersType; /** * Controls the minimal number of visible leading and trailing lines surrounding the cursor. * Defaults to 0. @@ -451,7 +452,7 @@ export interface IEditorOptions { * Control indentation of wrapped lines. Can be: 'none', 'same', 'indent' or 'deepIndent'. * Defaults to 'same' in vscode and to 'none' in monaco-editor. */ - wrappingIndent?: string; + wrappingIndent?: 'none' | 'same' | 'indent' | 'deepIndent'; /** * Configure word wrapping characters. A break will be introduced before these characters. * Defaults to '{([+'. @@ -727,6 +728,9 @@ export interface IEditorOptions { * Controls fading out of unused variables. */ showUnused?: boolean; + + layoutInfo?: undefined; + wrappingInfo?: undefined; } /** @@ -909,30 +913,6 @@ function _cursorStyleFromString(cursorStyle: string | undefined, defaultValue: T return TextEditorCursorStyle.Line; } -export interface InternalEditorScrollbarOptions { - readonly arrowSize: number; - readonly vertical: ScrollbarVisibility; - readonly horizontal: ScrollbarVisibility; - readonly useShadows: boolean; - readonly verticalHasArrows: boolean; - readonly horizontalHasArrows: boolean; - readonly handleMouseWheel: boolean; - readonly horizontalScrollbarSize: number; - readonly horizontalSliderSize: number; - readonly verticalScrollbarSize: number; - readonly verticalSliderSize: number; - readonly mouseWheelScrollSensitivity: number; - readonly fastScrollSensitivity: number; -} - -export interface InternalEditorMinimapOptions { - readonly enabled: boolean; - readonly side: 'right' | 'left'; - readonly showSlider: 'always' | 'mouseover'; - readonly renderCharacters: boolean; - readonly maxColumn: number; -} - export interface InternalEditorFindOptions { readonly seedSearchStringFromSelection: boolean; readonly autoFindInSelection: boolean; @@ -969,33 +949,10 @@ export interface InternalParameterHintOptions { readonly cycle: boolean; } -export interface EditorWrappingInfo { - readonly inDiffEditor: boolean; - readonly isDominatedByLongLines: boolean; - readonly isWordWrapMinified: boolean; - readonly isViewportWrapping: boolean; - readonly wrappingColumn: number; - readonly wrappingIndent: WrappingIndent; - readonly wordWrapBreakBeforeCharacters: string; - readonly wordWrapBreakAfterCharacters: string; - readonly wordWrapBreakObtrusiveCharacters: string; -} - -export const enum RenderLineNumbersType { - Off = 0, - On = 1, - Relative = 2, - Interval = 3, - Custom = 4 -} - export interface InternalEditorViewOptions { readonly extraEditorClassName: string; readonly disableMonospaceOptimizations: boolean; readonly rulers: number[]; - readonly ariaLabel: string; - readonly renderLineNumbers: RenderLineNumbersType; - readonly renderCustomLineNumbers: ((lineNumber: number) => string) | null; readonly cursorSurroundingLines: number; readonly glyphMargin: boolean; readonly revealHorizontalRightPadding: number; @@ -1018,8 +975,6 @@ export interface InternalEditorViewOptions { readonly renderIndentGuides: boolean; readonly highlightActiveIndentGuide: boolean; readonly renderLineHighlight: 'none' | 'gutter' | 'line' | 'all'; - readonly scrollbar: InternalEditorScrollbarOptions; - readonly minimap: InternalEditorMinimapOptions; readonly fixedOverflowWidgets: boolean; } @@ -1045,7 +1000,6 @@ export interface EditorContribOptions { readonly selectionHighlight: boolean; readonly occurrencesHighlight: boolean; readonly codeLens: boolean; - readonly folding: boolean; readonly foldingStrategy: 'auto' | 'indentation'; readonly showFoldingControls: 'always' | 'mouseover'; readonly matchBrackets: boolean; @@ -1062,21 +1016,12 @@ export interface EditorContribOptions { * @internal */ export interface IValidatedEditorOptions { - readonly inDiffEditor: boolean; readonly wordSeparators: string; - readonly lineNumbersMinChars: number; readonly lineDecorationsWidth: number | string; readonly readOnly: boolean; readonly mouseStyle: 'text' | 'default' | 'copy'; readonly disableLayerHinting: boolean; readonly automaticLayout: boolean; - readonly wordWrap: 'off' | 'on' | 'wordWrapColumn' | 'bounded'; - readonly wordWrapColumn: number; - readonly wordWrapMinified: boolean; - readonly wrappingIndent: WrappingIndent; - readonly wordWrapBreakBeforeCharacters: string; - readonly wordWrapBreakAfterCharacters: string; - readonly wordWrapBreakObtrusiveCharacters: string; readonly autoClosingBrackets: EditorAutoClosingStrategy; readonly autoClosingQuotes: EditorAutoClosingStrategy; readonly autoClosingOvertype: EditorAutoClosingOvertypeStrategy; @@ -1088,7 +1033,6 @@ export interface IValidatedEditorOptions { readonly useTabStops: boolean; readonly multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey'; readonly multiCursorMergeOverlapping: boolean; - readonly accessibilitySupport: 'auto' | 'off' | 'on'; readonly showUnused: boolean; readonly viewInfo: InternalEditorViewOptions; @@ -1128,10 +1072,8 @@ export class InternalEditorOptions { readonly copyWithSyntaxHighlighting: boolean; // ---- grouped options - readonly layoutInfo: EditorLayoutInfo; readonly fontInfo: FontInfo; readonly viewInfo: InternalEditorViewOptions; - readonly wrappingInfo: EditorWrappingInfo; readonly contribInfo: EditorContribOptions; /** @@ -1143,7 +1085,6 @@ export class InternalEditorOptions { editorClassName: string; lineHeight: number; readOnly: boolean; - accessibilitySupport: AccessibilitySupport; multiCursorModifier: 'altKey' | 'ctrlKey' | 'metaKey'; multiCursorMergeOverlapping: boolean; wordSeparators: string; @@ -1157,10 +1098,8 @@ export class InternalEditorOptions { dragAndDrop: boolean; emptySelectionClipboard: boolean; copyWithSyntaxHighlighting: boolean; - layoutInfo: EditorLayoutInfo; fontInfo: FontInfo; viewInfo: InternalEditorViewOptions; - wrappingInfo: EditorWrappingInfo; contribInfo: EditorContribOptions; showUnused: boolean; }) { @@ -1169,7 +1108,6 @@ export class InternalEditorOptions { this.editorClassName = source.editorClassName; this.lineHeight = source.lineHeight | 0; this.readOnly = source.readOnly; - this.accessibilitySupport = source.accessibilitySupport; this.multiCursorModifier = source.multiCursorModifier; this.multiCursorMergeOverlapping = source.multiCursorMergeOverlapping; this.wordSeparators = source.wordSeparators; @@ -1183,10 +1121,8 @@ export class InternalEditorOptions { this.dragAndDrop = source.dragAndDrop; this.emptySelectionClipboard = source.emptySelectionClipboard; this.copyWithSyntaxHighlighting = source.copyWithSyntaxHighlighting; - this.layoutInfo = source.layoutInfo; this.fontInfo = source.fontInfo; this.viewInfo = source.viewInfo; - this.wrappingInfo = source.wrappingInfo; this.contribInfo = source.contribInfo; this.showUnused = source.showUnused; } @@ -1201,7 +1137,6 @@ export class InternalEditorOptions { && this.editorClassName === other.editorClassName && this.lineHeight === other.lineHeight && this.readOnly === other.readOnly - && this.accessibilitySupport === other.accessibilitySupport && this.multiCursorModifier === other.multiCursorModifier && this.multiCursorMergeOverlapping === other.multiCursorMergeOverlapping && this.wordSeparators === other.wordSeparators @@ -1216,10 +1151,8 @@ export class InternalEditorOptions { && this.showUnused === other.showUnused && this.emptySelectionClipboard === other.emptySelectionClipboard && this.copyWithSyntaxHighlighting === other.copyWithSyntaxHighlighting - && InternalEditorOptions._equalsLayoutInfo(this.layoutInfo, other.layoutInfo) && this.fontInfo.equals(other.fontInfo) && InternalEditorOptions._equalsViewOptions(this.viewInfo, other.viewInfo) - && InternalEditorOptions._equalsWrappingInfo(this.wrappingInfo, other.wrappingInfo) && InternalEditorOptions._equalsContribOptions(this.contribInfo, other.contribInfo) ); } @@ -1240,7 +1173,6 @@ export class InternalEditorOptions { editorClassName: (this.editorClassName !== newOpts.editorClassName), lineHeight: (this.lineHeight !== newOpts.lineHeight), readOnly: (this.readOnly !== newOpts.readOnly), - accessibilitySupport: (this.accessibilitySupport !== newOpts.accessibilitySupport), multiCursorModifier: (this.multiCursorModifier !== newOpts.multiCursorModifier), multiCursorMergeOverlapping: (this.multiCursorMergeOverlapping !== newOpts.multiCursorMergeOverlapping), wordSeparators: (this.wordSeparators !== newOpts.wordSeparators), @@ -1254,55 +1186,12 @@ export class InternalEditorOptions { dragAndDrop: (this.dragAndDrop !== newOpts.dragAndDrop), emptySelectionClipboard: (this.emptySelectionClipboard !== newOpts.emptySelectionClipboard), copyWithSyntaxHighlighting: (this.copyWithSyntaxHighlighting !== newOpts.copyWithSyntaxHighlighting), - layoutInfo: (!InternalEditorOptions._equalsLayoutInfo(this.layoutInfo, newOpts.layoutInfo)), fontInfo: (!this.fontInfo.equals(newOpts.fontInfo)), viewInfo: (!InternalEditorOptions._equalsViewOptions(this.viewInfo, newOpts.viewInfo)), - wrappingInfo: (!InternalEditorOptions._equalsWrappingInfo(this.wrappingInfo, newOpts.wrappingInfo)), contribInfo: (!InternalEditorOptions._equalsContribOptions(this.contribInfo, newOpts.contribInfo)) }; } - /** - * @internal - */ - private static _equalsLayoutInfo(a: EditorLayoutInfo, b: EditorLayoutInfo): boolean { - return ( - a.width === b.width - && a.height === b.height - && a.glyphMarginLeft === b.glyphMarginLeft - && a.glyphMarginWidth === b.glyphMarginWidth - && a.glyphMarginHeight === b.glyphMarginHeight - && a.lineNumbersLeft === b.lineNumbersLeft - && a.lineNumbersWidth === b.lineNumbersWidth - && a.lineNumbersHeight === b.lineNumbersHeight - && a.decorationsLeft === b.decorationsLeft - && a.decorationsWidth === b.decorationsWidth - && a.decorationsHeight === b.decorationsHeight - && a.contentLeft === b.contentLeft - && a.contentWidth === b.contentWidth - && a.contentHeight === b.contentHeight - && a.renderMinimap === b.renderMinimap - && a.minimapLeft === b.minimapLeft - && a.minimapWidth === b.minimapWidth - && a.viewportColumn === b.viewportColumn - && a.verticalScrollbarWidth === b.verticalScrollbarWidth - && a.horizontalScrollbarHeight === b.horizontalScrollbarHeight - && this._equalsOverviewRuler(a.overviewRuler, b.overviewRuler) - ); - } - - /** - * @internal - */ - private static _equalsOverviewRuler(a: OverviewRulerPosition, b: OverviewRulerPosition): boolean { - return ( - a.width === b.width - && a.height === b.height - && a.top === b.top - && a.right === b.right - ); - } - /** * @internal */ @@ -1311,9 +1200,6 @@ export class InternalEditorOptions { a.extraEditorClassName === b.extraEditorClassName && a.disableMonospaceOptimizations === b.disableMonospaceOptimizations && arrays.equals(a.rulers, b.rulers) - && a.ariaLabel === b.ariaLabel - && a.renderLineNumbers === b.renderLineNumbers - && a.renderCustomLineNumbers === b.renderCustomLineNumbers && a.cursorSurroundingLines === b.cursorSurroundingLines && a.glyphMargin === b.glyphMargin && a.revealHorizontalRightPadding === b.revealHorizontalRightPadding @@ -1336,46 +1222,10 @@ export class InternalEditorOptions { && a.renderIndentGuides === b.renderIndentGuides && a.highlightActiveIndentGuide === b.highlightActiveIndentGuide && a.renderLineHighlight === b.renderLineHighlight - && this._equalsScrollbarOptions(a.scrollbar, b.scrollbar) - && this._equalsMinimapOptions(a.minimap, b.minimap) && a.fixedOverflowWidgets === b.fixedOverflowWidgets ); } - /** - * @internal - */ - private static _equalsScrollbarOptions(a: InternalEditorScrollbarOptions, b: InternalEditorScrollbarOptions): boolean { - return ( - a.arrowSize === b.arrowSize - && a.vertical === b.vertical - && a.horizontal === b.horizontal - && a.useShadows === b.useShadows - && a.verticalHasArrows === b.verticalHasArrows - && a.horizontalHasArrows === b.horizontalHasArrows - && a.handleMouseWheel === b.handleMouseWheel - && a.horizontalScrollbarSize === b.horizontalScrollbarSize - && a.horizontalSliderSize === b.horizontalSliderSize - && a.verticalScrollbarSize === b.verticalScrollbarSize - && a.verticalSliderSize === b.verticalSliderSize - && a.mouseWheelScrollSensitivity === b.mouseWheelScrollSensitivity - && a.fastScrollSensitivity === b.fastScrollSensitivity - ); - } - - /** - * @internal - */ - private static _equalsMinimapOptions(a: InternalEditorMinimapOptions, b: InternalEditorMinimapOptions): boolean { - return ( - a.enabled === b.enabled - && a.side === b.side - && a.showSlider === b.showSlider - && a.renderCharacters === b.renderCharacters - && a.maxColumn === b.maxColumn - ); - } - /** * @internal */ @@ -1439,23 +1289,6 @@ export class InternalEditorOptions { } } - /** - * @internal - */ - private static _equalsWrappingInfo(a: EditorWrappingInfo, b: EditorWrappingInfo): boolean { - return ( - a.inDiffEditor === b.inDiffEditor - && a.isDominatedByLongLines === b.isDominatedByLongLines - && a.isWordWrapMinified === b.isWordWrapMinified - && a.isViewportWrapping === b.isViewportWrapping - && a.wrappingColumn === b.wrappingColumn - && a.wrappingIndent === b.wrappingIndent - && a.wordWrapBreakBeforeCharacters === b.wordWrapBreakBeforeCharacters - && a.wordWrapBreakAfterCharacters === b.wordWrapBreakAfterCharacters - && a.wordWrapBreakObtrusiveCharacters === b.wordWrapBreakObtrusiveCharacters - ); - } - /** * @internal */ @@ -1482,7 +1315,6 @@ export class InternalEditorOptions { && a.selectionHighlight === b.selectionHighlight && a.occurrencesHighlight === b.occurrencesHighlight && a.codeLens === b.codeLens - && a.folding === b.folding && a.foldingStrategy === b.foldingStrategy && a.showFoldingControls === b.showFoldingControls && a.matchBrackets === b.matchBrackets @@ -1512,6 +1344,1012 @@ export class InternalEditorOptions { } } +/** + * An event describing that the configuration of the editor has changed. + */ +export interface IConfigurationChangedEvent { + hasChanged(id: EditorOptionId): boolean; + readonly canUseLayerHinting: boolean; + readonly pixelRatio: boolean; + readonly editorClassName: boolean; + readonly lineHeight: boolean; + readonly readOnly: boolean; + readonly multiCursorModifier: boolean; + readonly multiCursorMergeOverlapping: boolean; + readonly wordSeparators: boolean; + readonly autoClosingBrackets: boolean; + readonly autoClosingQuotes: boolean; + readonly autoClosingOvertype: boolean; + readonly autoSurround: boolean; + readonly autoIndent: boolean; + readonly useTabStops: boolean; + readonly tabFocusMode: boolean; + readonly dragAndDrop: boolean; + readonly emptySelectionClipboard: boolean; + readonly copyWithSyntaxHighlighting: boolean; + readonly fontInfo: boolean; + readonly viewInfo: boolean; + readonly contribInfo: boolean; +} + +export interface IEnvironmentalOptions { + readonly outerWidth: number; + readonly outerHeight: number; + readonly fontInfo: FontInfo; + readonly extraEditorClassName: string; + readonly isDominatedByLongLines: boolean; + readonly lineNumbersDigitCount: number; + readonly emptySelectionClipboard: boolean; + readonly pixelRatio: number; + readonly tabFocusMode: boolean; + readonly accessibilitySupport: AccessibilitySupport; +} + +function _boolean(value: any, defaultValue: T): boolean | T { + if (typeof value === 'undefined') { + return defaultValue; + } + if (value === 'false') { + // treat the string 'false' as false + return false; + } + return Boolean(value); +} + +function _booleanMap(value: { [key: string]: boolean } | undefined, defaultValue: { [key: string]: boolean }): { [key: string]: boolean } { + if (!value) { + return defaultValue; + } + + const out = Object.create(null); + for (const k of Object.keys(value)) { + const v = value[k]; + if (typeof v === 'boolean') { + out[k] = v; + } + } + return out; +} + +function _string(value: any, defaultValue: string): string { + if (typeof value !== 'string') { + return defaultValue; + } + return value; +} + +function _stringSet(value: T | undefined, defaultValue: T, allowedValues: T[]): T { + if (typeof value !== 'string') { + return defaultValue; + } + if (allowedValues.indexOf(value) === -1) { + return defaultValue; + } + return value; +} + +function _clampedInt(value: any, defaultValue: number, minimum: number, maximum: number): number { + let r: number; + if (typeof value === 'undefined') { + r = defaultValue; + } else { + r = parseInt(value, 10); + if (isNaN(r)) { + r = defaultValue; + } + } + r = Math.max(minimum, r); + r = Math.min(maximum, r); + return r | 0; +} + +function _float(value: any, defaultValue: number): number { + let r = parseFloat(value); + if (isNaN(r)) { + r = defaultValue; + } + return r; +} + +function _wrappingIndentFromString(wrappingIndent: 'none' | 'same' | 'indent' | 'deepIndent'): WrappingIndent { + switch (wrappingIndent) { + case 'none': return WrappingIndent.None; + case 'same': return WrappingIndent.Same; + case 'indent': return WrappingIndent.Indent; + case 'deepIndent': return WrappingIndent.DeepIndent; + } +} + +function _cursorBlinkingStyleFromString(cursorBlinkingStyle: string | undefined, defaultValue: TextEditorCursorBlinkingStyle): TextEditorCursorBlinkingStyle { + if (typeof cursorBlinkingStyle !== 'string') { + return defaultValue; + } + switch (cursorBlinkingStyle) { + case 'blink': + return TextEditorCursorBlinkingStyle.Blink; + case 'smooth': + return TextEditorCursorBlinkingStyle.Smooth; + case 'phase': + return TextEditorCursorBlinkingStyle.Phase; + case 'expand': + return TextEditorCursorBlinkingStyle.Expand; + case 'visible': // maintain compatibility + case 'solid': + return TextEditorCursorBlinkingStyle.Solid; + } + return TextEditorCursorBlinkingStyle.Blink; +} + +function _scrollbarVisibilityFromString(visibility: string | undefined, defaultValue: ScrollbarVisibility): ScrollbarVisibility { + if (typeof visibility !== 'string') { + return defaultValue; + } + switch (visibility) { + case 'hidden': + return ScrollbarVisibility.Hidden; + case 'visible': + return ScrollbarVisibility.Visible; + default: + return ScrollbarVisibility.Auto; + } +} + +/** + * @internal + */ +export class EditorOptionsValidator { + + /** + * Validate raw editor options. + * i.e. since they can be defined by the user, they might be invalid. + */ + public static validate(opts: IEditorOptions, defaults: IValidatedEditorOptions): IValidatedEditorOptions { + const viewInfo = this._sanitizeViewInfo(opts, defaults.viewInfo); + const contribInfo = this._sanitizeContribInfo(opts, defaults.contribInfo); + + let configuredMulticursorModifier: 'altKey' | 'metaKey' | 'ctrlKey' | undefined = undefined; + if (typeof opts.multiCursorModifier === 'string') { + if (opts.multiCursorModifier === 'ctrlCmd') { + configuredMulticursorModifier = platform.isMacintosh ? 'metaKey' : 'ctrlKey'; + } else { + configuredMulticursorModifier = 'altKey'; + } + } + const multiCursorModifier = _stringSet<'altKey' | 'metaKey' | 'ctrlKey'>(configuredMulticursorModifier, defaults.multiCursorModifier, ['altKey', 'metaKey', 'ctrlKey']); + + let autoClosingBrackets: EditorAutoClosingStrategy; + let autoClosingQuotes: EditorAutoClosingStrategy; + let autoSurround: EditorAutoSurroundStrategy; + if (typeof opts.autoClosingBrackets === 'boolean' && opts.autoClosingBrackets === false) { + // backwards compatibility: disable all on boolean false + autoClosingBrackets = 'never'; + autoClosingQuotes = 'never'; + autoSurround = 'never'; + } else { + autoClosingBrackets = _stringSet(opts.autoClosingBrackets, defaults.autoClosingBrackets, ['always', 'languageDefined', 'beforeWhitespace', 'never']); + autoClosingQuotes = _stringSet(opts.autoClosingQuotes, defaults.autoClosingQuotes, ['always', 'languageDefined', 'beforeWhitespace', 'never']); + autoSurround = _stringSet(opts.autoSurround, defaults.autoSurround, ['languageDefined', 'brackets', 'quotes', 'never']); + } + + return { + wordSeparators: _string(opts.wordSeparators, defaults.wordSeparators), + lineDecorationsWidth: (typeof opts.lineDecorationsWidth === 'undefined' ? defaults.lineDecorationsWidth : opts.lineDecorationsWidth), + readOnly: _boolean(opts.readOnly, defaults.readOnly), + mouseStyle: _stringSet<'text' | 'default' | 'copy'>(opts.mouseStyle, defaults.mouseStyle, ['text', 'default', 'copy']), + disableLayerHinting: _boolean(opts.disableLayerHinting, defaults.disableLayerHinting), + automaticLayout: _boolean(opts.automaticLayout, defaults.automaticLayout), + autoClosingBrackets, + autoClosingQuotes, + autoClosingOvertype: _stringSet(opts.autoClosingOvertype, defaults.autoClosingOvertype, ['always', 'auto', 'never']), + autoSurround, + autoIndent: _boolean(opts.autoIndent, defaults.autoIndent), + dragAndDrop: _boolean(opts.dragAndDrop, defaults.dragAndDrop), + emptySelectionClipboard: _boolean(opts.emptySelectionClipboard, defaults.emptySelectionClipboard), + copyWithSyntaxHighlighting: _boolean(opts.copyWithSyntaxHighlighting, defaults.copyWithSyntaxHighlighting), + useTabStops: _boolean(opts.useTabStops, defaults.useTabStops), + multiCursorModifier: multiCursorModifier, + multiCursorMergeOverlapping: _boolean(opts.multiCursorMergeOverlapping, defaults.multiCursorMergeOverlapping), + showUnused: _boolean(opts.showUnused, defaults.showUnused), + viewInfo: viewInfo, + contribInfo: contribInfo, + }; + } + + private static _sanitizeFindOpts(opts: IEditorFindOptions | undefined, defaults: InternalEditorFindOptions): InternalEditorFindOptions { + if (typeof opts !== 'object') { + return defaults; + } + + return { + seedSearchStringFromSelection: _boolean(opts.seedSearchStringFromSelection, defaults.seedSearchStringFromSelection), + autoFindInSelection: _boolean(opts.autoFindInSelection, defaults.autoFindInSelection), + globalFindClipboard: _boolean(opts.globalFindClipboard, defaults.globalFindClipboard), + addExtraSpaceOnTop: _boolean(opts.addExtraSpaceOnTop, defaults.addExtraSpaceOnTop) + }; + } + + private static _sanitizeParameterHintOpts(opts: IEditorParameterHintOptions | undefined, defaults: InternalParameterHintOptions): InternalParameterHintOptions { + if (typeof opts !== 'object') { + return defaults; + } + + return { + enabled: _boolean(opts.enabled, defaults.enabled), + cycle: _boolean(opts.cycle, defaults.cycle) + }; + } + + private static _sanitizeHoverOpts(_opts: boolean | IEditorHoverOptions | undefined, defaults: InternalEditorHoverOptions): InternalEditorHoverOptions { + let opts: IEditorHoverOptions; + if (typeof _opts === 'boolean') { + opts = { + enabled: _opts + }; + } else if (typeof _opts === 'object') { + opts = _opts; + } else { + return defaults; + } + + return { + enabled: _boolean(opts.enabled, defaults.enabled), + delay: _clampedInt(opts.delay, defaults.delay, 0, 10000), + sticky: _boolean(opts.sticky, defaults.sticky) + }; + } + + private static _sanitizeSuggestOpts(opts: IEditorOptions, defaults: InternalSuggestOptions): InternalSuggestOptions { + const suggestOpts = opts.suggest || {}; + return { + filterGraceful: _boolean(suggestOpts.filterGraceful, defaults.filterGraceful), + snippets: _stringSet<'top' | 'bottom' | 'inline' | 'none'>(opts.snippetSuggestions, defaults.snippets, ['top', 'bottom', 'inline', 'none']), + snippetsPreventQuickSuggestions: _boolean(suggestOpts.snippetsPreventQuickSuggestions, defaults.filterGraceful), + localityBonus: _boolean(suggestOpts.localityBonus, defaults.localityBonus), + shareSuggestSelections: _boolean(suggestOpts.shareSuggestSelections, defaults.shareSuggestSelections), + showIcons: _boolean(suggestOpts.showIcons, defaults.showIcons), + maxVisibleSuggestions: _clampedInt(suggestOpts.maxVisibleSuggestions, defaults.maxVisibleSuggestions, 1, 15), + filteredTypes: isObject(suggestOpts.filteredTypes) ? suggestOpts.filteredTypes : Object.create(null) + }; + } + + private static _sanitizeGotoLocationOpts(opts: IEditorOptions, defaults: InternalGoToLocationOptions): InternalGoToLocationOptions { + const gotoOpts = opts.gotoLocation || {}; + return { + multiple: _stringSet<'peek' | 'gotoAndPeek' | 'goto'>(gotoOpts.multiple, defaults.multiple, ['peek', 'gotoAndPeek', 'goto']) + }; + } + + private static _sanitizeTabCompletionOpts(opts: boolean | 'on' | 'off' | 'onlySnippets' | undefined, defaults: 'on' | 'off' | 'onlySnippets'): 'on' | 'off' | 'onlySnippets' { + if (opts === false) { + return 'off'; + } else if (opts === true) { + return 'onlySnippets'; + } else { + return _stringSet<'on' | 'off' | 'onlySnippets'>(opts, defaults, ['on', 'off', 'onlySnippets']); + } + } + + private static _sanitizeViewInfo(opts: IEditorOptions, defaults: InternalEditorViewOptions): InternalEditorViewOptions { + + let rulers: number[] = []; + if (Array.isArray(opts.rulers)) { + for (let i = 0, len = opts.rulers.length; i < len; i++) { + rulers.push(_clampedInt(opts.rulers[i], 0, 0, 10000)); + } + rulers.sort(); + } + + const fontLigatures = _boolean(opts.fontLigatures, defaults.fontLigatures); + const disableMonospaceOptimizations = _boolean(opts.disableMonospaceOptimizations, defaults.disableMonospaceOptimizations) || fontLigatures; + + let renderWhitespace = opts.renderWhitespace; + { + // Compatibility with old true or false values + if (renderWhitespace === true) { + renderWhitespace = 'boundary'; + } else if (renderWhitespace === false) { + renderWhitespace = 'none'; + } + renderWhitespace = _stringSet<'none' | 'boundary' | 'selection' | 'all'>(renderWhitespace, defaults.renderWhitespace, ['none', 'boundary', 'selection', 'all']); + } + + let renderLineHighlight = opts.renderLineHighlight; + { + // Compatibility with old true or false values + if (renderLineHighlight === true) { + renderLineHighlight = 'line'; + } else if (renderLineHighlight === false) { + renderLineHighlight = 'none'; + } + renderLineHighlight = _stringSet<'none' | 'gutter' | 'line' | 'all'>(renderLineHighlight, defaults.renderLineHighlight, ['none', 'gutter', 'line', 'all']); + } + + return { + extraEditorClassName: _string(opts.extraEditorClassName, defaults.extraEditorClassName), + disableMonospaceOptimizations: disableMonospaceOptimizations, + rulers: rulers, + cursorSurroundingLines: _clampedInt(opts.cursorSurroundingLines, defaults.cursorWidth, 0, Number.MAX_VALUE), + glyphMargin: _boolean(opts.glyphMargin, defaults.glyphMargin), + revealHorizontalRightPadding: _clampedInt(opts.revealHorizontalRightPadding, defaults.revealHorizontalRightPadding, 0, 1000), + roundedSelection: _boolean(opts.roundedSelection, defaults.roundedSelection), + overviewRulerLanes: _clampedInt(opts.overviewRulerLanes, defaults.overviewRulerLanes, 0, 3), + overviewRulerBorder: _boolean(opts.overviewRulerBorder, defaults.overviewRulerBorder), + cursorBlinking: _cursorBlinkingStyleFromString(opts.cursorBlinking, defaults.cursorBlinking), + mouseWheelZoom: _boolean(opts.mouseWheelZoom, defaults.mouseWheelZoom), + cursorSmoothCaretAnimation: _boolean(opts.cursorSmoothCaretAnimation, defaults.cursorSmoothCaretAnimation), + cursorStyle: _cursorStyleFromString(opts.cursorStyle, defaults.cursorStyle), + cursorWidth: _clampedInt(opts.cursorWidth, defaults.cursorWidth, 0, Number.MAX_VALUE), + hideCursorInOverviewRuler: _boolean(opts.hideCursorInOverviewRuler, defaults.hideCursorInOverviewRuler), + scrollBeyondLastLine: _boolean(opts.scrollBeyondLastLine, defaults.scrollBeyondLastLine), + scrollBeyondLastColumn: _clampedInt(opts.scrollBeyondLastColumn, defaults.scrollBeyondLastColumn, 0, Constants.MAX_SAFE_SMALL_INTEGER), + smoothScrolling: _boolean(opts.smoothScrolling, defaults.smoothScrolling), + stopRenderingLineAfter: _clampedInt(opts.stopRenderingLineAfter, defaults.stopRenderingLineAfter, -1, Constants.MAX_SAFE_SMALL_INTEGER), + renderWhitespace: renderWhitespace, + renderControlCharacters: _boolean(opts.renderControlCharacters, defaults.renderControlCharacters), + fontLigatures: fontLigatures, + renderIndentGuides: _boolean(opts.renderIndentGuides, defaults.renderIndentGuides), + highlightActiveIndentGuide: _boolean(opts.highlightActiveIndentGuide, defaults.highlightActiveIndentGuide), + renderLineHighlight: renderLineHighlight, + fixedOverflowWidgets: _boolean(opts.fixedOverflowWidgets, defaults.fixedOverflowWidgets), + }; + } + + private static _sanitizeContribInfo(opts: IEditorOptions, defaults: EditorContribOptions): EditorContribOptions { + let quickSuggestions: boolean | { other: boolean, comments: boolean, strings: boolean }; + if (typeof opts.quickSuggestions === 'object') { + quickSuggestions = { other: true, ...opts.quickSuggestions }; + } else { + quickSuggestions = _boolean(opts.quickSuggestions, defaults.quickSuggestions); + } + // Compatibility support for acceptSuggestionOnEnter + if (typeof opts.acceptSuggestionOnEnter === 'boolean') { + opts.acceptSuggestionOnEnter = opts.acceptSuggestionOnEnter ? 'on' : 'off'; + } + const find = this._sanitizeFindOpts(opts.find, defaults.find); + return { + hover: this._sanitizeHoverOpts(opts.hover, defaults.hover), + links: _boolean(opts.links, defaults.links), + contextmenu: _boolean(opts.contextmenu, defaults.contextmenu), + quickSuggestions: quickSuggestions, + quickSuggestionsDelay: _clampedInt(opts.quickSuggestionsDelay, defaults.quickSuggestionsDelay, Constants.MIN_SAFE_SMALL_INTEGER, Constants.MAX_SAFE_SMALL_INTEGER), + parameterHints: this._sanitizeParameterHintOpts(opts.parameterHints, defaults.parameterHints), + formatOnType: _boolean(opts.formatOnType, defaults.formatOnType), + formatOnPaste: _boolean(opts.formatOnPaste, defaults.formatOnPaste), + suggestOnTriggerCharacters: _boolean(opts.suggestOnTriggerCharacters, defaults.suggestOnTriggerCharacters), + acceptSuggestionOnEnter: _stringSet<'on' | 'smart' | 'off'>(opts.acceptSuggestionOnEnter, defaults.acceptSuggestionOnEnter, ['on', 'smart', 'off']), + acceptSuggestionOnCommitCharacter: _boolean(opts.acceptSuggestionOnCommitCharacter, defaults.acceptSuggestionOnCommitCharacter), + wordBasedSuggestions: _boolean(opts.wordBasedSuggestions, defaults.wordBasedSuggestions), + suggestSelection: _stringSet<'first' | 'recentlyUsed' | 'recentlyUsedByPrefix'>(opts.suggestSelection, defaults.suggestSelection, ['first', 'recentlyUsed', 'recentlyUsedByPrefix']), + suggestFontSize: _clampedInt(opts.suggestFontSize, defaults.suggestFontSize, 0, 1000), + suggestLineHeight: _clampedInt(opts.suggestLineHeight, defaults.suggestLineHeight, 0, 1000), + tabCompletion: this._sanitizeTabCompletionOpts(opts.tabCompletion, defaults.tabCompletion), + suggest: this._sanitizeSuggestOpts(opts, defaults.suggest), + gotoLocation: this._sanitizeGotoLocationOpts(opts, defaults.gotoLocation), + selectionHighlight: _boolean(opts.selectionHighlight, defaults.selectionHighlight), + occurrencesHighlight: _boolean(opts.occurrencesHighlight, defaults.occurrencesHighlight), + codeLens: _boolean(opts.codeLens, defaults.codeLens), + foldingStrategy: _stringSet<'auto' | 'indentation'>(opts.foldingStrategy, defaults.foldingStrategy, ['auto', 'indentation']), + showFoldingControls: _stringSet<'always' | 'mouseover'>(opts.showFoldingControls, defaults.showFoldingControls, ['always', 'mouseover']), + matchBrackets: _boolean(opts.matchBrackets, defaults.matchBrackets), + find: find, + colorDecorators: _boolean(opts.colorDecorators, defaults.colorDecorators), + lightbulbEnabled: _boolean(opts.lightbulb ? opts.lightbulb.enabled : false, defaults.lightbulbEnabled), + codeActionsOnSave: _booleanMap(opts.codeActionsOnSave, {}), + codeActionsOnSaveTimeout: _clampedInt(opts.codeActionsOnSaveTimeout, defaults.codeActionsOnSaveTimeout, 1, 10000) + }; + } +} + +/** + * @internal + */ +export class InternalEditorOptionsFactory { + + public static createInternalEditorOptions(env: IEnvironmentalOptions, opts: IValidatedEditorOptions) { + + let className = 'monaco-editor'; + if (opts.viewInfo.extraEditorClassName) { + className += ' ' + opts.viewInfo.extraEditorClassName; + } + if (env.extraEditorClassName) { + className += ' ' + env.extraEditorClassName; + } + if (opts.viewInfo.fontLigatures) { + className += ' enable-ligatures'; + } + if (opts.mouseStyle === 'default') { + className += ' mouse-default'; + } else if (opts.mouseStyle === 'copy') { + className += ' mouse-copy'; + } + + return new InternalEditorOptions({ + canUseLayerHinting: opts.disableLayerHinting ? false : true, + pixelRatio: env.pixelRatio, + editorClassName: className, + lineHeight: env.fontInfo.lineHeight, + readOnly: opts.readOnly, + multiCursorModifier: opts.multiCursorModifier, + multiCursorMergeOverlapping: opts.multiCursorMergeOverlapping, + wordSeparators: opts.wordSeparators, + autoClosingBrackets: opts.autoClosingBrackets, + autoClosingQuotes: opts.autoClosingQuotes, + autoClosingOvertype: opts.autoClosingOvertype, + autoSurround: opts.autoSurround, + autoIndent: opts.autoIndent, + useTabStops: opts.useTabStops, + tabFocusMode: opts.readOnly ? true : env.tabFocusMode, + dragAndDrop: opts.dragAndDrop, + emptySelectionClipboard: opts.emptySelectionClipboard && env.emptySelectionClipboard, + copyWithSyntaxHighlighting: opts.copyWithSyntaxHighlighting, + fontInfo: env.fontInfo, + viewInfo: opts.viewInfo, + contribInfo: opts.contribInfo, + showUnused: opts.showUnused, + }); + } +} + +/** + * @internal + */ +export interface IEditorLayoutProviderOpts { + readonly outerWidth: number; + readonly outerHeight: number; + + readonly showGlyphMargin: boolean; + readonly lineHeight: number; + + readonly showLineNumbers: boolean; + readonly lineNumbersMinChars: number; + readonly lineNumbersDigitCount: number; + + readonly lineDecorationsWidth: number; + + readonly typicalHalfwidthCharacterWidth: number; + readonly maxDigitWidth: number; + + readonly verticalScrollbarWidth: number; + readonly verticalScrollbarHasArrows: boolean; + readonly scrollbarArrowSize: number; + readonly horizontalScrollbarHeight: number; + + readonly minimap: boolean; + readonly minimapSide: string; + readonly minimapRenderCharacters: boolean; + readonly minimapMaxColumn: number; + readonly pixelRatio: number; +} + +const DEFAULT_WINDOWS_FONT_FAMILY = 'Consolas, \'Courier New\', monospace'; +const DEFAULT_MAC_FONT_FAMILY = 'Menlo, Monaco, \'Courier New\', monospace'; +const DEFAULT_LINUX_FONT_FAMILY = '\'Droid Sans Mono\', \'monospace\', monospace, \'Droid Sans Fallback\''; + +/** + * @internal + */ +export const EDITOR_FONT_DEFAULTS = { + fontFamily: ( + platform.isMacintosh ? DEFAULT_MAC_FONT_FAMILY : (platform.isLinux ? DEFAULT_LINUX_FONT_FAMILY : DEFAULT_WINDOWS_FONT_FAMILY) + ), + fontWeight: 'normal', + fontSize: ( + platform.isMacintosh ? 12 : 14 + ), + lineHeight: 0, + letterSpacing: 0, +}; + +/** + * @internal + */ +export const EDITOR_MODEL_DEFAULTS = { + tabSize: 4, + indentSize: 4, + insertSpaces: true, + detectIndentation: true, + trimAutoWhitespace: true, + largeFileOptimizations: true +}; + +/** + * @internal + */ +export const EDITOR_DEFAULTS: IValidatedEditorOptions = { + wordSeparators: USUAL_WORD_SEPARATORS, + lineDecorationsWidth: 10, + readOnly: false, + mouseStyle: 'text', + disableLayerHinting: false, + automaticLayout: false, + autoClosingBrackets: 'languageDefined', + autoClosingQuotes: 'languageDefined', + autoClosingOvertype: 'auto', + autoSurround: 'languageDefined', + autoIndent: true, + dragAndDrop: true, + emptySelectionClipboard: true, + copyWithSyntaxHighlighting: true, + useTabStops: true, + multiCursorModifier: 'altKey', + multiCursorMergeOverlapping: true, + showUnused: true, + + viewInfo: { + extraEditorClassName: '', + disableMonospaceOptimizations: false, + rulers: [], + cursorSurroundingLines: 0, + glyphMargin: true, + revealHorizontalRightPadding: 30, + roundedSelection: true, + overviewRulerLanes: 2, + overviewRulerBorder: true, + cursorBlinking: TextEditorCursorBlinkingStyle.Blink, + mouseWheelZoom: false, + cursorSmoothCaretAnimation: false, + cursorStyle: TextEditorCursorStyle.Line, + cursorWidth: 0, + hideCursorInOverviewRuler: false, + scrollBeyondLastLine: true, + scrollBeyondLastColumn: 5, + smoothScrolling: false, + stopRenderingLineAfter: 10000, + renderWhitespace: 'none', + renderControlCharacters: false, + fontLigatures: false, + renderIndentGuides: true, + highlightActiveIndentGuide: true, + renderLineHighlight: 'line', + fixedOverflowWidgets: false, + }, + + contribInfo: { + hover: { + enabled: true, + delay: 300, + sticky: true + }, + links: true, + contextmenu: true, + quickSuggestions: { other: true, comments: false, strings: false }, + quickSuggestionsDelay: 10, + parameterHints: { + enabled: true, + cycle: false + }, + formatOnType: false, + formatOnPaste: false, + suggestOnTriggerCharacters: true, + acceptSuggestionOnEnter: 'on', + acceptSuggestionOnCommitCharacter: true, + wordBasedSuggestions: true, + suggestSelection: 'recentlyUsed', + suggestFontSize: 0, + suggestLineHeight: 0, + tabCompletion: 'off', + suggest: { + filterGraceful: true, + snippets: 'inline', + snippetsPreventQuickSuggestions: true, + localityBonus: false, + shareSuggestSelections: false, + showIcons: true, + maxVisibleSuggestions: 12, + filteredTypes: Object.create(null) + }, + gotoLocation: { + multiple: 'peek' + }, + selectionHighlight: true, + occurrencesHighlight: true, + codeLens: true, + foldingStrategy: 'auto', + showFoldingControls: 'mouseover', + matchBrackets: true, + find: { + seedSearchStringFromSelection: true, + autoFindInSelection: false, + globalFindClipboard: false, + addExtraSpaceOnTop: true + }, + colorDecorators: true, + lightbulbEnabled: true, + codeActionsOnSave: {}, + codeActionsOnSaveTimeout: 750 + }, +}; + +export interface IRawEditorOptionsBag extends IEditorOptions { + [key: string]: any; +} + +/** + * @internal + */ +export class RawEditorOptions { + private readonly _values: any[] = []; + public _read(id: EditorOptionId): T | undefined { + return this._values[id]; + } + public _write(id: EditorOptionId, value: T | undefined): void { + this._values[id] = value; + } +} + +/** + * @internal + */ +export class ValidatedEditorOptions { + private readonly _values: any[] = []; + public _read(option: EditorOptionId): T { + return this._values[option]; + } + public _write(option: EditorOptionId, value: T): void { + this._values[option] = value; + } +} + +export interface IComputedEditorOptions { + get>(id: EditorOptionId): ComputedEditorOptionValue; +} + +/** + * @internal + */ +export class ComputedEditorOptions implements IComputedEditorOptions { + private readonly _values: any[] = []; + public _read(id: EditorOptionId): T { + return this._values[id]; + } + public get>(id: EditorOptionId): ComputedEditorOptionValue { + return this._values[id]; + } + public _write(id: EditorOptionId, value: T): void { + this._values[id] = value; + } +} + +/** + * @internal + */ +export class ChangedEditorOptions { + private readonly _values: boolean[] = []; + public get(id: EditorOptionId): boolean { + return this._values[id]; + } + public _write(id: EditorOptionId, value: boolean): void { + this._values[id] = value; + } +} + +export type PossibleKeyName = { [K in keyof IEditorOptions]: IEditorOptions[K] extends V | undefined ? K : never }[keyof IEditorOptions]; + +export interface IEditorOption { + readonly id: EditorOptionId; + readonly name: PossibleKeyName; + readonly defaultValue: T2; + read(options: IRawEditorOptionsBag): T1 | undefined; + mix(a: T1 | undefined, b: T1 | undefined): T1 | undefined; + validate(input: T1 | undefined): T2; + compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: T2): T3; + equals(a: T3, b: T3): boolean; +} + +/** + * @internal + */ +export const editorOptionsRegistry: IEditorOption[] = []; + +function registerEditorOption(option: IEditorOption): IEditorOption { + editorOptionsRegistry[option.id] = option; + return option; +} + +export abstract class BaseEditorOption implements IEditorOption { + + public readonly id: EditorOptionId; + public readonly name: PossibleKeyName; + public readonly defaultValue: T2; + + constructor(id: EditorOptionId, name: PossibleKeyName, defaultValue: T2, deps: EditorOptionId[] = []) { + this.id = id; + this.name = name; + this.defaultValue = defaultValue; + for (const dep of deps) { + assert.ok(dep < id); + } + } + public read(options: IRawEditorOptionsBag): T1 | undefined { + return options[this.name]; + } + public mix(a: T1 | undefined, b: T1 | undefined): T1 | undefined { + switch (typeof b) { + case 'bigint': return b; + case 'boolean': return b; + case 'function': return b; + case 'number': return b; + case 'object': return (Array.isArray(b) || typeof a !== 'object' ? b : objects.mixin(objects.mixin({}, a), b)); + case 'string': return b; + default: + return a; + } + } + public abstract validate(input: T1 | undefined): T2; + public abstract compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: T2): T3; + public equals(a: T3, b: T3): boolean { + return (a === b); + } +} + +class EditorBooleanOption extends BaseEditorOption { + public validate(input: boolean | undefined): boolean { + return _boolean(input, this.defaultValue); + } + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: boolean): boolean { + return value; + } +} + +class EditorIntOption extends BaseEditorOption { + public readonly minimum: number; + public readonly maximum: number; + constructor(id: EditorOptionId, name: PossibleKeyName, defaultValue: number, minimum: number, maximum: number, deps: EditorOptionId[] = []) { + super(id, name, defaultValue, deps); + this.minimum = minimum; + this.maximum = maximum; + } + public validate(input: number | undefined): number { + return _clampedInt(input, this.defaultValue, this.minimum, this.maximum); + } + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: number): number { + return value; + } +} + +class EditorFloatOption extends BaseEditorOption { + public readonly validationFn: (value: number) => number; + constructor(id: EditorOptionId, name: PossibleKeyName, defaultValue: number, validationFn: (value: number) => number, deps: EditorOptionId[] = []) { + super(id, name, defaultValue, deps); + this.validationFn = validationFn; + } + public validate(input: number | undefined): number { + return this.validationFn(_float(input, this.defaultValue)); + } + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: number): number { + return value; + } +} + +class EditorStringOption extends BaseEditorOption { + public validate(input: string | undefined): string { + return _string(input, this.defaultValue); + } + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: string): string { + return value; + } +} + +class EditorEnumOption extends BaseEditorOption { + public readonly allowedValues: T1[]; + public readonly convert: (value: T1) => T2; + constructor(id: EditorOptionId, name: PossibleKeyName, defaultValue: T1, allowedValues: T1[], convert: (value: T1) => T2, deps: EditorOptionId[] = []) { + super(id, name, defaultValue, deps); + this.allowedValues = allowedValues; + this.convert = convert; + } + public validate(input: T1 | undefined): T1 { + return _stringSet(input, this.defaultValue, this.allowedValues); + } + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: T1): T2 { + return this.convert(value); + } +} + +class EditorPassthroughOption extends BaseEditorOption { + public validate(input: T | undefined): T { + if (typeof input === 'undefined') { + return this.defaultValue; + } + return input; + } + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: T): T { + return value; + } +} + +//#region renderLineNumbers + +export type LineNumbersType = 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string); + +export const enum RenderLineNumbersType { + Off = 0, + On = 1, + Relative = 2, + Interval = 3, + Custom = 4 +} + +export interface InternalEditorRenderLineNumbersOptions { + readonly renderType: RenderLineNumbersType; + readonly renderFn: ((lineNumber: number) => string) | null; +} + +class EditorRenderLineNumbersOption extends BaseEditorOption { + public validate(lineNumbers: LineNumbersType | undefined): InternalEditorRenderLineNumbersOptions { + let renderType: RenderLineNumbersType = this.defaultValue.renderType; + let renderFn: ((lineNumber: number) => string) | null = this.defaultValue.renderFn; + + if (typeof lineNumbers !== 'undefined') { + if (typeof lineNumbers === 'function') { + renderType = RenderLineNumbersType.Custom; + renderFn = lineNumbers; + } else if (lineNumbers === 'interval') { + renderType = RenderLineNumbersType.Interval; + } else if (lineNumbers === 'relative') { + renderType = RenderLineNumbersType.Relative; + } else if (lineNumbers === 'on') { + renderType = RenderLineNumbersType.On; + } else { + renderType = RenderLineNumbersType.Off; + } + } + + return { + renderType, + renderFn + }; + } + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: InternalEditorRenderLineNumbersOptions): InternalEditorRenderLineNumbersOptions { + return value; + } + public equals(a: InternalEditorRenderLineNumbersOptions, b: InternalEditorRenderLineNumbersOptions): boolean { + return ( + a.renderType === b.renderType + && a.renderFn === b.renderFn + ); + } +} + +//#endregion + +//#region minimap + +export interface InternalEditorMinimapOptions { + readonly enabled: boolean; + readonly side: 'right' | 'left'; + readonly showSlider: 'always' | 'mouseover'; + readonly renderCharacters: boolean; + readonly maxColumn: number; +} + +class EditorMinimapOption extends BaseEditorOption { + public validate(input: IEditorMinimapOptions | undefined): InternalEditorMinimapOptions { + if (typeof input !== 'object') { + return this.defaultValue; + } + return { + enabled: _boolean(input.enabled, this.defaultValue.enabled), + side: _stringSet<'right' | 'left'>(input.side, this.defaultValue.side, ['right', 'left']), + showSlider: _stringSet<'always' | 'mouseover'>(input.showSlider, this.defaultValue.showSlider, ['always', 'mouseover']), + renderCharacters: _boolean(input.renderCharacters, this.defaultValue.renderCharacters), + maxColumn: _clampedInt(input.maxColumn, this.defaultValue.maxColumn, 1, 10000), + }; + } + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: InternalEditorMinimapOptions): InternalEditorMinimapOptions { + return value; + } + public equals(a: InternalEditorMinimapOptions, b: InternalEditorMinimapOptions): boolean { + return ( + a.enabled === b.enabled + && a.side === b.side + && a.showSlider === b.showSlider + && a.renderCharacters === b.renderCharacters + && a.maxColumn === b.maxColumn + ); + } +} + +//#endregion + +//#region accessibilitySupport + +class EditorAccessibilitySupportOption extends BaseEditorOption<'auto' | 'off' | 'on', 'auto' | 'off' | 'on', AccessibilitySupport> { + public validate(input: 'auto' | 'off' | 'on' | undefined): 'auto' | 'off' | 'on' { + return _stringSet<'auto' | 'off' | 'on'>(input, this.defaultValue, ['auto', 'off', 'on']); + } + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: 'auto' | 'off' | 'on'): AccessibilitySupport { + if (value === 'auto') { + // The editor reads the `accessibilitySupport` from the environment + return env.accessibilitySupport; + } else if (value === 'on') { + return AccessibilitySupport.Enabled; + } else { + return AccessibilitySupport.Disabled; + } + } +} + +//#endregion + +//#region ariaLabel + +class EditorAriaLabel extends BaseEditorOption { + public validate(input: string | undefined): string { + return _string(input, this.defaultValue); + } + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: string): string { + const accessibilitySupport = options.get(EditorOptionId.accessibilitySupport); + if (accessibilitySupport === AccessibilitySupport.Disabled) { + return nls.localize('accessibilityOffAriaLabel', "The editor is not accessible at this time. Press Alt+F1 for options."); + } + return value; + } +} + +//#endregion + +//#region scrollbar + +export interface InternalEditorScrollbarOptions { + readonly arrowSize: number; + readonly vertical: ScrollbarVisibility; + readonly horizontal: ScrollbarVisibility; + readonly useShadows: boolean; + readonly verticalHasArrows: boolean; + readonly horizontalHasArrows: boolean; + readonly handleMouseWheel: boolean; + readonly horizontalScrollbarSize: number; + readonly horizontalSliderSize: number; + readonly verticalScrollbarSize: number; + readonly verticalSliderSize: number; +} + +class EditorScrollbarOption extends BaseEditorOption { + public validate(input: IEditorScrollbarOptions | undefined): InternalEditorScrollbarOptions { + if (typeof input !== 'object') { + return this.defaultValue; + } + const horizontalScrollbarSize = _clampedInt(input.horizontalScrollbarSize, this.defaultValue.horizontalScrollbarSize, 0, 1000); + const verticalScrollbarSize = _clampedInt(input.verticalScrollbarSize, this.defaultValue.verticalScrollbarSize, 0, 1000); + return { + arrowSize: _clampedInt(input.arrowSize, this.defaultValue.arrowSize, 0, 1000), + vertical: _scrollbarVisibilityFromString(input.vertical, this.defaultValue.vertical), + horizontal: _scrollbarVisibilityFromString(input.horizontal, this.defaultValue.horizontal), + useShadows: _boolean(input.useShadows, this.defaultValue.useShadows), + verticalHasArrows: _boolean(input.verticalHasArrows, this.defaultValue.verticalHasArrows), + horizontalHasArrows: _boolean(input.horizontalHasArrows, this.defaultValue.horizontalHasArrows), + handleMouseWheel: _boolean(input.handleMouseWheel, this.defaultValue.handleMouseWheel), + horizontalScrollbarSize: horizontalScrollbarSize, + horizontalSliderSize: _clampedInt(input.horizontalSliderSize, horizontalScrollbarSize, 0, 1000), + verticalScrollbarSize: verticalScrollbarSize, + verticalSliderSize: _clampedInt(input.verticalSliderSize, verticalScrollbarSize, 0, 1000), + }; + } + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: InternalEditorScrollbarOptions): InternalEditorScrollbarOptions { + return value; + } + public equals(a: InternalEditorScrollbarOptions, b: InternalEditorScrollbarOptions): boolean { + return ( + a.arrowSize === b.arrowSize + && a.vertical === b.vertical + && a.horizontal === b.horizontal + && a.useShadows === b.useShadows + && a.verticalHasArrows === b.verticalHasArrows + && a.horizontalHasArrows === b.horizontalHasArrows + && a.handleMouseWheel === b.handleMouseWheel + && a.horizontalScrollbarSize === b.horizontalScrollbarSize + && a.horizontalSliderSize === b.horizontalSliderSize + && a.verticalScrollbarSize === b.verticalScrollbarSize + && a.verticalSliderSize === b.verticalSliderSize + ); + } +} + +//#endregion + +//#region layoutInfo + /** * A description for the overview ruler position. */ @@ -1634,827 +2472,93 @@ export interface EditorLayoutInfo { readonly overviewRuler: OverviewRulerPosition; } -/** - * An event describing that the configuration of the editor has changed. - */ -export interface IConfigurationChangedEvent { - hasChanged(id: EditorOptionId): boolean; - readonly canUseLayerHinting: boolean; - readonly pixelRatio: boolean; - readonly editorClassName: boolean; - readonly lineHeight: boolean; - readonly readOnly: boolean; - readonly accessibilitySupport: boolean; - readonly multiCursorModifier: boolean; - readonly multiCursorMergeOverlapping: boolean; - readonly wordSeparators: boolean; - readonly autoClosingBrackets: boolean; - readonly autoClosingQuotes: boolean; - readonly autoClosingOvertype: boolean; - readonly autoSurround: boolean; - readonly autoIndent: boolean; - readonly useTabStops: boolean; - readonly tabFocusMode: boolean; - readonly dragAndDrop: boolean; - readonly emptySelectionClipboard: boolean; - readonly copyWithSyntaxHighlighting: boolean; - readonly layoutInfo: boolean; - readonly fontInfo: boolean; - readonly viewInfo: boolean; - readonly wrappingInfo: boolean; - readonly contribInfo: boolean; -} - /** * @internal */ -export interface IEnvironmentalOptions { - readonly outerWidth: number; - readonly outerHeight: number; - readonly fontInfo: FontInfo; - readonly extraEditorClassName: string; - readonly isDominatedByLongLines: boolean; - readonly lineNumbersDigitCount: number; - readonly emptySelectionClipboard: boolean; - readonly pixelRatio: number; - readonly tabFocusMode: boolean; - readonly accessibilitySupport: AccessibilitySupport; -} - -function _boolean(value: any, defaultValue: T): boolean | T { - if (typeof value === 'undefined') { - return defaultValue; +export class EditorLayoutInfoComputer extends BaseEditorOption { + public validate(input: undefined): undefined { + return undefined; } - if (value === 'false') { - // treat the string 'false' as false - return false; - } - return Boolean(value); -} - -function _booleanMap(value: { [key: string]: boolean } | undefined, defaultValue: { [key: string]: boolean }): { [key: string]: boolean } { - if (!value) { - return defaultValue; - } - - const out = Object.create(null); - for (const k of Object.keys(value)) { - const v = value[k]; - if (typeof v === 'boolean') { - out[k] = v; - } - } - return out; -} - -function _string(value: any, defaultValue: string): string { - if (typeof value !== 'string') { - return defaultValue; - } - return value; -} - -function _stringSet(value: T | undefined, defaultValue: T, allowedValues: T[]): T { - if (typeof value !== 'string') { - return defaultValue; - } - if (allowedValues.indexOf(value) === -1) { - return defaultValue; - } - return value; -} - -function _clampedInt(value: any, defaultValue: number, minimum: number, maximum: number): number { - let r: number; - if (typeof value === 'undefined') { - r = defaultValue; - } else { - r = parseInt(value, 10); - if (isNaN(r)) { - r = defaultValue; - } - } - r = Math.max(minimum, r); - r = Math.min(maximum, r); - return r | 0; -} - -function _float(value: any, defaultValue: number): number { - let r = parseFloat(value); - if (isNaN(r)) { - r = defaultValue; - } - return r; -} - -function _wrappingIndentFromString(wrappingIndent: string | undefined, defaultValue: WrappingIndent): WrappingIndent { - if (typeof wrappingIndent !== 'string') { - return defaultValue; - } - if (wrappingIndent === 'same') { - return WrappingIndent.Same; - } else if (wrappingIndent === 'indent') { - return WrappingIndent.Indent; - } else if (wrappingIndent === 'deepIndent') { - return WrappingIndent.DeepIndent; - } else { - return WrappingIndent.None; - } -} - -function _cursorBlinkingStyleFromString(cursorBlinkingStyle: string | undefined, defaultValue: TextEditorCursorBlinkingStyle): TextEditorCursorBlinkingStyle { - if (typeof cursorBlinkingStyle !== 'string') { - return defaultValue; - } - switch (cursorBlinkingStyle) { - case 'blink': - return TextEditorCursorBlinkingStyle.Blink; - case 'smooth': - return TextEditorCursorBlinkingStyle.Smooth; - case 'phase': - return TextEditorCursorBlinkingStyle.Phase; - case 'expand': - return TextEditorCursorBlinkingStyle.Expand; - case 'visible': // maintain compatibility - case 'solid': - return TextEditorCursorBlinkingStyle.Solid; - } - return TextEditorCursorBlinkingStyle.Blink; -} - -function _scrollbarVisibilityFromString(visibility: string | undefined, defaultValue: ScrollbarVisibility): ScrollbarVisibility { - if (typeof visibility !== 'string') { - return defaultValue; - } - switch (visibility) { - case 'hidden': - return ScrollbarVisibility.Hidden; - case 'visible': - return ScrollbarVisibility.Visible; - default: - return ScrollbarVisibility.Auto; - } -} - -/** - * @internal - */ -export class EditorOptionsValidator { - - /** - * Validate raw editor options. - * i.e. since they can be defined by the user, they might be invalid. - */ - public static validate(opts: IEditorOptions, defaults: IValidatedEditorOptions): IValidatedEditorOptions { - let wordWrap = opts.wordWrap; - { - // Compatibility with old true or false values - if (wordWrap === true) { - wordWrap = 'on'; - } else if (wordWrap === false) { - wordWrap = 'off'; - } - - wordWrap = _stringSet<'off' | 'on' | 'wordWrapColumn' | 'bounded'>(wordWrap, defaults.wordWrap, ['off', 'on', 'wordWrapColumn', 'bounded']); - } - - const viewInfo = this._sanitizeViewInfo(opts, defaults.viewInfo); - const contribInfo = this._sanitizeContribInfo(opts, defaults.contribInfo); - - let configuredMulticursorModifier: 'altKey' | 'metaKey' | 'ctrlKey' | undefined = undefined; - if (typeof opts.multiCursorModifier === 'string') { - if (opts.multiCursorModifier === 'ctrlCmd') { - configuredMulticursorModifier = platform.isMacintosh ? 'metaKey' : 'ctrlKey'; - } else { - configuredMulticursorModifier = 'altKey'; - } - } - const multiCursorModifier = _stringSet<'altKey' | 'metaKey' | 'ctrlKey'>(configuredMulticursorModifier, defaults.multiCursorModifier, ['altKey', 'metaKey', 'ctrlKey']); - - let autoClosingBrackets: EditorAutoClosingStrategy; - let autoClosingQuotes: EditorAutoClosingStrategy; - let autoSurround: EditorAutoSurroundStrategy; - if (typeof opts.autoClosingBrackets === 'boolean' && opts.autoClosingBrackets === false) { - // backwards compatibility: disable all on boolean false - autoClosingBrackets = 'never'; - autoClosingQuotes = 'never'; - autoSurround = 'never'; - } else { - autoClosingBrackets = _stringSet(opts.autoClosingBrackets, defaults.autoClosingBrackets, ['always', 'languageDefined', 'beforeWhitespace', 'never']); - autoClosingQuotes = _stringSet(opts.autoClosingQuotes, defaults.autoClosingQuotes, ['always', 'languageDefined', 'beforeWhitespace', 'never']); - autoSurround = _stringSet(opts.autoSurround, defaults.autoSurround, ['languageDefined', 'brackets', 'quotes', 'never']); - } - - return { - inDiffEditor: _boolean(opts.inDiffEditor, defaults.inDiffEditor), - wordSeparators: _string(opts.wordSeparators, defaults.wordSeparators), - lineNumbersMinChars: _clampedInt(opts.lineNumbersMinChars, defaults.lineNumbersMinChars, 1, 10), - lineDecorationsWidth: (typeof opts.lineDecorationsWidth === 'undefined' ? defaults.lineDecorationsWidth : opts.lineDecorationsWidth), - readOnly: _boolean(opts.readOnly, defaults.readOnly), - mouseStyle: _stringSet<'text' | 'default' | 'copy'>(opts.mouseStyle, defaults.mouseStyle, ['text', 'default', 'copy']), - disableLayerHinting: _boolean(opts.disableLayerHinting, defaults.disableLayerHinting), - automaticLayout: _boolean(opts.automaticLayout, defaults.automaticLayout), - wordWrap: wordWrap, - wordWrapColumn: _clampedInt(opts.wordWrapColumn, defaults.wordWrapColumn, 1, Constants.MAX_SAFE_SMALL_INTEGER), - wordWrapMinified: _boolean(opts.wordWrapMinified, defaults.wordWrapMinified), - wrappingIndent: _wrappingIndentFromString(opts.wrappingIndent, defaults.wrappingIndent), - wordWrapBreakBeforeCharacters: _string(opts.wordWrapBreakBeforeCharacters, defaults.wordWrapBreakBeforeCharacters), - wordWrapBreakAfterCharacters: _string(opts.wordWrapBreakAfterCharacters, defaults.wordWrapBreakAfterCharacters), - wordWrapBreakObtrusiveCharacters: _string(opts.wordWrapBreakObtrusiveCharacters, defaults.wordWrapBreakObtrusiveCharacters), - autoClosingBrackets, - autoClosingQuotes, - autoClosingOvertype: _stringSet(opts.autoClosingOvertype, defaults.autoClosingOvertype, ['always', 'auto', 'never']), - autoSurround, - autoIndent: _boolean(opts.autoIndent, defaults.autoIndent), - dragAndDrop: _boolean(opts.dragAndDrop, defaults.dragAndDrop), - emptySelectionClipboard: _boolean(opts.emptySelectionClipboard, defaults.emptySelectionClipboard), - copyWithSyntaxHighlighting: _boolean(opts.copyWithSyntaxHighlighting, defaults.copyWithSyntaxHighlighting), - useTabStops: _boolean(opts.useTabStops, defaults.useTabStops), - multiCursorModifier: multiCursorModifier, - multiCursorMergeOverlapping: _boolean(opts.multiCursorMergeOverlapping, defaults.multiCursorMergeOverlapping), - accessibilitySupport: _stringSet<'auto' | 'on' | 'off'>(opts.accessibilitySupport, defaults.accessibilitySupport, ['auto', 'on', 'off']), - showUnused: _boolean(opts.showUnused, defaults.showUnused), - viewInfo: viewInfo, - contribInfo: contribInfo, - }; - } - - private static _sanitizeScrollbarOpts(opts: IEditorScrollbarOptions | undefined, defaults: InternalEditorScrollbarOptions, mouseWheelScrollSensitivity: number, fastScrollSensitivity: number): InternalEditorScrollbarOptions { - if (typeof opts !== 'object') { - return defaults; - } - const horizontalScrollbarSize = _clampedInt(opts.horizontalScrollbarSize, defaults.horizontalScrollbarSize, 0, 1000); - const verticalScrollbarSize = _clampedInt(opts.verticalScrollbarSize, defaults.verticalScrollbarSize, 0, 1000); - return { - vertical: _scrollbarVisibilityFromString(opts.vertical, defaults.vertical), - horizontal: _scrollbarVisibilityFromString(opts.horizontal, defaults.horizontal), - - arrowSize: _clampedInt(opts.arrowSize, defaults.arrowSize, 0, 1000), - useShadows: _boolean(opts.useShadows, defaults.useShadows), - - verticalHasArrows: _boolean(opts.verticalHasArrows, defaults.verticalHasArrows), - horizontalHasArrows: _boolean(opts.horizontalHasArrows, defaults.horizontalHasArrows), - - horizontalScrollbarSize: horizontalScrollbarSize, - horizontalSliderSize: _clampedInt(opts.horizontalSliderSize, horizontalScrollbarSize, 0, 1000), - - verticalScrollbarSize: verticalScrollbarSize, - verticalSliderSize: _clampedInt(opts.verticalSliderSize, verticalScrollbarSize, 0, 1000), - - handleMouseWheel: _boolean(opts.handleMouseWheel, defaults.handleMouseWheel), - mouseWheelScrollSensitivity: mouseWheelScrollSensitivity, - fastScrollSensitivity: fastScrollSensitivity, - }; - } - - private static _sanitizeMinimapOpts(opts: IEditorMinimapOptions | undefined, defaults: InternalEditorMinimapOptions): InternalEditorMinimapOptions { - if (typeof opts !== 'object') { - return defaults; - } - return { - enabled: _boolean(opts.enabled, defaults.enabled), - side: _stringSet<'right' | 'left'>(opts.side, defaults.side, ['right', 'left']), - showSlider: _stringSet<'always' | 'mouseover'>(opts.showSlider, defaults.showSlider, ['always', 'mouseover']), - renderCharacters: _boolean(opts.renderCharacters, defaults.renderCharacters), - maxColumn: _clampedInt(opts.maxColumn, defaults.maxColumn, 1, 10000), - }; - } - - private static _sanitizeFindOpts(opts: IEditorFindOptions | undefined, defaults: InternalEditorFindOptions): InternalEditorFindOptions { - if (typeof opts !== 'object') { - return defaults; - } - - return { - seedSearchStringFromSelection: _boolean(opts.seedSearchStringFromSelection, defaults.seedSearchStringFromSelection), - autoFindInSelection: _boolean(opts.autoFindInSelection, defaults.autoFindInSelection), - globalFindClipboard: _boolean(opts.globalFindClipboard, defaults.globalFindClipboard), - addExtraSpaceOnTop: _boolean(opts.addExtraSpaceOnTop, defaults.addExtraSpaceOnTop) - }; - } - - private static _sanitizeParameterHintOpts(opts: IEditorParameterHintOptions | undefined, defaults: InternalParameterHintOptions): InternalParameterHintOptions { - if (typeof opts !== 'object') { - return defaults; - } - - return { - enabled: _boolean(opts.enabled, defaults.enabled), - cycle: _boolean(opts.cycle, defaults.cycle) - }; - } - - private static _sanitizeHoverOpts(_opts: boolean | IEditorHoverOptions | undefined, defaults: InternalEditorHoverOptions): InternalEditorHoverOptions { - let opts: IEditorHoverOptions; - if (typeof _opts === 'boolean') { - opts = { - enabled: _opts - }; - } else if (typeof _opts === 'object') { - opts = _opts; - } else { - return defaults; - } - - return { - enabled: _boolean(opts.enabled, defaults.enabled), - delay: _clampedInt(opts.delay, defaults.delay, 0, 10000), - sticky: _boolean(opts.sticky, defaults.sticky) - }; - } - - private static _sanitizeSuggestOpts(opts: IEditorOptions, defaults: InternalSuggestOptions): InternalSuggestOptions { - const suggestOpts = opts.suggest || {}; - return { - filterGraceful: _boolean(suggestOpts.filterGraceful, defaults.filterGraceful), - snippets: _stringSet<'top' | 'bottom' | 'inline' | 'none'>(opts.snippetSuggestions, defaults.snippets, ['top', 'bottom', 'inline', 'none']), - snippetsPreventQuickSuggestions: _boolean(suggestOpts.snippetsPreventQuickSuggestions, defaults.filterGraceful), - localityBonus: _boolean(suggestOpts.localityBonus, defaults.localityBonus), - shareSuggestSelections: _boolean(suggestOpts.shareSuggestSelections, defaults.shareSuggestSelections), - showIcons: _boolean(suggestOpts.showIcons, defaults.showIcons), - maxVisibleSuggestions: _clampedInt(suggestOpts.maxVisibleSuggestions, defaults.maxVisibleSuggestions, 1, 15), - filteredTypes: isObject(suggestOpts.filteredTypes) ? suggestOpts.filteredTypes : Object.create(null) - }; - } - - private static _sanitizeGotoLocationOpts(opts: IEditorOptions, defaults: InternalGoToLocationOptions): InternalGoToLocationOptions { - const gotoOpts = opts.gotoLocation || {}; - return { - multiple: _stringSet<'peek' | 'gotoAndPeek' | 'goto'>(gotoOpts.multiple, defaults.multiple, ['peek', 'gotoAndPeek', 'goto']) - }; - } - - private static _sanitizeTabCompletionOpts(opts: boolean | 'on' | 'off' | 'onlySnippets' | undefined, defaults: 'on' | 'off' | 'onlySnippets'): 'on' | 'off' | 'onlySnippets' { - if (opts === false) { - return 'off'; - } else if (opts === true) { - return 'onlySnippets'; - } else { - return _stringSet<'on' | 'off' | 'onlySnippets'>(opts, defaults, ['on', 'off', 'onlySnippets']); - } - } - - private static _sanitizeViewInfo(opts: IEditorOptions, defaults: InternalEditorViewOptions): InternalEditorViewOptions { - - let rulers: number[] = []; - if (Array.isArray(opts.rulers)) { - for (let i = 0, len = opts.rulers.length; i < len; i++) { - rulers.push(_clampedInt(opts.rulers[i], 0, 0, 10000)); - } - rulers.sort(); - } - - let renderLineNumbers: RenderLineNumbersType = defaults.renderLineNumbers; - let renderCustomLineNumbers: ((lineNumber: number) => string) | null = defaults.renderCustomLineNumbers; - - if (typeof opts.lineNumbers !== 'undefined') { - let lineNumbers = opts.lineNumbers; - - // Compatibility with old true or false values - if (lineNumbers === true) { - lineNumbers = 'on'; - } else if (lineNumbers === false) { - lineNumbers = 'off'; - } - - if (typeof lineNumbers === 'function') { - renderLineNumbers = RenderLineNumbersType.Custom; - renderCustomLineNumbers = lineNumbers; - } else if (lineNumbers === 'interval') { - renderLineNumbers = RenderLineNumbersType.Interval; - } else if (lineNumbers === 'relative') { - renderLineNumbers = RenderLineNumbersType.Relative; - } else if (lineNumbers === 'on') { - renderLineNumbers = RenderLineNumbersType.On; - } else { - renderLineNumbers = RenderLineNumbersType.Off; - } - } - - const fontLigatures = _boolean(opts.fontLigatures, defaults.fontLigatures); - const disableMonospaceOptimizations = _boolean(opts.disableMonospaceOptimizations, defaults.disableMonospaceOptimizations) || fontLigatures; - - let renderWhitespace = opts.renderWhitespace; - { - // Compatibility with old true or false values - if (renderWhitespace === true) { - renderWhitespace = 'boundary'; - } else if (renderWhitespace === false) { - renderWhitespace = 'none'; - } - renderWhitespace = _stringSet<'none' | 'boundary' | 'selection' | 'all'>(renderWhitespace, defaults.renderWhitespace, ['none', 'boundary', 'selection', 'all']); - } - - let renderLineHighlight = opts.renderLineHighlight; - { - // Compatibility with old true or false values - if (renderLineHighlight === true) { - renderLineHighlight = 'line'; - } else if (renderLineHighlight === false) { - renderLineHighlight = 'none'; - } - renderLineHighlight = _stringSet<'none' | 'gutter' | 'line' | 'all'>(renderLineHighlight, defaults.renderLineHighlight, ['none', 'gutter', 'line', 'all']); - } - - let mouseWheelScrollSensitivity = _float(opts.mouseWheelScrollSensitivity, defaults.scrollbar.mouseWheelScrollSensitivity); - if (mouseWheelScrollSensitivity === 0) { - // Disallow 0, as it would prevent/block scrolling - mouseWheelScrollSensitivity = 1; - } - - let fastScrollSensitivity = _float(opts.fastScrollSensitivity, defaults.scrollbar.fastScrollSensitivity); - if (fastScrollSensitivity <= 0) { - fastScrollSensitivity = defaults.scrollbar.fastScrollSensitivity; - } - const scrollbar = this._sanitizeScrollbarOpts(opts.scrollbar, defaults.scrollbar, mouseWheelScrollSensitivity, fastScrollSensitivity); - const minimap = this._sanitizeMinimapOpts(opts.minimap, defaults.minimap); - - return { - extraEditorClassName: _string(opts.extraEditorClassName, defaults.extraEditorClassName), - disableMonospaceOptimizations: disableMonospaceOptimizations, - rulers: rulers, - ariaLabel: _string(opts.ariaLabel, defaults.ariaLabel), - cursorSurroundingLines: _clampedInt(opts.cursorSurroundingLines, defaults.cursorWidth, 0, Number.MAX_VALUE), - renderLineNumbers: renderLineNumbers, - renderCustomLineNumbers: renderCustomLineNumbers, - glyphMargin: _boolean(opts.glyphMargin, defaults.glyphMargin), - revealHorizontalRightPadding: _clampedInt(opts.revealHorizontalRightPadding, defaults.revealHorizontalRightPadding, 0, 1000), - roundedSelection: _boolean(opts.roundedSelection, defaults.roundedSelection), - overviewRulerLanes: _clampedInt(opts.overviewRulerLanes, defaults.overviewRulerLanes, 0, 3), - overviewRulerBorder: _boolean(opts.overviewRulerBorder, defaults.overviewRulerBorder), - cursorBlinking: _cursorBlinkingStyleFromString(opts.cursorBlinking, defaults.cursorBlinking), - mouseWheelZoom: _boolean(opts.mouseWheelZoom, defaults.mouseWheelZoom), - cursorSmoothCaretAnimation: _boolean(opts.cursorSmoothCaretAnimation, defaults.cursorSmoothCaretAnimation), - cursorStyle: _cursorStyleFromString(opts.cursorStyle, defaults.cursorStyle), - cursorWidth: _clampedInt(opts.cursorWidth, defaults.cursorWidth, 0, Number.MAX_VALUE), - hideCursorInOverviewRuler: _boolean(opts.hideCursorInOverviewRuler, defaults.hideCursorInOverviewRuler), - scrollBeyondLastLine: _boolean(opts.scrollBeyondLastLine, defaults.scrollBeyondLastLine), - scrollBeyondLastColumn: _clampedInt(opts.scrollBeyondLastColumn, defaults.scrollBeyondLastColumn, 0, Constants.MAX_SAFE_SMALL_INTEGER), - smoothScrolling: _boolean(opts.smoothScrolling, defaults.smoothScrolling), - stopRenderingLineAfter: _clampedInt(opts.stopRenderingLineAfter, defaults.stopRenderingLineAfter, -1, Constants.MAX_SAFE_SMALL_INTEGER), - renderWhitespace: renderWhitespace, - renderControlCharacters: _boolean(opts.renderControlCharacters, defaults.renderControlCharacters), - fontLigatures: fontLigatures, - renderIndentGuides: _boolean(opts.renderIndentGuides, defaults.renderIndentGuides), - highlightActiveIndentGuide: _boolean(opts.highlightActiveIndentGuide, defaults.highlightActiveIndentGuide), - renderLineHighlight: renderLineHighlight, - scrollbar: scrollbar, - minimap: minimap, - fixedOverflowWidgets: _boolean(opts.fixedOverflowWidgets, defaults.fixedOverflowWidgets), - }; - } - - private static _sanitizeContribInfo(opts: IEditorOptions, defaults: EditorContribOptions): EditorContribOptions { - let quickSuggestions: boolean | { other: boolean, comments: boolean, strings: boolean }; - if (typeof opts.quickSuggestions === 'object') { - quickSuggestions = { other: true, ...opts.quickSuggestions }; - } else { - quickSuggestions = _boolean(opts.quickSuggestions, defaults.quickSuggestions); - } - // Compatibility support for acceptSuggestionOnEnter - if (typeof opts.acceptSuggestionOnEnter === 'boolean') { - opts.acceptSuggestionOnEnter = opts.acceptSuggestionOnEnter ? 'on' : 'off'; - } - const find = this._sanitizeFindOpts(opts.find, defaults.find); - return { - hover: this._sanitizeHoverOpts(opts.hover, defaults.hover), - links: _boolean(opts.links, defaults.links), - contextmenu: _boolean(opts.contextmenu, defaults.contextmenu), - quickSuggestions: quickSuggestions, - quickSuggestionsDelay: _clampedInt(opts.quickSuggestionsDelay, defaults.quickSuggestionsDelay, Constants.MIN_SAFE_SMALL_INTEGER, Constants.MAX_SAFE_SMALL_INTEGER), - parameterHints: this._sanitizeParameterHintOpts(opts.parameterHints, defaults.parameterHints), - formatOnType: _boolean(opts.formatOnType, defaults.formatOnType), - formatOnPaste: _boolean(opts.formatOnPaste, defaults.formatOnPaste), - suggestOnTriggerCharacters: _boolean(opts.suggestOnTriggerCharacters, defaults.suggestOnTriggerCharacters), - acceptSuggestionOnEnter: _stringSet<'on' | 'smart' | 'off'>(opts.acceptSuggestionOnEnter, defaults.acceptSuggestionOnEnter, ['on', 'smart', 'off']), - acceptSuggestionOnCommitCharacter: _boolean(opts.acceptSuggestionOnCommitCharacter, defaults.acceptSuggestionOnCommitCharacter), - wordBasedSuggestions: _boolean(opts.wordBasedSuggestions, defaults.wordBasedSuggestions), - suggestSelection: _stringSet<'first' | 'recentlyUsed' | 'recentlyUsedByPrefix'>(opts.suggestSelection, defaults.suggestSelection, ['first', 'recentlyUsed', 'recentlyUsedByPrefix']), - suggestFontSize: _clampedInt(opts.suggestFontSize, defaults.suggestFontSize, 0, 1000), - suggestLineHeight: _clampedInt(opts.suggestLineHeight, defaults.suggestLineHeight, 0, 1000), - tabCompletion: this._sanitizeTabCompletionOpts(opts.tabCompletion, defaults.tabCompletion), - suggest: this._sanitizeSuggestOpts(opts, defaults.suggest), - gotoLocation: this._sanitizeGotoLocationOpts(opts, defaults.gotoLocation), - selectionHighlight: _boolean(opts.selectionHighlight, defaults.selectionHighlight), - occurrencesHighlight: _boolean(opts.occurrencesHighlight, defaults.occurrencesHighlight), - codeLens: _boolean(opts.codeLens, defaults.codeLens), - folding: _boolean(opts.folding, defaults.folding), - foldingStrategy: _stringSet<'auto' | 'indentation'>(opts.foldingStrategy, defaults.foldingStrategy, ['auto', 'indentation']), - showFoldingControls: _stringSet<'always' | 'mouseover'>(opts.showFoldingControls, defaults.showFoldingControls, ['always', 'mouseover']), - matchBrackets: _boolean(opts.matchBrackets, defaults.matchBrackets), - find: find, - colorDecorators: _boolean(opts.colorDecorators, defaults.colorDecorators), - lightbulbEnabled: _boolean(opts.lightbulb ? opts.lightbulb.enabled : false, defaults.lightbulbEnabled), - codeActionsOnSave: _booleanMap(opts.codeActionsOnSave, {}), - codeActionsOnSaveTimeout: _clampedInt(opts.codeActionsOnSaveTimeout, defaults.codeActionsOnSaveTimeout, 1, 10000) - }; - } -} - -/** - * @internal - */ -export class InternalEditorOptionsFactory { - - private static _tweakValidatedOptions(opts: IValidatedEditorOptions, accessibilitySupport: AccessibilitySupport): IValidatedEditorOptions { - const accessibilityIsOff = (accessibilitySupport === AccessibilitySupport.Disabled); - return { - inDiffEditor: opts.inDiffEditor, - wordSeparators: opts.wordSeparators, - lineNumbersMinChars: opts.lineNumbersMinChars, - lineDecorationsWidth: opts.lineDecorationsWidth, - readOnly: opts.readOnly, - mouseStyle: opts.mouseStyle, - disableLayerHinting: opts.disableLayerHinting, - automaticLayout: opts.automaticLayout, - wordWrap: opts.wordWrap, - wordWrapColumn: opts.wordWrapColumn, - wordWrapMinified: opts.wordWrapMinified, - wrappingIndent: opts.wrappingIndent, - wordWrapBreakBeforeCharacters: opts.wordWrapBreakBeforeCharacters, - wordWrapBreakAfterCharacters: opts.wordWrapBreakAfterCharacters, - wordWrapBreakObtrusiveCharacters: opts.wordWrapBreakObtrusiveCharacters, - autoClosingBrackets: opts.autoClosingBrackets, - autoClosingQuotes: opts.autoClosingQuotes, - autoClosingOvertype: opts.autoClosingOvertype, - autoSurround: opts.autoSurround, - autoIndent: opts.autoIndent, - dragAndDrop: opts.dragAndDrop, - emptySelectionClipboard: opts.emptySelectionClipboard, - copyWithSyntaxHighlighting: opts.copyWithSyntaxHighlighting, - useTabStops: opts.useTabStops, - multiCursorModifier: opts.multiCursorModifier, - multiCursorMergeOverlapping: opts.multiCursorMergeOverlapping, - accessibilitySupport: opts.accessibilitySupport, - showUnused: opts.showUnused, - - viewInfo: { - extraEditorClassName: opts.viewInfo.extraEditorClassName, - disableMonospaceOptimizations: opts.viewInfo.disableMonospaceOptimizations, - rulers: opts.viewInfo.rulers, - ariaLabel: (accessibilityIsOff ? nls.localize('accessibilityOffAriaLabel', "The editor is not accessible at this time. Press Alt+F1 for options.") : opts.viewInfo.ariaLabel), - renderLineNumbers: opts.viewInfo.renderLineNumbers, - renderCustomLineNumbers: opts.viewInfo.renderCustomLineNumbers, - cursorSurroundingLines: opts.viewInfo.cursorSurroundingLines, - glyphMargin: opts.viewInfo.glyphMargin, - revealHorizontalRightPadding: opts.viewInfo.revealHorizontalRightPadding, - roundedSelection: opts.viewInfo.roundedSelection, - overviewRulerLanes: opts.viewInfo.overviewRulerLanes, - overviewRulerBorder: opts.viewInfo.overviewRulerBorder, - cursorBlinking: opts.viewInfo.cursorBlinking, - mouseWheelZoom: opts.viewInfo.mouseWheelZoom, - cursorSmoothCaretAnimation: opts.viewInfo.cursorSmoothCaretAnimation, - cursorStyle: opts.viewInfo.cursorStyle, - cursorWidth: opts.viewInfo.cursorWidth, - hideCursorInOverviewRuler: opts.viewInfo.hideCursorInOverviewRuler, - scrollBeyondLastLine: opts.viewInfo.scrollBeyondLastLine, - scrollBeyondLastColumn: opts.viewInfo.scrollBeyondLastColumn, - smoothScrolling: opts.viewInfo.smoothScrolling, - stopRenderingLineAfter: opts.viewInfo.stopRenderingLineAfter, - renderWhitespace: opts.viewInfo.renderWhitespace, - renderControlCharacters: opts.viewInfo.renderControlCharacters, - fontLigatures: opts.viewInfo.fontLigatures, - renderIndentGuides: opts.viewInfo.renderIndentGuides, - highlightActiveIndentGuide: opts.viewInfo.highlightActiveIndentGuide, - renderLineHighlight: opts.viewInfo.renderLineHighlight, - scrollbar: opts.viewInfo.scrollbar, - minimap: { - enabled: opts.viewInfo.minimap.enabled, - side: opts.viewInfo.minimap.side, - renderCharacters: opts.viewInfo.minimap.renderCharacters, - showSlider: opts.viewInfo.minimap.showSlider, - maxColumn: opts.viewInfo.minimap.maxColumn - }, - fixedOverflowWidgets: opts.viewInfo.fixedOverflowWidgets - }, - - contribInfo: { - hover: opts.contribInfo.hover, - links: opts.contribInfo.links, - contextmenu: opts.contribInfo.contextmenu, - quickSuggestions: opts.contribInfo.quickSuggestions, - quickSuggestionsDelay: opts.contribInfo.quickSuggestionsDelay, - parameterHints: opts.contribInfo.parameterHints, - formatOnType: opts.contribInfo.formatOnType, - formatOnPaste: opts.contribInfo.formatOnPaste, - suggestOnTriggerCharacters: opts.contribInfo.suggestOnTriggerCharacters, - acceptSuggestionOnEnter: opts.contribInfo.acceptSuggestionOnEnter, - acceptSuggestionOnCommitCharacter: opts.contribInfo.acceptSuggestionOnCommitCharacter, - wordBasedSuggestions: opts.contribInfo.wordBasedSuggestions, - suggestSelection: opts.contribInfo.suggestSelection, - suggestFontSize: opts.contribInfo.suggestFontSize, - suggestLineHeight: opts.contribInfo.suggestLineHeight, - tabCompletion: opts.contribInfo.tabCompletion, - suggest: opts.contribInfo.suggest, - gotoLocation: opts.contribInfo.gotoLocation, - selectionHighlight: opts.contribInfo.selectionHighlight, - occurrencesHighlight: opts.contribInfo.occurrencesHighlight, - codeLens: opts.contribInfo.codeLens, - folding: opts.contribInfo.folding, - foldingStrategy: opts.contribInfo.foldingStrategy, - showFoldingControls: opts.contribInfo.showFoldingControls, - matchBrackets: opts.contribInfo.matchBrackets, - find: opts.contribInfo.find, - colorDecorators: opts.contribInfo.colorDecorators, - lightbulbEnabled: opts.contribInfo.lightbulbEnabled, - codeActionsOnSave: opts.contribInfo.codeActionsOnSave, - codeActionsOnSaveTimeout: opts.contribInfo.codeActionsOnSaveTimeout - } - }; - } - - public static createInternalEditorOptions(env: IEnvironmentalOptions, _opts: IValidatedEditorOptions) { - - let accessibilitySupport: AccessibilitySupport; - if (_opts.accessibilitySupport === 'auto') { - // The editor reads the `accessibilitySupport` from the environment - accessibilitySupport = env.accessibilitySupport; - } else if (_opts.accessibilitySupport === 'on') { - accessibilitySupport = AccessibilitySupport.Enabled; - } else { - accessibilitySupport = AccessibilitySupport.Disabled; - } - - // Disable some non critical features to get as best performance as possible - // See https://github.com/Microsoft/vscode/issues/26730 - const opts = this._tweakValidatedOptions(_opts, accessibilitySupport); + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: undefined): EditorLayoutInfo { + const glyphMargin = options.get(EditorOptionId.glyphMargin); + const lineNumbersMinChars = options.get(EditorOptionId.lineNumbersMinChars); + const rawLineDecorationsWidth = options.get(EditorOptionId.lineDecorationsWidth); + const folding = options.get(EditorOptionId.folding); + const minimap = options.get(EditorOptionId.minimap); + const scrollbar = options.get(EditorOptionId.scrollbar); + const renderLineNumbers = options.get(EditorOptionId.renderLineNumbers); let lineDecorationsWidth: number; - if (typeof opts.lineDecorationsWidth === 'string' && /^\d+(\.\d+)?ch$/.test(opts.lineDecorationsWidth)) { - const multiple = parseFloat(opts.lineDecorationsWidth.substr(0, opts.lineDecorationsWidth.length - 2)); + if (typeof rawLineDecorationsWidth === 'string' && /^\d+(\.\d+)?ch$/.test(rawLineDecorationsWidth)) { + const multiple = parseFloat(rawLineDecorationsWidth.substr(0, rawLineDecorationsWidth.length - 2)); lineDecorationsWidth = multiple * env.fontInfo.typicalHalfwidthCharacterWidth; } else { - lineDecorationsWidth = _clampedInt(opts.lineDecorationsWidth, 0, 0, 1000); + lineDecorationsWidth = _clampedInt(rawLineDecorationsWidth, 0, 0, 1000); } - if (opts.contribInfo.folding) { + if (folding) { lineDecorationsWidth += 16; } - const layoutInfo = EditorLayoutProvider.compute({ + return EditorLayoutInfoComputer.compute({ outerWidth: env.outerWidth, outerHeight: env.outerHeight, - showGlyphMargin: opts.viewInfo.glyphMargin, + showGlyphMargin: glyphMargin, lineHeight: env.fontInfo.lineHeight, - showLineNumbers: (opts.viewInfo.renderLineNumbers !== RenderLineNumbersType.Off), - lineNumbersMinChars: opts.lineNumbersMinChars, + showLineNumbers: (renderLineNumbers.renderType !== RenderLineNumbersType.Off), + lineNumbersMinChars: lineNumbersMinChars, lineNumbersDigitCount: env.lineNumbersDigitCount, lineDecorationsWidth: lineDecorationsWidth, typicalHalfwidthCharacterWidth: env.fontInfo.typicalHalfwidthCharacterWidth, maxDigitWidth: env.fontInfo.maxDigitWidth, - verticalScrollbarWidth: opts.viewInfo.scrollbar.verticalScrollbarSize, - horizontalScrollbarHeight: opts.viewInfo.scrollbar.horizontalScrollbarSize, - scrollbarArrowSize: opts.viewInfo.scrollbar.arrowSize, - verticalScrollbarHasArrows: opts.viewInfo.scrollbar.verticalHasArrows, - minimap: opts.viewInfo.minimap.enabled, - minimapSide: opts.viewInfo.minimap.side, - minimapRenderCharacters: opts.viewInfo.minimap.renderCharacters, - minimapMaxColumn: opts.viewInfo.minimap.maxColumn, + verticalScrollbarWidth: scrollbar.verticalScrollbarSize, + horizontalScrollbarHeight: scrollbar.horizontalScrollbarSize, + scrollbarArrowSize: scrollbar.arrowSize, + verticalScrollbarHasArrows: scrollbar.verticalHasArrows, + minimap: minimap.enabled, + minimapSide: minimap.side, + minimapRenderCharacters: minimap.renderCharacters, + minimapMaxColumn: minimap.maxColumn, pixelRatio: env.pixelRatio }); - - let bareWrappingInfo: { isWordWrapMinified: boolean; isViewportWrapping: boolean; wrappingColumn: number; } | null = null; - { - const wordWrap = opts.wordWrap; - const wordWrapColumn = opts.wordWrapColumn; - const wordWrapMinified = opts.wordWrapMinified; - - if (accessibilitySupport === AccessibilitySupport.Enabled) { - // See https://github.com/Microsoft/vscode/issues/27766 - // Never enable wrapping when a screen reader is attached - // because arrow down etc. will not move the cursor in the way - // a screen reader expects. - bareWrappingInfo = { - isWordWrapMinified: false, - isViewportWrapping: false, - wrappingColumn: -1 - }; - } else if (wordWrapMinified && env.isDominatedByLongLines) { - // Force viewport width wrapping if model is dominated by long lines - bareWrappingInfo = { - isWordWrapMinified: true, - isViewportWrapping: true, - wrappingColumn: Math.max(1, layoutInfo.viewportColumn) - }; - } else if (wordWrap === 'on') { - bareWrappingInfo = { - isWordWrapMinified: false, - isViewportWrapping: true, - wrappingColumn: Math.max(1, layoutInfo.viewportColumn) - }; - } else if (wordWrap === 'bounded') { - bareWrappingInfo = { - isWordWrapMinified: false, - isViewportWrapping: true, - wrappingColumn: Math.min(Math.max(1, layoutInfo.viewportColumn), wordWrapColumn) - }; - } else if (wordWrap === 'wordWrapColumn') { - bareWrappingInfo = { - isWordWrapMinified: false, - isViewportWrapping: false, - wrappingColumn: wordWrapColumn - }; - } else { - bareWrappingInfo = { - isWordWrapMinified: false, - isViewportWrapping: false, - wrappingColumn: -1 - }; - } - } - - const wrappingInfo: EditorWrappingInfo = { - inDiffEditor: opts.inDiffEditor, - isDominatedByLongLines: env.isDominatedByLongLines, - isWordWrapMinified: bareWrappingInfo.isWordWrapMinified, - isViewportWrapping: bareWrappingInfo.isViewportWrapping, - wrappingColumn: bareWrappingInfo.wrappingColumn, - wrappingIndent: opts.wrappingIndent, - wordWrapBreakBeforeCharacters: opts.wordWrapBreakBeforeCharacters, - wordWrapBreakAfterCharacters: opts.wordWrapBreakAfterCharacters, - wordWrapBreakObtrusiveCharacters: opts.wordWrapBreakObtrusiveCharacters, - }; - - let className = 'monaco-editor'; - if (opts.viewInfo.extraEditorClassName) { - className += ' ' + opts.viewInfo.extraEditorClassName; - } - if (env.extraEditorClassName) { - className += ' ' + env.extraEditorClassName; - } - if (opts.viewInfo.fontLigatures) { - className += ' enable-ligatures'; - } - if (opts.mouseStyle === 'default') { - className += ' mouse-default'; - } else if (opts.mouseStyle === 'copy') { - className += ' mouse-copy'; - } - - return new InternalEditorOptions({ - canUseLayerHinting: opts.disableLayerHinting ? false : true, - pixelRatio: env.pixelRatio, - editorClassName: className, - lineHeight: env.fontInfo.lineHeight, - readOnly: opts.readOnly, - accessibilitySupport: accessibilitySupport, - multiCursorModifier: opts.multiCursorModifier, - multiCursorMergeOverlapping: opts.multiCursorMergeOverlapping, - wordSeparators: opts.wordSeparators, - autoClosingBrackets: opts.autoClosingBrackets, - autoClosingQuotes: opts.autoClosingQuotes, - autoClosingOvertype: opts.autoClosingOvertype, - autoSurround: opts.autoSurround, - autoIndent: opts.autoIndent, - useTabStops: opts.useTabStops, - tabFocusMode: opts.readOnly ? true : env.tabFocusMode, - dragAndDrop: opts.dragAndDrop, - emptySelectionClipboard: opts.emptySelectionClipboard && env.emptySelectionClipboard, - copyWithSyntaxHighlighting: opts.copyWithSyntaxHighlighting, - layoutInfo: layoutInfo, - fontInfo: env.fontInfo, - viewInfo: opts.viewInfo, - wrappingInfo: wrappingInfo, - contribInfo: opts.contribInfo, - showUnused: opts.showUnused, - }); } -} + public equals(a: EditorLayoutInfo, b: EditorLayoutInfo): boolean { + return ( + a.width === b.width + && a.height === b.height + && a.glyphMarginLeft === b.glyphMarginLeft + && a.glyphMarginWidth === b.glyphMarginWidth + && a.glyphMarginHeight === b.glyphMarginHeight + && a.lineNumbersLeft === b.lineNumbersLeft + && a.lineNumbersWidth === b.lineNumbersWidth + && a.lineNumbersHeight === b.lineNumbersHeight + && a.decorationsLeft === b.decorationsLeft + && a.decorationsWidth === b.decorationsWidth + && a.decorationsHeight === b.decorationsHeight + && a.contentLeft === b.contentLeft + && a.contentWidth === b.contentWidth + && a.contentHeight === b.contentHeight + && a.renderMinimap === b.renderMinimap + && a.minimapLeft === b.minimapLeft + && a.minimapWidth === b.minimapWidth + && a.viewportColumn === b.viewportColumn + && a.verticalScrollbarWidth === b.verticalScrollbarWidth + && a.horizontalScrollbarHeight === b.horizontalScrollbarHeight + && EditorLayoutInfoComputer._equalsOverviewRuler(a.overviewRuler, b.overviewRuler) + ); + } -/** - * @internal - */ -export interface IEditorLayoutProviderOpts { - readonly outerWidth: number; - readonly outerHeight: number; + /** + * @internal + */ + private static _equalsOverviewRuler(a: OverviewRulerPosition, b: OverviewRulerPosition): boolean { + return ( + a.width === b.width + && a.height === b.height + && a.top === b.top + && a.right === b.right + ); + } - readonly showGlyphMargin: boolean; - readonly lineHeight: number; - - readonly showLineNumbers: boolean; - readonly lineNumbersMinChars: number; - readonly lineNumbersDigitCount: number; - - readonly lineDecorationsWidth: number; - - readonly typicalHalfwidthCharacterWidth: number; - readonly maxDigitWidth: number; - - readonly verticalScrollbarWidth: number; - readonly verticalScrollbarHasArrows: boolean; - readonly scrollbarArrowSize: number; - readonly horizontalScrollbarHeight: number; - - readonly minimap: boolean; - readonly minimapSide: string; - readonly minimapRenderCharacters: boolean; - readonly minimapMaxColumn: number; - readonly pixelRatio: number; -} - -/** - * @internal - */ -export class EditorLayoutProvider { public static compute(_opts: IEditorLayoutProviderOpts): EditorLayoutInfo { const outerWidth = _opts.outerWidth | 0; const outerHeight = _opts.outerHeight | 0; @@ -2588,300 +2692,169 @@ export class EditorLayoutProvider { } } -const DEFAULT_WINDOWS_FONT_FAMILY = 'Consolas, \'Courier New\', monospace'; -const DEFAULT_MAC_FONT_FAMILY = 'Menlo, Monaco, \'Courier New\', monospace'; -const DEFAULT_LINUX_FONT_FAMILY = '\'Droid Sans Mono\', \'monospace\', monospace, \'Droid Sans Fallback\''; +//#endregion -/** - * @internal - */ -export const EDITOR_FONT_DEFAULTS = { - fontFamily: ( - platform.isMacintosh ? DEFAULT_MAC_FONT_FAMILY : (platform.isLinux ? DEFAULT_LINUX_FONT_FAMILY : DEFAULT_WINDOWS_FONT_FAMILY) - ), - fontWeight: 'normal', - fontSize: ( - platform.isMacintosh ? 12 : 14 - ), - lineHeight: 0, - letterSpacing: 0, -}; +//#region wrappingInfo -/** - * @internal - */ -export const EDITOR_MODEL_DEFAULTS = { - tabSize: 4, - indentSize: 4, - insertSpaces: true, - detectIndentation: true, - trimAutoWhitespace: true, - largeFileOptimizations: true -}; - -/** - * @internal - */ -export const EDITOR_DEFAULTS: IValidatedEditorOptions = { - inDiffEditor: false, - wordSeparators: USUAL_WORD_SEPARATORS, - lineNumbersMinChars: 5, - lineDecorationsWidth: 10, - readOnly: false, - mouseStyle: 'text', - disableLayerHinting: false, - automaticLayout: false, - wordWrap: 'off', - wordWrapColumn: 80, - wordWrapMinified: true, - wrappingIndent: WrappingIndent.Same, - wordWrapBreakBeforeCharacters: '([{‘“〈《「『【〔([{「£¥$£¥++', - wordWrapBreakAfterCharacters: ' \t})]?|/&,;¢°′″‰℃、。。、¢,.:;?!%・・ゝゞヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻ァィゥェォャュョッー”〉》」』】〕)]}」', - wordWrapBreakObtrusiveCharacters: '.', - autoClosingBrackets: 'languageDefined', - autoClosingQuotes: 'languageDefined', - autoClosingOvertype: 'auto', - autoSurround: 'languageDefined', - autoIndent: true, - dragAndDrop: true, - emptySelectionClipboard: true, - copyWithSyntaxHighlighting: true, - useTabStops: true, - multiCursorModifier: 'altKey', - multiCursorMergeOverlapping: true, - accessibilitySupport: 'auto', - showUnused: true, - - viewInfo: { - extraEditorClassName: '', - disableMonospaceOptimizations: false, - rulers: [], - ariaLabel: nls.localize('editorViewAccessibleLabel', "Editor content"), - renderLineNumbers: RenderLineNumbersType.On, - renderCustomLineNumbers: null, - cursorSurroundingLines: 0, - glyphMargin: true, - revealHorizontalRightPadding: 30, - roundedSelection: true, - overviewRulerLanes: 2, - overviewRulerBorder: true, - cursorBlinking: TextEditorCursorBlinkingStyle.Blink, - mouseWheelZoom: false, - cursorSmoothCaretAnimation: false, - cursorStyle: TextEditorCursorStyle.Line, - cursorWidth: 0, - hideCursorInOverviewRuler: false, - scrollBeyondLastLine: true, - scrollBeyondLastColumn: 5, - smoothScrolling: false, - stopRenderingLineAfter: 10000, - renderWhitespace: 'none', - renderControlCharacters: false, - fontLigatures: false, - renderIndentGuides: true, - highlightActiveIndentGuide: true, - renderLineHighlight: 'line', - scrollbar: { - vertical: ScrollbarVisibility.Auto, - horizontal: ScrollbarVisibility.Auto, - arrowSize: 11, - useShadows: true, - verticalHasArrows: false, - horizontalHasArrows: false, - horizontalScrollbarSize: 10, - horizontalSliderSize: 10, - verticalScrollbarSize: 14, - verticalSliderSize: 14, - handleMouseWheel: true, - mouseWheelScrollSensitivity: 1, - fastScrollSensitivity: 5, - }, - minimap: { - enabled: true, - side: 'right', - showSlider: 'mouseover', - renderCharacters: true, - maxColumn: 120 - }, - fixedOverflowWidgets: false, - }, - - contribInfo: { - hover: { - enabled: true, - delay: 300, - sticky: true - }, - links: true, - contextmenu: true, - quickSuggestions: { other: true, comments: false, strings: false }, - quickSuggestionsDelay: 10, - parameterHints: { - enabled: true, - cycle: false - }, - formatOnType: false, - formatOnPaste: false, - suggestOnTriggerCharacters: true, - acceptSuggestionOnEnter: 'on', - acceptSuggestionOnCommitCharacter: true, - wordBasedSuggestions: true, - suggestSelection: 'recentlyUsed', - suggestFontSize: 0, - suggestLineHeight: 0, - tabCompletion: 'off', - suggest: { - filterGraceful: true, - snippets: 'inline', - snippetsPreventQuickSuggestions: true, - localityBonus: false, - shareSuggestSelections: false, - showIcons: true, - maxVisibleSuggestions: 12, - filteredTypes: Object.create(null) - }, - gotoLocation: { - multiple: 'peek' - }, - selectionHighlight: true, - occurrencesHighlight: true, - codeLens: true, - folding: true, - foldingStrategy: 'auto', - showFoldingControls: 'mouseover', - matchBrackets: true, - find: { - seedSearchStringFromSelection: true, - autoFindInSelection: false, - globalFindClipboard: false, - addExtraSpaceOnTop: true - }, - colorDecorators: true, - lightbulbEnabled: true, - codeActionsOnSave: {}, - codeActionsOnSaveTimeout: 750 - }, -}; - -export interface IRawEditorOptionsBag { - [key: string]: any; +export interface EditorWrappingInfo { + readonly isDominatedByLongLines: boolean; + readonly isWordWrapMinified: boolean; + readonly isViewportWrapping: boolean; + readonly wrappingColumn: number; } -/** - * @internal - */ -export class RawEditorOptions { - private readonly _values: any[] = []; - public _read(id: EditorOptionId): T | undefined { - return this._values[id]; +class EditorWrappingInfoComputer extends BaseEditorOption { + public mix(a: undefined, b: undefined): undefined { + return undefined; } - public _write(id: EditorOptionId, value: T | undefined): void { - this._values[id] = value; + public validate(input: undefined): undefined { + return undefined; + } + public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: undefined): EditorWrappingInfo { + const wordWrap = options.get(EditorOptionId.wordWrap); + const wordWrapColumn = options.get(EditorOptionId.wordWrapColumn); + const wordWrapMinified = options.get(EditorOptionId.wordWrapMinified); + const layoutInfo = options.get(EditorOptionId.layoutInfo); + const accessibilitySupport = options.get(EditorOptionId.accessibilitySupport); + + let bareWrappingInfo: { isWordWrapMinified: boolean; isViewportWrapping: boolean; wrappingColumn: number; } | null = null; + { + if (accessibilitySupport === AccessibilitySupport.Enabled) { + // See https://github.com/Microsoft/vscode/issues/27766 + // Never enable wrapping when a screen reader is attached + // because arrow down etc. will not move the cursor in the way + // a screen reader expects. + bareWrappingInfo = { + isWordWrapMinified: false, + isViewportWrapping: false, + wrappingColumn: -1 + }; + } else if (wordWrapMinified && env.isDominatedByLongLines) { + // Force viewport width wrapping if model is dominated by long lines + bareWrappingInfo = { + isWordWrapMinified: true, + isViewportWrapping: true, + wrappingColumn: Math.max(1, layoutInfo.viewportColumn) + }; + } else if (wordWrap === 'on') { + bareWrappingInfo = { + isWordWrapMinified: false, + isViewportWrapping: true, + wrappingColumn: Math.max(1, layoutInfo.viewportColumn) + }; + } else if (wordWrap === 'bounded') { + bareWrappingInfo = { + isWordWrapMinified: false, + isViewportWrapping: true, + wrappingColumn: Math.min(Math.max(1, layoutInfo.viewportColumn), wordWrapColumn) + }; + } else if (wordWrap === 'wordWrapColumn') { + bareWrappingInfo = { + isWordWrapMinified: false, + isViewportWrapping: false, + wrappingColumn: wordWrapColumn + }; + } else { + bareWrappingInfo = { + isWordWrapMinified: false, + isViewportWrapping: false, + wrappingColumn: -1 + }; + } + } + + return { + isDominatedByLongLines: env.isDominatedByLongLines, + isWordWrapMinified: bareWrappingInfo.isWordWrapMinified, + isViewportWrapping: bareWrappingInfo.isViewportWrapping, + wrappingColumn: bareWrappingInfo.wrappingColumn, + }; + } + public equals(a: EditorWrappingInfo, b: EditorWrappingInfo): boolean { + return ( + a.isDominatedByLongLines === b.isDominatedByLongLines + && a.isWordWrapMinified === b.isWordWrapMinified + && a.isViewportWrapping === b.isViewportWrapping + && a.wrappingColumn === b.wrappingColumn + ); } } -/** - * @internal - */ -export class ValidatedEditorOptions { - private readonly _values: any[] = []; - public _read(option: EditorOptionId): T { - return this._values[option]; - } - public _write(option: EditorOptionId, value: T): void { - this._values[option] = value; - } -} - -/** - * @internal - */ -export class ComputedEditorOptions { - private readonly _values: any[] = []; - public _read(id: EditorOptionId): T { - return this._values[id]; - } - public _write(id: EditorOptionId, value: T): void { - this._values[id] = value; - } -} - -/** - * @internal - */ -export class ChangedEditorOptions { - private readonly _values: boolean[] = []; - public get(id: EditorOptionId): boolean { - return this._values[id]; - } - public _write(id: EditorOptionId, value: boolean): void { - this._values[id] = value; - } -} - -export interface IEditorOption { - readonly id: EditorOptionId; - readonly name: string; - readonly defaultValue: T1; - read(options: IRawEditorOptionsBag): T1 | undefined; - mix(a: T1 | undefined, b: T1 | undefined): T1 | undefined; - validate(input: T1 | undefined): T2; - compute(value: T2): T3; - equals(a: T3, b: T3): boolean; -} - -class BooleanEditorOption implements IEditorOption { - public readonly id: EditorOptionId; - public readonly name: string; - public readonly defaultValue: boolean; - - constructor(id: EditorOptionId, name: string, defaultValue: boolean) { - this.id = id; - this.name = name; - this.defaultValue = defaultValue; - } - - public read(options: IRawEditorOptionsBag): boolean | undefined { - return options[this.name]; - } - - public mix(a: boolean | undefined, b: boolean | undefined): boolean | undefined { - return (typeof b !== 'undefined' ? b : a); - } - - public validate(input: boolean | undefined): boolean { - return _boolean(input, this.defaultValue); - } - - public compute(value: boolean): boolean { - return value; - } - - public equals(a: boolean, b: boolean): boolean { - return (a === b); - } -} - -/** - * @internal - */ -export const editorOptionsRegistry: IEditorOption[] = []; - -function registerEditorOption(option: IEditorOption): IEditorOption { - editorOptionsRegistry[option.id] = option; - return option; -} +//#endregion export const enum EditorOptionId { + accessibilitySupport, + ariaLabel, + fastScrollSensitivity, + folding, + glyphMargin, + inDiffEditor, + lineDecorationsWidth, + lineNumbersMinChars, + minimap, + mouseWheelScrollSensitivity, renderFinalNewline, + renderLineNumbers, + scrollbar, selectionClipboard, selectOnLineNumbers, + wordWrap, + wordWrapBreakAfterCharacters, + wordWrapBreakBeforeCharacters, + wordWrapBreakObtrusiveCharacters, + wordWrapColumn, + wordWrapMinified, + wrappingIndent, + + layoutInfo, + wrappingInfo, } export const EditorOption = { - renderFinalNewline: registerEditorOption(new BooleanEditorOption(EditorOptionId.renderFinalNewline, 'renderFinalNewline', true)), - selectionClipboard: registerEditorOption(new BooleanEditorOption(EditorOptionId.selectionClipboard, 'selectionClipboard', true)), - selectOnLineNumbers: registerEditorOption(new BooleanEditorOption(EditorOptionId.selectOnLineNumbers, 'selectOnLineNumbers', true)), + accessibilitySupport: registerEditorOption(new EditorAccessibilitySupportOption(EditorOptionId.accessibilitySupport, 'accessibilitySupport', 'auto')), + ariaLabel: registerEditorOption(new EditorAriaLabel(EditorOptionId.ariaLabel, 'ariaLabel', nls.localize('editorViewAccessibleLabel', "Editor content"), [EditorOptionId.accessibilitySupport])), + fastScrollSensitivity: registerEditorOption(new EditorFloatOption(EditorOptionId.fastScrollSensitivity, 'fastScrollSensitivity', 5, x => (x <= 0 ? 5 : x))), + folding: registerEditorOption(new EditorBooleanOption(EditorOptionId.folding, 'folding', true)), + glyphMargin: registerEditorOption(new EditorBooleanOption(EditorOptionId.glyphMargin, 'glyphMargin', true)), + inDiffEditor: registerEditorOption(new EditorBooleanOption(EditorOptionId.inDiffEditor, 'inDiffEditor', false)), + lineDecorationsWidth: registerEditorOption(new EditorPassthroughOption(EditorOptionId.lineDecorationsWidth, 'lineDecorationsWidth', 10)), + lineNumbersMinChars: registerEditorOption(new EditorIntOption(EditorOptionId.lineNumbersMinChars, 'lineNumbersMinChars', 5, 1, 10)), + minimap: registerEditorOption(new EditorMinimapOption(EditorOptionId.minimap, 'minimap', { + enabled: true, + side: 'right', + showSlider: 'mouseover', + renderCharacters: true, + maxColumn: 120, + })), + mouseWheelScrollSensitivity: registerEditorOption(new EditorFloatOption(EditorOptionId.mouseWheelScrollSensitivity, 'mouseWheelScrollSensitivity', 1, x => (x === 0 ? 1 : x))), + renderFinalNewline: registerEditorOption(new EditorBooleanOption(EditorOptionId.renderFinalNewline, 'renderFinalNewline', true)), + renderLineNumbers: registerEditorOption(new EditorRenderLineNumbersOption(EditorOptionId.renderLineNumbers, 'lineNumbers', { renderType: RenderLineNumbersType.On, renderFn: null })), + scrollbar: registerEditorOption(new EditorScrollbarOption(EditorOptionId.scrollbar, 'scrollbar', { + vertical: ScrollbarVisibility.Auto, + horizontal: ScrollbarVisibility.Auto, + arrowSize: 11, + useShadows: true, + verticalHasArrows: false, + horizontalHasArrows: false, + horizontalScrollbarSize: 10, + horizontalSliderSize: 10, + verticalScrollbarSize: 14, + verticalSliderSize: 14, + handleMouseWheel: true, + })), + selectionClipboard: registerEditorOption(new EditorBooleanOption(EditorOptionId.selectionClipboard, 'selectionClipboard', true)), + selectOnLineNumbers: registerEditorOption(new EditorBooleanOption(EditorOptionId.selectOnLineNumbers, 'selectOnLineNumbers', true)), + wordWrap: registerEditorOption(new EditorEnumOption<'off' | 'on' | 'wordWrapColumn' | 'bounded'>(EditorOptionId.wordWrap, 'wordWrap', 'off', ['off', 'on', 'wordWrapColumn', 'bounded'], x => x)), + wordWrapBreakAfterCharacters: registerEditorOption(new EditorStringOption(EditorOptionId.wordWrapBreakAfterCharacters, 'wordWrapBreakAfterCharacters', ' \t})]?|/&,;¢°′″‰℃、。。、¢,.:;?!%・・ゝゞヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻ァィゥェォャュョッー”〉》」』】〕)]}」')), + wordWrapBreakBeforeCharacters: registerEditorOption(new EditorStringOption(EditorOptionId.wordWrapBreakBeforeCharacters, 'wordWrapBreakBeforeCharacters', '([{‘“〈《「『【〔([{「£¥$£¥++')), + wordWrapBreakObtrusiveCharacters: registerEditorOption(new EditorStringOption(EditorOptionId.wordWrapBreakObtrusiveCharacters, 'wordWrapBreakObtrusiveCharacters', '.')), + wordWrapColumn: registerEditorOption(new EditorIntOption(EditorOptionId.wordWrapColumn, 'wordWrapColumn', 80, 1, Constants.MAX_SAFE_SMALL_INTEGER)), + wordWrapMinified: registerEditorOption(new EditorBooleanOption(EditorOptionId.wordWrapMinified, 'wordWrapMinified', true)), + wrappingIndent: registerEditorOption(new EditorEnumOption<'none' | 'same' | 'indent' | 'deepIndent', WrappingIndent>(EditorOptionId.wrappingIndent, 'wrappingIndent', 'same', ['none', 'same', 'indent', 'deepIndent'], _wrappingIndentFromString)), + + // Leave these at the end! + layoutInfo: registerEditorOption(new EditorLayoutInfoComputer(EditorOptionId.layoutInfo, 'layoutInfo', undefined, [EditorOptionId.glyphMargin, EditorOptionId.lineDecorationsWidth, EditorOptionId.folding, EditorOptionId.minimap, EditorOptionId.scrollbar, EditorOptionId.renderLineNumbers])), + wrappingInfo: registerEditorOption(new EditorWrappingInfoComputer(EditorOptionId.wrappingInfo, 'wrappingInfo', undefined, [EditorOptionId.wordWrap, EditorOptionId.wordWrapColumn, EditorOptionId.wordWrapMinified, EditorOptionId.layoutInfo, EditorOptionId.accessibilitySupport])), }; export type ComputedEditorOptionValue> = T extends IEditorOption ? R : never; diff --git a/src/vs/editor/common/controller/cursorCommon.ts b/src/vs/editor/common/controller/cursorCommon.ts index 87c3878b61c..80775a63bd2 100644 --- a/src/vs/editor/common/controller/cursorCommon.ts +++ b/src/vs/editor/common/controller/cursorCommon.ts @@ -6,7 +6,7 @@ import { CharCode } from 'vs/base/common/charCode'; import { onUnexpectedError } from 'vs/base/common/errors'; import * as strings from 'vs/base/common/strings'; -import { EditorAutoClosingStrategy, EditorAutoSurroundStrategy, IConfigurationChangedEvent, EditorAutoClosingOvertypeStrategy } from 'vs/editor/common/config/editorOptions'; +import { EditorAutoClosingStrategy, EditorAutoSurroundStrategy, IConfigurationChangedEvent, EditorAutoClosingOvertypeStrategy, EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; import { CursorChangeReason } from 'vs/editor/common/controller/cursorEvents'; import { Position } from 'vs/editor/common/core/position'; import { Range } from 'vs/editor/common/core/range'; @@ -112,7 +112,7 @@ export class CursorConfiguration { public static shouldRecreate(e: IConfigurationChangedEvent): boolean { return ( - e.layoutInfo + e.hasChanged(EditorOptionId.layoutInfo) || e.wordSeparators || e.emptySelectionClipboard || e.multiCursorMergeOverlapping @@ -133,13 +133,15 @@ export class CursorConfiguration { ) { this._languageIdentifier = languageIdentifier; - let c = configuration.editor; + const c = configuration.editor; + const options = configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); this.readOnly = c.readOnly; this.tabSize = modelOptions.tabSize; this.indentSize = modelOptions.indentSize; this.insertSpaces = modelOptions.insertSpaces; - this.pageSize = Math.max(1, Math.floor(c.layoutInfo.height / c.fontInfo.lineHeight) - 2); + this.pageSize = Math.max(1, Math.floor(layoutInfo.height / c.fontInfo.lineHeight) - 2); this.lineHeight = c.lineHeight; this.useTabStops = c.useTabStops; this.wordSeparators = c.wordSeparators; diff --git a/src/vs/editor/common/editorCommon.ts b/src/vs/editor/common/editorCommon.ts index f070525b99b..6c954159234 100644 --- a/src/vs/editor/common/editorCommon.ts +++ b/src/vs/editor/common/editorCommon.ts @@ -152,8 +152,7 @@ export interface IConfiguration extends IDisposable { onDidChange(listener: (e: editorOptions.IConfigurationChangedEvent) => void): IDisposable; readonly editor: editorOptions.InternalEditorOptions; - - getOption>(id: editorOptions.EditorOptionId): editorOptions.ComputedEditorOptionValue; + readonly options: editorOptions.IComputedEditorOptions; setMaxLineNumber(maxLineNumber: number): void; updateOptions(newOptions: editorOptions.IEditorOptions): void; diff --git a/src/vs/editor/common/standalone/standaloneEnums.ts b/src/vs/editor/common/standalone/standaloneEnums.ts index 1af333dd0a4..d3b4118c433 100644 --- a/src/vs/editor/common/standalone/standaloneEnums.ts +++ b/src/vs/editor/common/standalone/standaloneEnums.ts @@ -332,6 +332,15 @@ export enum CursorChangeReason { Redo = 6 } +export enum AccessibilitySupport { + /** + * This should be the browser case where it is not known if a screen reader is attached or no. + */ + Unknown = 0, + Disabled = 1, + Enabled = 2 +} + export enum RenderMinimap { None = 0, Small = 1, @@ -431,9 +440,30 @@ export enum RenderLineNumbersType { } export enum EditorOptionId { - renderFinalNewline = 0, - selectionClipboard = 1, - selectOnLineNumbers = 2 + accessibilitySupport = 0, + ariaLabel = 1, + fastScrollSensitivity = 2, + folding = 3, + glyphMargin = 4, + inDiffEditor = 5, + lineDecorationsWidth = 6, + lineNumbersMinChars = 7, + minimap = 8, + mouseWheelScrollSensitivity = 9, + renderFinalNewline = 10, + renderLineNumbers = 11, + scrollbar = 12, + selectionClipboard = 13, + selectOnLineNumbers = 14, + wordWrap = 15, + wordWrapBreakAfterCharacters = 16, + wordWrapBreakBeforeCharacters = 17, + wordWrapBreakObtrusiveCharacters = 18, + wordWrapColumn = 19, + wordWrapMinified = 20, + wrappingIndent = 21, + layoutInfo = 22, + wrappingInfo = 23 } /** diff --git a/src/vs/editor/common/view/viewEvents.ts b/src/vs/editor/common/view/viewEvents.ts index 962579d3f0f..47006636def 100644 --- a/src/vs/editor/common/view/viewEvents.ts +++ b/src/vs/editor/common/view/viewEvents.ts @@ -6,7 +6,7 @@ import * as errors from 'vs/base/common/errors'; import { Disposable, IDisposable, toDisposable } from 'vs/base/common/lifecycle'; import { ScrollEvent } from 'vs/base/common/scrollable'; -import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions'; +import { IConfigurationChangedEvent, EditorOptionId } from 'vs/editor/common/config/editorOptions'; import { Range } from 'vs/editor/common/core/range'; import { Selection } from 'vs/editor/common/core/selection'; import { ScrollType } from 'vs/editor/common/editorCommon'; @@ -34,32 +34,32 @@ export class ViewConfigurationChangedEvent { public readonly type = ViewEventType.ViewConfigurationChanged; + public readonly _source: IConfigurationChangedEvent; public readonly canUseLayerHinting: boolean; public readonly pixelRatio: boolean; public readonly editorClassName: boolean; public readonly lineHeight: boolean; public readonly readOnly: boolean; - public readonly accessibilitySupport: boolean; public readonly emptySelectionClipboard: boolean; public readonly copyWithSyntaxHighlighting: boolean; - public readonly layoutInfo: boolean; public readonly fontInfo: boolean; public readonly viewInfo: boolean; - public readonly wrappingInfo: boolean; constructor(source: IConfigurationChangedEvent) { + this._source = source; this.canUseLayerHinting = source.canUseLayerHinting; this.pixelRatio = source.pixelRatio; this.editorClassName = source.editorClassName; this.lineHeight = source.lineHeight; this.readOnly = source.readOnly; - this.accessibilitySupport = source.accessibilitySupport; this.emptySelectionClipboard = source.emptySelectionClipboard; this.copyWithSyntaxHighlighting = source.copyWithSyntaxHighlighting; - this.layoutInfo = source.layoutInfo; this.fontInfo = source.fontInfo; this.viewInfo = source.viewInfo; - this.wrappingInfo = source.wrappingInfo; + } + + public hasChanged(id: EditorOptionId): boolean { + return this._source.hasChanged(id); } } diff --git a/src/vs/editor/common/viewLayout/viewLayout.ts b/src/vs/editor/common/viewLayout/viewLayout.ts index ad24479b4b2..978aa54a3bb 100644 --- a/src/vs/editor/common/viewLayout/viewLayout.ts +++ b/src/vs/editor/common/viewLayout/viewLayout.ts @@ -6,7 +6,7 @@ import { Event } from 'vs/base/common/event'; import { Disposable, IDisposable } from 'vs/base/common/lifecycle'; import { IScrollDimensions, IScrollPosition, ScrollEvent, Scrollable, ScrollbarVisibility } from 'vs/base/common/scrollable'; -import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions'; +import { IConfigurationChangedEvent, EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; import * as editorCommon from 'vs/editor/common/editorCommon'; import { LinesLayout } from 'vs/editor/common/viewLayout/linesLayout'; import { IPartialViewLinesViewportData } from 'vs/editor/common/viewLayout/viewLinesViewportData'; @@ -27,14 +27,17 @@ export class ViewLayout extends Disposable implements IViewLayout { super(); this._configuration = configuration; + const options = this._configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); + this._linesLayout = new LinesLayout(lineCount, this._configuration.editor.lineHeight); this.scrollable = this._register(new Scrollable(0, scheduleAtNextAnimationFrame)); this._configureSmoothScrollDuration(); this.scrollable.setScrollDimensions({ - width: configuration.editor.layoutInfo.contentWidth, - height: configuration.editor.layoutInfo.contentHeight + width: layoutInfo.contentWidth, + height: layoutInfo.contentHeight }); this.onDidScroll = this.scrollable.onScroll; @@ -59,10 +62,12 @@ export class ViewLayout extends Disposable implements IViewLayout { if (e.lineHeight) { this._linesLayout.setLineHeight(this._configuration.editor.lineHeight); } - if (e.layoutInfo) { + if (e.hasChanged(EditorOptionId.layoutInfo)) { + const options = this._configuration.options; + const layoutInfo = options.get(EditorOptionId.layoutInfo); this.scrollable.setScrollDimensions({ - width: this._configuration.editor.layoutInfo.contentWidth, - height: this._configuration.editor.layoutInfo.contentHeight + width: layoutInfo.contentWidth, + height: layoutInfo.contentHeight }); } if (e.viewInfo) { @@ -83,7 +88,9 @@ export class ViewLayout extends Disposable implements IViewLayout { // ---- end view event handlers private _getHorizontalScrollbarHeight(scrollDimensions: IScrollDimensions): number { - if (this._configuration.editor.viewInfo.scrollbar.horizontal === ScrollbarVisibility.Hidden) { + const options = this._configuration.options; + const scrollbar = options.get(EditorOptionId.scrollbar); + if (scrollbar.horizontal === ScrollbarVisibility.Hidden) { // horizontal scrollbar not visible return 0; } @@ -91,7 +98,7 @@ export class ViewLayout extends Disposable implements IViewLayout { // horizontal scrollbar not visible return 0; } - return this._configuration.editor.viewInfo.scrollbar.horizontalScrollbarSize; + return scrollbar.horizontalScrollbarSize; } private _getTotalHeight(): number { @@ -138,7 +145,9 @@ export class ViewLayout extends Disposable implements IViewLayout { } private _computeScrollWidth(maxLineWidth: number, viewportWidth: number): number { - let isViewportWrapping = this._configuration.editor.wrappingInfo.isViewportWrapping; + const options = this._configuration.options; + const wrappingInfo = options.get(EditorOptionId.wrappingInfo); + let isViewportWrapping = wrappingInfo.isViewportWrapping; if (!isViewportWrapping) { const extraHorizontalSpace = this._configuration.editor.viewInfo.scrollBeyondLastColumn * this._configuration.editor.fontInfo.typicalHalfwidthCharacterWidth; const whitespaceMinWidth = this._linesLayout.getWhitespaceMinWidth(); diff --git a/src/vs/editor/common/viewModel/viewModelImpl.ts b/src/vs/editor/common/viewModel/viewModelImpl.ts index 65284147a64..73350e18214 100644 --- a/src/vs/editor/common/viewModel/viewModelImpl.ts +++ b/src/vs/editor/common/viewModel/viewModelImpl.ts @@ -6,7 +6,7 @@ import { Color } from 'vs/base/common/color'; import { IDisposable } from 'vs/base/common/lifecycle'; import * as strings from 'vs/base/common/strings'; -import { IConfigurationChangedEvent, EDITOR_FONT_DEFAULTS } from 'vs/editor/common/config/editorOptions'; +import { IConfigurationChangedEvent, EDITOR_FONT_DEFAULTS, EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; import { IPosition, Position } from 'vs/editor/common/core/position'; import { IRange, Range } from 'vs/editor/common/core/range'; import * as editorCommon from 'vs/editor/common/editorCommon'; @@ -60,20 +60,26 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel } else { const conf = this.configuration.editor; + const options = this.configuration.options; + const wrappingInfo = options.get(EditorOptionId.wrappingInfo); + const wordWrapBreakAfterCharacters = options.get(EditorOptionId.wordWrapBreakAfterCharacters); + const wordWrapBreakBeforeCharacters = options.get(EditorOptionId.wordWrapBreakBeforeCharacters); + const wordWrapBreakObtrusiveCharacters = options.get(EditorOptionId.wordWrapBreakObtrusiveCharacters); + const wrappingIndent = options.get(EditorOptionId.wrappingIndent); let hardWrappingLineMapperFactory = new CharacterHardWrappingLineMapperFactory( - conf.wrappingInfo.wordWrapBreakBeforeCharacters, - conf.wrappingInfo.wordWrapBreakAfterCharacters, - conf.wrappingInfo.wordWrapBreakObtrusiveCharacters + wordWrapBreakBeforeCharacters, + wordWrapBreakAfterCharacters, + wordWrapBreakObtrusiveCharacters ); this.lines = new SplitLinesCollection( this.model, hardWrappingLineMapperFactory, this.model.getOptions().tabSize, - conf.wrappingInfo.wrappingColumn, + wrappingInfo.wrappingColumn, conf.fontInfo.typicalFullwidthCharacterWidth / conf.fontInfo.typicalHalfwidthCharacterWidth, - conf.wrappingInfo.wrappingIndent + wrappingIndent ); } @@ -147,8 +153,11 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel let restorePreviousViewportStart = false; const conf = this.configuration.editor; + const options = this.configuration.options; + const wrappingInfo = options.get(EditorOptionId.wrappingInfo); + const wrappingIndent = options.get(EditorOptionId.wrappingIndent); - if (this.lines.setWrappingSettings(conf.wrappingInfo.wrappingIndent, conf.wrappingInfo.wrappingColumn, conf.fontInfo.typicalFullwidthCharacterWidth / conf.fontInfo.typicalHalfwidthCharacterWidth)) { + if (this.lines.setWrappingSettings(wrappingIndent, wrappingInfo.wrappingColumn, conf.fontInfo.typicalFullwidthCharacterWidth / conf.fontInfo.typicalHalfwidthCharacterWidth)) { eventsCollector.emit(new viewEvents.ViewFlushedEvent()); eventsCollector.emit(new viewEvents.ViewLineMappingChangedEvent()); eventsCollector.emit(new viewEvents.ViewDecorationsChangedEvent()); diff --git a/src/vs/editor/contrib/find/findWidget.ts b/src/vs/editor/contrib/find/findWidget.ts index d35752a078d..3b31b2e3b57 100644 --- a/src/vs/editor/contrib/find/findWidget.ts +++ b/src/vs/editor/contrib/find/findWidget.ts @@ -23,7 +23,7 @@ import { toDisposable } from 'vs/base/common/lifecycle'; import * as platform from 'vs/base/common/platform'; import * as strings from 'vs/base/common/strings'; import { ICodeEditor, IOverlayWidget, IOverlayWidgetPosition, IViewZone, OverlayWidgetPositionPreference } from 'vs/editor/browser/editorBrowser'; -import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions'; +import { IConfigurationChangedEvent, EditorOptionId } from 'vs/editor/common/config/editorOptions'; import { Range } from 'vs/editor/common/core/range'; import { CONTEXT_FIND_INPUT_FOCUSED, CONTEXT_REPLACE_INPUT_FOCUSED, FIND_IDS, MATCHES_LIMIT } from 'vs/editor/contrib/find/findModel'; import { FindReplaceState, FindReplaceStateChangedEvent } from 'vs/editor/contrib/find/findState'; @@ -183,11 +183,11 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas } this._updateButtons(); } - if (e.layoutInfo) { + if (e.hasChanged(EditorOptionId.layoutInfo)) { this._tryUpdateWidgetWidth(); } - if (e.accessibilitySupport) { + if (e.hasChanged(EditorOptionId.accessibilitySupport)) { this.updateAccessibilitySupport(); } @@ -642,7 +642,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas return; } - const editorContentWidth = this._codeEditor.getConfiguration().layoutInfo.contentWidth; + const layoutInfo = this._codeEditor.getLayoutInfo(); + const editorContentWidth = layoutInfo.contentWidth; if (editorContentWidth <= 0) { // for example, diff view original editor @@ -652,8 +653,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas dom.removeClass(this._domNode, 'hiddenEditor'); } - const editorWidth = this._codeEditor.getConfiguration().layoutInfo.width; - const minimapWidth = this._codeEditor.getConfiguration().layoutInfo.minimapWidth; + const editorWidth = layoutInfo.width; + const minimapWidth = layoutInfo.minimapWidth; let collapsedFindWidget = false; let reducedFindWidget = false; let narrowFindWidget = false; @@ -1187,7 +1188,8 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas if (!this._resized || currentWidth === FIND_WIDGET_INITIAL_WIDTH) { // 1. never resized before, double click should maximizes it // 2. users resized it already but its width is the same as default - width = this._codeEditor.getConfiguration().layoutInfo.width - 28 - this._codeEditor.getConfiguration().layoutInfo.minimapWidth - 15; + const layoutInfo = this._codeEditor.getLayoutInfo(); + width = layoutInfo.width - 28 - layoutInfo.minimapWidth - 15; this._resized = true; } else { /** diff --git a/src/vs/editor/contrib/folding/folding.ts b/src/vs/editor/contrib/folding/folding.ts index cd7cdbe1d13..4a705db696e 100644 --- a/src/vs/editor/contrib/folding/folding.ts +++ b/src/vs/editor/contrib/folding/folding.ts @@ -18,7 +18,7 @@ import { FoldingModel, setCollapseStateAtLevel, CollapseMemento, setCollapseStat import { FoldingDecorationProvider } from './foldingDecorations'; import { FoldingRegions, FoldingRegion } from './foldingRanges'; import { EditorContextKeys } from 'vs/editor/common/editorContextKeys'; -import { IConfigurationChangedEvent } from 'vs/editor/common/config/editorOptions'; +import { IConfigurationChangedEvent, EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; import { IMarginData, IEmptyContentData } from 'vs/editor/browser/controller/mouseTarget'; import { HiddenRangeModel } from 'vs/editor/contrib/folding/hiddenRangeModel'; import { IRange } from 'vs/editor/common/core/range'; @@ -87,7 +87,8 @@ export class FoldingController extends Disposable implements IEditorContribution ) { super(); this.editor = editor; - this._isEnabled = this.editor.getConfiguration().contribInfo.folding; + const options = this.editor.getOptions(); + this._isEnabled = options.get(EditorOptionId.folding); this._autoHideFoldingControls = this.editor.getConfiguration().contribInfo.showFoldingControls === 'mouseover'; this._useFoldingProviders = this.editor.getConfiguration().contribInfo.foldingStrategy !== 'indentation'; @@ -109,9 +110,10 @@ export class FoldingController extends Disposable implements IEditorContribution this._register(this.editor.onDidChangeModel(() => this.onModelChanged())); this._register(this.editor.onDidChangeConfiguration((e: IConfigurationChangedEvent) => { - if (e.contribInfo) { + if (e.contribInfo || e.hasChanged(EditorOptionId.folding)) { let oldIsEnabled = this._isEnabled; - this._isEnabled = this.editor.getConfiguration().contribInfo.folding; + const options = this.editor.getOptions(); + this._isEnabled = options.get(EditorOptionId.folding); this.foldingEnabled.set(this._isEnabled); if (oldIsEnabled !== this._isEnabled) { this.onModelChanged(); diff --git a/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts b/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts index 1981153c0c8..dc640cc2b3c 100644 --- a/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts +++ b/src/vs/editor/standalone/browser/accessibilityHelp/accessibilityHelp.ts @@ -31,6 +31,7 @@ import { contrastBorder, editorWidgetBackground, widgetShadow, editorWidgetForeg import { registerThemingParticipant } from 'vs/platform/theme/common/themeService'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; import { AccessibilityHelpNLS } from 'vs/editor/common/standaloneStrings'; +import { EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; const CONTEXT_ACCESSIBILITY_WIDGET_VISIBLE = new RawContextKey('accessibilityHelpWidgetVisible', false); @@ -224,6 +225,7 @@ class AccessibilityHelpWidget extends Widget implements IOverlayWidget { private _buildContent() { let opts = this._editor.getConfiguration(); + const options = this._editor.getOptions(); const selections = this._editor.getSelections(); let charactersSelected = 0; @@ -239,7 +241,7 @@ class AccessibilityHelpWidget extends Widget implements IOverlayWidget { let text = getSelectionLabel(selections, charactersSelected); - if (opts.wrappingInfo.inDiffEditor) { + if (options.get(EditorOptionId.inDiffEditor)) { if (opts.readOnly) { text += AccessibilityHelpNLS.readonlyDiffEditor; } else { diff --git a/src/vs/editor/standalone/browser/standaloneEditor.ts b/src/vs/editor/standalone/browser/standaloneEditor.ts index c3936c2a1b7..70d17b7f81b 100644 --- a/src/vs/editor/standalone/browser/standaloneEditor.ts +++ b/src/vs/editor/standalone/browser/standaloneEditor.ts @@ -352,6 +352,7 @@ export function createMonacoEditorAPI(): typeof monaco.editor { remeasureFonts: remeasureFonts, // enums + AccessibilitySupport: standaloneEnums.AccessibilitySupport, ScrollbarVisibility: standaloneEnums.ScrollbarVisibility, WrappingIndent: standaloneEnums.WrappingIndent, OverviewRulerLane: standaloneEnums.OverviewRulerLane, @@ -372,6 +373,7 @@ export function createMonacoEditorAPI(): typeof monaco.editor { EditorOptionId: standaloneEnums.EditorOptionId, // classes + BaseEditorOption: editorOptions.BaseEditorOption, InternalEditorOptions: editorOptions.InternalEditorOptions, BareFontInfo: BareFontInfo, FontInfo: FontInfo, diff --git a/src/vs/editor/test/common/config/commonEditorConfig.test.ts b/src/vs/editor/test/common/config/commonEditorConfig.test.ts index b35959ae2c2..649c7f9718b 100644 --- a/src/vs/editor/test/common/config/commonEditorConfig.test.ts +++ b/src/vs/editor/test/common/config/commonEditorConfig.test.ts @@ -4,7 +4,7 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; import { IEnvConfiguration } from 'vs/editor/common/config/commonEditorConfig'; -import { IEditorHoverOptions } from 'vs/editor/common/config/editorOptions'; +import { IEditorHoverOptions, EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; import { EditorZoom } from 'vs/editor/common/config/editorZoom'; import { TestConfiguration } from 'vs/editor/test/common/mocks/testConfiguration'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; @@ -67,8 +67,10 @@ suite('Common Editor Config', () => { } function assertWrapping(config: TestConfiguration, isViewportWrapping: boolean, wrappingColumn: number): void { - assert.equal(config.editor.wrappingInfo.isViewportWrapping, isViewportWrapping); - assert.equal(config.editor.wrappingInfo.wrappingColumn, wrappingColumn); + const options = config.options; + const wrappingInfo = options.get(EditorOptionId.wrappingInfo); + assert.equal(wrappingInfo.isViewportWrapping, isViewportWrapping); + assert.equal(wrappingInfo.wrappingColumn, wrappingColumn); } test('wordWrap default', () => { diff --git a/src/vs/editor/test/common/viewLayout/editorLayoutProvider.test.ts b/src/vs/editor/test/common/viewLayout/editorLayoutProvider.test.ts index e35df432fcd..593f7b74126 100644 --- a/src/vs/editor/test/common/viewLayout/editorLayoutProvider.test.ts +++ b/src/vs/editor/test/common/viewLayout/editorLayoutProvider.test.ts @@ -4,12 +4,12 @@ *--------------------------------------------------------------------------------------------*/ import * as assert from 'assert'; -import { EditorLayoutInfo, EditorLayoutProvider, IEditorLayoutProviderOpts, RenderMinimap } from 'vs/editor/common/config/editorOptions'; +import { EditorLayoutInfo, EditorLayoutInfoComputer, IEditorLayoutProviderOpts, RenderMinimap } from 'vs/editor/common/config/editorOptions'; suite('Editor ViewLayout - EditorLayoutProvider', () => { function doTest(input: IEditorLayoutProviderOpts, expected: EditorLayoutInfo): void { - let actual = EditorLayoutProvider.compute(input); + let actual = EditorLayoutInfoComputer.compute(input); assert.deepEqual(actual, expected); } diff --git a/src/vs/editor/test/common/viewModel/splitLinesCollection.test.ts b/src/vs/editor/test/common/viewModel/splitLinesCollection.test.ts index 9b053429da8..20ba2e12437 100644 --- a/src/vs/editor/test/common/viewModel/splitLinesCollection.test.ts +++ b/src/vs/editor/test/common/viewModel/splitLinesCollection.test.ts @@ -19,6 +19,7 @@ import { PrefixSumComputer } from 'vs/editor/common/viewModel/prefixSumComputer' import { ILineMapping, ISimpleModel, SplitLine, SplitLinesCollection } from 'vs/editor/common/viewModel/splitLinesCollection'; import { ViewLineData } from 'vs/editor/common/viewModel/viewModel'; import { TestConfiguration } from 'vs/editor/test/common/mocks/testConfiguration'; +import { EditorOptionId, EditorOption } from 'vs/editor/common/config/editorOptions'; suite('Editor ViewModel - SplitLinesCollection', () => { test('SplitLine', () => { @@ -88,15 +89,20 @@ suite('Editor ViewModel - SplitLinesCollection', () => { }); function withSplitLinesCollection(text: string, callback: (model: TextModel, linesCollection: SplitLinesCollection) => void): void { - let config = new TestConfiguration({}); + const config = new TestConfiguration({}); + const wrappingInfo = config.options.get(EditorOptionId.wrappingInfo); + const wordWrapBreakAfterCharacters = config.options.get(EditorOptionId.wordWrapBreakAfterCharacters); + const wordWrapBreakBeforeCharacters = config.options.get(EditorOptionId.wordWrapBreakBeforeCharacters); + const wordWrapBreakObtrusiveCharacters = config.options.get(EditorOptionId.wordWrapBreakObtrusiveCharacters); + const wrappingIndent = config.options.get(EditorOptionId.wrappingIndent); - let hardWrappingLineMapperFactory = new CharacterHardWrappingLineMapperFactory( - config.editor.wrappingInfo.wordWrapBreakBeforeCharacters, - config.editor.wrappingInfo.wordWrapBreakAfterCharacters, - config.editor.wrappingInfo.wordWrapBreakObtrusiveCharacters + const hardWrappingLineMapperFactory = new CharacterHardWrappingLineMapperFactory( + wordWrapBreakBeforeCharacters, + wordWrapBreakAfterCharacters, + wordWrapBreakObtrusiveCharacters ); - let model = TextModel.createFromString([ + const model = TextModel.createFromString([ 'int main() {', '\tprintf("Hello world!");', '}', @@ -105,13 +111,13 @@ suite('Editor ViewModel - SplitLinesCollection', () => { '}', ].join('\n')); - let linesCollection = new SplitLinesCollection( + const linesCollection = new SplitLinesCollection( model, hardWrappingLineMapperFactory, model.getOptions().tabSize, - config.editor.wrappingInfo.wrappingColumn, + wrappingInfo.wrappingColumn, config.editor.fontInfo.typicalFullwidthCharacterWidth / config.editor.fontInfo.typicalHalfwidthCharacterWidth, - config.editor.wrappingInfo.wrappingIndent + wrappingIndent ); callback(model, linesCollection); @@ -732,25 +738,30 @@ suite('SplitLinesCollection', () => { }); function withSplitLinesCollection(model: TextModel, wordWrap: 'on' | 'off' | 'wordWrapColumn' | 'bounded', wordWrapColumn: number, callback: (splitLinesCollection: SplitLinesCollection) => void): void { - let configuration = new TestConfiguration({ + const configuration = new TestConfiguration({ wordWrap: wordWrap, wordWrapColumn: wordWrapColumn, wrappingIndent: 'indent' }); + const wrappingInfo = configuration.options.get(EditorOptionId.wrappingInfo); + const wordWrapBreakAfterCharacters = configuration.options.get(EditorOptionId.wordWrapBreakAfterCharacters); + const wordWrapBreakBeforeCharacters = configuration.options.get(EditorOptionId.wordWrapBreakBeforeCharacters); + const wordWrapBreakObtrusiveCharacters = configuration.options.get(EditorOptionId.wordWrapBreakObtrusiveCharacters); + const wrappingIndent = configuration.options.get(EditorOptionId.wrappingIndent); - let factory = new CharacterHardWrappingLineMapperFactory( - configuration.editor.wrappingInfo.wordWrapBreakBeforeCharacters, - configuration.editor.wrappingInfo.wordWrapBreakAfterCharacters, - configuration.editor.wrappingInfo.wordWrapBreakObtrusiveCharacters + const factory = new CharacterHardWrappingLineMapperFactory( + wordWrapBreakBeforeCharacters, + wordWrapBreakAfterCharacters, + wordWrapBreakObtrusiveCharacters ); - let linesCollection = new SplitLinesCollection( + const linesCollection = new SplitLinesCollection( model, factory, model.getOptions().tabSize, - configuration.editor.wrappingInfo.wrappingColumn, + wrappingInfo.wrappingColumn, configuration.editor.fontInfo.typicalFullwidthCharacterWidth / configuration.editor.fontInfo.typicalHalfwidthCharacterWidth, - configuration.editor.wrappingInfo.wrappingIndent + wrappingIndent ); callback(linesCollection); diff --git a/src/vs/monaco.d.ts b/src/vs/monaco.d.ts index 87d85008895..32d7a932be4 100644 --- a/src/vs/monaco.d.ts +++ b/src/vs/monaco.d.ts @@ -2408,6 +2408,15 @@ declare namespace monaco.editor { readonly reason: CursorChangeReason; } + export enum AccessibilitySupport { + /** + * This should be the browser case where it is not known if a screen reader is attached or no. + */ + Unknown = 0, + Disabled = 1, + Enabled = 2 + } + /** * Configuration options for editor scrollbars */ @@ -2653,7 +2662,7 @@ declare namespace monaco.editor { * Otherwise, line numbers will not be rendered. * Defaults to true. */ - lineNumbers?: 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string); + lineNumbers?: LineNumbersType; /** * Controls the minimal number of visible leading and trailing lines surrounding the cursor. * Defaults to 0. @@ -2826,7 +2835,7 @@ declare namespace monaco.editor { * Control indentation of wrapped lines. Can be: 'none', 'same', 'indent' or 'deepIndent'. * Defaults to 'same' in vscode and to 'none' in monaco-editor. */ - wrappingIndent?: string; + wrappingIndent?: 'none' | 'same' | 'indent' | 'deepIndent'; /** * Configure word wrapping characters. A break will be introduced before these characters. * Defaults to '{([+'. @@ -3105,6 +3114,8 @@ declare namespace monaco.editor { * Controls fading out of unused variables. */ showUnused?: boolean; + layoutInfo?: undefined; + wrappingInfo?: undefined; } /** @@ -3228,30 +3239,6 @@ declare namespace monaco.editor { UnderlineThin = 6 } - export interface InternalEditorScrollbarOptions { - readonly arrowSize: number; - readonly vertical: ScrollbarVisibility; - readonly horizontal: ScrollbarVisibility; - readonly useShadows: boolean; - readonly verticalHasArrows: boolean; - readonly horizontalHasArrows: boolean; - readonly handleMouseWheel: boolean; - readonly horizontalScrollbarSize: number; - readonly horizontalSliderSize: number; - readonly verticalScrollbarSize: number; - readonly verticalSliderSize: number; - readonly mouseWheelScrollSensitivity: number; - readonly fastScrollSensitivity: number; - } - - export interface InternalEditorMinimapOptions { - readonly enabled: boolean; - readonly side: 'right' | 'left'; - readonly showSlider: 'always' | 'mouseover'; - readonly renderCharacters: boolean; - readonly maxColumn: number; - } - export interface InternalEditorFindOptions { readonly seedSearchStringFromSelection: boolean; readonly autoFindInSelection: boolean; @@ -3284,33 +3271,10 @@ declare namespace monaco.editor { readonly cycle: boolean; } - export interface EditorWrappingInfo { - readonly inDiffEditor: boolean; - readonly isDominatedByLongLines: boolean; - readonly isWordWrapMinified: boolean; - readonly isViewportWrapping: boolean; - readonly wrappingColumn: number; - readonly wrappingIndent: WrappingIndent; - readonly wordWrapBreakBeforeCharacters: string; - readonly wordWrapBreakAfterCharacters: string; - readonly wordWrapBreakObtrusiveCharacters: string; - } - - export enum RenderLineNumbersType { - Off = 0, - On = 1, - Relative = 2, - Interval = 3, - Custom = 4 - } - export interface InternalEditorViewOptions { readonly extraEditorClassName: string; readonly disableMonospaceOptimizations: boolean; readonly rulers: number[]; - readonly ariaLabel: string; - readonly renderLineNumbers: RenderLineNumbersType; - readonly renderCustomLineNumbers: ((lineNumber: number) => string) | null; readonly cursorSurroundingLines: number; readonly glyphMargin: boolean; readonly revealHorizontalRightPadding: number; @@ -3333,8 +3297,6 @@ declare namespace monaco.editor { readonly renderIndentGuides: boolean; readonly highlightActiveIndentGuide: boolean; readonly renderLineHighlight: 'none' | 'gutter' | 'line' | 'all'; - readonly scrollbar: InternalEditorScrollbarOptions; - readonly minimap: InternalEditorMinimapOptions; readonly fixedOverflowWidgets: boolean; } @@ -3364,7 +3326,6 @@ declare namespace monaco.editor { readonly selectionHighlight: boolean; readonly occurrencesHighlight: boolean; readonly codeLens: boolean; - readonly folding: boolean; readonly foldingStrategy: 'auto' | 'indentation'; readonly showFoldingControls: 'always' | 'mouseover'; readonly matchBrackets: boolean; @@ -3399,13 +3360,124 @@ declare namespace monaco.editor { readonly dragAndDrop: boolean; readonly emptySelectionClipboard: boolean; readonly copyWithSyntaxHighlighting: boolean; - readonly layoutInfo: EditorLayoutInfo; readonly fontInfo: FontInfo; readonly viewInfo: InternalEditorViewOptions; - readonly wrappingInfo: EditorWrappingInfo; readonly contribInfo: EditorContribOptions; } + /** + * An event describing that the configuration of the editor has changed. + */ + export interface IConfigurationChangedEvent { + hasChanged(id: EditorOptionId): boolean; + readonly canUseLayerHinting: boolean; + readonly pixelRatio: boolean; + readonly editorClassName: boolean; + readonly lineHeight: boolean; + readonly readOnly: boolean; + readonly multiCursorModifier: boolean; + readonly multiCursorMergeOverlapping: boolean; + readonly wordSeparators: boolean; + readonly autoClosingBrackets: boolean; + readonly autoClosingQuotes: boolean; + readonly autoClosingOvertype: boolean; + readonly autoSurround: boolean; + readonly autoIndent: boolean; + readonly useTabStops: boolean; + readonly tabFocusMode: boolean; + readonly dragAndDrop: boolean; + readonly emptySelectionClipboard: boolean; + readonly copyWithSyntaxHighlighting: boolean; + readonly fontInfo: boolean; + readonly viewInfo: boolean; + readonly contribInfo: boolean; + } + + export interface IEnvironmentalOptions { + readonly outerWidth: number; + readonly outerHeight: number; + readonly fontInfo: FontInfo; + readonly extraEditorClassName: string; + readonly isDominatedByLongLines: boolean; + readonly lineNumbersDigitCount: number; + readonly emptySelectionClipboard: boolean; + readonly pixelRatio: number; + readonly tabFocusMode: boolean; + readonly accessibilitySupport: AccessibilitySupport; + } + + export interface IRawEditorOptionsBag extends IEditorOptions { + [key: string]: any; + } + + export interface IComputedEditorOptions { + get>(id: EditorOptionId): ComputedEditorOptionValue; + } + + export type PossibleKeyName = { + [K in keyof IEditorOptions]: IEditorOptions[K] extends V | undefined ? K : never; + }[keyof IEditorOptions]; + + export interface IEditorOption { + readonly id: EditorOptionId; + readonly name: PossibleKeyName; + readonly defaultValue: T2; + read(options: IRawEditorOptionsBag): T1 | undefined; + mix(a: T1 | undefined, b: T1 | undefined): T1 | undefined; + validate(input: T1 | undefined): T2; + compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: T2): T3; + equals(a: T3, b: T3): boolean; + } + + export abstract class BaseEditorOption implements IEditorOption { + readonly id: EditorOptionId; + readonly name: PossibleKeyName; + readonly defaultValue: T2; + constructor(id: EditorOptionId, name: PossibleKeyName, defaultValue: T2, deps?: EditorOptionId[]); + read(options: IRawEditorOptionsBag): T1 | undefined; + mix(a: T1 | undefined, b: T1 | undefined): T1 | undefined; + abstract validate(input: T1 | undefined): T2; + abstract compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: T2): T3; + equals(a: T3, b: T3): boolean; + } + + export type LineNumbersType = 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string); + + export enum RenderLineNumbersType { + Off = 0, + On = 1, + Relative = 2, + Interval = 3, + Custom = 4 + } + + export interface InternalEditorRenderLineNumbersOptions { + readonly renderType: RenderLineNumbersType; + readonly renderFn: ((lineNumber: number) => string) | null; + } + + export interface InternalEditorMinimapOptions { + readonly enabled: boolean; + readonly side: 'right' | 'left'; + readonly showSlider: 'always' | 'mouseover'; + readonly renderCharacters: boolean; + readonly maxColumn: number; + } + + export interface InternalEditorScrollbarOptions { + readonly arrowSize: number; + readonly vertical: ScrollbarVisibility; + readonly horizontal: ScrollbarVisibility; + readonly useShadows: boolean; + readonly verticalHasArrows: boolean; + readonly horizontalHasArrows: boolean; + readonly handleMouseWheel: boolean; + readonly horizontalScrollbarSize: number; + readonly horizontalSliderSize: number; + readonly verticalScrollbarSize: number; + readonly verticalSliderSize: number; + } + /** * A description for the overview ruler position. */ @@ -3518,62 +3590,65 @@ declare namespace monaco.editor { readonly overviewRuler: OverviewRulerPosition; } - /** - * An event describing that the configuration of the editor has changed. - */ - export interface IConfigurationChangedEvent { - hasChanged(id: EditorOptionId): boolean; - readonly canUseLayerHinting: boolean; - readonly pixelRatio: boolean; - readonly editorClassName: boolean; - readonly lineHeight: boolean; - readonly readOnly: boolean; - readonly accessibilitySupport: boolean; - readonly multiCursorModifier: boolean; - readonly multiCursorMergeOverlapping: boolean; - readonly wordSeparators: boolean; - readonly autoClosingBrackets: boolean; - readonly autoClosingQuotes: boolean; - readonly autoClosingOvertype: boolean; - readonly autoSurround: boolean; - readonly autoIndent: boolean; - readonly useTabStops: boolean; - readonly tabFocusMode: boolean; - readonly dragAndDrop: boolean; - readonly emptySelectionClipboard: boolean; - readonly copyWithSyntaxHighlighting: boolean; - readonly layoutInfo: boolean; - readonly fontInfo: boolean; - readonly viewInfo: boolean; - readonly wrappingInfo: boolean; - readonly contribInfo: boolean; - } - - export interface IRawEditorOptionsBag { - [key: string]: any; - } - - export interface IEditorOption { - readonly id: EditorOptionId; - readonly name: string; - readonly defaultValue: T1; - read(options: IRawEditorOptionsBag): T1 | undefined; - mix(a: T1 | undefined, b: T1 | undefined): T1 | undefined; - validate(input: T1 | undefined): T2; - compute(value: T2): T3; - equals(a: T3, b: T3): boolean; + export interface EditorWrappingInfo { + readonly isDominatedByLongLines: boolean; + readonly isWordWrapMinified: boolean; + readonly isViewportWrapping: boolean; + readonly wrappingColumn: number; } export enum EditorOptionId { - renderFinalNewline = 0, - selectionClipboard = 1, - selectOnLineNumbers = 2 + accessibilitySupport = 0, + ariaLabel = 1, + fastScrollSensitivity = 2, + folding = 3, + glyphMargin = 4, + inDiffEditor = 5, + lineDecorationsWidth = 6, + lineNumbersMinChars = 7, + minimap = 8, + mouseWheelScrollSensitivity = 9, + renderFinalNewline = 10, + renderLineNumbers = 11, + scrollbar = 12, + selectionClipboard = 13, + selectOnLineNumbers = 14, + wordWrap = 15, + wordWrapBreakAfterCharacters = 16, + wordWrapBreakBeforeCharacters = 17, + wordWrapBreakObtrusiveCharacters = 18, + wordWrapColumn = 19, + wordWrapMinified = 20, + wrappingIndent = 21, + layoutInfo = 22, + wrappingInfo = 23 } export const EditorOption: { + accessibilitySupport: IEditorOption<"auto" | "on" | "off", "auto" | "on" | "off", any>; + ariaLabel: IEditorOption; + fastScrollSensitivity: IEditorOption; + folding: IEditorOption; + glyphMargin: IEditorOption; + inDiffEditor: IEditorOption; + lineDecorationsWidth: IEditorOption; + lineNumbersMinChars: IEditorOption; + minimap: IEditorOption; + mouseWheelScrollSensitivity: IEditorOption; renderFinalNewline: IEditorOption; + renderLineNumbers: IEditorOption; + scrollbar: IEditorOption; selectionClipboard: IEditorOption; selectOnLineNumbers: IEditorOption; + wordWrap: IEditorOption<"on" | "off" | "wordWrapColumn" | "bounded", "on" | "off" | "wordWrapColumn" | "bounded", "on" | "off" | "wordWrapColumn" | "bounded">; + wordWrapBreakAfterCharacters: IEditorOption; + wordWrapBreakBeforeCharacters: IEditorOption; + wordWrapBreakObtrusiveCharacters: IEditorOption; + wordWrapColumn: IEditorOption; + wordWrapMinified: IEditorOption; + wrappingIndent: IEditorOption<"none" | "same" | "indent" | "deepIndent", "none" | "same" | "indent" | "deepIndent", WrappingIndent>; + layoutInfo: IEditorOption; + wrappingInfo: IEditorOption; }; export type ComputedEditorOptionValue> = T extends IEditorOption ? R : never; @@ -4027,6 +4102,7 @@ declare namespace monaco.editor { * Returns the current editor's configuration */ getConfiguration(): InternalEditorOptions; + getOptions(): IComputedEditorOptions; getOption>(id: EditorOptionId): ComputedEditorOptionValue; /** * Get value of the current model attached to this editor. diff --git a/src/vs/workbench/api/browser/mainThreadEditor.ts b/src/vs/workbench/api/browser/mainThreadEditor.ts index ff8e1cd5138..10437ec2ed6 100644 --- a/src/vs/workbench/api/browser/mainThreadEditor.ts +++ b/src/vs/workbench/api/browser/mainThreadEditor.ts @@ -6,7 +6,7 @@ import { Emitter, Event } from 'vs/base/common/event'; import { DisposableStore } from 'vs/base/common/lifecycle'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; -import { RenderLineNumbersType, TextEditorCursorStyle, cursorStyleToString } from 'vs/editor/common/config/editorOptions'; +import { RenderLineNumbersType, TextEditorCursorStyle, cursorStyleToString, EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; import { IRange, Range } from 'vs/editor/common/core/range'; import { ISelection, Selection } from 'vs/editor/common/core/selection'; import * as editorCommon from 'vs/editor/common/editorCommon'; @@ -59,8 +59,10 @@ export class MainThreadTextEditorProperties { let lineNumbers: RenderLineNumbersType; if (codeEditor) { const codeEditorOpts = codeEditor.getConfiguration(); + const options = codeEditor.getOptions(); + const renderLineNumbers = options.get(EditorOptionId.renderLineNumbers); cursorStyle = codeEditorOpts.viewInfo.cursorStyle; - lineNumbers = codeEditorOpts.viewInfo.renderLineNumbers; + lineNumbers = renderLineNumbers.renderType; } else if (previousProperties) { cursorStyle = previousProperties.options.cursorStyle; lineNumbers = previousProperties.options.lineNumbers; diff --git a/src/vs/workbench/browser/parts/editor/editorStatus.ts b/src/vs/workbench/browser/parts/editor/editorStatus.ts index ed5bbacdd3e..f96fcd3b787 100644 --- a/src/vs/workbench/browser/parts/editor/editorStatus.ts +++ b/src/vs/workbench/browser/parts/editor/editorStatus.ts @@ -35,7 +35,7 @@ import { ICommandService, CommandsRegistry } from 'vs/platform/commands/common/c import { IExtensionGalleryService } from 'vs/platform/extensionManagement/common/extensionManagement'; import { ITextFileService, SUPPORTED_ENCODINGS } from 'vs/workbench/services/textfile/common/textfiles'; import { ICursorPositionChangedEvent } from 'vs/editor/common/controller/cursorEvents'; -import { IConfigurationChangedEvent, IEditorOptions } from 'vs/editor/common/config/editorOptions'; +import { IConfigurationChangedEvent, IEditorOptions, EditorOptionId } from 'vs/editor/common/config/editorOptions'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; import { ConfigurationTarget, IConfigurationService } from 'vs/platform/configuration/common/configuration'; import { deepClone } from 'vs/base/common/objects'; @@ -584,7 +584,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution { // Hook Listener for Configuration changes this.activeEditorListeners.add(activeCodeEditor.onDidChangeConfiguration((event: IConfigurationChangedEvent) => { - if (event.accessibilitySupport) { + if (event.hasChanged(EditorOptionId.accessibilitySupport)) { this.onScreenReaderModeChange(activeCodeEditor); } })); diff --git a/src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts b/src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts index eb15bf10a1f..e8472a05fe6 100644 --- a/src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts +++ b/src/vs/workbench/contrib/codeEditor/browser/toggleWordWrap.ts @@ -10,7 +10,7 @@ import { URI } from 'vs/base/common/uri'; import { ICodeEditor } from 'vs/editor/browser/editorBrowser'; import { EditorAction, ServicesAccessor, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions'; import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService'; -import { EDITOR_DEFAULTS, InternalEditorOptions } from 'vs/editor/common/config/editorOptions'; +import { EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; import { IEditorContribution } from 'vs/editor/common/editorCommon'; import { ITextModel } from 'vs/editor/common/model'; import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration'; @@ -68,7 +68,7 @@ function readWordWrapState(model: ITextModel, configurationService: ITextResourc const _transientState = readTransientState(model, codeEditorService); return { configuredWordWrap: _configuredWordWrap, - configuredWordWrapMinified: (typeof _configuredWordWrapMinified === 'boolean' ? _configuredWordWrapMinified : EDITOR_DEFAULTS.wordWrapMinified), + configuredWordWrapMinified: (typeof _configuredWordWrapMinified === 'boolean' ? _configuredWordWrapMinified : EditorOption.wordWrapMinified.defaultValue), transientState: _transientState }; } @@ -83,10 +83,9 @@ function toggleWordWrap(editor: ICodeEditor, state: IWordWrapState): IWordWrapSt }; } - const config = editor.getConfiguration(); let transientState: IWordWrapTransientState; - const actualWrappingInfo = config.wrappingInfo; + const actualWrappingInfo = editor.getOption(EditorOptionId.wrappingInfo); if (actualWrappingInfo.isWordWrapMinified) { // => wrapping due to minified file transientState = { @@ -139,8 +138,7 @@ class ToggleWordWrapAction extends EditorAction { if (!editor.hasModel()) { return; } - const editorConfiguration = editor.getConfiguration(); - if (editorConfiguration.wrappingInfo.inDiffEditor) { + if (editor.getOption(EditorOptionId.inDiffEditor)) { // Cannot change wrapping settings inside the diff editor const notificationService = accessor.get(INotificationService); notificationService.info(nls.localize('wordWrap.notInDiffEditor', "Cannot toggle word wrap in a diff editor.")); @@ -177,20 +175,22 @@ class ToggleWordWrapController extends Disposable implements IEditorContribution ) { super(); - const configuration = this.editor.getConfiguration(); - const isWordWrapMinified = this.contextKeyService.createKey(isWordWrapMinifiedKey, this._isWordWrapMinified(configuration)); - const isDominatedByLongLines = this.contextKeyService.createKey(isDominatedByLongLinesKey, this._isDominatedByLongLines(configuration)); - const inDiffEditor = this.contextKeyService.createKey(inDiffEditorKey, this._inDiffEditor(configuration)); + const options = this.editor.getOptions(); + const wrappingInfo = options.get(EditorOptionId.wrappingInfo); + const isWordWrapMinified = this.contextKeyService.createKey(isWordWrapMinifiedKey, wrappingInfo.isWordWrapMinified); + const isDominatedByLongLines = this.contextKeyService.createKey(isDominatedByLongLinesKey, wrappingInfo.isDominatedByLongLines); + const inDiffEditor = this.contextKeyService.createKey(inDiffEditorKey, options.get(EditorOptionId.inDiffEditor)); let currentlyApplyingEditorConfig = false; this._register(editor.onDidChangeConfiguration((e) => { - if (!e.wrappingInfo) { + if (!e.hasChanged(EditorOptionId.wrappingInfo) || !e.hasChanged(EditorOptionId.inDiffEditor)) { return; } - const configuration = this.editor.getConfiguration(); - isWordWrapMinified.set(this._isWordWrapMinified(configuration)); - isDominatedByLongLines.set(this._isDominatedByLongLines(configuration)); - inDiffEditor.set(this._inDiffEditor(configuration)); + const options = this.editor.getOptions(); + const wrappingInfo = options.get(EditorOptionId.wrappingInfo); + isWordWrapMinified.set(wrappingInfo.isWordWrapMinified); + isDominatedByLongLines.set(wrappingInfo.isDominatedByLongLines); + inDiffEditor.set(options.get(EditorOptionId.inDiffEditor)); if (!currentlyApplyingEditorConfig) { // I am not the cause of the word wrap getting changed ensureWordWrapSettings(); @@ -216,8 +216,7 @@ class ToggleWordWrapController extends Disposable implements IEditorContribution return; } - const configuration = this.editor.getConfiguration(); - if (this._inDiffEditor(configuration)) { + if (this.editor.getOption(EditorOptionId.inDiffEditor)) { return; } @@ -255,18 +254,6 @@ class ToggleWordWrapController extends Disposable implements IEditorContribution }); } - private _isWordWrapMinified(config: InternalEditorOptions): boolean { - return config.wrappingInfo.isWordWrapMinified; - } - - private _isDominatedByLongLines(config: InternalEditorOptions): boolean { - return config.wrappingInfo.isDominatedByLongLines; - } - - private _inDiffEditor(config: InternalEditorOptions): boolean { - return config.wrappingInfo.inDiffEditor; - } - public getId(): string { return ToggleWordWrapController._ID; } diff --git a/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts b/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts index d5cfcfb4f19..94a1a359481 100644 --- a/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts +++ b/src/vs/workbench/contrib/comments/browser/commentsEditorContribution.ts @@ -37,6 +37,7 @@ import { COMMENTEDITOR_DECORATION_KEY, ReviewZoneWidget } from 'vs/workbench/con import { ctxCommentEditorFocused, SimpleCommentEditor } from 'vs/workbench/contrib/comments/browser/simpleCommentEditor'; import { IEditorService } from 'vs/workbench/services/editor/common/editorService'; import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget'; +import { EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; export const ID = 'editor.contrib.review'; @@ -590,7 +591,7 @@ export class ReviewController implements IEditorContribution { } this._commentInfos = commentInfos; - let lineDecorationsWidth: number = this.editor.getConfiguration().layoutInfo.decorationsWidth; + let lineDecorationsWidth: number = this.editor.getLayoutInfo().decorationsWidth; if (this._commentInfos.some(info => Boolean(info.commentingRanges && (Array.isArray(info.commentingRanges) ? info.commentingRanges : info.commentingRanges.ranges).length))) { if (!this._commentingRangeSpaceReserved) { @@ -601,7 +602,8 @@ export class ReviewController implements IEditorContribution { extraEditorClassName = configuredExtraClassName.split(' '); } - if (this.editor.getConfiguration().contribInfo.folding) { + const options = this.editor.getOptions(); + if (options.get(EditorOptionId.folding)) { lineDecorationsWidth -= 16; } lineDecorationsWidth += 9; diff --git a/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts b/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts index 66678cbfffb..6b738378609 100644 --- a/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts +++ b/src/vs/workbench/contrib/preferences/browser/preferencesWidgets.ts @@ -33,6 +33,7 @@ import { IWorkspaceContextService, IWorkspaceFolder, WorkbenchState } from 'vs/p import { PANEL_ACTIVE_TITLE_BORDER, PANEL_ACTIVE_TITLE_FOREGROUND, PANEL_INACTIVE_TITLE_FOREGROUND } from 'vs/workbench/common/theme'; import { IWorkbenchEnvironmentService } from 'vs/workbench/services/environment/common/environmentService'; import { ISettingsGroup } from 'vs/workbench/services/preferences/common/preferences'; +import { EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; export class SettingsHeaderWidget extends Widget implements IViewZone { @@ -85,8 +86,9 @@ export class SettingsHeaderWidget extends Widget implements IViewZone { private layout(): void { const configuration = this.editor.getConfiguration(); + const options = this.editor.getOptions(); this.titleContainer.style.fontSize = configuration.fontInfo.fontSize + 'px'; - if (!configuration.contribInfo.folding) { + if (!options.get(EditorOptionId.folding)) { this.titleContainer.style.paddingLeft = '6px'; } } diff --git a/src/vs/workbench/contrib/quickopen/browser/gotoLineHandler.ts b/src/vs/workbench/contrib/quickopen/browser/gotoLineHandler.ts index 3dcbb07c16c..eaafa00f21b 100644 --- a/src/vs/workbench/contrib/quickopen/browser/gotoLineHandler.ts +++ b/src/vs/workbench/contrib/quickopen/browser/gotoLineHandler.ts @@ -16,7 +16,7 @@ import { IQuickOpenService } from 'vs/platform/quickOpen/common/quickOpen'; import { IRange } from 'vs/editor/common/core/range'; import { overviewRulerRangeHighlight } from 'vs/editor/common/view/editorColorRegistry'; import { themeColorFromId } from 'vs/platform/theme/common/themeService'; -import { IEditorOptions, RenderLineNumbersType } from 'vs/editor/common/config/editorOptions'; +import { IEditorOptions, RenderLineNumbersType, EditorOption, EditorOptionId } from 'vs/editor/common/config/editorOptions'; import { IEditorService, SIDE_GROUP } from 'vs/workbench/services/editor/common/editorService'; import { isCodeEditor, isDiffEditor } from 'vs/editor/browser/editorBrowser'; import { IEditorGroup } from 'vs/workbench/services/editor/common/editorGroupsService'; @@ -50,8 +50,9 @@ export class GotoLineAction extends QuickOpenAction { let restoreOptions: IEditorOptions | null = null; if (isCodeEditor(activeTextEditorWidget)) { - const config = activeTextEditorWidget.getConfiguration(); - if (config.viewInfo.renderLineNumbers === RenderLineNumbersType.Relative) { + const options = activeTextEditorWidget.getOptions(); + const renderLineNumbers = options.get(EditorOptionId.renderLineNumbers); + if (renderLineNumbers.renderType === RenderLineNumbersType.Relative) { activeTextEditorWidget.updateOptions({ lineNumbers: 'on' });