/*--------------------------------------------------------------------------------------------- * Copyright (c) Microsoft Corporation. All rights reserved. * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ import * as nls from 'vs/nls'; import * as platform from 'vs/base/common/platform'; import { ScrollbarVisibility } from 'vs/base/common/scrollable'; import { FontInfo } from 'vs/editor/common/config/fontInfo'; import { Constants } from 'vs/editor/common/core/uint'; import { USUAL_WORD_SEPARATORS } from 'vs/editor/common/model/wordHelper'; import { AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility'; import { isObject } from 'vs/base/common/types'; import { IConfigurationPropertySchema } from 'vs/platform/configuration/common/configurationRegistry'; import { IDimension } from 'vs/editor/common/editorCommon'; //#region typed options /** * Configuration options for auto closing quotes and brackets */ export type EditorAutoClosingStrategy = 'always' | 'languageDefined' | 'beforeWhitespace' | 'never'; /** * Configuration options for auto wrapping quotes and brackets */ export type EditorAutoSurroundStrategy = 'languageDefined' | 'quotes' | 'brackets' | 'never'; /** * Configuration options for typing over closing quotes or brackets */ export type EditorAutoClosingOvertypeStrategy = 'always' | 'auto' | 'never'; /** * Configuration options for the editor. */ export interface IEditorOptions { /** * This editor is used inside a diff editor. */ inDiffEditor?: boolean; /** * The aria label for the editor's textarea (when it is focused). */ ariaLabel?: string; /** * Render vertical lines at the specified columns. * Defaults to empty array. */ rulers?: number[]; /** * A string containing the word separators used when doing word navigation. * Defaults to `~!@#$%^&*()-=+[{]}\\|;:\'",.<>/? */ wordSeparators?: string; /** * Enable Linux primary clipboard. * Defaults to true. */ selectionClipboard?: boolean; /** * Control the rendering of line numbers. * If it is a function, it will be invoked when rendering a line number and the return value will be rendered. * Otherwise, if it is a truey, line numbers will be rendered normally (equivalent of using an identity function). * Otherwise, line numbers will not be rendered. * Defaults to true. */ lineNumbers?: LineNumbersType; /** * Controls the minimal number of visible leading and trailing lines surrounding the cursor. * Defaults to 0. */ cursorSurroundingLines?: number; /** * Render last line number when the file ends with a newline. * Defaults to true. */ renderFinalNewline?: boolean; /** * Should the corresponding line be selected when clicking on the line number? * Defaults to true. */ selectOnLineNumbers?: boolean; /** * Control the width of line numbers, by reserving horizontal space for rendering at least an amount of digits. * Defaults to 5. */ lineNumbersMinChars?: number; /** * Enable the rendering of the glyph margin. * Defaults to true in vscode and to false in monaco-editor. */ glyphMargin?: boolean; /** * The width reserved for line decorations (in px). * Line decorations are placed between line numbers and the editor content. * You can pass in a string in the format floating point followed by "ch". e.g. 1.3ch. * Defaults to 10. */ lineDecorationsWidth?: number | string; /** * When revealing the cursor, a virtual padding (px) is added to the cursor, turning it into a rectangle. * This virtual padding ensures that the cursor gets revealed before hitting the edge of the viewport. * Defaults to 30 (px). */ revealHorizontalRightPadding?: number; /** * Render the editor selection with rounded borders. * Defaults to true. */ roundedSelection?: boolean; /** * Class name to be added to the editor. */ extraEditorClassName?: string; /** * Should the editor be read only. * Defaults to false. */ readOnly?: boolean; /** * Control the behavior and rendering of the scrollbars. */ scrollbar?: IEditorScrollbarOptions; /** * Control the behavior and rendering of the minimap. */ minimap?: IEditorMinimapOptions; /** * Control the behavior of the find widget. */ find?: IEditorFindOptions; /** * Display overflow widgets as `fixed`. * Defaults to `false`. */ fixedOverflowWidgets?: boolean; /** * The number of vertical lanes the overview ruler should render. * Defaults to 2. */ overviewRulerLanes?: number; /** * Controls if a border should be drawn around the overview ruler. * Defaults to `true`. */ overviewRulerBorder?: boolean; /** * Control the cursor animation style, possible values are 'blink', 'smooth', 'phase', 'expand' and 'solid'. * Defaults to 'blink'. */ cursorBlinking?: 'blink' | 'smooth' | 'phase' | 'expand' | 'solid'; /** * Zoom the font in the editor when using the mouse wheel in combination with holding Ctrl. * Defaults to false. */ mouseWheelZoom?: boolean; /** * Control the mouse pointer style, either 'text' or 'default' or 'copy' * Defaults to 'text' */ mouseStyle?: 'text' | 'default' | 'copy'; /** * Enable smooth caret animation. * Defaults to false. */ cursorSmoothCaretAnimation?: boolean; /** * Control the cursor style, either 'block' or 'line'. * Defaults to 'line'. */ cursorStyle?: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin'; /** * Control the width of the cursor when cursorStyle is set to 'line' */ cursorWidth?: number; /** * Enable font ligatures. * Defaults to false. */ fontLigatures?: boolean | string; /** * Disable the use of `will-change` for the editor margin and lines layers. * The usage of `will-change` acts as a hint for browsers to create an extra layer. * Defaults to false. */ disableLayerHinting?: boolean; /** * Disable the optimizations for monospace fonts. * Defaults to false. */ disableMonospaceOptimizations?: boolean; /** * Should the cursor be hidden in the overview ruler. * Defaults to false. */ hideCursorInOverviewRuler?: boolean; /** * Enable that scrolling can go one screen size after the last line. * Defaults to true. */ scrollBeyondLastLine?: boolean; /** * Enable that scrolling can go beyond the last column by a number of columns. * Defaults to 5. */ scrollBeyondLastColumn?: number; /** * Enable that the editor animates scrolling to a position. * Defaults to false. */ smoothScrolling?: boolean; /** * Enable that the editor will install an interval to check if its container dom node size has changed. * Enabling this might have a severe performance impact. * Defaults to false. */ automaticLayout?: boolean; /** * Control the wrapping of the editor. * When `wordWrap` = "off", the lines will never wrap. * When `wordWrap` = "on", the lines will wrap at the viewport width. * When `wordWrap` = "wordWrapColumn", the lines will wrap at `wordWrapColumn`. * When `wordWrap` = "bounded", the lines will wrap at min(viewport width, wordWrapColumn). * Defaults to "off". */ wordWrap?: 'off' | 'on' | 'wordWrapColumn' | 'bounded'; /** * Control the wrapping of the editor. * When `wordWrap` = "off", the lines will never wrap. * When `wordWrap` = "on", the lines will wrap at the viewport width. * When `wordWrap` = "wordWrapColumn", the lines will wrap at `wordWrapColumn`. * When `wordWrap` = "bounded", the lines will wrap at min(viewport width, wordWrapColumn). * Defaults to 80. */ wordWrapColumn?: number; /** * Force word wrapping when the text appears to be of a minified/generated file. * Defaults to true. */ wordWrapMinified?: boolean; /** * Control indentation of wrapped lines. Can be: 'none', 'same', 'indent' or 'deepIndent'. * Defaults to 'same' in vscode and to 'none' in monaco-editor. */ wrappingIndent?: 'none' | 'same' | 'indent' | 'deepIndent'; /** * Configure word wrapping characters. A break will be introduced before these characters. * Defaults to '{([+'. */ wordWrapBreakBeforeCharacters?: string; /** * Configure word wrapping characters. A break will be introduced after these characters. * Defaults to ' \t})]?|&,;'. */ wordWrapBreakAfterCharacters?: string; /** * Configure word wrapping characters. A break will be introduced after these characters only if no `wordWrapBreakBeforeCharacters` or `wordWrapBreakAfterCharacters` were found. * Defaults to '.'. */ wordWrapBreakObtrusiveCharacters?: string; /** * Performance guard: Stop rendering a line after x characters. * Defaults to 10000. * Use -1 to never stop rendering */ stopRenderingLineAfter?: number; /** * Configure the editor's hover. */ hover?: IEditorHoverOptions; /** * Enable detecting links and making them clickable. * Defaults to true. */ links?: boolean; /** * Enable inline color decorators and color picker rendering. */ colorDecorators?: boolean; /** * Enable custom contextmenu. * Defaults to true. */ contextmenu?: boolean; /** * A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events. * Defaults to 1. */ mouseWheelScrollSensitivity?: number; /** * FastScrolling mulitplier speed when pressing `Alt` * Defaults to 5. */ fastScrollSensitivity?: number; /** * The modifier to be used to add multiple cursors with the mouse. * Defaults to 'alt' */ multiCursorModifier?: 'ctrlCmd' | 'alt'; /** * Merge overlapping selections. * Defaults to true */ multiCursorMergeOverlapping?: boolean; /** * Configure the behaviour when pasting a text with the line count equal to the cursor count. * Defaults to 'spread'. */ multiCursorPaste?: 'spread' | 'full'; /** * Configure the editor's accessibility support. * Defaults to 'auto'. It is best to leave this to 'auto'. */ accessibilitySupport?: 'auto' | 'off' | 'on'; /** * Suggest options. */ suggest?: ISuggestOptions; /** * */ gotoLocation?: IGotoLocationOptions; /** * Enable quick suggestions (shadow suggestions) * Defaults to true. */ quickSuggestions?: boolean | IQuickSuggestionsOptions; /** * Quick suggestions show delay (in ms) * Defaults to 10 (ms) */ quickSuggestionsDelay?: number; /** * Parameter hint options. */ parameterHints?: IEditorParameterHintOptions; /** * Options for auto closing brackets. * Defaults to language defined behavior. */ autoClosingBrackets?: EditorAutoClosingStrategy; /** * Options for auto closing quotes. * Defaults to language defined behavior. */ autoClosingQuotes?: EditorAutoClosingStrategy; /** * Options for typing over closing quotes or brackets. */ autoClosingOvertype?: EditorAutoClosingOvertypeStrategy; /** * Options for auto surrounding. * Defaults to always allowing auto surrounding. */ autoSurround?: EditorAutoSurroundStrategy; /** * Enable auto indentation adjustment. * Defaults to false. */ autoIndent?: boolean; /** * Enable format on type. * Defaults to false. */ formatOnType?: boolean; /** * Enable format on paste. * Defaults to false. */ formatOnPaste?: boolean; /** * Controls if the editor should allow to move selections via drag and drop. * Defaults to false. */ dragAndDrop?: boolean; /** * Enable the suggestion box to pop-up on trigger characters. * Defaults to true. */ suggestOnTriggerCharacters?: boolean; /** * Accept suggestions on ENTER. * Defaults to 'on'. */ acceptSuggestionOnEnter?: 'on' | 'smart' | 'off'; /** * Accept suggestions on provider defined characters. * Defaults to true. */ acceptSuggestionOnCommitCharacter?: boolean; /** * Enable snippet suggestions. Default to 'true'. */ snippetSuggestions?: 'top' | 'bottom' | 'inline' | 'none'; /** * Copying without a selection copies the current line. */ emptySelectionClipboard?: boolean; /** * Syntax highlighting is copied. */ copyWithSyntaxHighlighting?: boolean; /** * The history mode for suggestions. */ suggestSelection?: 'first' | 'recentlyUsed' | 'recentlyUsedByPrefix'; /** * The font size for the suggest widget. * Defaults to the editor font size. */ suggestFontSize?: number; /** * The line height for the suggest widget. * Defaults to the editor line height. */ suggestLineHeight?: number; /** * Enable tab completion. */ tabCompletion?: 'on' | 'off' | 'onlySnippets'; /** * Enable selection highlight. * Defaults to true. */ selectionHighlight?: boolean; /** * Enable semantic occurrences highlight. * Defaults to true. */ occurrencesHighlight?: boolean; /** * Show code lens * Defaults to true. */ codeLens?: boolean; /** * Control the behavior and rendering of the code action lightbulb. */ lightbulb?: IEditorLightbulbOptions; /** * Timeout for running code actions on save. */ codeActionsOnSaveTimeout?: number; /** * Enable code folding * Defaults to true. */ folding?: boolean; /** * Selects the folding strategy. 'auto' uses the strategies contributed for the current document, 'indentation' uses the indentation based folding strategy. * Defaults to 'auto'. */ foldingStrategy?: 'auto' | 'indentation'; /** * Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter. * Defaults to 'mouseover'. */ showFoldingControls?: 'always' | 'mouseover'; /** * Enable highlighting of matching brackets. * Defaults to true. */ matchBrackets?: boolean; /** * Enable rendering of whitespace. * Defaults to none. */ renderWhitespace?: 'none' | 'boundary' | 'selection' | 'all'; /** * Enable rendering of control characters. * Defaults to false. */ renderControlCharacters?: boolean; /** * Enable rendering of indent guides. * Defaults to true. */ renderIndentGuides?: boolean; /** * Enable highlighting of the active indent guide. * Defaults to true. */ highlightActiveIndentGuide?: boolean; /** * Enable rendering of current line highlight. * Defaults to all. */ renderLineHighlight?: 'none' | 'gutter' | 'line' | 'all'; /** * Inserting and deleting whitespace follows tab stops. */ useTabStops?: boolean; /** * The font family */ fontFamily?: string; /** * The font weight */ fontWeight?: string; /** * The font size */ fontSize?: number; /** * The line height */ lineHeight?: number; /** * The letter spacing */ letterSpacing?: number; /** * Controls fading out of unused variables. */ showUnused?: boolean; } export interface IEditorConstructionOptions extends IEditorOptions { /** * The initial editor dimension (to avoid measuring the container). */ dimension?: IDimension; } /** * Configuration options for the diff editor. */ export interface IDiffEditorOptions extends IEditorOptions { /** * Allow the user to resize the diff editor split view. * Defaults to true. */ enableSplitViewResizing?: boolean; /** * Render the differences in two side-by-side editors. * Defaults to true. */ renderSideBySide?: boolean; /** * Compute the diff by ignoring leading/trailing whitespace * Defaults to true. */ ignoreTrimWhitespace?: boolean; /** * Render +/- indicators for added/deleted changes. * Defaults to true. */ renderIndicators?: boolean; /** * Original model should be editable? * Defaults to false. */ originalEditable?: boolean; } //#endregion /** * An event describing that the configuration of the editor has changed. */ export class ConfigurationChangedEvent { private readonly _values: boolean[]; /** * @internal */ constructor(values: boolean[]) { this._values = values; } /** * @internal */ public hasChanged(id: EditorOption): boolean { return this._values[id]; } } /** * @internal */ export class ValidatedEditorOptions { private readonly _values: any[] = []; public _read(option: EditorOption): T { return this._values[option]; } public get(id: T): FindComputedEditorOptionValueById { return this._values[id]; } public _write(option: EditorOption, value: T): void { this._values[option] = value; } } /** * @internal */ export interface IComputedEditorOptions { get(id: T): FindComputedEditorOptionValueById; } //#region IEditorOption /** * @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; } /** * @internal */ export interface IEditorOption { readonly id: K1; readonly name: string; readonly defaultValue: V; /** * @internal */ readonly schema: IConfigurationPropertySchema | { [path: string]: IConfigurationPropertySchema; } | undefined; /** * @internal */ validate(input: any): V; /** * @internal */ compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: V): V; } type PossibleKeyName0 = { [K in keyof IEditorOptions]: IEditorOptions[K] extends V | undefined ? K : never }[keyof IEditorOptions]; type PossibleKeyName = NonNullable>; /** * @internal */ abstract class BaseEditorOption implements IEditorOption { public readonly id: K1; public readonly name: string; public readonly defaultValue: V; public readonly schema: IConfigurationPropertySchema | { [path: string]: IConfigurationPropertySchema; } | undefined; constructor(id: K1, name: string, defaultValue: V, schema?: IConfigurationPropertySchema | { [path: string]: IConfigurationPropertySchema; }) { this.id = id; this.name = name; this.defaultValue = defaultValue; this.schema = schema; } public abstract validate(input: any): V; public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: V): V { return value; } } /** * @internal */ abstract class ComputedEditorOption implements IEditorOption { public readonly id: K1; public readonly name: '_never_'; public readonly defaultValue: V; public readonly deps: EditorOption[] | null; public readonly schema: IConfigurationPropertySchema | undefined = undefined; constructor(id: K1, deps: EditorOption[] | null = null) { this.id = id; this.name = '_never_'; this.defaultValue = undefined; this.deps = deps; } public validate(input: any): V { return this.defaultValue; } public abstract compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: V): V; } class SimpleEditorOption implements IEditorOption { public readonly id: K1; public readonly name: PossibleKeyName; public readonly defaultValue: V; public readonly schema: IConfigurationPropertySchema | undefined; constructor(id: K1, name: PossibleKeyName, defaultValue: V, schema?: IConfigurationPropertySchema) { this.id = id; this.name = name; this.defaultValue = defaultValue; this.schema = schema; } public validate(input: any): V { if (typeof input === 'undefined') { return this.defaultValue; } return input as any; } public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: V): V { return value; } } class EditorBooleanOption extends SimpleEditorOption { public static boolean(value: any, defaultValue: boolean): boolean { if (typeof value === 'undefined') { return defaultValue; } if (value === 'false') { // treat the string 'false' as false return false; } return Boolean(value); } constructor(id: K1, name: PossibleKeyName, defaultValue: boolean, schema: IConfigurationPropertySchema | undefined = undefined) { if (typeof schema !== 'undefined') { schema.type = 'boolean'; schema.default = defaultValue; } super(id, name, defaultValue, schema); } public validate(input: any): boolean { return EditorBooleanOption.boolean(input, this.defaultValue); } } class EditorIntOption extends SimpleEditorOption { public static 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; } public readonly minimum: number; public readonly maximum: number; constructor(id: K1, name: PossibleKeyName, defaultValue: number, minimum: number, maximum: number, schema: IConfigurationPropertySchema | undefined = undefined) { if (typeof schema !== 'undefined') { schema.type = 'integer'; schema.default = defaultValue; schema.minimum = minimum; schema.maximum = maximum; } super(id, name, defaultValue, schema); this.minimum = minimum; this.maximum = maximum; } public validate(input: any): number { return EditorIntOption.clampedInt(input, this.defaultValue, this.minimum, this.maximum); } } class EditorFloatOption extends SimpleEditorOption { public static clamp(n: number, min: number, max: number): number { if (n < min) { return min; } if (n > max) { return max; } return n; } public static float(value: any, defaultValue: number): number { if (typeof value === 'number') { return value; } if (typeof value === 'undefined') { return defaultValue; } const r = parseFloat(value); return (isNaN(r) ? defaultValue : r); } public readonly validationFn: (value: number) => number; constructor(id: K1, name: PossibleKeyName, defaultValue: number, validationFn: (value: number) => number, schema?: IConfigurationPropertySchema) { if (typeof schema !== 'undefined') { schema.type = 'number'; schema.default = defaultValue; } super(id, name, defaultValue, schema); this.validationFn = validationFn; } public validate(input: any): number { return this.validationFn(EditorFloatOption.float(input, this.defaultValue)); } } class EditorStringOption extends SimpleEditorOption { public static string(value: any, defaultValue: string): string { if (typeof value !== 'string') { return defaultValue; } return value; } constructor(id: K1, name: PossibleKeyName, defaultValue: string, schema: IConfigurationPropertySchema | undefined = undefined) { if (typeof schema !== 'undefined') { schema.type = 'string'; schema.default = defaultValue; } super(id, name, defaultValue, schema); } public validate(input: any): string { return EditorStringOption.string(input, this.defaultValue); } } class EditorStringEnumOption extends SimpleEditorOption { public static stringSet(value: T | undefined, defaultValue: T, allowedValues: ReadonlyArray): T { if (typeof value !== 'string') { return defaultValue; } if (allowedValues.indexOf(value) === -1) { return defaultValue; } return value; } private readonly _allowedValues: ReadonlyArray; constructor(id: K1, name: PossibleKeyName, defaultValue: V, allowedValues: ReadonlyArray, schema: IConfigurationPropertySchema | undefined = undefined) { if (typeof schema !== 'undefined') { schema.type = 'string'; schema.enum = allowedValues; schema.default = defaultValue; } super(id, name, defaultValue, schema); this._allowedValues = allowedValues; } public validate(input: any): V { return EditorStringEnumOption.stringSet(input, this.defaultValue, this._allowedValues); } } class EditorEnumOption extends BaseEditorOption { private readonly _allowedValues: T[]; private readonly _convert: (value: T) => V; constructor(id: K1, name: PossibleKeyName, defaultValue: V, defaultStringValue: string, allowedValues: T[], convert: (value: T) => V, schema: IConfigurationPropertySchema | undefined = undefined) { if (typeof schema !== 'undefined') { schema.type = 'string'; schema.enum = allowedValues; schema.default = defaultStringValue; } super(id, name, defaultValue, schema); this._allowedValues = allowedValues; this._convert = convert; } public validate(input: any): V { if (typeof input !== 'string') { return this.defaultValue; } if (this._allowedValues.indexOf(input) === -1) { return this.defaultValue; } return this._convert(input); } } //#endregion //#region accessibilitySupport class EditorAccessibilitySupport extends BaseEditorOption { constructor() { super( EditorOption.accessibilitySupport, 'accessibilitySupport', AccessibilitySupport.Unknown, { type: 'string', enum: ['auto', 'on', 'off'], enumDescriptions: [ nls.localize('accessibilitySupport.auto', "The editor will use platform APIs to detect when a Screen Reader is attached."), 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: 'auto', description: nls.localize('accessibilitySupport', "Controls whether the editor should run in a mode where it is optimized for screen readers.") } ); } public validate(input: any): AccessibilitySupport { switch (input) { case 'auto': return AccessibilitySupport.Unknown; case 'off': return AccessibilitySupport.Disabled; case 'on': return AccessibilitySupport.Enabled; } return this.defaultValue; } public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: AccessibilitySupport): AccessibilitySupport { if (value === AccessibilitySupport.Unknown) { // The editor reads the `accessibilitySupport` from the environment return env.accessibilitySupport; } return value; } } //#endregion //#region cursorBlinking /** * The kind of animation in which the editor's cursor should be rendered. */ export const enum TextEditorCursorBlinkingStyle { /** * Hidden */ Hidden = 0, /** * Blinking */ Blink = 1, /** * Blinking with smooth fading */ Smooth = 2, /** * Blinking with prolonged filled state and smooth fading */ Phase = 3, /** * Expand collapse animation on the y axis */ Expand = 4, /** * No-Blinking */ Solid = 5 } function _cursorBlinkingStyleFromString(cursorBlinkingStyle: 'blink' | 'smooth' | 'phase' | 'expand' | 'solid'): TextEditorCursorBlinkingStyle { switch (cursorBlinkingStyle) { case 'blink': return TextEditorCursorBlinkingStyle.Blink; case 'smooth': return TextEditorCursorBlinkingStyle.Smooth; case 'phase': return TextEditorCursorBlinkingStyle.Phase; case 'expand': return TextEditorCursorBlinkingStyle.Expand; case 'solid': return TextEditorCursorBlinkingStyle.Solid; } } //#endregion //#region cursorStyle /** * The style in which the editor's cursor should be rendered. */ export enum TextEditorCursorStyle { /** * As a vertical line (sitting between two characters). */ Line = 1, /** * As a block (sitting on top of a character). */ Block = 2, /** * As a horizontal line (sitting under a character). */ Underline = 3, /** * As a thin vertical line (sitting between two characters). */ LineThin = 4, /** * As an outlined block (sitting on top of a character). */ BlockOutline = 5, /** * As a thin horizontal line (sitting under a character). */ UnderlineThin = 6 } /** * @internal */ export function cursorStyleToString(cursorStyle: TextEditorCursorStyle): 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin' { switch (cursorStyle) { case TextEditorCursorStyle.Line: return 'line'; case TextEditorCursorStyle.Block: return 'block'; case TextEditorCursorStyle.Underline: return 'underline'; case TextEditorCursorStyle.LineThin: return 'line-thin'; case TextEditorCursorStyle.BlockOutline: return 'block-outline'; case TextEditorCursorStyle.UnderlineThin: return 'underline-thin'; } } function _cursorStyleFromString(cursorStyle: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin'): TextEditorCursorStyle { switch (cursorStyle) { case 'line': return TextEditorCursorStyle.Line; case 'block': return TextEditorCursorStyle.Block; case 'underline': return TextEditorCursorStyle.Underline; case 'line-thin': return TextEditorCursorStyle.LineThin; case 'block-outline': return TextEditorCursorStyle.BlockOutline; case 'underline-thin': return TextEditorCursorStyle.UnderlineThin; } } //#endregion //#region editorClassName class EditorClassName extends ComputedEditorOption { constructor() { super(EditorOption.editorClassName, [EditorOption.mouseStyle, EditorOption.extraEditorClassName]); } public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: string): string { let className = 'monaco-editor'; if (options.get(EditorOption.extraEditorClassName)) { className += ' ' + options.get(EditorOption.extraEditorClassName); } if (env.extraEditorClassName) { className += ' ' + env.extraEditorClassName; } if (options.get(EditorOption.mouseStyle) === 'default') { className += ' mouse-default'; } else if (options.get(EditorOption.mouseStyle) === 'copy') { className += ' mouse-copy'; } return className; } } //#endregion //#region emptySelectionClipboard class EditorEmptySelectionClipboard extends EditorBooleanOption { constructor() { super( EditorOption.emptySelectionClipboard, 'emptySelectionClipboard', true, { description: nls.localize('emptySelectionClipboard', "Controls whether copying without a selection copies the current line.") } ); } public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: boolean): boolean { return value && env.emptySelectionClipboard; } } //#endregion //#region find /** * Configuration options for editor find widget */ export interface IEditorFindOptions { /** * Controls if we seed search string in the Find Widget with editor selection. */ seedSearchStringFromSelection?: boolean; /** * Controls if Find in Selection flag is turned on when multiple lines of text are selected in the editor. */ autoFindInSelection?: boolean; /* * Controls whether the Find Widget should add extra lines on top of the editor. */ addExtraSpaceOnTop?: boolean; /** * @internal * Controls if the Find Widget should read or modify the shared find clipboard on macOS */ globalFindClipboard?: boolean; } export type EditorFindOptions = Readonly>; class EditorFind extends BaseEditorOption { constructor() { const defaults: EditorFindOptions = { seedSearchStringFromSelection: true, autoFindInSelection: false, globalFindClipboard: false, addExtraSpaceOnTop: true }; super( EditorOption.find, 'find', defaults, { 'editor.find.seedSearchStringFromSelection': { type: 'boolean', default: defaults.seedSearchStringFromSelection, description: nls.localize('find.seedSearchStringFromSelection', "Controls whether the search string in the Find Widget is seeded from the editor selection.") }, 'editor.find.autoFindInSelection': { type: 'boolean', default: defaults.autoFindInSelection, description: nls.localize('find.autoFindInSelection', "Controls whether the find operation is carried out on selected text or the entire file in the editor.") }, 'editor.find.globalFindClipboard': { type: 'boolean', default: defaults.globalFindClipboard, description: nls.localize('find.globalFindClipboard', "Controls whether the Find Widget should read or modify the shared find clipboard on macOS."), included: platform.isMacintosh }, 'editor.find.addExtraSpaceOnTop': { type: 'boolean', default: defaults.addExtraSpaceOnTop, description: nls.localize('find.addExtraSpaceOnTop', "Controls whether the Find Widget should add extra lines on top of the editor. When true, you can scroll beyond the first line when the Find Widget is visible.") } } ); } public validate(_input: any): EditorFindOptions { if (typeof _input !== 'object') { return this.defaultValue; } const input = _input as IEditorFindOptions; return { seedSearchStringFromSelection: EditorBooleanOption.boolean(input.seedSearchStringFromSelection, this.defaultValue.seedSearchStringFromSelection), autoFindInSelection: EditorBooleanOption.boolean(input.autoFindInSelection, this.defaultValue.autoFindInSelection), globalFindClipboard: EditorBooleanOption.boolean(input.globalFindClipboard, this.defaultValue.globalFindClipboard), addExtraSpaceOnTop: EditorBooleanOption.boolean(input.addExtraSpaceOnTop, this.defaultValue.addExtraSpaceOnTop) }; } } //#endregion //#region fontLigatures /** * @internal */ export class EditorFontLigatures extends BaseEditorOption { public static OFF = '"liga" off, "calt" off'; public static ON = '"liga" on, "calt" on'; constructor() { super( EditorOption.fontLigatures, 'fontLigatures', EditorFontLigatures.OFF, { anyOf: [ { type: 'boolean', description: nls.localize('fontLigatures', "Enables/Disables font ligatures."), }, { type: 'string', description: nls.localize('fontFeatureSettings', "Explicit font-feature-settings.") } ], default: false } ); } public validate(input: any): string { if (typeof input === 'undefined') { return this.defaultValue; } if (typeof input === 'string') { if (input === 'false') { return EditorFontLigatures.OFF; } if (input === 'true') { return EditorFontLigatures.ON; } return input; } if (Boolean(input)) { return EditorFontLigatures.ON; } return EditorFontLigatures.OFF; } } //#endregion //#region fontInfo class EditorFontInfo extends ComputedEditorOption { constructor() { super(EditorOption.fontInfo); } public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: FontInfo): FontInfo { return env.fontInfo; } } //#endregion //#region fontSize class EditorFontSize extends SimpleEditorOption { constructor() { super( EditorOption.fontSize, 'fontSize', EDITOR_FONT_DEFAULTS.fontSize, { type: 'number', default: EDITOR_FONT_DEFAULTS.fontSize, description: nls.localize('fontSize', "Controls the font size in pixels.") } ); } public validate(input: any): number { let r = EditorFloatOption.float(input, this.defaultValue); if (r === 0) { return EDITOR_FONT_DEFAULTS.fontSize; } return EditorFloatOption.clamp(r, 8, 100); } public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: number): number { // The final fontSize respects the editor zoom level. // So take the result from env.fontInfo return env.fontInfo.fontSize; } } //#endregion //#region gotoLocation /** * Configuration options for go to location */ export interface IGotoLocationOptions { /** * Control how goto-command work when having multiple results. */ multiple?: 'peek' | 'gotoAndPeek' | 'goto'; } export type GoToLocationOptions = Readonly>; class EditorGoToLocation extends BaseEditorOption { constructor() { const defaults: GoToLocationOptions = { multiple: 'peek' }; super( EditorOption.gotoLocation, 'gotoLocation', defaults, { 'editor.gotoLocation.multiple': { description: nls.localize('editor.gotoLocation.multiple', "Controls the behavior of 'Go To' commands, like Go To Definition, when multiple target locations exist."), type: 'string', enum: ['peek', 'gotoAndPeek', 'goto'], default: defaults.multiple, enumDescriptions: [ nls.localize('editor.gotoLocation.multiple.peek', 'Show peek view of the results (default)'), nls.localize('editor.gotoLocation.multiple.gotoAndPeek', 'Go to the primary result and show a peek view'), nls.localize('editor.gotoLocation.multiple.goto', 'Go to the primary result and enable peek-less navigation to others') ] }, } ); } public validate(_input: any): GoToLocationOptions { if (typeof _input !== 'object') { return this.defaultValue; } const input = _input as IGotoLocationOptions; return { multiple: EditorStringEnumOption.stringSet<'peek' | 'gotoAndPeek' | 'goto'>(input.multiple, this.defaultValue.multiple, ['peek', 'gotoAndPeek', 'goto']) }; } } //#endregion //#region hover /** * Configuration options for editor hover */ export interface IEditorHoverOptions { /** * Enable the hover. * Defaults to true. */ enabled?: boolean; /** * Delay for showing the hover. * Defaults to 300. */ delay?: number; /** * Is the hover sticky such that it can be clicked and its contents selected? * Defaults to true. */ sticky?: boolean; } export type EditorHoverOptions = Readonly>; class EditorHover extends BaseEditorOption { constructor() { const defaults: EditorHoverOptions = { enabled: true, delay: 300, sticky: true }; super( EditorOption.hover, 'hover', defaults, { 'editor.hover.enabled': { type: 'boolean', default: defaults.enabled, description: nls.localize('hover.enabled', "Controls whether the hover is shown.") }, 'editor.hover.delay': { type: 'number', default: defaults.delay, description: nls.localize('hover.delay', "Controls the delay in milliseconds after which the hover is shown.") }, 'editor.hover.sticky': { type: 'boolean', default: defaults.sticky, description: nls.localize('hover.sticky', "Controls whether the hover should remain visible when mouse is moved over it.") }, } ); } public validate(_input: any): EditorHoverOptions { if (typeof _input !== 'object') { return this.defaultValue; } const input = _input as IEditorHoverOptions; return { enabled: EditorBooleanOption.boolean(input.enabled, this.defaultValue.enabled), delay: EditorIntOption.clampedInt(input.delay, this.defaultValue.delay, 0, 10000), sticky: EditorBooleanOption.boolean(input.sticky, this.defaultValue.sticky) }; } } //#endregion //#region layoutInfo /** * A description for the overview ruler position. */ export interface OverviewRulerPosition { /** * Width of the overview ruler */ readonly width: number; /** * Height of the overview ruler */ readonly height: number; /** * Top position for the overview ruler */ readonly top: number; /** * Right position for the overview ruler */ readonly right: number; } export const enum RenderMinimap { None = 0, Small = 1, Large = 2, SmallBlocks = 3, LargeBlocks = 4, } /** * The internal layout details of the editor. */ export interface EditorLayoutInfo { /** * Full editor width. */ readonly width: number; /** * Full editor height. */ readonly height: number; /** * Left position for the glyph margin. */ readonly glyphMarginLeft: number; /** * The width of the glyph margin. */ readonly glyphMarginWidth: number; /** * The height of the glyph margin. */ readonly glyphMarginHeight: number; /** * Left position for the line numbers. */ readonly lineNumbersLeft: number; /** * The width of the line numbers. */ readonly lineNumbersWidth: number; /** * The height of the line numbers. */ readonly lineNumbersHeight: number; /** * Left position for the line decorations. */ readonly decorationsLeft: number; /** * The width of the line decorations. */ readonly decorationsWidth: number; /** * The height of the line decorations. */ readonly decorationsHeight: number; /** * Left position for the content (actual text) */ readonly contentLeft: number; /** * The width of the content (actual text) */ readonly contentWidth: number; /** * The height of the content (actual height) */ readonly contentHeight: number; /** * The position for the minimap */ readonly minimapLeft: number; /** * The width of the minimap */ readonly minimapWidth: number; /** * Minimap render type */ readonly renderMinimap: RenderMinimap; /** * The number of columns (of typical characters) fitting on a viewport line. */ readonly viewportColumn: number; /** * The width of the vertical scrollbar. */ readonly verticalScrollbarWidth: number; /** * The height of the horizontal scrollbar. */ readonly horizontalScrollbarHeight: number; /** * The position of the overview ruler. */ readonly overviewRuler: OverviewRulerPosition; } /** * @internal */ export interface EditorLayoutInfoComputerEnv { outerWidth: number; outerHeight: number; lineHeight: number; lineNumbersDigitCount: number; typicalHalfwidthCharacterWidth: number; maxDigitWidth: number; pixelRatio: number; } /** * @internal */ export class EditorLayoutInfoComputer extends ComputedEditorOption { constructor() { super( EditorOption.layoutInfo, [EditorOption.glyphMargin, EditorOption.lineDecorationsWidth, EditorOption.folding, EditorOption.minimap, EditorOption.scrollbar, EditorOption.lineNumbers] ); } public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: EditorLayoutInfo): EditorLayoutInfo { return EditorLayoutInfoComputer.computeLayout(options, { outerWidth: env.outerWidth, outerHeight: env.outerHeight, lineHeight: env.fontInfo.lineHeight, lineNumbersDigitCount: env.lineNumbersDigitCount, typicalHalfwidthCharacterWidth: env.fontInfo.typicalHalfwidthCharacterWidth, maxDigitWidth: env.fontInfo.maxDigitWidth, pixelRatio: env.pixelRatio }); } public static computeLayout(options: IComputedEditorOptions, env: EditorLayoutInfoComputerEnv): EditorLayoutInfo { const outerWidth = env.outerWidth | 0; const outerHeight = env.outerHeight | 0; const lineHeight = env.lineHeight | 0; const lineNumbersDigitCount = env.lineNumbersDigitCount | 0; const typicalHalfwidthCharacterWidth = env.typicalHalfwidthCharacterWidth; const maxDigitWidth = env.maxDigitWidth; const pixelRatio = env.pixelRatio; const showGlyphMargin = options.get(EditorOption.glyphMargin); const showLineNumbers = (options.get(EditorOption.lineNumbers).renderType !== RenderLineNumbersType.Off); const lineNumbersMinChars = options.get(EditorOption.lineNumbersMinChars) | 0; const minimap = options.get(EditorOption.minimap); const minimapEnabled = minimap.enabled; const minimapSide = minimap.side; const minimapRenderCharacters = minimap.renderCharacters; const minimapMaxColumn = minimap.maxColumn | 0; const scrollbar = options.get(EditorOption.scrollbar); const verticalScrollbarWidth = scrollbar.verticalScrollbarSize | 0; const verticalScrollbarHasArrows = scrollbar.verticalHasArrows; const scrollbarArrowSize = scrollbar.arrowSize | 0; const horizontalScrollbarHeight = scrollbar.horizontalScrollbarSize | 0; const rawLineDecorationsWidth = options.get(EditorOption.lineDecorationsWidth); const folding = options.get(EditorOption.folding); let lineDecorationsWidth: number; if (typeof rawLineDecorationsWidth === 'string' && /^\d+(\.\d+)?ch$/.test(rawLineDecorationsWidth)) { const multiple = parseFloat(rawLineDecorationsWidth.substr(0, rawLineDecorationsWidth.length - 2)); lineDecorationsWidth = EditorIntOption.clampedInt(multiple * typicalHalfwidthCharacterWidth, 0, 0, 1000); } else { lineDecorationsWidth = EditorIntOption.clampedInt(rawLineDecorationsWidth, 0, 0, 1000); } if (folding) { lineDecorationsWidth += 16; } let lineNumbersWidth = 0; if (showLineNumbers) { const digitCount = Math.max(lineNumbersDigitCount, lineNumbersMinChars); lineNumbersWidth = Math.round(digitCount * maxDigitWidth); } let glyphMarginWidth = 0; if (showGlyphMargin) { glyphMarginWidth = lineHeight; } let glyphMarginLeft = 0; let lineNumbersLeft = glyphMarginLeft + glyphMarginWidth; let decorationsLeft = lineNumbersLeft + lineNumbersWidth; let contentLeft = decorationsLeft + lineDecorationsWidth; const remainingWidth = outerWidth - glyphMarginWidth - lineNumbersWidth - lineDecorationsWidth; let renderMinimap: RenderMinimap; let minimapLeft: number; let minimapWidth: number; let contentWidth: number; if (!minimapEnabled) { minimapLeft = 0; minimapWidth = 0; renderMinimap = RenderMinimap.None; contentWidth = remainingWidth; } else { let minimapCharWidth: number; if (pixelRatio >= 2) { renderMinimap = minimapRenderCharacters ? RenderMinimap.Large : RenderMinimap.LargeBlocks; minimapCharWidth = 2 / pixelRatio; } else { renderMinimap = minimapRenderCharacters ? RenderMinimap.Small : RenderMinimap.SmallBlocks; minimapCharWidth = 1 / pixelRatio; } // Given: // (leaving 2px for the cursor to have space after the last character) // viewportColumn = (contentWidth - verticalScrollbarWidth - 2) / typicalHalfwidthCharacterWidth // minimapWidth = viewportColumn * minimapCharWidth // contentWidth = remainingWidth - minimapWidth // What are good values for contentWidth and minimapWidth ? // minimapWidth = ((contentWidth - verticalScrollbarWidth - 2) / typicalHalfwidthCharacterWidth) * minimapCharWidth // typicalHalfwidthCharacterWidth * minimapWidth = (contentWidth - verticalScrollbarWidth - 2) * minimapCharWidth // typicalHalfwidthCharacterWidth * minimapWidth = (remainingWidth - minimapWidth - verticalScrollbarWidth - 2) * minimapCharWidth // (typicalHalfwidthCharacterWidth + minimapCharWidth) * minimapWidth = (remainingWidth - verticalScrollbarWidth - 2) * minimapCharWidth // minimapWidth = ((remainingWidth - verticalScrollbarWidth - 2) * minimapCharWidth) / (typicalHalfwidthCharacterWidth + minimapCharWidth) minimapWidth = Math.max(0, Math.floor(((remainingWidth - verticalScrollbarWidth - 2) * minimapCharWidth) / (typicalHalfwidthCharacterWidth + minimapCharWidth))); let minimapColumns = minimapWidth / minimapCharWidth; if (minimapColumns > minimapMaxColumn) { minimapWidth = Math.floor(minimapMaxColumn * minimapCharWidth); } contentWidth = remainingWidth - minimapWidth; if (minimapSide === 'left') { minimapLeft = 0; glyphMarginLeft += minimapWidth; lineNumbersLeft += minimapWidth; decorationsLeft += minimapWidth; contentLeft += minimapWidth; } else { minimapLeft = outerWidth - minimapWidth - verticalScrollbarWidth; } } // (leaving 2px for the cursor to have space after the last character) const viewportColumn = Math.max(1, Math.floor((contentWidth - verticalScrollbarWidth - 2) / typicalHalfwidthCharacterWidth)); const verticalArrowSize = (verticalScrollbarHasArrows ? scrollbarArrowSize : 0); return { width: outerWidth, height: outerHeight, glyphMarginLeft: glyphMarginLeft, glyphMarginWidth: glyphMarginWidth, glyphMarginHeight: outerHeight, lineNumbersLeft: lineNumbersLeft, lineNumbersWidth: lineNumbersWidth, lineNumbersHeight: outerHeight, decorationsLeft: decorationsLeft, decorationsWidth: lineDecorationsWidth, decorationsHeight: outerHeight, contentLeft: contentLeft, contentWidth: contentWidth, contentHeight: outerHeight, renderMinimap: renderMinimap, minimapLeft: minimapLeft, minimapWidth: minimapWidth, viewportColumn: viewportColumn, verticalScrollbarWidth: verticalScrollbarWidth, horizontalScrollbarHeight: horizontalScrollbarHeight, overviewRuler: { top: verticalArrowSize, width: verticalScrollbarWidth, height: (outerHeight - 2 * verticalArrowSize), right: 0 } }; } } //#endregion //#region lightbulb /** * Configuration options for editor lightbulb */ export interface IEditorLightbulbOptions { /** * Enable the lightbulb code action. * Defaults to true. */ enabled?: boolean; } export type EditorLightbulbOptions = Readonly>; class EditorLightbulb extends BaseEditorOption { constructor() { const defaults: EditorLightbulbOptions = { enabled: true }; super( EditorOption.lightbulb, 'lightbulb', defaults, { 'editor.lightbulb.enabled': { type: 'boolean', default: defaults.enabled, description: nls.localize('codeActions', "Enables the code action lightbulb in the editor.") }, } ); } public validate(_input: any): EditorLightbulbOptions { if (typeof _input !== 'object') { return this.defaultValue; } const input = _input as IEditorLightbulbOptions; return { enabled: EditorBooleanOption.boolean(input.enabled, this.defaultValue.enabled) }; } } //#endregion //#region lineHeight class EditorLineHeight extends EditorIntOption { constructor() { super( EditorOption.lineHeight, 'lineHeight', EDITOR_FONT_DEFAULTS.lineHeight, 0, 150, { description: nls.localize('lineHeight', "Controls the line height. Use 0 to compute the line height from the font size.") } ); } public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: number): number { // The lineHeight is computed from the fontSize if it is 0. // Moreover, the final lineHeight respects the editor zoom level. // So take the result from env.fontInfo return env.fontInfo.lineHeight; } } //#endregion //#region minimap /** * Configuration options for editor minimap */ export interface IEditorMinimapOptions { /** * Enable the rendering of the minimap. * Defaults to true. */ enabled?: boolean; /** * Control the side of the minimap in editor. * Defaults to 'right'. */ side?: 'right' | 'left'; /** * Control the rendering of the minimap slider. * Defaults to 'mouseover'. */ showSlider?: 'always' | 'mouseover'; /** * Render the actual text on a line (as opposed to color blocks). * Defaults to true. */ renderCharacters?: boolean; /** * Limit the width of the minimap to render at most a certain number of columns. * Defaults to 120. */ maxColumn?: number; } export type EditorMinimapOptions = Readonly>; class EditorMinimap extends BaseEditorOption { constructor() { const defaults: EditorMinimapOptions = { enabled: true, side: 'right', showSlider: 'mouseover', renderCharacters: true, maxColumn: 120, }; super( EditorOption.minimap, 'minimap', defaults, { 'editor.minimap.enabled': { type: 'boolean', default: defaults.enabled, description: nls.localize('minimap.enabled', "Controls whether the minimap is shown.") }, 'editor.minimap.side': { type: 'string', enum: ['left', 'right'], default: defaults.side, description: nls.localize('minimap.side', "Controls the side where to render the minimap.") }, 'editor.minimap.showSlider': { type: 'string', enum: ['always', 'mouseover'], default: defaults.showSlider, description: nls.localize('minimap.showSlider', "Controls whether the minimap slider is automatically hidden.") }, 'editor.minimap.renderCharacters': { type: 'boolean', default: defaults.renderCharacters, description: nls.localize('minimap.renderCharacters', "Render the actual characters on a line as opposed to color blocks.") }, 'editor.minimap.maxColumn': { type: 'number', default: defaults.maxColumn, description: nls.localize('minimap.maxColumn', "Limit the width of the minimap to render at most a certain number of columns.") }, } ); } public validate(_input: any): EditorMinimapOptions { if (typeof _input !== 'object') { return this.defaultValue; } const input = _input as IEditorMinimapOptions; return { enabled: EditorBooleanOption.boolean(input.enabled, this.defaultValue.enabled), side: EditorStringEnumOption.stringSet<'right' | 'left'>(input.side, this.defaultValue.side, ['right', 'left']), showSlider: EditorStringEnumOption.stringSet<'always' | 'mouseover'>(input.showSlider, this.defaultValue.showSlider, ['always', 'mouseover']), renderCharacters: EditorBooleanOption.boolean(input.renderCharacters, this.defaultValue.renderCharacters), maxColumn: EditorIntOption.clampedInt(input.maxColumn, this.defaultValue.maxColumn, 1, 10000), }; } } //#endregion //#region multiCursorModifier function _multiCursorModifierFromString(multiCursorModifier: 'ctrlCmd' | 'alt'): 'altKey' | 'metaKey' | 'ctrlKey' { if (multiCursorModifier === 'ctrlCmd') { return (platform.isMacintosh ? 'metaKey' : 'ctrlKey'); } return 'altKey'; } //#endregion //#region parameterHints /** * Configuration options for parameter hints */ export interface IEditorParameterHintOptions { /** * Enable parameter hints. * Defaults to true. */ enabled?: boolean; /** * Enable cycling of parameter hints. * Defaults to false. */ cycle?: boolean; } export type InternalParameterHintOptions = Readonly>; class EditorParameterHints extends BaseEditorOption { constructor() { const defaults: InternalParameterHintOptions = { enabled: true, cycle: false }; super( EditorOption.parameterHints, 'parameterHints', defaults, { 'editor.parameterHints.enabled': { type: 'boolean', default: defaults.enabled, description: nls.localize('parameterHints.enabled', "Enables a pop-up that shows parameter documentation and type information as you type.") }, 'editor.parameterHints.cycle': { type: 'boolean', default: defaults.cycle, description: nls.localize('parameterHints.cycle', "Controls whether the parameter hints menu cycles or closes when reaching the end of the list.") }, } ); } public validate(_input: any): InternalParameterHintOptions { if (typeof _input !== 'object') { return this.defaultValue; } const input = _input as IEditorParameterHintOptions; return { enabled: EditorBooleanOption.boolean(input.enabled, this.defaultValue.enabled), cycle: EditorBooleanOption.boolean(input.cycle, this.defaultValue.cycle) }; } } //#endregion //#region pixelRatio class EditorPixelRatio extends ComputedEditorOption { constructor() { super(EditorOption.pixelRatio); } public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: number): number { return env.pixelRatio; } } //#endregion //#region quickSuggestions /** * Configuration options for quick suggestions */ export interface IQuickSuggestionsOptions { other: boolean; comments: boolean; strings: boolean; } export type ValidQuickSuggestionsOptions = boolean | Readonly>; class EditorQuickSuggestions extends BaseEditorOption { public readonly defaultValue: Readonly>; constructor() { const defaults: ValidQuickSuggestionsOptions = { other: true, comments: false, strings: false }; super( EditorOption.quickSuggestions, 'quickSuggestions', defaults, { anyOf: [ { type: 'boolean', }, { type: 'object', properties: { strings: { type: 'boolean', default: defaults.strings, description: nls.localize('quickSuggestions.strings', "Enable quick suggestions inside strings.") }, comments: { type: 'boolean', default: defaults.comments, description: nls.localize('quickSuggestions.comments', "Enable quick suggestions inside comments.") }, other: { type: 'boolean', default: defaults.other, description: nls.localize('quickSuggestions.other', "Enable quick suggestions outside of strings and comments.") }, } } ], default: defaults, description: nls.localize('quickSuggestions', "Controls whether suggestions should automatically show up while typing.") } ); this.defaultValue = defaults; } public validate(_input: any): ValidQuickSuggestionsOptions { if (typeof _input === 'boolean') { return _input; } if (typeof _input === 'object') { const input = _input as IQuickSuggestionsOptions; const opts = { other: EditorBooleanOption.boolean(input.other, this.defaultValue.other), comments: EditorBooleanOption.boolean(input.comments, this.defaultValue.comments), strings: EditorBooleanOption.boolean(input.strings, this.defaultValue.strings), }; if (opts.other && opts.comments && opts.strings) { return true; // all on } else if (!opts.other && !opts.comments && !opts.strings) { return false; // all off } else { return opts; } } return this.defaultValue; } } //#endregion //#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 { constructor() { super( EditorOption.lineNumbers, 'lineNumbers', { renderType: RenderLineNumbersType.On, renderFn: null }, { type: 'string', enum: ['off', 'on', 'relative', 'interval'], enumDescriptions: [ nls.localize('lineNumbers.off', "Line numbers are not rendered."), nls.localize('lineNumbers.on', "Line numbers are rendered as absolute number."), nls.localize('lineNumbers.relative', "Line numbers are rendered as distance in lines to cursor position."), nls.localize('lineNumbers.interval', "Line numbers are rendered every 10 lines.") ], default: 'on', description: nls.localize('lineNumbers', "Controls the display of line numbers.") } ); } public validate(lineNumbers: any): 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 }; } } //#endregion //#region rulers class EditorRulers extends SimpleEditorOption { constructor() { const defaults: number[] = []; super( EditorOption.rulers, 'rulers', defaults, { type: 'array', items: { type: 'number' }, default: defaults, description: nls.localize('rulers', "Render vertical rulers after a certain number of monospace characters. Use multiple values for multiple rulers. No rulers are drawn if array is empty.") } ); } public validate(input: any): number[] { if (Array.isArray(input)) { let rulers: number[] = []; for (let value of input) { rulers.push(EditorIntOption.clampedInt(value, 0, 0, 10000)); } rulers.sort(); return rulers; } return this.defaultValue; } } //#endregion //#region scrollbar /** * Configuration options for editor scrollbars */ export interface IEditorScrollbarOptions { /** * The size of arrows (if displayed). * Defaults to 11. */ arrowSize?: number; /** * Render vertical scrollbar. * Defaults to 'auto'. */ vertical?: 'auto' | 'visible' | 'hidden'; /** * Render horizontal scrollbar. * Defaults to 'auto'. */ horizontal?: 'auto' | 'visible' | 'hidden'; /** * Cast horizontal and vertical shadows when the content is scrolled. * Defaults to true. */ useShadows?: boolean; /** * Render arrows at the top and bottom of the vertical scrollbar. * Defaults to false. */ verticalHasArrows?: boolean; /** * Render arrows at the left and right of the horizontal scrollbar. * Defaults to false. */ horizontalHasArrows?: boolean; /** * Listen to mouse wheel events and react to them by scrolling. * Defaults to true. */ handleMouseWheel?: boolean; /** * Height in pixels for the horizontal scrollbar. * Defaults to 10 (px). */ horizontalScrollbarSize?: number; /** * Width in pixels for the vertical scrollbar. * Defaults to 10 (px). */ verticalScrollbarSize?: number; /** * Width in pixels for the vertical slider. * Defaults to `verticalScrollbarSize`. */ verticalSliderSize?: number; /** * Height in pixels for the horizontal slider. * Defaults to `horizontalScrollbarSize`. */ horizontalSliderSize?: 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; } 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; } } class EditorScrollbar extends BaseEditorOption { constructor() { super( EditorOption.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, } ); } public validate(_input: any): InternalEditorScrollbarOptions { if (typeof _input !== 'object') { return this.defaultValue; } const input = _input as IEditorScrollbarOptions; const horizontalScrollbarSize = EditorIntOption.clampedInt(input.horizontalScrollbarSize, this.defaultValue.horizontalScrollbarSize, 0, 1000); const verticalScrollbarSize = EditorIntOption.clampedInt(input.verticalScrollbarSize, this.defaultValue.verticalScrollbarSize, 0, 1000); return { arrowSize: EditorIntOption.clampedInt(input.arrowSize, this.defaultValue.arrowSize, 0, 1000), vertical: _scrollbarVisibilityFromString(input.vertical, this.defaultValue.vertical), horizontal: _scrollbarVisibilityFromString(input.horizontal, this.defaultValue.horizontal), useShadows: EditorBooleanOption.boolean(input.useShadows, this.defaultValue.useShadows), verticalHasArrows: EditorBooleanOption.boolean(input.verticalHasArrows, this.defaultValue.verticalHasArrows), horizontalHasArrows: EditorBooleanOption.boolean(input.horizontalHasArrows, this.defaultValue.horizontalHasArrows), handleMouseWheel: EditorBooleanOption.boolean(input.handleMouseWheel, this.defaultValue.handleMouseWheel), horizontalScrollbarSize: horizontalScrollbarSize, horizontalSliderSize: EditorIntOption.clampedInt(input.horizontalSliderSize, horizontalScrollbarSize, 0, 1000), verticalScrollbarSize: verticalScrollbarSize, verticalSliderSize: EditorIntOption.clampedInt(input.verticalSliderSize, verticalScrollbarSize, 0, 1000), }; } } //#endregion //#region suggest /** * Configuration options for editor suggest widget */ export interface ISuggestOptions { /** * Enable graceful matching. Defaults to true. */ filterGraceful?: boolean; /** * Prevent quick suggestions when a snippet is active. Defaults to true. */ snippetsPreventQuickSuggestions?: boolean; /** * Favours words that appear close to the cursor. */ localityBonus?: boolean; /** * Enable using global storage for remembering suggestions. */ shareSuggestSelections?: boolean; /** * Enable or disable icons in suggestions. Defaults to true. */ showIcons?: boolean; /** * Max suggestions to show in suggestions. Defaults to 12. */ maxVisibleSuggestions?: number; /** * Names of suggestion types to filter. */ filteredTypes?: Record; } export type InternalSuggestOptions = Readonly>; class EditorSuggest extends BaseEditorOption { constructor() { const defaults: InternalSuggestOptions = { filterGraceful: true, snippetsPreventQuickSuggestions: true, localityBonus: false, shareSuggestSelections: false, showIcons: true, maxVisibleSuggestions: 12, filteredTypes: Object.create(null) }; super( EditorOption.suggest, 'suggest', defaults, { 'editor.suggest.filterGraceful': { type: 'boolean', default: defaults.filterGraceful, description: nls.localize('suggest.filterGraceful', "Controls whether filtering and sorting suggestions accounts for small typos.") }, 'editor.suggest.localityBonus': { type: 'boolean', default: defaults.localityBonus, description: nls.localize('suggest.localityBonus', "Controls whether sorting favours words that appear close to the cursor.") }, 'editor.suggest.shareSuggestSelections': { type: 'boolean', default: defaults.shareSuggestSelections, markdownDescription: nls.localize('suggest.shareSuggestSelections', "Controls whether remembered suggestion selections are shared between multiple workspaces and windows (needs `#editor.suggestSelection#`).") }, 'editor.suggest.snippetsPreventQuickSuggestions': { type: 'boolean', default: defaults.snippetsPreventQuickSuggestions, description: nls.localize('suggest.snippetsPreventQuickSuggestions', "Control whether an active snippet prevents quick suggestions.") }, 'editor.suggest.showIcons': { type: 'boolean', default: defaults.showIcons, description: nls.localize('suggest.showIcons', "Controls whether to show or hide icons in suggestions.") }, 'editor.suggest.maxVisibleSuggestions': { type: 'number', default: defaults.maxVisibleSuggestions, minimum: 1, maximum: 15, description: nls.localize('suggest.maxVisibleSuggestions', "Controls how many suggestions IntelliSense will show before showing a scrollbar (maximum 15).") }, 'editor.suggest.filteredTypes': { type: 'object', default: { keyword: true, snippet: true }, markdownDescription: nls.localize('suggest.filtered', "Controls whether some suggestion types should be filtered from IntelliSense. A list of suggestion types can be found here: https://code.visualstudio.com/docs/editor/intellisense#_types-of-completions."), properties: { method: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.method', "When set to `false` IntelliSense never shows `method` suggestions.") }, function: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.function', "When set to `false` IntelliSense never shows `function` suggestions.") }, constructor: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.constructor', "When set to `false` IntelliSense never shows `constructor` suggestions.") }, field: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.field', "When set to `false` IntelliSense never shows `field` suggestions.") }, variable: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.variable', "When set to `false` IntelliSense never shows `variable` suggestions.") }, class: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.class', "When set to `false` IntelliSense never shows `class` suggestions.") }, struct: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.struct', "When set to `false` IntelliSense never shows `struct` suggestions.") }, interface: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.interface', "When set to `false` IntelliSense never shows `interface` suggestions.") }, module: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.module', "When set to `false` IntelliSense never shows `module` suggestions.") }, property: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.property', "When set to `false` IntelliSense never shows `property` suggestions.") }, event: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.event', "When set to `false` IntelliSense never shows `event` suggestions.") }, operator: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.operator', "When set to `false` IntelliSense never shows `operator` suggestions.") }, unit: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.unit', "When set to `false` IntelliSense never shows `unit` suggestions.") }, value: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.value', "When set to `false` IntelliSense never shows `value` suggestions.") }, constant: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.constant', "When set to `false` IntelliSense never shows `constant` suggestions.") }, enum: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.enum', "When set to `false` IntelliSense never shows `enum` suggestions.") }, enumMember: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.enumMember', "When set to `false` IntelliSense never shows `enumMember` suggestions.") }, keyword: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.keyword', "When set to `false` IntelliSense never shows `keyword` suggestions.") }, text: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.text', "When set to `false` IntelliSense never shows `text` suggestions.") }, color: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.color', "When set to `false` IntelliSense never shows `color` suggestions.") }, file: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.file', "When set to `false` IntelliSense never shows `file` suggestions.") }, reference: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.reference', "When set to `false` IntelliSense never shows `reference` suggestions.") }, customcolor: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.customcolor', "When set to `false` IntelliSense never shows `customcolor` suggestions.") }, folder: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.folder', "When set to `false` IntelliSense never shows `folder` suggestions.") }, typeParameter: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.typeParameter', "When set to `false` IntelliSense never shows `typeParameter` suggestions.") }, snippet: { type: 'boolean', default: true, markdownDescription: nls.localize('suggest.filtered.snippet', "When set to `false` IntelliSense never shows `snippet` suggestions.") }, } }, } ); } public validate(_input: any): InternalSuggestOptions { if (typeof _input !== 'object') { return this.defaultValue; } const input = _input as ISuggestOptions; return { filterGraceful: EditorBooleanOption.boolean(input.filterGraceful, this.defaultValue.filterGraceful), snippetsPreventQuickSuggestions: EditorBooleanOption.boolean(input.snippetsPreventQuickSuggestions, this.defaultValue.filterGraceful), localityBonus: EditorBooleanOption.boolean(input.localityBonus, this.defaultValue.localityBonus), shareSuggestSelections: EditorBooleanOption.boolean(input.shareSuggestSelections, this.defaultValue.shareSuggestSelections), showIcons: EditorBooleanOption.boolean(input.showIcons, this.defaultValue.showIcons), maxVisibleSuggestions: EditorIntOption.clampedInt(input.maxVisibleSuggestions, this.defaultValue.maxVisibleSuggestions, 1, 15), filteredTypes: isObject(input.filteredTypes) ? input.filteredTypes : Object.create(null) }; } } //#endregion //#region tabFocusMode class EditorTabFocusMode extends ComputedEditorOption { constructor() { super(EditorOption.tabFocusMode, [EditorOption.readOnly]); } public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: boolean): boolean { const readOnly = options.get(EditorOption.readOnly); return (readOnly ? true : env.tabFocusMode); } } //#endregion //#region wrappingIndent /** * Describes how to indent wrapped lines. */ export const enum WrappingIndent { /** * No indentation => wrapped lines begin at column 1. */ None = 0, /** * Same => wrapped lines get the same indentation as the parent. */ Same = 1, /** * Indent => wrapped lines get +1 indentation toward the parent. */ Indent = 2, /** * DeepIndent => wrapped lines get +2 indentation toward the parent. */ DeepIndent = 3 } 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; } } //#endregion //#region wrappingInfo export interface EditorWrappingInfo { readonly isDominatedByLongLines: boolean; readonly isWordWrapMinified: boolean; readonly isViewportWrapping: boolean; readonly wrappingColumn: number; } class EditorWrappingInfoComputer extends ComputedEditorOption { constructor() { super(EditorOption.wrappingInfo, [EditorOption.wordWrap, EditorOption.wordWrapColumn, EditorOption.wordWrapMinified, EditorOption.layoutInfo, EditorOption.accessibilitySupport]); } public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: EditorWrappingInfo): EditorWrappingInfo { const wordWrap = options.get(EditorOption.wordWrap); const wordWrapColumn = options.get(EditorOption.wordWrapColumn); const wordWrapMinified = options.get(EditorOption.wordWrapMinified); const layoutInfo = options.get(EditorOption.layoutInfo); const accessibilitySupport = options.get(EditorOption.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, }; } } //#endregion 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 editorOptionsRegistry: IEditorOption[] = []; function register(option: IEditorOption): IEditorOption { editorOptionsRegistry[option.id] = option; return option; } /** * @internal */ export const enum EditorOption { acceptSuggestionOnCommitCharacter, acceptSuggestionOnEnter, accessibilitySupport, ariaLabel, autoClosingBrackets, autoClosingOvertype, autoClosingQuotes, autoIndent, automaticLayout, autoSurround, codeLens, colorDecorators, contextmenu, copyWithSyntaxHighlighting, cursorBlinking, cursorSmoothCaretAnimation, cursorStyle, cursorSurroundingLines, cursorWidth, disableLayerHinting, disableMonospaceOptimizations, dragAndDrop, emptySelectionClipboard, extraEditorClassName, fastScrollSensitivity, find, fixedOverflowWidgets, folding, foldingStrategy, fontFamily, fontInfo, fontLigatures, fontSize, fontWeight, formatOnPaste, formatOnType, glyphMargin, gotoLocation, hideCursorInOverviewRuler, highlightActiveIndentGuide, hover, inDiffEditor, letterSpacing, lightbulb, lineDecorationsWidth, lineHeight, lineNumbers, lineNumbersMinChars, links, matchBrackets, minimap, mouseStyle, mouseWheelScrollSensitivity, mouseWheelZoom, multiCursorMergeOverlapping, multiCursorModifier, multiCursorPaste, occurrencesHighlight, overviewRulerBorder, overviewRulerLanes, parameterHints, quickSuggestions, quickSuggestionsDelay, readOnly, renderControlCharacters, renderIndentGuides, renderFinalNewline, renderLineHighlight, renderWhitespace, revealHorizontalRightPadding, roundedSelection, rulers, scrollbar, scrollBeyondLastColumn, scrollBeyondLastLine, selectionClipboard, selectionHighlight, selectOnLineNumbers, showFoldingControls, showUnused, snippetSuggestions, smoothScrolling, stopRenderingLineAfter, suggest, suggestFontSize, suggestLineHeight, suggestOnTriggerCharacters, suggestSelection, tabCompletion, useTabStops, wordSeparators, wordWrap, wordWrapBreakAfterCharacters, wordWrapBreakBeforeCharacters, wordWrapBreakObtrusiveCharacters, wordWrapColumn, wordWrapMinified, wrappingIndent, // Leave these at the end (because they have dependencies!) editorClassName, pixelRatio, tabFocusMode, layoutInfo, wrappingInfo, } /** * @internal */ export const EditorOptions = { acceptSuggestionOnCommitCharacter: register(new EditorBooleanOption( EditorOption.acceptSuggestionOnCommitCharacter, 'acceptSuggestionOnCommitCharacter', true, { markdownDescription: nls.localize('acceptSuggestionOnCommitCharacter', "Controls whether suggestions should be accepted on commit characters. For example, in JavaScript, the semi-colon (`;`) can be a commit character that accepts a suggestion and types that character.") } )), acceptSuggestionOnEnter: register(new EditorStringEnumOption( EditorOption.acceptSuggestionOnEnter, 'acceptSuggestionOnEnter', 'on' as 'on' | 'smart' | 'off', ['on', 'smart', 'off'] as const, { markdownEnumDescriptions: [ '', nls.localize('acceptSuggestionOnEnterSmart', "Only accept a suggestion with `Enter` when it makes a textual change."), '' ], markdownDescription: nls.localize('acceptSuggestionOnEnter', "Controls whether suggestions should be accepted on `Enter`, in addition to `Tab`. Helps to avoid ambiguity between inserting new lines or accepting suggestions.") } )), accessibilitySupport: register(new EditorAccessibilitySupport()), ariaLabel: register(new EditorStringOption( EditorOption.ariaLabel, 'ariaLabel', nls.localize('editorViewAccessibleLabel', "Editor content") )), autoClosingBrackets: register(new EditorStringEnumOption( EditorOption.autoClosingBrackets, 'autoClosingBrackets', 'languageDefined' as 'always' | 'languageDefined' | 'beforeWhitespace' | 'never', ['always', 'languageDefined', 'beforeWhitespace', 'never'] as const, { enumDescriptions: [ '', nls.localize('editor.autoClosingBrackets.languageDefined', "Use language configurations to determine when to autoclose brackets."), nls.localize('editor.autoClosingBrackets.beforeWhitespace', "Autoclose brackets only when the cursor is to the left of whitespace."), '', ], description: nls.localize('autoClosingBrackets', "Controls whether the editor should automatically close brackets after the user adds an opening bracket.") } )), autoClosingOvertype: register(new EditorStringEnumOption( EditorOption.autoClosingOvertype, 'autoClosingOvertype', 'auto' as 'always' | 'auto' | 'never', ['always', 'auto', 'never'] as const, { enumDescriptions: [ '', nls.localize('editor.autoClosingOvertype.auto', "Type over closing quotes or brackets only if they were automatically inserted."), '', ], description: nls.localize('autoClosingOvertype', "Controls whether the editor should type over closing quotes or brackets.") } )), autoClosingQuotes: register(new EditorStringEnumOption( EditorOption.autoClosingQuotes, 'autoClosingQuotes', 'languageDefined' as 'always' | 'languageDefined' | 'beforeWhitespace' | 'never', ['always', 'languageDefined', 'beforeWhitespace', 'never'] as const, { enumDescriptions: [ '', nls.localize('editor.autoClosingQuotes.languageDefined', "Use language configurations to determine when to autoclose quotes."), nls.localize('editor.autoClosingQuotes.beforeWhitespace', "Autoclose quotes only when the cursor is to the left of whitespace."), '', ], description: nls.localize('autoClosingQuotes', "Controls whether the editor should automatically close quotes after the user adds an opening quote.") } )), autoIndent: register(new EditorBooleanOption( EditorOption.autoIndent, 'autoIndent', true, { description: nls.localize('autoIndent', "Controls whether the editor should automatically adjust the indentation when users type, paste or move lines. Extensions with indentation rules of the language must be available.") } )), automaticLayout: register(new EditorBooleanOption( EditorOption.automaticLayout, 'automaticLayout', false, )), autoSurround: register(new EditorStringEnumOption( EditorOption.autoSurround, 'autoSurround', 'languageDefined' as 'languageDefined' | 'quotes' | 'brackets' | 'never', ['languageDefined', 'quotes', 'brackets', 'never'] as const, { enumDescriptions: [ nls.localize('editor.autoSurround.languageDefined', "Use language configurations to determine when to automatically surround selections."), nls.localize('editor.autoSurround.quotes', "Surround with quotes but not brackets."), nls.localize('editor.autoSurround.brackets', "Surround with brackets but not quotes."), '' ], description: nls.localize('autoSurround', "Controls whether the editor should automatically surround selections.") } )), codeLens: register(new EditorBooleanOption( EditorOption.codeLens, 'codeLens', true, { description: nls.localize('codeLens', "Controls whether the editor shows CodeLens.") } )), colorDecorators: register(new EditorBooleanOption( EditorOption.colorDecorators, 'colorDecorators', true, { description: nls.localize('colorDecorators', "Controls whether the editor should render the inline color decorators and color picker.") } )), contextmenu: register(new EditorBooleanOption( EditorOption.contextmenu, 'contextmenu', true, )), copyWithSyntaxHighlighting: register(new EditorBooleanOption( EditorOption.copyWithSyntaxHighlighting, 'copyWithSyntaxHighlighting', true, { description: nls.localize('copyWithSyntaxHighlighting', "Controls whether syntax highlighting should be copied into the clipboard.") } )), cursorBlinking: register(new EditorEnumOption( EditorOption.cursorBlinking, 'cursorBlinking', TextEditorCursorBlinkingStyle.Blink, 'blink', ['blink', 'smooth', 'phase', 'expand', 'solid'], _cursorBlinkingStyleFromString, { description: nls.localize('cursorBlinking', "Control the cursor animation style.") } )), cursorSmoothCaretAnimation: register(new EditorBooleanOption( EditorOption.cursorSmoothCaretAnimation, 'cursorSmoothCaretAnimation', false, { description: nls.localize('cursorSmoothCaretAnimation', "Controls whether the smooth caret animation should be enabled.") } )), cursorStyle: register(new EditorEnumOption( EditorOption.cursorStyle, 'cursorStyle', TextEditorCursorStyle.Line, 'line', ['line', 'block', 'underline', 'line-thin', 'block-outline', 'underline-thin'], _cursorStyleFromString, { description: nls.localize('cursorStyle', "Controls the cursor style.") } )), cursorSurroundingLines: register(new EditorIntOption( EditorOption.cursorSurroundingLines, 'cursorSurroundingLines', 0, 0, Constants.MAX_SAFE_SMALL_INTEGER, { description: nls.localize('cursorSurroundingLines', "Controls the minimal number of visible leading and trailing lines surrounding the cursor. Known as 'scrollOff' or `scrollOffset` in some other editors.") } )), cursorWidth: register(new EditorIntOption( EditorOption.cursorWidth, 'cursorWidth', 0, 0, Constants.MAX_SAFE_SMALL_INTEGER, { markdownDescription: nls.localize('cursorWidth', "Controls the width of the cursor when `#editor.cursorStyle#` is set to `line`.") } )), disableLayerHinting: register(new EditorBooleanOption( EditorOption.disableLayerHinting, 'disableLayerHinting', false, )), disableMonospaceOptimizations: register(new EditorBooleanOption( EditorOption.disableMonospaceOptimizations, 'disableMonospaceOptimizations', false )), dragAndDrop: register(new EditorBooleanOption( EditorOption.dragAndDrop, 'dragAndDrop', true, { description: nls.localize('dragAndDrop', "Controls whether the editor should allow moving selections via drag and drop.") } )), emptySelectionClipboard: register(new EditorEmptySelectionClipboard()), extraEditorClassName: register(new EditorStringOption( EditorOption.extraEditorClassName, 'extraEditorClassName', '', )), fastScrollSensitivity: register(new EditorFloatOption( EditorOption.fastScrollSensitivity, 'fastScrollSensitivity', 5, x => (x <= 0 ? 5 : x), { markdownDescription: nls.localize('fastScrollSensitivity', "Scrolling speed multiplier when pressing `Alt`.") } )), find: register(new EditorFind()), fixedOverflowWidgets: register(new EditorBooleanOption( EditorOption.fixedOverflowWidgets, 'fixedOverflowWidgets', false, )), folding: register(new EditorBooleanOption( EditorOption.folding, 'folding', true, { description: nls.localize('folding', "Controls whether the editor has code folding enabled.") } )), foldingStrategy: register(new EditorStringEnumOption( EditorOption.foldingStrategy, 'foldingStrategy', 'auto' as 'auto' | 'indentation', ['auto', 'indentation'] as const, { markdownDescription: nls.localize('foldingStrategy', "Controls the strategy for computing folding ranges. `auto` uses a language specific folding strategy, if available. `indentation` uses the indentation based folding strategy.") } )), fontFamily: register(new EditorStringOption( EditorOption.fontFamily, 'fontFamily', EDITOR_FONT_DEFAULTS.fontFamily, { description: nls.localize('fontFamily', "Controls the font family.") } )), fontInfo: register(new EditorFontInfo()), fontLigatures2: register(new EditorFontLigatures()), fontSize: register(new EditorFontSize()), fontWeight: register(new EditorStringOption( EditorOption.fontWeight, 'fontWeight', EDITOR_FONT_DEFAULTS.fontWeight, { enum: ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'], description: nls.localize('fontWeight', "Controls the font weight.") } )), formatOnPaste: register(new EditorBooleanOption( EditorOption.formatOnPaste, 'formatOnPaste', false, { description: nls.localize('formatOnPaste', "Controls whether the editor should automatically format the pasted content. A formatter must be available and the formatter should be able to format a range in a document.") } )), formatOnType: register(new EditorBooleanOption( EditorOption.formatOnType, 'formatOnType', false, { description: nls.localize('formatOnType', "Controls whether the editor should automatically format the line after typing.") } )), glyphMargin: register(new EditorBooleanOption( EditorOption.glyphMargin, 'glyphMargin', true, { description: nls.localize('glyphMargin', "Controls whether the editor should render the vertical glyph margin. Glyph margin is mostly used for debugging.") } )), gotoLocation: register(new EditorGoToLocation()), hideCursorInOverviewRuler: register(new EditorBooleanOption( EditorOption.hideCursorInOverviewRuler, 'hideCursorInOverviewRuler', false, { description: nls.localize('hideCursorInOverviewRuler', "Controls whether the cursor should be hidden in the overview ruler.") } )), highlightActiveIndentGuide: register(new EditorBooleanOption( EditorOption.highlightActiveIndentGuide, 'highlightActiveIndentGuide', true, { description: nls.localize('highlightActiveIndentGuide', "Controls whether the editor should highlight the active indent guide.") } )), hover: register(new EditorHover()), inDiffEditor: register(new EditorBooleanOption( EditorOption.inDiffEditor, 'inDiffEditor', false, )), letterSpacing: register(new EditorFloatOption( EditorOption.letterSpacing, 'letterSpacing', EDITOR_FONT_DEFAULTS.letterSpacing, x => EditorFloatOption.clamp(x, -5, 20), { description: nls.localize('letterSpacing', "Controls the letter spacing in pixels.") } )), lightbulb: register(new EditorLightbulb()), lineDecorationsWidth: register(new SimpleEditorOption(EditorOption.lineDecorationsWidth, 'lineDecorationsWidth', 10 as number | string)), lineHeight: register(new EditorLineHeight()), lineNumbers: register(new EditorRenderLineNumbersOption()), lineNumbersMinChars: register(new EditorIntOption( EditorOption.lineNumbersMinChars, 'lineNumbersMinChars', 5, 1, 10 )), links: register(new EditorBooleanOption( EditorOption.links, 'links', true, { description: nls.localize('links', "Controls whether the editor should detect links and make them clickable.") } )), matchBrackets: register(new EditorBooleanOption( EditorOption.matchBrackets, 'matchBrackets', true, { description: nls.localize('matchBrackets', "Highlight matching brackets when one of them is selected.") } )), minimap: register(new EditorMinimap()), mouseStyle: register(new EditorStringEnumOption( EditorOption.mouseStyle, 'mouseStyle', 'text' as 'text' | 'default' | 'copy', ['text', 'default', 'copy'] as const, )), mouseWheelScrollSensitivity: register(new EditorFloatOption( EditorOption.mouseWheelScrollSensitivity, 'mouseWheelScrollSensitivity', 1, x => (x === 0 ? 1 : x), { markdownDescription: nls.localize('mouseWheelScrollSensitivity', "A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events.") } )), mouseWheelZoom: register(new EditorBooleanOption( EditorOption.mouseWheelZoom, 'mouseWheelZoom', false, { markdownDescription: nls.localize('mouseWheelZoom', "Zoom the font of the editor when using mouse wheel and holding `Ctrl`.") } )), multiCursorMergeOverlapping: register(new EditorBooleanOption( EditorOption.multiCursorMergeOverlapping, 'multiCursorMergeOverlapping', true, { description: nls.localize('multiCursorMergeOverlapping', "Merge multiple cursors when they are overlapping.") } )), multiCursorModifier: register(new EditorEnumOption( EditorOption.multiCursorModifier, 'multiCursorModifier', 'altKey', 'alt', ['ctrlCmd', 'alt'], _multiCursorModifierFromString, { markdownEnumDescriptions: [ nls.localize('multiCursorModifier.ctrlCmd', "Maps to `Control` on Windows and Linux and to `Command` on macOS."), nls.localize('multiCursorModifier.alt', "Maps to `Alt` on Windows and Linux and to `Option` on macOS.") ], markdownDescription: nls.localize({ key: 'multiCursorModifier', comment: [ '- `ctrlCmd` refers to a value the setting can take and should not be localized.', '- `Control` and `Command` refer to the modifier keys Ctrl or Cmd on the keyboard and can be localized.' ] }, "The modifier to be used to add multiple cursors with the mouse. The Go To Definition and Open Link mouse gestures will adapt such that they do not conflict with the multicursor modifier. [Read more](https://code.visualstudio.com/docs/editor/codebasics#_multicursor-modifier).") } )), multiCursorPaste: register(new EditorStringEnumOption( EditorOption.multiCursorPaste, 'multiCursorPaste', 'spread' as 'spread' | 'full', ['spread', 'full'] as const, { markdownEnumDescriptions: [ nls.localize('multiCursorPaste.spread', "Each cursor pastes a single line of the text."), nls.localize('multiCursorPaste.full', "Each cursor pastes the full text.") ], markdownDescription: nls.localize('multiCursorPaste', "Controls pasting when the line count of the pasted text matches the cursor count.") } )), occurrencesHighlight: register(new EditorBooleanOption( EditorOption.occurrencesHighlight, 'occurrencesHighlight', true, { description: nls.localize('occurrencesHighlight', "Controls whether the editor should highlight semantic symbol occurrences.") } )), overviewRulerBorder: register(new EditorBooleanOption( EditorOption.overviewRulerBorder, 'overviewRulerBorder', true, { description: nls.localize('overviewRulerBorder', "Controls whether a border should be drawn around the overview ruler.") } )), overviewRulerLanes: register(new EditorIntOption( EditorOption.overviewRulerLanes, 'overviewRulerLanes', 3, 0, 3, { description: nls.localize('overviewRulerLanes', "Controls the number of decorations that can show up at the same position in the overview ruler.") } )), parameterHints: register(new EditorParameterHints()), quickSuggestions: register(new EditorQuickSuggestions()), quickSuggestionsDelay: register(new EditorIntOption( EditorOption.quickSuggestionsDelay, 'quickSuggestionsDelay', 10, 0, Constants.MAX_SAFE_SMALL_INTEGER, { description: nls.localize('quickSuggestionsDelay', "Controls the delay in milliseconds after which quick suggestions will show up.") } )), readOnly: register(new EditorBooleanOption( EditorOption.readOnly, 'readOnly', false, )), renderControlCharacters: register(new EditorBooleanOption( EditorOption.renderControlCharacters, 'renderControlCharacters', false, { description: nls.localize('renderControlCharacters', "Controls whether the editor should render control characters.") } )), renderIndentGuides: register(new EditorBooleanOption( EditorOption.renderIndentGuides, 'renderIndentGuides', true, { description: nls.localize('renderIndentGuides', "Controls whether the editor should render indent guides.") } )), renderFinalNewline: register(new EditorBooleanOption( EditorOption.renderFinalNewline, 'renderFinalNewline', true, { description: nls.localize('renderFinalNewline', "Render last line number when the file ends with a newline.") } )), renderLineHighlight: register(new EditorStringEnumOption( EditorOption.renderLineHighlight, 'renderLineHighlight', 'line' as 'none' | 'gutter' | 'line' | 'all', ['none', 'gutter', 'line', 'all'] as const, { enumDescriptions: [ '', '', '', nls.localize('renderLineHighlight.all', "Highlights both the gutter and the current line."), ], description: nls.localize('renderLineHighlight', "Controls how the editor should render the current line highlight.") } )), renderWhitespace: register(new EditorStringEnumOption( EditorOption.renderWhitespace, 'renderWhitespace', 'none' as 'none' | 'boundary' | 'selection' | 'all', ['none', 'boundary', 'selection', 'all'] as const, { enumDescriptions: [ '', nls.localize('renderWhitespace.boundary', "Render whitespace characters except for single spaces between words."), nls.localize('renderWhitespace.selection', "Render whitespace characters only on selected text."), '' ], description: nls.localize('renderWhitespace', "Controls how the editor should render whitespace characters.") } )), revealHorizontalRightPadding: register(new EditorIntOption( EditorOption.revealHorizontalRightPadding, 'revealHorizontalRightPadding', 30, 0, 1000, )), roundedSelection: register(new EditorBooleanOption( EditorOption.roundedSelection, 'roundedSelection', true, { description: nls.localize('roundedSelection', "Controls whether selections should have rounded corners.") } )), rulers: register(new EditorRulers()), scrollbar: register(new EditorScrollbar()), scrollBeyondLastColumn: register(new EditorIntOption( EditorOption.scrollBeyondLastColumn, 'scrollBeyondLastColumn', 5, 0, Constants.MAX_SAFE_SMALL_INTEGER, { description: nls.localize('scrollBeyondLastColumn', "Controls the number of extra characters beyond which the editor will scroll horizontally.") } )), scrollBeyondLastLine: register(new EditorBooleanOption( EditorOption.scrollBeyondLastLine, 'scrollBeyondLastLine', true, { description: nls.localize('scrollBeyondLastLine', "Controls whether the editor will scroll beyond the last line.") } )), selectionClipboard: register(new EditorBooleanOption( EditorOption.selectionClipboard, 'selectionClipboard', true, { description: nls.localize('selectionClipboard', "Controls whether the Linux primary clipboard should be supported."), included: platform.isLinux } )), selectionHighlight: register(new EditorBooleanOption( EditorOption.selectionHighlight, 'selectionHighlight', true, { description: nls.localize('selectionHighlight', "Controls whether the editor should highlight matches similar to the selection.") } )), selectOnLineNumbers: register(new EditorBooleanOption( EditorOption.selectOnLineNumbers, 'selectOnLineNumbers', true, )), showFoldingControls: register(new EditorStringEnumOption( EditorOption.showFoldingControls, 'showFoldingControls', 'mouseover' as 'always' | 'mouseover', ['always', 'mouseover'] as const, { description: nls.localize('showFoldingControls', "Controls whether the fold controls on the gutter are automatically hidden.") } )), showUnused: register(new EditorBooleanOption( EditorOption.showUnused, 'showUnused', true, { description: nls.localize('showUnused', "Controls fading out of unused code.") } )), snippetSuggestions: register(new EditorStringEnumOption( EditorOption.snippetSuggestions, 'snippetSuggestions', 'inline' as 'top' | 'bottom' | 'inline' | 'none', ['top', 'bottom', 'inline', 'none'] as const, { enumDescriptions: [ nls.localize('snippetSuggestions.top', "Show snippet suggestions on top of other suggestions."), nls.localize('snippetSuggestions.bottom', "Show snippet suggestions below other suggestions."), nls.localize('snippetSuggestions.inline', "Show snippets suggestions with other suggestions."), nls.localize('snippetSuggestions.none', "Do not show snippet suggestions."), ], description: nls.localize('snippetSuggestions', "Controls whether snippets are shown with other suggestions and how they are sorted.") } )), smoothScrolling: register(new EditorBooleanOption( EditorOption.smoothScrolling, 'smoothScrolling', false, { description: nls.localize('smoothScrolling', "Controls whether the editor will scroll using an animation.") } )), stopRenderingLineAfter: register(new EditorIntOption( EditorOption.stopRenderingLineAfter, 'stopRenderingLineAfter', 10000, -1, Constants.MAX_SAFE_SMALL_INTEGER, )), suggest: register(new EditorSuggest()), suggestFontSize: register(new EditorIntOption( EditorOption.suggestFontSize, 'suggestFontSize', 0, 0, 1000, { markdownDescription: nls.localize('suggestFontSize', "Font size for the suggest widget. When set to `0`, the value of `#editor.fontSize#` is used.") } )), suggestLineHeight: register(new EditorIntOption( EditorOption.suggestLineHeight, 'suggestLineHeight', 0, 0, 1000, { markdownDescription: nls.localize('suggestLineHeight', "Line height for the suggest widget. When set to `0`, the value of `#editor.lineHeight#` is used.") } )), suggestOnTriggerCharacters: register(new EditorBooleanOption( EditorOption.suggestOnTriggerCharacters, 'suggestOnTriggerCharacters', true, { description: nls.localize('suggestOnTriggerCharacters', "Controls whether suggestions should automatically show up when typing trigger characters.") } )), suggestSelection: register(new EditorStringEnumOption( EditorOption.suggestSelection, 'suggestSelection', 'recentlyUsed' as 'first' | 'recentlyUsed' | 'recentlyUsedByPrefix', ['first', 'recentlyUsed', 'recentlyUsedByPrefix'] as const, { markdownEnumDescriptions: [ nls.localize('suggestSelection.first', "Always select the first suggestion."), nls.localize('suggestSelection.recentlyUsed', "Select recent suggestions unless further typing selects one, e.g. `console.| -> console.log` because `log` has been completed recently."), nls.localize('suggestSelection.recentlyUsedByPrefix', "Select suggestions based on previous prefixes that have completed those suggestions, e.g. `co -> console` and `con -> const`."), ], description: nls.localize('suggestSelection', "Controls how suggestions are pre-selected when showing the suggest list.") } )), tabCompletion: register(new EditorStringEnumOption( EditorOption.tabCompletion, 'tabCompletion', 'off' as 'on' | 'off' | 'onlySnippets', ['on', 'off', 'onlySnippets'] as const, { enumDescriptions: [ nls.localize('tabCompletion.on', "Tab complete will insert the best matching suggestion when pressing tab."), nls.localize('tabCompletion.off', "Disable tab completions."), nls.localize('tabCompletion.onlySnippets', "Tab complete snippets when their prefix match. Works best when 'quickSuggestions' aren't enabled."), ], description: nls.localize('tabCompletion', "Enables tab completions.") } )), useTabStops: register(new EditorBooleanOption( EditorOption.useTabStops, 'useTabStops', true, { description: nls.localize('useTabStops', "Inserting and deleting whitespace follows tab stops.") } )), wordSeparators: register(new EditorStringOption( EditorOption.wordSeparators, 'wordSeparators', USUAL_WORD_SEPARATORS, { description: nls.localize('wordSeparators', "Characters that will be used as word separators when doing word related navigations or operations.") } )), wordWrap: register(new EditorStringEnumOption( EditorOption.wordWrap, 'wordWrap', 'off' as 'off' | 'on' | 'wordWrapColumn' | 'bounded', ['off', 'on', 'wordWrapColumn', 'bounded'] as const, { markdownEnumDescriptions: [ nls.localize('wordWrap.off', "Lines will never wrap."), nls.localize('wordWrap.on', "Lines will wrap at the viewport width."), nls.localize({ key: 'wordWrap.wordWrapColumn', comment: [ '- `editor.wordWrapColumn` refers to a different setting and should not be localized.' ] }, "Lines will wrap at `#editor.wordWrapColumn#`."), nls.localize({ key: 'wordWrap.bounded', comment: [ '- viewport means the edge of the visible window size.', '- `editor.wordWrapColumn` refers to a different setting and should not be localized.' ] }, "Lines will wrap at the minimum of viewport and `#editor.wordWrapColumn#`."), ], description: nls.localize({ key: 'wordWrap', comment: [ '- \'off\', \'on\', \'wordWrapColumn\' and \'bounded\' refer to values the setting can take and should not be localized.', '- `editor.wordWrapColumn` refers to a different setting and should not be localized.' ] }, "Controls how lines should wrap.") } )), wordWrapBreakAfterCharacters: register(new EditorStringOption( EditorOption.wordWrapBreakAfterCharacters, 'wordWrapBreakAfterCharacters', ' \t})]?|/&,;¢°′″‰℃、。。、¢,.:;?!%・・ゝゞヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻ァィゥェォャュョッー”〉》」』】〕)]}」', )), wordWrapBreakBeforeCharacters: register(new EditorStringOption( EditorOption.wordWrapBreakBeforeCharacters, 'wordWrapBreakBeforeCharacters', '([{‘“〈《「『【〔([{「£¥$£¥++' )), wordWrapBreakObtrusiveCharacters: register(new EditorStringOption( EditorOption.wordWrapBreakObtrusiveCharacters, 'wordWrapBreakObtrusiveCharacters', '.' )), wordWrapColumn: register(new EditorIntOption( EditorOption.wordWrapColumn, 'wordWrapColumn', 80, 1, Constants.MAX_SAFE_SMALL_INTEGER, { markdownDescription: nls.localize({ key: 'wordWrapColumn', comment: [ '- `editor.wordWrap` refers to a different setting and should not be localized.', '- \'wordWrapColumn\' and \'bounded\' refer to values the different setting can take and should not be localized.' ] }, "Controls the wrapping column of the editor when `#editor.wordWrap#` is `wordWrapColumn` or `bounded`.") } )), wordWrapMinified: register(new EditorBooleanOption( EditorOption.wordWrapMinified, 'wordWrapMinified', true, )), wrappingIndent: register(new EditorEnumOption( EditorOption.wrappingIndent, 'wrappingIndent', WrappingIndent.Same, 'same', ['none', 'same', 'indent', 'deepIndent'], _wrappingIndentFromString, { enumDescriptions: [ nls.localize('wrappingIndent.none', "No indentation. Wrapped lines begin at column 1."), nls.localize('wrappingIndent.same', "Wrapped lines get the same indentation as the parent."), nls.localize('wrappingIndent.indent', "Wrapped lines get +1 indentation toward the parent."), nls.localize('wrappingIndent.deepIndent', "Wrapped lines get +2 indentation toward the parent."), ], description: nls.localize('wrappingIndent', "Controls the indentation of wrapped lines."), } )), // Leave these at the end (because they have dependencies!) editorClassName: register(new EditorClassName()), pixelRatio: register(new EditorPixelRatio()), tabFocusMode: register(new EditorTabFocusMode()), layoutInfo: register(new EditorLayoutInfoComputer()), wrappingInfo: register(new EditorWrappingInfoComputer()), }; /** * @internal */ type EditorOptionsType = typeof EditorOptions; /** * @internal */ type FindEditorOptionsKeyById = { [K in keyof EditorOptionsType]: EditorOptionsType[K]['id'] extends T ? K : never }[keyof EditorOptionsType]; /** * @internal */ type ComputedEditorOptionValue> = T extends IEditorOption ? R : never; /** * @internal */ export type FindComputedEditorOptionValueById = NonNullable]>>;