Book a Demo!
CoCalc Logo Icon
StoreFeaturesDocsShareSupportNewsAboutPoliciesSign UpSign In
microsoft
GitHub Repository: microsoft/vscode
Path: blob/main/src/vs/editor/common/config/editorOptions.ts
5240 views
1
/*---------------------------------------------------------------------------------------------
2
* Copyright (c) Microsoft Corporation. All rights reserved.
3
* Licensed under the MIT License. See License.txt in the project root for license information.
4
*--------------------------------------------------------------------------------------------*/
5
6
import * as arrays from '../../../base/common/arrays.js';
7
import { IMarkdownString } from '../../../base/common/htmlContent.js';
8
import { IJSONSchema } from '../../../base/common/jsonSchema.js';
9
import * as objects from '../../../base/common/objects.js';
10
import * as platform from '../../../base/common/platform.js';
11
import { ScrollbarVisibility } from '../../../base/common/scrollable.js';
12
import { Constants } from '../../../base/common/uint.js';
13
import { EDITOR_FONT_DEFAULTS, FONT_VARIATION_OFF, FONT_VARIATION_TRANSLATE, FontInfo } from './fontInfo.js';
14
import { EDITOR_MODEL_DEFAULTS } from '../core/misc/textModelDefaults.js';
15
import { USUAL_WORD_SEPARATORS } from '../core/wordHelper.js';
16
import * as nls from '../../../nls.js';
17
import { AccessibilitySupport } from '../../../platform/accessibility/common/accessibility.js';
18
import { IConfigurationPropertySchema } from '../../../platform/configuration/common/configurationRegistry.js';
19
20
//#region typed options
21
22
/**
23
* Configuration options for auto closing quotes and brackets
24
*/
25
export type EditorAutoClosingStrategy = 'always' | 'languageDefined' | 'beforeWhitespace' | 'never';
26
27
/**
28
* Configuration options for auto wrapping quotes and brackets
29
*/
30
export type EditorAutoSurroundStrategy = 'languageDefined' | 'quotes' | 'brackets' | 'never';
31
32
/**
33
* Configuration options for typing over closing quotes or brackets
34
*/
35
export type EditorAutoClosingEditStrategy = 'always' | 'auto' | 'never';
36
37
type Unknown<T> = { [K in keyof T]: unknown };
38
39
/**
40
* Configuration options for auto indentation in the editor
41
*/
42
export const enum EditorAutoIndentStrategy {
43
None = 0,
44
Keep = 1,
45
Brackets = 2,
46
Advanced = 3,
47
Full = 4
48
}
49
50
/**
51
* Configuration options for the editor.
52
*/
53
export interface IEditorOptions {
54
/**
55
* This editor is used inside a diff editor.
56
*/
57
inDiffEditor?: boolean;
58
/**
59
* This editor is allowed to use variable line heights.
60
*/
61
allowVariableLineHeights?: boolean;
62
/**
63
* This editor is allowed to use variable font-sizes and font-families
64
*/
65
allowVariableFonts?: boolean;
66
/**
67
* This editor is allowed to use variable font-sizes and font-families in accessibility mode
68
*/
69
allowVariableFontsInAccessibilityMode?: boolean;
70
/**
71
* The aria label for the editor's textarea (when it is focused).
72
*/
73
ariaLabel?: string;
74
75
/**
76
* Whether the aria-required attribute should be set on the editors textarea.
77
*/
78
ariaRequired?: boolean;
79
/**
80
* Control whether a screen reader announces inline suggestion content immediately.
81
*/
82
screenReaderAnnounceInlineSuggestion?: boolean;
83
/**
84
* The `tabindex` property of the editor's textarea
85
*/
86
tabIndex?: number;
87
/**
88
* Render vertical lines at the specified columns.
89
* Defaults to empty array.
90
*/
91
rulers?: (number | IRulerOption)[];
92
/**
93
* Locales used for segmenting lines into words when doing word related navigations or operations.
94
*
95
* Specify the BCP 47 language tag of the word you wish to recognize (e.g., ja, zh-CN, zh-Hant-TW, etc.).
96
* Defaults to empty array
97
*/
98
wordSegmenterLocales?: string | string[];
99
/**
100
* A string containing the word separators used when doing word navigation.
101
* Defaults to `~!@#$%^&*()-=+[{]}\\|;:\'",.<>/?
102
*/
103
wordSeparators?: string;
104
/**
105
* Enable Linux primary clipboard.
106
* Defaults to true.
107
*/
108
selectionClipboard?: boolean;
109
/**
110
* Control the rendering of line numbers.
111
* If it is a function, it will be invoked when rendering a line number and the return value will be rendered.
112
* Otherwise, if it is a truthy, line numbers will be rendered normally (equivalent of using an identity function).
113
* Otherwise, line numbers will not be rendered.
114
* Defaults to `on`.
115
*/
116
lineNumbers?: LineNumbersType;
117
/**
118
* Controls the minimal number of visible leading and trailing lines surrounding the cursor.
119
* Defaults to 0.
120
*/
121
cursorSurroundingLines?: number;
122
/**
123
* Controls when `cursorSurroundingLines` should be enforced
124
* Defaults to `default`, `cursorSurroundingLines` is not enforced when cursor position is changed
125
* by mouse.
126
*/
127
cursorSurroundingLinesStyle?: 'default' | 'all';
128
/**
129
* Render last line number when the file ends with a newline.
130
* Defaults to 'on' for Windows and macOS and 'dimmed' for Linux.
131
*/
132
renderFinalNewline?: 'on' | 'off' | 'dimmed';
133
/**
134
* Remove unusual line terminators like LINE SEPARATOR (LS), PARAGRAPH SEPARATOR (PS).
135
* Defaults to 'prompt'.
136
*/
137
unusualLineTerminators?: 'auto' | 'off' | 'prompt';
138
/**
139
* Should the corresponding line be selected when clicking on the line number?
140
* Defaults to true.
141
*/
142
selectOnLineNumbers?: boolean;
143
/**
144
* Control the width of line numbers, by reserving horizontal space for rendering at least an amount of digits.
145
* Defaults to 5.
146
*/
147
lineNumbersMinChars?: number;
148
/**
149
* Enable the rendering of the glyph margin.
150
* Defaults to true in vscode and to false in monaco-editor.
151
*/
152
glyphMargin?: boolean;
153
/**
154
* The width reserved for line decorations (in px).
155
* Line decorations are placed between line numbers and the editor content.
156
* You can pass in a string in the format floating point followed by "ch". e.g. 1.3ch.
157
* Defaults to 10.
158
*/
159
lineDecorationsWidth?: number | string;
160
/**
161
* When revealing the cursor, a virtual padding (px) is added to the cursor, turning it into a rectangle.
162
* This virtual padding ensures that the cursor gets revealed before hitting the edge of the viewport.
163
* Defaults to 30 (px).
164
*/
165
revealHorizontalRightPadding?: number;
166
/**
167
* Render the editor selection with rounded borders.
168
* Defaults to true.
169
*/
170
roundedSelection?: boolean;
171
/**
172
* Class name to be added to the editor.
173
*/
174
extraEditorClassName?: string;
175
/**
176
* Should the editor be read only. See also `domReadOnly`.
177
* Defaults to false.
178
*/
179
readOnly?: boolean;
180
/**
181
* The message to display when the editor is readonly.
182
*/
183
readOnlyMessage?: IMarkdownString;
184
/**
185
* Should the textarea used for input use the DOM `readonly` attribute.
186
* Defaults to false.
187
*/
188
domReadOnly?: boolean;
189
/**
190
* Enable linked editing.
191
* Defaults to false.
192
*/
193
linkedEditing?: boolean;
194
/**
195
* deprecated, use linkedEditing instead
196
*/
197
renameOnType?: boolean;
198
/**
199
* Should the editor render validation decorations.
200
* Defaults to editable.
201
*/
202
renderValidationDecorations?: 'editable' | 'on' | 'off';
203
/**
204
* Control the behavior and rendering of the scrollbars.
205
*/
206
scrollbar?: IEditorScrollbarOptions;
207
/**
208
* Control the behavior of sticky scroll options
209
*/
210
stickyScroll?: IEditorStickyScrollOptions;
211
/**
212
* Control the behavior and rendering of the minimap.
213
*/
214
minimap?: IEditorMinimapOptions;
215
/**
216
* Control the behavior of the find widget.
217
*/
218
find?: IEditorFindOptions;
219
/**
220
* Display overflow widgets as `fixed`.
221
* Defaults to `false`.
222
*/
223
fixedOverflowWidgets?: boolean;
224
/**
225
* Allow content widgets and overflow widgets to overflow the editor viewport.
226
* Defaults to `true`.
227
*/
228
allowOverflow?: boolean;
229
/**
230
* The number of vertical lanes the overview ruler should render.
231
* Defaults to 3.
232
*/
233
overviewRulerLanes?: number;
234
/**
235
* Controls if a border should be drawn around the overview ruler.
236
* Defaults to `true`.
237
*/
238
overviewRulerBorder?: boolean;
239
/**
240
* Control the cursor animation style, possible values are 'blink', 'smooth', 'phase', 'expand' and 'solid'.
241
* Defaults to 'blink'.
242
*/
243
cursorBlinking?: 'blink' | 'smooth' | 'phase' | 'expand' | 'solid';
244
/**
245
* Zoom the font in the editor when using the mouse wheel in combination with holding Ctrl.
246
* Defaults to false.
247
*/
248
mouseWheelZoom?: boolean;
249
/**
250
* Control the mouse pointer style, either 'text' or 'default' or 'copy'
251
* Defaults to 'text'
252
*/
253
mouseStyle?: 'text' | 'default' | 'copy';
254
/**
255
* Enable smooth caret animation.
256
* Defaults to 'off'.
257
*/
258
cursorSmoothCaretAnimation?: 'off' | 'explicit' | 'on';
259
/**
260
* Control the cursor style in insert mode.
261
* Defaults to 'line'.
262
*/
263
cursorStyle?: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin';
264
/**
265
* Control the cursor style in overtype mode.
266
* Defaults to 'block'.
267
*/
268
overtypeCursorStyle?: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin';
269
/**
270
* Controls whether paste in overtype mode should overwrite or insert.
271
*/
272
overtypeOnPaste?: boolean;
273
/**
274
* Control the width of the cursor when cursorStyle is set to 'line'
275
*/
276
cursorWidth?: number;
277
/**
278
* Control the height of the cursor when cursorStyle is set to 'line'
279
*/
280
cursorHeight?: number;
281
/**
282
* Enable font ligatures.
283
* Defaults to false.
284
*/
285
fontLigatures?: boolean | string;
286
/**
287
* Enable font variations.
288
* Defaults to false.
289
*/
290
fontVariations?: boolean | string;
291
/**
292
* Controls whether to use default color decorations or not using the default document color provider
293
*/
294
defaultColorDecorators?: 'auto' | 'always' | 'never';
295
/**
296
* Disable the use of `transform: translate3d(0px, 0px, 0px)` for the editor margin and lines layers.
297
* The usage of `transform: translate3d(0px, 0px, 0px)` acts as a hint for browsers to create an extra layer.
298
* Defaults to false.
299
*/
300
disableLayerHinting?: boolean;
301
/**
302
* Disable the optimizations for monospace fonts.
303
* Defaults to false.
304
*/
305
disableMonospaceOptimizations?: boolean;
306
/**
307
* Should the cursor be hidden in the overview ruler.
308
* Defaults to false.
309
*/
310
hideCursorInOverviewRuler?: boolean;
311
/**
312
* Enable that scrolling can go one screen size after the last line.
313
* Defaults to true.
314
*/
315
scrollBeyondLastLine?: boolean;
316
/**
317
* Scroll editor on middle click
318
*/
319
scrollOnMiddleClick?: boolean;
320
/**
321
* Enable that scrolling can go beyond the last column by a number of columns.
322
* Defaults to 5.
323
*/
324
scrollBeyondLastColumn?: number;
325
/**
326
* Enable that the editor animates scrolling to a position.
327
* Defaults to false.
328
*/
329
smoothScrolling?: boolean;
330
/**
331
* Enable that the editor will install a ResizeObserver to check if its container dom node size has changed.
332
* Defaults to false.
333
*/
334
automaticLayout?: boolean;
335
/**
336
* Control the wrapping of the editor.
337
* When `wordWrap` = "off", the lines will never wrap.
338
* When `wordWrap` = "on", the lines will wrap at the viewport width.
339
* When `wordWrap` = "wordWrapColumn", the lines will wrap at `wordWrapColumn`.
340
* When `wordWrap` = "bounded", the lines will wrap at min(viewport width, wordWrapColumn).
341
* Defaults to "off".
342
*/
343
wordWrap?: 'off' | 'on' | 'wordWrapColumn' | 'bounded';
344
/**
345
* Override the `wordWrap` setting.
346
*/
347
wordWrapOverride1?: 'off' | 'on' | 'inherit';
348
/**
349
* Override the `wordWrapOverride1` setting.
350
*/
351
wordWrapOverride2?: 'off' | 'on' | 'inherit';
352
/**
353
* Control the wrapping of the editor.
354
* When `wordWrap` = "off", the lines will never wrap.
355
* When `wordWrap` = "on", the lines will wrap at the viewport width.
356
* When `wordWrap` = "wordWrapColumn", the lines will wrap at `wordWrapColumn`.
357
* When `wordWrap` = "bounded", the lines will wrap at min(viewport width, wordWrapColumn).
358
* Defaults to 80.
359
*/
360
wordWrapColumn?: number;
361
/**
362
* Control indentation of wrapped lines. Can be: 'none', 'same', 'indent' or 'deepIndent'.
363
* Defaults to 'same' in vscode and to 'none' in monaco-editor.
364
*/
365
wrappingIndent?: 'none' | 'same' | 'indent' | 'deepIndent';
366
/**
367
* Controls the wrapping strategy to use.
368
* Defaults to 'simple'.
369
*/
370
wrappingStrategy?: 'simple' | 'advanced';
371
/**
372
* Create a softwrap on every quoted "\n" literal.
373
* Defaults to false.
374
*/
375
wrapOnEscapedLineFeeds?: boolean;
376
/**
377
* Configure word wrapping characters. A break will be introduced before these characters.
378
*/
379
wordWrapBreakBeforeCharacters?: string;
380
/**
381
* Configure word wrapping characters. A break will be introduced after these characters.
382
*/
383
wordWrapBreakAfterCharacters?: string;
384
/**
385
* Sets whether line breaks appear wherever the text would otherwise overflow its content box.
386
* When wordBreak = 'normal', Use the default line break rule.
387
* When wordBreak = 'keepAll', Word breaks should not be used for Chinese/Japanese/Korean (CJK) text. Non-CJK text behavior is the same as for normal.
388
*/
389
wordBreak?: 'normal' | 'keepAll';
390
/**
391
* Performance guard: Stop rendering a line after x characters.
392
* Defaults to 10000.
393
* Use -1 to never stop rendering
394
*/
395
stopRenderingLineAfter?: number;
396
/**
397
* Configure the editor's hover.
398
*/
399
hover?: IEditorHoverOptions;
400
/**
401
* Enable detecting links and making them clickable.
402
* Defaults to true.
403
*/
404
links?: boolean;
405
/**
406
* Enable inline color decorators and color picker rendering.
407
*/
408
colorDecorators?: boolean;
409
/**
410
* Controls what is the condition to spawn a color picker from a color dectorator
411
*/
412
colorDecoratorsActivatedOn?: 'clickAndHover' | 'click' | 'hover';
413
/**
414
* Controls the max number of color decorators that can be rendered in an editor at once.
415
*/
416
colorDecoratorsLimit?: number;
417
/**
418
* Control the behaviour of comments in the editor.
419
*/
420
comments?: IEditorCommentsOptions;
421
/**
422
* Enable custom contextmenu.
423
* Defaults to true.
424
*/
425
contextmenu?: boolean;
426
/**
427
* A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events.
428
* Defaults to 1.
429
*/
430
mouseWheelScrollSensitivity?: number;
431
/**
432
* FastScrolling mulitplier speed when pressing `Alt`
433
* Defaults to 5.
434
*/
435
fastScrollSensitivity?: number;
436
/**
437
* Enable that the editor scrolls only the predominant axis. Prevents horizontal drift when scrolling vertically on a trackpad.
438
* Defaults to true.
439
*/
440
scrollPredominantAxis?: boolean;
441
/**
442
* Make scrolling inertial - mostly useful with touchpad on linux.
443
*/
444
inertialScroll?: boolean;
445
/**
446
* Enable that the selection with the mouse and keys is doing column selection.
447
* Defaults to false.
448
*/
449
columnSelection?: boolean;
450
/**
451
* The modifier to be used to add multiple cursors with the mouse.
452
* Defaults to 'alt'
453
*/
454
multiCursorModifier?: 'ctrlCmd' | 'alt';
455
/**
456
* Merge overlapping selections.
457
* Defaults to true
458
*/
459
multiCursorMergeOverlapping?: boolean;
460
/**
461
* Configure the behaviour when pasting a text with the line count equal to the cursor count.
462
* Defaults to 'spread'.
463
*/
464
multiCursorPaste?: 'spread' | 'full';
465
/**
466
* Controls the max number of text cursors that can be in an active editor at once.
467
*/
468
multiCursorLimit?: number;
469
/**
470
* Enables middle mouse button to open links and Go To Definition
471
*/
472
mouseMiddleClickAction?: MouseMiddleClickAction;
473
/**
474
* Configure the editor's accessibility support.
475
* Defaults to 'auto'. It is best to leave this to 'auto'.
476
*/
477
accessibilitySupport?: 'auto' | 'off' | 'on';
478
/**
479
* Controls the number of lines in the editor that can be read out by a screen reader
480
*/
481
accessibilityPageSize?: number;
482
/**
483
* Suggest options.
484
*/
485
suggest?: ISuggestOptions;
486
inlineSuggest?: IInlineSuggestOptions;
487
/**
488
* Smart select options.
489
*/
490
smartSelect?: ISmartSelectOptions;
491
/**
492
*
493
*/
494
gotoLocation?: IGotoLocationOptions;
495
/**
496
* Enable quick suggestions (shadow suggestions)
497
* Defaults to true.
498
*/
499
quickSuggestions?: boolean | IQuickSuggestionsOptions;
500
/**
501
* Quick suggestions show delay (in ms)
502
* Defaults to 10 (ms)
503
*/
504
quickSuggestionsDelay?: number;
505
/**
506
* Controls the spacing around the editor.
507
*/
508
padding?: IEditorPaddingOptions;
509
/**
510
* Parameter hint options.
511
*/
512
parameterHints?: IEditorParameterHintOptions;
513
/**
514
* Options for auto closing brackets.
515
* Defaults to language defined behavior.
516
*/
517
autoClosingBrackets?: EditorAutoClosingStrategy;
518
/**
519
* Options for auto closing comments.
520
* Defaults to language defined behavior.
521
*/
522
autoClosingComments?: EditorAutoClosingStrategy;
523
/**
524
* Options for auto closing quotes.
525
* Defaults to language defined behavior.
526
*/
527
autoClosingQuotes?: EditorAutoClosingStrategy;
528
/**
529
* Options for pressing backspace near quotes or bracket pairs.
530
*/
531
autoClosingDelete?: EditorAutoClosingEditStrategy;
532
/**
533
* Options for typing over closing quotes or brackets.
534
*/
535
autoClosingOvertype?: EditorAutoClosingEditStrategy;
536
/**
537
* Options for auto surrounding.
538
* Defaults to always allowing auto surrounding.
539
*/
540
autoSurround?: EditorAutoSurroundStrategy;
541
/**
542
* Controls whether the editor should automatically adjust the indentation when users type, paste, move or indent lines.
543
* Defaults to advanced.
544
*/
545
autoIndent?: 'none' | 'keep' | 'brackets' | 'advanced' | 'full';
546
/**
547
* Boolean which controls whether to autoindent on paste
548
*/
549
autoIndentOnPaste?: boolean;
550
/**
551
* Boolean which controls whether to autoindent on paste within a string when autoIndentOnPaste is enabled.
552
*/
553
autoIndentOnPasteWithinString?: boolean;
554
/**
555
* Emulate selection behaviour of tab characters when using spaces for indentation.
556
* This means selection will stick to tab stops.
557
*/
558
stickyTabStops?: boolean;
559
/**
560
* Enable format on type.
561
* Defaults to false.
562
*/
563
formatOnType?: boolean;
564
/**
565
* Enable format on paste.
566
* Defaults to false.
567
*/
568
formatOnPaste?: boolean;
569
/**
570
* Controls if the editor should allow to move selections via drag and drop.
571
* Defaults to false.
572
*/
573
dragAndDrop?: boolean;
574
/**
575
* Enable the suggestion box to pop-up on trigger characters.
576
* Defaults to true.
577
*/
578
suggestOnTriggerCharacters?: boolean;
579
/**
580
* Accept suggestions on ENTER.
581
* Defaults to 'on'.
582
*/
583
acceptSuggestionOnEnter?: 'on' | 'smart' | 'off';
584
/**
585
* Accept suggestions on provider defined characters.
586
* Defaults to true.
587
*/
588
acceptSuggestionOnCommitCharacter?: boolean;
589
/**
590
* Enable snippet suggestions. Default to 'true'.
591
*/
592
snippetSuggestions?: 'top' | 'bottom' | 'inline' | 'none';
593
/**
594
* Copying without a selection copies the current line.
595
*/
596
emptySelectionClipboard?: boolean;
597
/**
598
* Syntax highlighting is copied.
599
*/
600
copyWithSyntaxHighlighting?: boolean;
601
/**
602
* The history mode for suggestions.
603
*/
604
suggestSelection?: 'first' | 'recentlyUsed' | 'recentlyUsedByPrefix';
605
/**
606
* The font size for the suggest widget.
607
* Defaults to the editor font size.
608
*/
609
suggestFontSize?: number;
610
/**
611
* The line height for the suggest widget.
612
* Defaults to the editor line height.
613
*/
614
suggestLineHeight?: number;
615
/**
616
* Enable tab completion.
617
*/
618
tabCompletion?: 'on' | 'off' | 'onlySnippets';
619
/**
620
* Enable selection highlight.
621
* Defaults to true.
622
*/
623
selectionHighlight?: boolean;
624
/**
625
* Enable selection highlight for multiline selections.
626
* Defaults to false.
627
*/
628
selectionHighlightMultiline?: boolean;
629
/**
630
* Maximum length (in characters) for selection highlights.
631
* Set to 0 to have an unlimited length.
632
*/
633
selectionHighlightMaxLength?: number;
634
/**
635
* Enable semantic occurrences highlight.
636
* Defaults to 'singleFile'.
637
* 'off' disables occurrence highlighting
638
* 'singleFile' triggers occurrence highlighting in the current document
639
* 'multiFile' triggers occurrence highlighting across valid open documents
640
*/
641
occurrencesHighlight?: 'off' | 'singleFile' | 'multiFile';
642
/**
643
* Controls delay for occurrences highlighting
644
* Defaults to 250.
645
* Minimum value is 0
646
* Maximum value is 2000
647
*/
648
occurrencesHighlightDelay?: number;
649
/**
650
* Show code lens
651
* Defaults to true.
652
*/
653
codeLens?: boolean;
654
/**
655
* Code lens font family. Defaults to editor font family.
656
*/
657
codeLensFontFamily?: string;
658
/**
659
* Code lens font size. Default to 90% of the editor font size
660
*/
661
codeLensFontSize?: number;
662
/**
663
* Control the behavior and rendering of the code action lightbulb.
664
*/
665
lightbulb?: IEditorLightbulbOptions;
666
/**
667
* Timeout for running code actions on save.
668
*/
669
codeActionsOnSaveTimeout?: number;
670
/**
671
* Enable code folding.
672
* Defaults to true.
673
*/
674
folding?: boolean;
675
/**
676
* Selects the folding strategy. 'auto' uses the strategies contributed for the current document, 'indentation' uses the indentation based folding strategy.
677
* Defaults to 'auto'.
678
*/
679
foldingStrategy?: 'auto' | 'indentation';
680
/**
681
* Enable highlight for folded regions.
682
* Defaults to true.
683
*/
684
foldingHighlight?: boolean;
685
/**
686
* Auto fold imports folding regions.
687
* Defaults to true.
688
*/
689
foldingImportsByDefault?: boolean;
690
/**
691
* Maximum number of foldable regions.
692
* Defaults to 5000.
693
*/
694
foldingMaximumRegions?: number;
695
/**
696
* Controls whether the fold actions in the gutter stay always visible or hide unless the mouse is over the gutter.
697
* Defaults to 'mouseover'.
698
*/
699
showFoldingControls?: 'always' | 'never' | 'mouseover';
700
/**
701
* Controls whether clicking on the empty content after a folded line will unfold the line.
702
* Defaults to false.
703
*/
704
unfoldOnClickAfterEndOfLine?: boolean;
705
/**
706
* Enable highlighting of matching brackets.
707
* Defaults to 'always'.
708
*/
709
matchBrackets?: 'never' | 'near' | 'always';
710
/**
711
* Enable experimental rendering using WebGPU.
712
* Defaults to 'off'.
713
*/
714
experimentalGpuAcceleration?: 'on' | 'off';
715
/**
716
* Enable experimental whitespace rendering.
717
* Defaults to 'svg'.
718
*/
719
experimentalWhitespaceRendering?: 'svg' | 'font' | 'off';
720
/**
721
* Enable rendering of whitespace.
722
* Defaults to 'selection'.
723
*/
724
renderWhitespace?: 'none' | 'boundary' | 'selection' | 'trailing' | 'all';
725
/**
726
* Enable rendering of control characters.
727
* Defaults to true.
728
*/
729
renderControlCharacters?: boolean;
730
/**
731
* Enable rendering of current line highlight.
732
* Defaults to all.
733
*/
734
renderLineHighlight?: 'none' | 'gutter' | 'line' | 'all';
735
/**
736
* Control if the current line highlight should be rendered only the editor is focused.
737
* Defaults to false.
738
*/
739
renderLineHighlightOnlyWhenFocus?: boolean;
740
/**
741
* Inserting and deleting whitespace follows tab stops.
742
*/
743
useTabStops?: boolean;
744
/**
745
* Controls whether the editor should automatically remove indentation whitespace when joining lines with Delete.
746
* Defaults to false.
747
*/
748
trimWhitespaceOnDelete?: boolean;
749
/**
750
* The font family
751
*/
752
fontFamily?: string;
753
/**
754
* The font weight
755
*/
756
fontWeight?: string;
757
/**
758
* The font size
759
*/
760
fontSize?: number;
761
/**
762
* The line height
763
*/
764
lineHeight?: number;
765
/**
766
* The letter spacing
767
*/
768
letterSpacing?: number;
769
/**
770
* Controls fading out of unused variables.
771
*/
772
showUnused?: boolean;
773
/**
774
* Controls whether to focus the inline editor in the peek widget by default.
775
* Defaults to false.
776
*/
777
peekWidgetDefaultFocus?: 'tree' | 'editor';
778
779
/**
780
* Sets a placeholder for the editor.
781
* If set, the placeholder is shown if the editor is empty.
782
*/
783
placeholder?: string | undefined;
784
785
/**
786
* Controls whether the definition link opens element in the peek widget.
787
* Defaults to false.
788
*/
789
definitionLinkOpensInPeek?: boolean;
790
/**
791
* Controls strikethrough deprecated variables.
792
*/
793
showDeprecated?: boolean;
794
/**
795
* Controls whether suggestions allow matches in the middle of the word instead of only at the beginning
796
*/
797
matchOnWordStartOnly?: boolean;
798
/**
799
* Control the behavior and rendering of the inline hints.
800
*/
801
inlayHints?: IEditorInlayHintsOptions;
802
/**
803
* Control if the editor should use shadow DOM.
804
*/
805
useShadowDOM?: boolean;
806
/**
807
* Controls the behavior of editor guides.
808
*/
809
guides?: IGuidesOptions;
810
811
/**
812
* Controls the behavior of the unicode highlight feature
813
* (by default, ambiguous and invisible characters are highlighted).
814
*/
815
unicodeHighlight?: IUnicodeHighlightOptions;
816
817
/**
818
* Configures bracket pair colorization (disabled by default).
819
*/
820
bracketPairColorization?: IBracketPairColorizationOptions;
821
822
/**
823
* Controls dropping into the editor from an external source.
824
*
825
* When enabled, this shows a preview of the drop location and triggers an `onDropIntoEditor` event.
826
*/
827
dropIntoEditor?: IDropIntoEditorOptions;
828
829
/**
830
* Sets whether the new experimental edit context should be used instead of the text area.
831
*/
832
editContext?: boolean;
833
834
/**
835
* Controls whether to render rich HTML screen reader content when the EditContext is enabled
836
*/
837
renderRichScreenReaderContent?: boolean;
838
839
/**
840
* Controls support for changing how content is pasted into the editor.
841
*/
842
pasteAs?: IPasteAsOptions;
843
844
/**
845
* Controls whether the editor / terminal receives tabs or defers them to the workbench for navigation.
846
*/
847
tabFocusMode?: boolean;
848
849
/**
850
* Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown.
851
*/
852
inlineCompletionsAccessibilityVerbose?: boolean;
853
}
854
855
/**
856
* @internal
857
* The width of the minimap gutter, in pixels.
858
*/
859
export const MINIMAP_GUTTER_WIDTH = 8;
860
861
export interface IDiffEditorBaseOptions {
862
/**
863
* Allow the user to resize the diff editor split view.
864
* Defaults to true.
865
*/
866
enableSplitViewResizing?: boolean;
867
868
/**
869
* The default ratio when rendering side-by-side editors.
870
* Must be a number between 0 and 1, min sizes apply.
871
* Defaults to 0.5
872
*/
873
splitViewDefaultRatio?: number;
874
875
/**
876
* Render the differences in two side-by-side editors.
877
* Defaults to true.
878
*/
879
renderSideBySide?: boolean;
880
881
/**
882
* When `renderSideBySide` is enabled, `useInlineViewWhenSpaceIsLimited` is set,
883
* and the diff editor has a width less than `renderSideBySideInlineBreakpoint`, the inline view is used.
884
*/
885
renderSideBySideInlineBreakpoint?: number | undefined;
886
887
/**
888
* When `renderSideBySide` is enabled, `useInlineViewWhenSpaceIsLimited` is set,
889
* and the diff editor has a width less than `renderSideBySideInlineBreakpoint`, the inline view is used.
890
*/
891
useInlineViewWhenSpaceIsLimited?: boolean;
892
893
/**
894
* If set, the diff editor is optimized for small views.
895
* Defaults to `false`.
896
*/
897
compactMode?: boolean;
898
899
/**
900
* Timeout in milliseconds after which diff computation is cancelled.
901
* Defaults to 5000.
902
*/
903
maxComputationTime?: number;
904
905
/**
906
* Maximum supported file size in MB.
907
* Defaults to 50.
908
*/
909
maxFileSize?: number;
910
911
/**
912
* Compute the diff by ignoring leading/trailing whitespace
913
* Defaults to true.
914
*/
915
ignoreTrimWhitespace?: boolean;
916
917
/**
918
* Render +/- indicators for added/deleted changes.
919
* Defaults to true.
920
*/
921
renderIndicators?: boolean;
922
923
/**
924
* Shows icons in the glyph margin to revert changes.
925
* Default to true.
926
*/
927
renderMarginRevertIcon?: boolean;
928
929
/**
930
* Indicates if the gutter menu should be rendered.
931
*/
932
renderGutterMenu?: boolean;
933
934
/**
935
* Original model should be editable?
936
* Defaults to false.
937
*/
938
originalEditable?: boolean;
939
940
/**
941
* Should the diff editor enable code lens?
942
* Defaults to false.
943
*/
944
diffCodeLens?: boolean;
945
946
/**
947
* Is the diff editor should render overview ruler
948
* Defaults to true
949
*/
950
renderOverviewRuler?: boolean;
951
952
/**
953
* Control the wrapping of the diff editor.
954
*/
955
diffWordWrap?: 'off' | 'on' | 'inherit';
956
957
/**
958
* Diff Algorithm
959
*/
960
diffAlgorithm?: 'legacy' | 'advanced';
961
962
/**
963
* Whether the diff editor aria label should be verbose.
964
*/
965
accessibilityVerbose?: boolean;
966
967
experimental?: {
968
/**
969
* Defaults to false.
970
*/
971
showMoves?: boolean;
972
973
showEmptyDecorations?: boolean;
974
975
/**
976
* Only applies when `renderSideBySide` is set to false.
977
*/
978
useTrueInlineView?: boolean;
979
};
980
981
/**
982
* Is the diff editor inside another editor
983
* Defaults to false
984
*/
985
isInEmbeddedEditor?: boolean;
986
987
/**
988
* If the diff editor should only show the difference review mode.
989
*/
990
onlyShowAccessibleDiffViewer?: boolean;
991
992
hideUnchangedRegions?: {
993
enabled?: boolean;
994
revealLineCount?: number;
995
minimumLineCount?: number;
996
contextLineCount?: number;
997
};
998
}
999
1000
/**
1001
* Configuration options for the diff editor.
1002
*/
1003
export interface IDiffEditorOptions extends IEditorOptions, IDiffEditorBaseOptions {
1004
}
1005
1006
/**
1007
* @internal
1008
*/
1009
export type ValidDiffEditorBaseOptions = Readonly<Required<IDiffEditorBaseOptions>>;
1010
1011
//#endregion
1012
1013
/**
1014
* An event describing that the configuration of the editor has changed.
1015
*/
1016
export class ConfigurationChangedEvent {
1017
private readonly _values: boolean[];
1018
/**
1019
* @internal
1020
*/
1021
constructor(values: boolean[]) {
1022
this._values = values;
1023
}
1024
public hasChanged(id: EditorOption): boolean {
1025
return this._values[id];
1026
}
1027
}
1028
1029
/**
1030
* All computed editor options.
1031
*/
1032
export interface IComputedEditorOptions {
1033
get<T extends EditorOption>(id: T): FindComputedEditorOptionValueById<T>;
1034
}
1035
1036
//#region IEditorOption
1037
1038
/**
1039
* @internal
1040
*/
1041
export interface IEnvironmentalOptions {
1042
readonly memory: ComputeOptionsMemory | null;
1043
readonly outerWidth: number;
1044
readonly outerHeight: number;
1045
readonly fontInfo: FontInfo;
1046
readonly extraEditorClassName: string;
1047
readonly isDominatedByLongLines: boolean;
1048
readonly viewLineCount: number;
1049
readonly lineNumbersDigitCount: number;
1050
readonly emptySelectionClipboard: boolean;
1051
readonly pixelRatio: number;
1052
readonly tabFocusMode: boolean;
1053
readonly inputMode: 'insert' | 'overtype';
1054
readonly accessibilitySupport: AccessibilitySupport;
1055
readonly glyphMarginDecorationLaneCount: number;
1056
readonly editContextSupported: boolean;
1057
}
1058
1059
/**
1060
* @internal
1061
*/
1062
export class ComputeOptionsMemory {
1063
1064
public stableMinimapLayoutInput: IMinimapLayoutInput | null;
1065
public stableFitMaxMinimapScale: number;
1066
public stableFitRemainingWidth: number;
1067
1068
constructor() {
1069
this.stableMinimapLayoutInput = null;
1070
this.stableFitMaxMinimapScale = 0;
1071
this.stableFitRemainingWidth = 0;
1072
}
1073
}
1074
1075
export interface IEditorOption<K extends EditorOption, V> {
1076
readonly id: K;
1077
readonly name: string;
1078
defaultValue: V;
1079
/**
1080
* @internal
1081
*/
1082
readonly schema: IConfigurationPropertySchema | { [path: string]: IConfigurationPropertySchema } | undefined;
1083
/**
1084
* @internal
1085
*/
1086
validate(input: unknown): V;
1087
/**
1088
* @internal
1089
*/
1090
compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: V): V;
1091
1092
/**
1093
* Might modify `value`.
1094
*/
1095
applyUpdate(value: V | undefined, update: V): ApplyUpdateResult<V>;
1096
}
1097
1098
/**
1099
* @internal
1100
*/
1101
type PossibleKeyName0<V> = { [K in keyof IEditorOptions]: IEditorOptions[K] extends V | undefined ? K : never }[keyof IEditorOptions];
1102
/**
1103
* @internal
1104
*/
1105
type PossibleKeyName<V> = NonNullable<PossibleKeyName0<V>>;
1106
1107
/**
1108
* @internal
1109
*/
1110
abstract class BaseEditorOption<K extends EditorOption, T, V> implements IEditorOption<K, V> {
1111
1112
public readonly id: K;
1113
public readonly name: string;
1114
public readonly defaultValue: V;
1115
public readonly schema: IConfigurationPropertySchema | { [path: string]: IConfigurationPropertySchema } | undefined;
1116
1117
constructor(id: K, name: PossibleKeyName<T>, defaultValue: V, schema?: IConfigurationPropertySchema | { [path: string]: IConfigurationPropertySchema }) {
1118
this.id = id;
1119
this.name = name;
1120
this.defaultValue = defaultValue;
1121
this.schema = schema;
1122
}
1123
1124
public applyUpdate(value: V | undefined, update: V): ApplyUpdateResult<V> {
1125
return applyUpdate(value, update);
1126
}
1127
1128
public abstract validate(input: unknown): V;
1129
1130
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: V): V {
1131
return value;
1132
}
1133
}
1134
1135
export class ApplyUpdateResult<T> {
1136
constructor(
1137
public readonly newValue: T,
1138
public readonly didChange: boolean
1139
) { }
1140
}
1141
1142
function applyUpdate<T>(value: T | undefined, update: T): ApplyUpdateResult<T> {
1143
if (typeof value !== 'object' || typeof update !== 'object' || !value || !update) {
1144
return new ApplyUpdateResult(update, value !== update);
1145
}
1146
if (Array.isArray(value) || Array.isArray(update)) {
1147
const arrayEquals = Array.isArray(value) && Array.isArray(update) && arrays.equals(value, update);
1148
return new ApplyUpdateResult(update, !arrayEquals);
1149
}
1150
let didChange = false;
1151
for (const key in update) {
1152
if (update.hasOwnProperty(key)) {
1153
const result = applyUpdate(value[key], update[key]);
1154
if (result.didChange) {
1155
value[key] = result.newValue;
1156
didChange = true;
1157
}
1158
}
1159
}
1160
return new ApplyUpdateResult(value, didChange);
1161
}
1162
1163
/**
1164
* @internal
1165
*/
1166
abstract class ComputedEditorOption<K extends EditorOption, V> implements IEditorOption<K, V> {
1167
1168
public readonly id: K;
1169
public readonly name: '_never_';
1170
public readonly defaultValue: V;
1171
public readonly schema: IConfigurationPropertySchema | undefined = undefined;
1172
1173
constructor(id: K, defaultValue: V) {
1174
this.id = id;
1175
this.name = '_never_';
1176
this.defaultValue = defaultValue;
1177
}
1178
1179
public applyUpdate(value: V | undefined, update: V): ApplyUpdateResult<V> {
1180
return applyUpdate(value, update);
1181
}
1182
1183
public validate(input: unknown): V {
1184
return this.defaultValue;
1185
}
1186
1187
public abstract compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: V): V;
1188
}
1189
1190
abstract class SimpleEditorOption<K extends EditorOption, V> implements IEditorOption<K, V> {
1191
1192
public readonly id: K;
1193
public readonly name: PossibleKeyName<V>;
1194
public readonly defaultValue: V;
1195
public readonly schema: IConfigurationPropertySchema | undefined;
1196
1197
constructor(id: K, name: PossibleKeyName<V>, defaultValue: V, schema?: IConfigurationPropertySchema) {
1198
this.id = id;
1199
this.name = name;
1200
this.defaultValue = defaultValue;
1201
this.schema = schema;
1202
}
1203
1204
public applyUpdate(value: V | undefined, update: V): ApplyUpdateResult<V> {
1205
return applyUpdate(value, update);
1206
}
1207
1208
public abstract validate(input: unknown): V;
1209
1210
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: V): V {
1211
return value;
1212
}
1213
}
1214
1215
/**
1216
* @internal
1217
*/
1218
export function boolean(value: unknown, defaultValue: boolean): boolean {
1219
if (typeof value === 'undefined') {
1220
return defaultValue;
1221
}
1222
if (value === 'false') {
1223
// treat the string 'false' as false
1224
return false;
1225
}
1226
return Boolean(value);
1227
}
1228
1229
class EditorBooleanOption<K extends EditorOption> extends SimpleEditorOption<K, boolean> {
1230
1231
constructor(id: K, name: PossibleKeyName<boolean>, defaultValue: boolean, schema: IConfigurationPropertySchema | undefined = undefined) {
1232
if (typeof schema !== 'undefined') {
1233
schema.type = 'boolean';
1234
schema.default = defaultValue;
1235
}
1236
super(id, name, defaultValue, schema);
1237
}
1238
1239
public override validate(input: unknown): boolean {
1240
return boolean(input, this.defaultValue);
1241
}
1242
}
1243
1244
/**
1245
* @internal
1246
*/
1247
export function clampedInt<T = number>(value: unknown, defaultValue: T, minimum: number, maximum: number): number | T {
1248
if (typeof value === 'string') {
1249
value = parseInt(value, 10);
1250
}
1251
if (typeof value !== 'number' || isNaN(value)) {
1252
return defaultValue;
1253
}
1254
let r = value;
1255
r = Math.max(minimum, r);
1256
r = Math.min(maximum, r);
1257
return r | 0;
1258
}
1259
1260
class EditorIntOption<K extends EditorOption> extends SimpleEditorOption<K, number> {
1261
1262
public static clampedInt<T>(value: unknown, defaultValue: T, minimum: number, maximum: number): number | T {
1263
return clampedInt(value, defaultValue, minimum, maximum);
1264
}
1265
1266
public readonly minimum: number;
1267
public readonly maximum: number;
1268
1269
constructor(id: K, name: PossibleKeyName<number>, defaultValue: number, minimum: number, maximum: number, schema: IConfigurationPropertySchema | undefined = undefined) {
1270
if (typeof schema !== 'undefined') {
1271
schema.type = 'integer';
1272
schema.default = defaultValue;
1273
schema.minimum = minimum;
1274
schema.maximum = maximum;
1275
}
1276
super(id, name, defaultValue, schema);
1277
this.minimum = minimum;
1278
this.maximum = maximum;
1279
}
1280
1281
public override validate(input: unknown): number {
1282
return EditorIntOption.clampedInt(input, this.defaultValue, this.minimum, this.maximum);
1283
}
1284
}
1285
/**
1286
* @internal
1287
*/
1288
export function clampedFloat<T extends number>(value: unknown, defaultValue: T, minimum: number, maximum: number): number | T {
1289
if (typeof value === 'undefined') {
1290
return defaultValue;
1291
}
1292
const r = EditorFloatOption.float(value, defaultValue);
1293
return EditorFloatOption.clamp(r, minimum, maximum);
1294
}
1295
1296
class EditorFloatOption<K extends EditorOption> extends SimpleEditorOption<K, number> {
1297
1298
public readonly minimum: number | undefined;
1299
public readonly maximum: number | undefined;
1300
1301
public static clamp(n: number, min: number, max: number): number {
1302
if (n < min) {
1303
return min;
1304
}
1305
if (n > max) {
1306
return max;
1307
}
1308
return n;
1309
}
1310
1311
public static float(value: unknown, defaultValue: number): number {
1312
if (typeof value === 'string') {
1313
value = parseFloat(value);
1314
}
1315
if (typeof value !== 'number' || isNaN(value)) {
1316
return defaultValue;
1317
}
1318
return value;
1319
}
1320
1321
public readonly validationFn: (value: number) => number;
1322
1323
constructor(id: K, name: PossibleKeyName<number>, defaultValue: number, validationFn: (value: number) => number, schema?: IConfigurationPropertySchema, minimum?: number, maximum?: number) {
1324
if (typeof schema !== 'undefined') {
1325
schema.type = 'number';
1326
schema.default = defaultValue;
1327
schema.minimum = minimum;
1328
schema.maximum = maximum;
1329
}
1330
super(id, name, defaultValue, schema);
1331
this.validationFn = validationFn;
1332
this.minimum = minimum;
1333
this.maximum = maximum;
1334
}
1335
1336
public override validate(input: unknown): number {
1337
return this.validationFn(EditorFloatOption.float(input, this.defaultValue));
1338
}
1339
}
1340
1341
class EditorStringOption<K extends EditorOption> extends SimpleEditorOption<K, string> {
1342
1343
public static string(value: unknown, defaultValue: string): string {
1344
if (typeof value !== 'string') {
1345
return defaultValue;
1346
}
1347
return value;
1348
}
1349
1350
constructor(id: K, name: PossibleKeyName<string>, defaultValue: string, schema: IConfigurationPropertySchema | undefined = undefined) {
1351
if (typeof schema !== 'undefined') {
1352
schema.type = 'string';
1353
schema.default = defaultValue;
1354
}
1355
super(id, name, defaultValue, schema);
1356
}
1357
1358
public override validate(input: unknown): string {
1359
return EditorStringOption.string(input, this.defaultValue);
1360
}
1361
}
1362
1363
/**
1364
* @internal
1365
*/
1366
export function stringSet<T extends string>(value: unknown, defaultValue: T, allowedValues: ReadonlyArray<T>, renamedValues?: Record<string, T>): T {
1367
if (typeof value !== 'string') {
1368
return defaultValue;
1369
}
1370
if (renamedValues && value in renamedValues) {
1371
return renamedValues[value];
1372
}
1373
if (allowedValues.indexOf(value as T) === -1) {
1374
return defaultValue;
1375
}
1376
return value as T;
1377
}
1378
1379
class EditorStringEnumOption<K extends EditorOption, V extends string> extends SimpleEditorOption<K, V> {
1380
1381
private readonly _allowedValues: ReadonlyArray<V>;
1382
1383
constructor(id: K, name: PossibleKeyName<V>, defaultValue: V, allowedValues: ReadonlyArray<V>, schema: IConfigurationPropertySchema | undefined = undefined) {
1384
if (typeof schema !== 'undefined') {
1385
schema.type = 'string';
1386
schema.enum = allowedValues.slice(0);
1387
schema.default = defaultValue;
1388
}
1389
super(id, name, defaultValue, schema);
1390
this._allowedValues = allowedValues;
1391
}
1392
1393
public override validate(input: unknown): V {
1394
return stringSet<V>(input, this.defaultValue, this._allowedValues);
1395
}
1396
}
1397
1398
class EditorEnumOption<K extends EditorOption, T extends string, V> extends BaseEditorOption<K, T, V> {
1399
1400
private readonly _allowedValues: T[];
1401
private readonly _convert: (value: T) => V;
1402
1403
constructor(id: K, name: PossibleKeyName<T>, defaultValue: V, defaultStringValue: string, allowedValues: T[], convert: (value: T) => V, schema: IConfigurationPropertySchema | undefined = undefined) {
1404
if (typeof schema !== 'undefined') {
1405
schema.type = 'string';
1406
schema.enum = allowedValues;
1407
schema.default = defaultStringValue;
1408
}
1409
super(id, name, defaultValue, schema);
1410
this._allowedValues = allowedValues;
1411
this._convert = convert;
1412
}
1413
1414
public validate(input: unknown): V {
1415
if (typeof input !== 'string') {
1416
return this.defaultValue;
1417
}
1418
if (this._allowedValues.indexOf(<T>input) === -1) {
1419
return this.defaultValue;
1420
}
1421
return this._convert(<T>input);
1422
}
1423
}
1424
1425
//#endregion
1426
1427
//#region autoIndent
1428
1429
function _autoIndentFromString(autoIndent: 'none' | 'keep' | 'brackets' | 'advanced' | 'full'): EditorAutoIndentStrategy {
1430
switch (autoIndent) {
1431
case 'none': return EditorAutoIndentStrategy.None;
1432
case 'keep': return EditorAutoIndentStrategy.Keep;
1433
case 'brackets': return EditorAutoIndentStrategy.Brackets;
1434
case 'advanced': return EditorAutoIndentStrategy.Advanced;
1435
case 'full': return EditorAutoIndentStrategy.Full;
1436
}
1437
}
1438
1439
//#endregion
1440
1441
//#region accessibilitySupport
1442
1443
class EditorAccessibilitySupport extends BaseEditorOption<EditorOption.accessibilitySupport, 'auto' | 'off' | 'on', AccessibilitySupport> {
1444
1445
constructor() {
1446
super(
1447
EditorOption.accessibilitySupport, 'accessibilitySupport', AccessibilitySupport.Unknown,
1448
{
1449
type: 'string',
1450
enum: ['auto', 'on', 'off'],
1451
enumDescriptions: [
1452
nls.localize('accessibilitySupport.auto', "Use platform APIs to detect when a Screen Reader is attached."),
1453
nls.localize('accessibilitySupport.on', "Optimize for usage with a Screen Reader."),
1454
nls.localize('accessibilitySupport.off', "Assume a screen reader is not attached."),
1455
],
1456
default: 'auto',
1457
tags: ['accessibility'],
1458
description: nls.localize('accessibilitySupport', "Controls if the UI should run in a mode where it is optimized for screen readers.")
1459
}
1460
);
1461
}
1462
1463
public validate(input: unknown): AccessibilitySupport {
1464
switch (input) {
1465
case 'auto': return AccessibilitySupport.Unknown;
1466
case 'off': return AccessibilitySupport.Disabled;
1467
case 'on': return AccessibilitySupport.Enabled;
1468
}
1469
return this.defaultValue;
1470
}
1471
1472
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: AccessibilitySupport): AccessibilitySupport {
1473
if (value === AccessibilitySupport.Unknown) {
1474
// The editor reads the `accessibilitySupport` from the environment
1475
return env.accessibilitySupport;
1476
}
1477
return value;
1478
}
1479
}
1480
1481
//#endregion
1482
1483
//#region comments
1484
1485
/**
1486
* Configuration options for editor comments
1487
*/
1488
export interface IEditorCommentsOptions {
1489
/**
1490
* Insert a space after the line comment token and inside the block comments tokens.
1491
* Defaults to true.
1492
*/
1493
insertSpace?: boolean;
1494
/**
1495
* Ignore empty lines when inserting line comments.
1496
* Defaults to true.
1497
*/
1498
ignoreEmptyLines?: boolean;
1499
}
1500
1501
/**
1502
* @internal
1503
*/
1504
export type EditorCommentsOptions = Readonly<Required<IEditorCommentsOptions>>;
1505
1506
class EditorComments extends BaseEditorOption<EditorOption.comments, IEditorCommentsOptions, EditorCommentsOptions> {
1507
1508
constructor() {
1509
const defaults: EditorCommentsOptions = {
1510
insertSpace: true,
1511
ignoreEmptyLines: true,
1512
};
1513
super(
1514
EditorOption.comments, 'comments', defaults,
1515
{
1516
'editor.comments.insertSpace': {
1517
type: 'boolean',
1518
default: defaults.insertSpace,
1519
description: nls.localize('comments.insertSpace', "Controls whether a space character is inserted when commenting.")
1520
},
1521
'editor.comments.ignoreEmptyLines': {
1522
type: 'boolean',
1523
default: defaults.ignoreEmptyLines,
1524
description: nls.localize('comments.ignoreEmptyLines', 'Controls if empty lines should be ignored with toggle, add or remove actions for line comments.')
1525
},
1526
}
1527
);
1528
}
1529
1530
public validate(_input: unknown): EditorCommentsOptions {
1531
if (!_input || typeof _input !== 'object') {
1532
return this.defaultValue;
1533
}
1534
const input = _input as Unknown<IEditorCommentsOptions>;
1535
return {
1536
insertSpace: boolean(input.insertSpace, this.defaultValue.insertSpace),
1537
ignoreEmptyLines: boolean(input.ignoreEmptyLines, this.defaultValue.ignoreEmptyLines),
1538
};
1539
}
1540
}
1541
1542
//#endregion
1543
1544
//#region cursorBlinking
1545
1546
/**
1547
* The kind of animation in which the editor's cursor should be rendered.
1548
*/
1549
export const enum TextEditorCursorBlinkingStyle {
1550
/**
1551
* Hidden
1552
*/
1553
Hidden = 0,
1554
/**
1555
* Blinking
1556
*/
1557
Blink = 1,
1558
/**
1559
* Blinking with smooth fading
1560
*/
1561
Smooth = 2,
1562
/**
1563
* Blinking with prolonged filled state and smooth fading
1564
*/
1565
Phase = 3,
1566
/**
1567
* Expand collapse animation on the y axis
1568
*/
1569
Expand = 4,
1570
/**
1571
* No-Blinking
1572
*/
1573
Solid = 5
1574
}
1575
1576
/**
1577
* @internal
1578
*/
1579
export function cursorBlinkingStyleFromString(cursorBlinkingStyle: 'blink' | 'smooth' | 'phase' | 'expand' | 'solid'): TextEditorCursorBlinkingStyle {
1580
switch (cursorBlinkingStyle) {
1581
case 'blink': return TextEditorCursorBlinkingStyle.Blink;
1582
case 'smooth': return TextEditorCursorBlinkingStyle.Smooth;
1583
case 'phase': return TextEditorCursorBlinkingStyle.Phase;
1584
case 'expand': return TextEditorCursorBlinkingStyle.Expand;
1585
case 'solid': return TextEditorCursorBlinkingStyle.Solid;
1586
}
1587
}
1588
1589
//#endregion
1590
1591
//#region cursorStyle
1592
1593
/**
1594
* The style in which the editor's cursor should be rendered.
1595
*/
1596
export enum TextEditorCursorStyle {
1597
/**
1598
* As a vertical line (sitting between two characters).
1599
*/
1600
Line = 1,
1601
/**
1602
* As a block (sitting on top of a character).
1603
*/
1604
Block = 2,
1605
/**
1606
* As a horizontal line (sitting under a character).
1607
*/
1608
Underline = 3,
1609
/**
1610
* As a thin vertical line (sitting between two characters).
1611
*/
1612
LineThin = 4,
1613
/**
1614
* As an outlined block (sitting on top of a character).
1615
*/
1616
BlockOutline = 5,
1617
/**
1618
* As a thin horizontal line (sitting under a character).
1619
*/
1620
UnderlineThin = 6
1621
}
1622
1623
/**
1624
* @internal
1625
*/
1626
export function cursorStyleToString(cursorStyle: TextEditorCursorStyle): 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin' {
1627
switch (cursorStyle) {
1628
case TextEditorCursorStyle.Line: return 'line';
1629
case TextEditorCursorStyle.Block: return 'block';
1630
case TextEditorCursorStyle.Underline: return 'underline';
1631
case TextEditorCursorStyle.LineThin: return 'line-thin';
1632
case TextEditorCursorStyle.BlockOutline: return 'block-outline';
1633
case TextEditorCursorStyle.UnderlineThin: return 'underline-thin';
1634
}
1635
}
1636
1637
/**
1638
* @internal
1639
*/
1640
export function cursorStyleFromString(cursorStyle: 'line' | 'block' | 'underline' | 'line-thin' | 'block-outline' | 'underline-thin'): TextEditorCursorStyle {
1641
switch (cursorStyle) {
1642
case 'line': return TextEditorCursorStyle.Line;
1643
case 'block': return TextEditorCursorStyle.Block;
1644
case 'underline': return TextEditorCursorStyle.Underline;
1645
case 'line-thin': return TextEditorCursorStyle.LineThin;
1646
case 'block-outline': return TextEditorCursorStyle.BlockOutline;
1647
case 'underline-thin': return TextEditorCursorStyle.UnderlineThin;
1648
}
1649
}
1650
1651
//#endregion
1652
1653
//#region editorClassName
1654
1655
class EditorClassName extends ComputedEditorOption<EditorOption.editorClassName, string> {
1656
1657
constructor() {
1658
super(EditorOption.editorClassName, '');
1659
}
1660
1661
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: string): string {
1662
const classNames = ['monaco-editor'];
1663
if (options.get(EditorOption.extraEditorClassName)) {
1664
classNames.push(options.get(EditorOption.extraEditorClassName));
1665
}
1666
if (env.extraEditorClassName) {
1667
classNames.push(env.extraEditorClassName);
1668
}
1669
if (options.get(EditorOption.mouseStyle) === 'default') {
1670
classNames.push('mouse-default');
1671
} else if (options.get(EditorOption.mouseStyle) === 'copy') {
1672
classNames.push('mouse-copy');
1673
}
1674
1675
if (options.get(EditorOption.showUnused)) {
1676
classNames.push('showUnused');
1677
}
1678
1679
if (options.get(EditorOption.showDeprecated)) {
1680
classNames.push('showDeprecated');
1681
}
1682
1683
return classNames.join(' ');
1684
}
1685
}
1686
1687
//#endregion
1688
1689
//#region emptySelectionClipboard
1690
1691
class EditorEmptySelectionClipboard extends EditorBooleanOption<EditorOption.emptySelectionClipboard> {
1692
1693
constructor() {
1694
super(
1695
EditorOption.emptySelectionClipboard, 'emptySelectionClipboard', true,
1696
{ description: nls.localize('emptySelectionClipboard', "Controls whether copying without a selection copies the current line.") }
1697
);
1698
}
1699
1700
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: boolean): boolean {
1701
return value && env.emptySelectionClipboard;
1702
}
1703
}
1704
1705
//#endregion
1706
1707
//#region find
1708
1709
/**
1710
* Configuration options for editor find widget
1711
*/
1712
export interface IEditorFindOptions {
1713
/**
1714
* Controls whether the cursor should move to find matches while typing.
1715
*/
1716
cursorMoveOnType?: boolean;
1717
/**
1718
* Controls whether the find widget should search as you type.
1719
*/
1720
findOnType?: boolean;
1721
/**
1722
* Controls if we seed search string in the Find Widget with editor selection.
1723
*/
1724
seedSearchStringFromSelection?: 'never' | 'always' | 'selection';
1725
/**
1726
* Controls if Find in Selection flag is turned on in the editor.
1727
*/
1728
autoFindInSelection?: 'never' | 'always' | 'multiline';
1729
/*
1730
* Controls whether the Find Widget should add extra lines on top of the editor.
1731
*/
1732
addExtraSpaceOnTop?: boolean;
1733
/**
1734
* @internal
1735
* Controls if the Find Widget should read or modify the shared find clipboard on macOS
1736
*/
1737
globalFindClipboard?: boolean;
1738
/**
1739
* Controls whether the search result and diff result automatically restarts from the beginning (or the end) when no further matches can be found
1740
*/
1741
loop?: boolean;
1742
/**
1743
* @internal
1744
* Controls how the find widget search history should be stored
1745
*/
1746
history?: 'never' | 'workspace';
1747
/**
1748
* @internal
1749
* Controls how the replace widget search history should be stored
1750
*/
1751
replaceHistory?: 'never' | 'workspace';
1752
}
1753
1754
/**
1755
* @internal
1756
*/
1757
export type EditorFindOptions = Readonly<Required<IEditorFindOptions>>;
1758
1759
class EditorFind extends BaseEditorOption<EditorOption.find, IEditorFindOptions, EditorFindOptions> {
1760
1761
constructor() {
1762
const defaults: EditorFindOptions = {
1763
cursorMoveOnType: true,
1764
findOnType: true,
1765
seedSearchStringFromSelection: 'always',
1766
autoFindInSelection: 'never',
1767
globalFindClipboard: false,
1768
addExtraSpaceOnTop: true,
1769
loop: true,
1770
history: 'workspace',
1771
replaceHistory: 'workspace',
1772
};
1773
super(
1774
EditorOption.find, 'find', defaults,
1775
{
1776
'editor.find.cursorMoveOnType': {
1777
type: 'boolean',
1778
default: defaults.cursorMoveOnType,
1779
description: nls.localize('find.cursorMoveOnType', "Controls whether the cursor should jump to find matches while typing.")
1780
},
1781
'editor.find.seedSearchStringFromSelection': {
1782
type: 'string',
1783
enum: ['never', 'always', 'selection'],
1784
default: defaults.seedSearchStringFromSelection,
1785
enumDescriptions: [
1786
nls.localize('editor.find.seedSearchStringFromSelection.never', 'Never seed search string from the editor selection.'),
1787
nls.localize('editor.find.seedSearchStringFromSelection.always', 'Always seed search string from the editor selection, including word at cursor position.'),
1788
nls.localize('editor.find.seedSearchStringFromSelection.selection', 'Only seed search string from the editor selection.')
1789
],
1790
description: nls.localize('find.seedSearchStringFromSelection', "Controls whether the search string in the Find Widget is seeded from the editor selection.")
1791
},
1792
'editor.find.autoFindInSelection': {
1793
type: 'string',
1794
enum: ['never', 'always', 'multiline'],
1795
default: defaults.autoFindInSelection,
1796
enumDescriptions: [
1797
nls.localize('editor.find.autoFindInSelection.never', 'Never turn on Find in Selection automatically (default).'),
1798
nls.localize('editor.find.autoFindInSelection.always', 'Always turn on Find in Selection automatically.'),
1799
nls.localize('editor.find.autoFindInSelection.multiline', 'Turn on Find in Selection automatically when multiple lines of content are selected.')
1800
],
1801
description: nls.localize('find.autoFindInSelection', "Controls the condition for turning on Find in Selection automatically.")
1802
},
1803
'editor.find.globalFindClipboard': {
1804
type: 'boolean',
1805
default: defaults.globalFindClipboard,
1806
description: nls.localize('find.globalFindClipboard', "Controls whether the Find Widget should read or modify the shared find clipboard on macOS."),
1807
included: platform.isMacintosh
1808
},
1809
'editor.find.addExtraSpaceOnTop': {
1810
type: 'boolean',
1811
default: defaults.addExtraSpaceOnTop,
1812
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.")
1813
},
1814
'editor.find.loop': {
1815
type: 'boolean',
1816
default: defaults.loop,
1817
description: nls.localize('find.loop', "Controls whether the search automatically restarts from the beginning (or the end) when no further matches can be found.")
1818
},
1819
'editor.find.history': {
1820
type: 'string',
1821
enum: ['never', 'workspace'],
1822
default: 'workspace',
1823
enumDescriptions: [
1824
nls.localize('editor.find.history.never', 'Do not store search history from the find widget.'),
1825
nls.localize('editor.find.history.workspace', 'Store search history across the active workspace'),
1826
],
1827
description: nls.localize('find.history', "Controls how the find widget history should be stored")
1828
},
1829
'editor.find.replaceHistory': {
1830
type: 'string',
1831
enum: ['never', 'workspace'],
1832
default: 'workspace',
1833
enumDescriptions: [
1834
nls.localize('editor.find.replaceHistory.never', 'Do not store history from the replace widget.'),
1835
nls.localize('editor.find.replaceHistory.workspace', 'Store replace history across the active workspace'),
1836
],
1837
description: nls.localize('find.replaceHistory', "Controls how the replace widget history should be stored")
1838
},
1839
'editor.find.findOnType': {
1840
type: 'boolean',
1841
default: defaults.findOnType,
1842
description: nls.localize('find.findOnType', "Controls whether the Find Widget should search as you type.")
1843
},
1844
}
1845
);
1846
}
1847
1848
public validate(_input: unknown): EditorFindOptions {
1849
if (!_input || typeof _input !== 'object') {
1850
return this.defaultValue;
1851
}
1852
const input = _input as Unknown<IEditorFindOptions>;
1853
return {
1854
cursorMoveOnType: boolean(input.cursorMoveOnType, this.defaultValue.cursorMoveOnType),
1855
findOnType: boolean(input.findOnType, this.defaultValue.findOnType),
1856
seedSearchStringFromSelection: typeof input.seedSearchStringFromSelection === 'boolean'
1857
? (input.seedSearchStringFromSelection ? 'always' : 'never')
1858
: stringSet<'never' | 'always' | 'selection'>(input.seedSearchStringFromSelection, this.defaultValue.seedSearchStringFromSelection, ['never', 'always', 'selection']),
1859
autoFindInSelection: typeof input.autoFindInSelection === 'boolean'
1860
? (input.autoFindInSelection ? 'always' : 'never')
1861
: stringSet<'never' | 'always' | 'multiline'>(input.autoFindInSelection, this.defaultValue.autoFindInSelection, ['never', 'always', 'multiline']),
1862
globalFindClipboard: boolean(input.globalFindClipboard, this.defaultValue.globalFindClipboard),
1863
addExtraSpaceOnTop: boolean(input.addExtraSpaceOnTop, this.defaultValue.addExtraSpaceOnTop),
1864
loop: boolean(input.loop, this.defaultValue.loop),
1865
history: stringSet<'never' | 'workspace'>(input.history, this.defaultValue.history, ['never', 'workspace']),
1866
replaceHistory: stringSet<'never' | 'workspace'>(input.replaceHistory, this.defaultValue.replaceHistory, ['never', 'workspace']),
1867
};
1868
}
1869
}
1870
1871
//#endregion
1872
1873
//#region fontLigatures
1874
1875
/**
1876
* @internal
1877
*/
1878
export class EditorFontLigatures extends BaseEditorOption<EditorOption.fontLigatures, boolean | string, string> {
1879
1880
public static OFF = '"liga" off, "calt" off';
1881
public static ON = '"liga" on, "calt" on';
1882
1883
constructor() {
1884
super(
1885
EditorOption.fontLigatures, 'fontLigatures', EditorFontLigatures.OFF,
1886
{
1887
anyOf: [
1888
{
1889
type: 'boolean',
1890
description: nls.localize('fontLigatures', "Enables/Disables font ligatures ('calt' and 'liga' font features). Change this to a string for fine-grained control of the 'font-feature-settings' CSS property."),
1891
},
1892
{
1893
type: 'string',
1894
description: nls.localize('fontFeatureSettings', "Explicit 'font-feature-settings' CSS property. A boolean can be passed instead if one only needs to turn on/off ligatures.")
1895
}
1896
],
1897
description: nls.localize('fontLigaturesGeneral', "Configures font ligatures or font features. Can be either a boolean to enable/disable ligatures or a string for the value of the CSS 'font-feature-settings' property."),
1898
default: false
1899
}
1900
);
1901
}
1902
1903
public validate(input: unknown): string {
1904
if (typeof input === 'undefined') {
1905
return this.defaultValue;
1906
}
1907
if (typeof input === 'string') {
1908
if (input === 'false' || input.length === 0) {
1909
return EditorFontLigatures.OFF;
1910
}
1911
if (input === 'true') {
1912
return EditorFontLigatures.ON;
1913
}
1914
return input;
1915
}
1916
if (Boolean(input)) {
1917
return EditorFontLigatures.ON;
1918
}
1919
return EditorFontLigatures.OFF;
1920
}
1921
}
1922
1923
//#endregion
1924
1925
//#region fontVariations
1926
1927
/**
1928
* @internal
1929
*/
1930
export class EditorFontVariations extends BaseEditorOption<EditorOption.fontVariations, boolean | string, string> {
1931
// Text is laid out using default settings.
1932
public static OFF = FONT_VARIATION_OFF;
1933
1934
// Translate `fontWeight` config to the `font-variation-settings` CSS property.
1935
public static TRANSLATE = FONT_VARIATION_TRANSLATE;
1936
1937
constructor() {
1938
super(
1939
EditorOption.fontVariations, 'fontVariations', EditorFontVariations.OFF,
1940
{
1941
anyOf: [
1942
{
1943
type: 'boolean',
1944
description: nls.localize('fontVariations', "Enables/Disables the translation from font-weight to font-variation-settings. Change this to a string for fine-grained control of the 'font-variation-settings' CSS property."),
1945
},
1946
{
1947
type: 'string',
1948
description: nls.localize('fontVariationSettings', "Explicit 'font-variation-settings' CSS property. A boolean can be passed instead if one only needs to translate font-weight to font-variation-settings.")
1949
}
1950
],
1951
description: nls.localize('fontVariationsGeneral', "Configures font variations. Can be either a boolean to enable/disable the translation from font-weight to font-variation-settings or a string for the value of the CSS 'font-variation-settings' property."),
1952
default: false
1953
}
1954
);
1955
}
1956
1957
public validate(input: unknown): string {
1958
if (typeof input === 'undefined') {
1959
return this.defaultValue;
1960
}
1961
if (typeof input === 'string') {
1962
if (input === 'false') {
1963
return EditorFontVariations.OFF;
1964
}
1965
if (input === 'true') {
1966
return EditorFontVariations.TRANSLATE;
1967
}
1968
return input;
1969
}
1970
if (Boolean(input)) {
1971
return EditorFontVariations.TRANSLATE;
1972
}
1973
return EditorFontVariations.OFF;
1974
}
1975
1976
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: string): string {
1977
// The value is computed from the fontWeight if it is true.
1978
// So take the result from env.fontInfo
1979
return env.fontInfo.fontVariationSettings;
1980
}
1981
}
1982
1983
//#endregion
1984
1985
//#region fontInfo
1986
1987
class EditorFontInfo extends ComputedEditorOption<EditorOption.fontInfo, FontInfo> {
1988
1989
constructor() {
1990
super(EditorOption.fontInfo, new FontInfo({
1991
pixelRatio: 0,
1992
fontFamily: '',
1993
fontWeight: '',
1994
fontSize: 0,
1995
fontFeatureSettings: '',
1996
fontVariationSettings: '',
1997
lineHeight: 0,
1998
letterSpacing: 0,
1999
isMonospace: false,
2000
typicalHalfwidthCharacterWidth: 0,
2001
typicalFullwidthCharacterWidth: 0,
2002
canUseHalfwidthRightwardsArrow: false,
2003
spaceWidth: 0,
2004
middotWidth: 0,
2005
wsmiddotWidth: 0,
2006
maxDigitWidth: 0,
2007
}, false));
2008
}
2009
2010
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: FontInfo): FontInfo {
2011
return env.fontInfo;
2012
}
2013
}
2014
2015
//#endregion
2016
2017
//#region effectiveCursorStyle
2018
2019
class EffectiveCursorStyle extends ComputedEditorOption<EditorOption.effectiveCursorStyle, TextEditorCursorStyle> {
2020
2021
constructor() {
2022
super(EditorOption.effectiveCursorStyle, TextEditorCursorStyle.Line);
2023
}
2024
2025
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: TextEditorCursorStyle): TextEditorCursorStyle {
2026
return env.inputMode === 'overtype' ?
2027
options.get(EditorOption.overtypeCursorStyle) :
2028
options.get(EditorOption.cursorStyle);
2029
}
2030
}
2031
2032
//#endregion
2033
2034
//#region effectiveExperimentalEditContext
2035
2036
class EffectiveEditContextEnabled extends ComputedEditorOption<EditorOption.effectiveEditContext, boolean> {
2037
2038
constructor() {
2039
super(EditorOption.effectiveEditContext, false);
2040
}
2041
2042
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions): boolean {
2043
return env.editContextSupported && options.get(EditorOption.editContext);
2044
}
2045
}
2046
2047
//#endregion
2048
2049
//#region effectiveAllowVariableFonts
2050
2051
class EffectiveAllowVariableFonts extends ComputedEditorOption<EditorOption.effectiveAllowVariableFonts, boolean> {
2052
2053
constructor() {
2054
super(EditorOption.effectiveAllowVariableFonts, false);
2055
}
2056
2057
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions): boolean {
2058
const accessibilitySupport = env.accessibilitySupport;
2059
if (accessibilitySupport === AccessibilitySupport.Enabled) {
2060
return options.get(EditorOption.allowVariableFontsInAccessibilityMode);
2061
} else {
2062
return options.get(EditorOption.allowVariableFonts);
2063
}
2064
}
2065
}
2066
2067
//#engregion
2068
2069
//#region fontSize
2070
2071
class EditorFontSize extends SimpleEditorOption<EditorOption.fontSize, number> {
2072
2073
constructor() {
2074
super(
2075
EditorOption.fontSize, 'fontSize', EDITOR_FONT_DEFAULTS.fontSize,
2076
{
2077
type: 'number',
2078
minimum: 6,
2079
maximum: 100,
2080
default: EDITOR_FONT_DEFAULTS.fontSize,
2081
description: nls.localize('fontSize', "Controls the font size in pixels.")
2082
}
2083
);
2084
}
2085
2086
public override validate(input: unknown): number {
2087
const r = EditorFloatOption.float(input, this.defaultValue);
2088
if (r === 0) {
2089
return EDITOR_FONT_DEFAULTS.fontSize;
2090
}
2091
return EditorFloatOption.clamp(r, 6, 100);
2092
}
2093
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: number): number {
2094
// The final fontSize respects the editor zoom level.
2095
// So take the result from env.fontInfo
2096
return env.fontInfo.fontSize;
2097
}
2098
}
2099
2100
//#endregion
2101
2102
//#region fontWeight
2103
2104
class EditorFontWeight extends BaseEditorOption<EditorOption.fontWeight, string, string> {
2105
private static SUGGESTION_VALUES = ['normal', 'bold', '100', '200', '300', '400', '500', '600', '700', '800', '900'];
2106
private static MINIMUM_VALUE = 1;
2107
private static MAXIMUM_VALUE = 1000;
2108
2109
constructor() {
2110
super(
2111
EditorOption.fontWeight, 'fontWeight', EDITOR_FONT_DEFAULTS.fontWeight,
2112
{
2113
anyOf: [
2114
{
2115
type: 'number',
2116
minimum: EditorFontWeight.MINIMUM_VALUE,
2117
maximum: EditorFontWeight.MAXIMUM_VALUE,
2118
errorMessage: nls.localize('fontWeightErrorMessage', "Only \"normal\" and \"bold\" keywords or numbers between 1 and 1000 are allowed.")
2119
},
2120
{
2121
type: 'string',
2122
pattern: '^(normal|bold|1000|[1-9][0-9]{0,2})$'
2123
},
2124
{
2125
enum: EditorFontWeight.SUGGESTION_VALUES
2126
}
2127
],
2128
default: EDITOR_FONT_DEFAULTS.fontWeight,
2129
description: nls.localize('fontWeight', "Controls the font weight. Accepts \"normal\" and \"bold\" keywords or numbers between 1 and 1000.")
2130
}
2131
);
2132
}
2133
2134
public validate(input: unknown): string {
2135
if (input === 'normal' || input === 'bold') {
2136
return input;
2137
}
2138
return String(EditorIntOption.clampedInt(input, EDITOR_FONT_DEFAULTS.fontWeight, EditorFontWeight.MINIMUM_VALUE, EditorFontWeight.MAXIMUM_VALUE));
2139
}
2140
}
2141
2142
//#endregion
2143
2144
//#region gotoLocation
2145
2146
export type GoToLocationValues = 'peek' | 'gotoAndPeek' | 'goto';
2147
2148
/**
2149
* Configuration options for go to location
2150
*/
2151
export interface IGotoLocationOptions {
2152
2153
multiple?: GoToLocationValues;
2154
2155
multipleDefinitions?: GoToLocationValues;
2156
multipleTypeDefinitions?: GoToLocationValues;
2157
multipleDeclarations?: GoToLocationValues;
2158
multipleImplementations?: GoToLocationValues;
2159
multipleReferences?: GoToLocationValues;
2160
multipleTests?: GoToLocationValues;
2161
2162
alternativeDefinitionCommand?: string;
2163
alternativeTypeDefinitionCommand?: string;
2164
alternativeDeclarationCommand?: string;
2165
alternativeImplementationCommand?: string;
2166
alternativeReferenceCommand?: string;
2167
alternativeTestsCommand?: string;
2168
}
2169
2170
/**
2171
* @internal
2172
*/
2173
export type GoToLocationOptions = Readonly<Required<IGotoLocationOptions>>;
2174
2175
class EditorGoToLocation extends BaseEditorOption<EditorOption.gotoLocation, IGotoLocationOptions, GoToLocationOptions> {
2176
2177
constructor() {
2178
const defaults: GoToLocationOptions = {
2179
multiple: 'peek',
2180
multipleDefinitions: 'peek',
2181
multipleTypeDefinitions: 'peek',
2182
multipleDeclarations: 'peek',
2183
multipleImplementations: 'peek',
2184
multipleReferences: 'peek',
2185
multipleTests: 'peek',
2186
alternativeDefinitionCommand: 'editor.action.goToReferences',
2187
alternativeTypeDefinitionCommand: 'editor.action.goToReferences',
2188
alternativeDeclarationCommand: 'editor.action.goToReferences',
2189
alternativeImplementationCommand: '',
2190
alternativeReferenceCommand: '',
2191
alternativeTestsCommand: '',
2192
};
2193
const jsonSubset: IJSONSchema = {
2194
type: 'string',
2195
enum: ['peek', 'gotoAndPeek', 'goto'],
2196
default: defaults.multiple,
2197
enumDescriptions: [
2198
nls.localize('editor.gotoLocation.multiple.peek', 'Show Peek view of the results (default)'),
2199
nls.localize('editor.gotoLocation.multiple.gotoAndPeek', 'Go to the primary result and show a Peek view'),
2200
nls.localize('editor.gotoLocation.multiple.goto', 'Go to the primary result and enable Peek-less navigation to others')
2201
]
2202
};
2203
const alternativeCommandOptions = ['', 'editor.action.referenceSearch.trigger', 'editor.action.goToReferences', 'editor.action.peekImplementation', 'editor.action.goToImplementation', 'editor.action.peekTypeDefinition', 'editor.action.goToTypeDefinition', 'editor.action.peekDeclaration', 'editor.action.revealDeclaration', 'editor.action.peekDefinition', 'editor.action.revealDefinitionAside', 'editor.action.revealDefinition'];
2204
super(
2205
EditorOption.gotoLocation, 'gotoLocation', defaults,
2206
{
2207
'editor.gotoLocation.multiple': {
2208
deprecationMessage: nls.localize('editor.gotoLocation.multiple.deprecated', "This setting is deprecated, please use separate settings like 'editor.editor.gotoLocation.multipleDefinitions' or 'editor.editor.gotoLocation.multipleImplementations' instead."),
2209
},
2210
'editor.gotoLocation.multipleDefinitions': {
2211
description: nls.localize('editor.editor.gotoLocation.multipleDefinitions', "Controls the behavior the 'Go to Definition'-command when multiple target locations exist."),
2212
...jsonSubset,
2213
},
2214
'editor.gotoLocation.multipleTypeDefinitions': {
2215
description: nls.localize('editor.editor.gotoLocation.multipleTypeDefinitions', "Controls the behavior the 'Go to Type Definition'-command when multiple target locations exist."),
2216
...jsonSubset,
2217
},
2218
'editor.gotoLocation.multipleDeclarations': {
2219
description: nls.localize('editor.editor.gotoLocation.multipleDeclarations', "Controls the behavior the 'Go to Declaration'-command when multiple target locations exist."),
2220
...jsonSubset,
2221
},
2222
'editor.gotoLocation.multipleImplementations': {
2223
description: nls.localize('editor.editor.gotoLocation.multipleImplemenattions', "Controls the behavior the 'Go to Implementations'-command when multiple target locations exist."),
2224
...jsonSubset,
2225
},
2226
'editor.gotoLocation.multipleReferences': {
2227
description: nls.localize('editor.editor.gotoLocation.multipleReferences', "Controls the behavior the 'Go to References'-command when multiple target locations exist."),
2228
...jsonSubset,
2229
},
2230
'editor.gotoLocation.alternativeDefinitionCommand': {
2231
type: 'string',
2232
default: defaults.alternativeDefinitionCommand,
2233
enum: alternativeCommandOptions,
2234
description: nls.localize('alternativeDefinitionCommand', "Alternative command id that is being executed when the result of 'Go to Definition' is the current location.")
2235
},
2236
'editor.gotoLocation.alternativeTypeDefinitionCommand': {
2237
type: 'string',
2238
default: defaults.alternativeTypeDefinitionCommand,
2239
enum: alternativeCommandOptions,
2240
description: nls.localize('alternativeTypeDefinitionCommand', "Alternative command id that is being executed when the result of 'Go to Type Definition' is the current location.")
2241
},
2242
'editor.gotoLocation.alternativeDeclarationCommand': {
2243
type: 'string',
2244
default: defaults.alternativeDeclarationCommand,
2245
enum: alternativeCommandOptions,
2246
description: nls.localize('alternativeDeclarationCommand', "Alternative command id that is being executed when the result of 'Go to Declaration' is the current location.")
2247
},
2248
'editor.gotoLocation.alternativeImplementationCommand': {
2249
type: 'string',
2250
default: defaults.alternativeImplementationCommand,
2251
enum: alternativeCommandOptions,
2252
description: nls.localize('alternativeImplementationCommand', "Alternative command id that is being executed when the result of 'Go to Implementation' is the current location.")
2253
},
2254
'editor.gotoLocation.alternativeReferenceCommand': {
2255
type: 'string',
2256
default: defaults.alternativeReferenceCommand,
2257
enum: alternativeCommandOptions,
2258
description: nls.localize('alternativeReferenceCommand', "Alternative command id that is being executed when the result of 'Go to Reference' is the current location.")
2259
},
2260
}
2261
);
2262
}
2263
2264
public validate(_input: unknown): GoToLocationOptions {
2265
if (!_input || typeof _input !== 'object') {
2266
return this.defaultValue;
2267
}
2268
const input = _input as Unknown<IGotoLocationOptions>;
2269
return {
2270
multiple: stringSet<GoToLocationValues>(input.multiple, this.defaultValue.multiple, ['peek', 'gotoAndPeek', 'goto']),
2271
multipleDefinitions: stringSet<GoToLocationValues>(input.multipleDefinitions, 'peek', ['peek', 'gotoAndPeek', 'goto']),
2272
multipleTypeDefinitions: stringSet<GoToLocationValues>(input.multipleTypeDefinitions, 'peek', ['peek', 'gotoAndPeek', 'goto']),
2273
multipleDeclarations: stringSet<GoToLocationValues>(input.multipleDeclarations, 'peek', ['peek', 'gotoAndPeek', 'goto']),
2274
multipleImplementations: stringSet<GoToLocationValues>(input.multipleImplementations, 'peek', ['peek', 'gotoAndPeek', 'goto']),
2275
multipleReferences: stringSet<GoToLocationValues>(input.multipleReferences, 'peek', ['peek', 'gotoAndPeek', 'goto']),
2276
multipleTests: stringSet<GoToLocationValues>(input.multipleTests, 'peek', ['peek', 'gotoAndPeek', 'goto']),
2277
alternativeDefinitionCommand: EditorStringOption.string(input.alternativeDefinitionCommand, this.defaultValue.alternativeDefinitionCommand),
2278
alternativeTypeDefinitionCommand: EditorStringOption.string(input.alternativeTypeDefinitionCommand, this.defaultValue.alternativeTypeDefinitionCommand),
2279
alternativeDeclarationCommand: EditorStringOption.string(input.alternativeDeclarationCommand, this.defaultValue.alternativeDeclarationCommand),
2280
alternativeImplementationCommand: EditorStringOption.string(input.alternativeImplementationCommand, this.defaultValue.alternativeImplementationCommand),
2281
alternativeReferenceCommand: EditorStringOption.string(input.alternativeReferenceCommand, this.defaultValue.alternativeReferenceCommand),
2282
alternativeTestsCommand: EditorStringOption.string(input.alternativeTestsCommand, this.defaultValue.alternativeTestsCommand),
2283
};
2284
}
2285
}
2286
2287
//#endregion
2288
2289
//#region hover
2290
2291
/**
2292
* Configuration options for editor hover
2293
*/
2294
export interface IEditorHoverOptions {
2295
/**
2296
* Enable the hover.
2297
* Defaults to 'on'.
2298
*/
2299
enabled?: 'on' | 'off' | 'onKeyboardModifier';
2300
/**
2301
* Delay for showing the hover.
2302
* Defaults to 300.
2303
*/
2304
delay?: number;
2305
/**
2306
* Is the hover sticky such that it can be clicked and its contents selected?
2307
* Defaults to true.
2308
*/
2309
sticky?: boolean;
2310
/**
2311
* Controls how long the hover is visible after you hovered out of it.
2312
* Require sticky setting to be true.
2313
*/
2314
hidingDelay?: number;
2315
/**
2316
* Should the hover be shown above the line if possible?
2317
* Defaults to false.
2318
*/
2319
above?: boolean;
2320
}
2321
2322
/**
2323
* @internal
2324
*/
2325
export type EditorHoverOptions = Readonly<Required<IEditorHoverOptions>>;
2326
2327
class EditorHover extends BaseEditorOption<EditorOption.hover, IEditorHoverOptions, EditorHoverOptions> {
2328
2329
constructor() {
2330
const defaults: EditorHoverOptions = {
2331
enabled: 'on',
2332
delay: 300,
2333
hidingDelay: 300,
2334
sticky: true,
2335
above: true,
2336
};
2337
super(
2338
EditorOption.hover, 'hover', defaults,
2339
{
2340
'editor.hover.enabled': {
2341
type: 'string',
2342
enum: ['on', 'off', 'onKeyboardModifier'],
2343
default: defaults.enabled,
2344
markdownEnumDescriptions: [
2345
nls.localize('hover.enabled.on', "Hover is enabled."),
2346
nls.localize('hover.enabled.off', "Hover is disabled."),
2347
nls.localize('hover.enabled.onKeyboardModifier', "Hover is shown when holding `{0}` or `Alt` (the opposite modifier of `#editor.multiCursorModifier#`)", platform.isMacintosh ? `Command` : `Control`)
2348
],
2349
description: nls.localize('hover.enabled', "Controls whether the hover is shown.")
2350
},
2351
'editor.hover.delay': {
2352
type: 'number',
2353
default: defaults.delay,
2354
minimum: 0,
2355
maximum: 10000,
2356
description: nls.localize('hover.delay', "Controls the delay in milliseconds after which the hover is shown.")
2357
},
2358
'editor.hover.sticky': {
2359
type: 'boolean',
2360
default: defaults.sticky,
2361
description: nls.localize('hover.sticky', "Controls whether the hover should remain visible when mouse is moved over it.")
2362
},
2363
'editor.hover.hidingDelay': {
2364
type: 'integer',
2365
minimum: 0,
2366
default: defaults.hidingDelay,
2367
markdownDescription: nls.localize('hover.hidingDelay', "Controls the delay in milliseconds after which the hover is hidden. Requires `#editor.hover.sticky#` to be enabled.")
2368
},
2369
'editor.hover.above': {
2370
type: 'boolean',
2371
default: defaults.above,
2372
description: nls.localize('hover.above', "Prefer showing hovers above the line, if there's space.")
2373
},
2374
}
2375
);
2376
}
2377
2378
public validate(_input: unknown): EditorHoverOptions {
2379
if (!_input || typeof _input !== 'object') {
2380
return this.defaultValue;
2381
}
2382
const input = _input as Unknown<IEditorHoverOptions>;
2383
return {
2384
enabled: stringSet<'on' | 'off' | 'onKeyboardModifier'>(input.enabled, this.defaultValue.enabled, ['on', 'off', 'onKeyboardModifier']),
2385
delay: EditorIntOption.clampedInt(input.delay, this.defaultValue.delay, 0, 10000),
2386
sticky: boolean(input.sticky, this.defaultValue.sticky),
2387
hidingDelay: EditorIntOption.clampedInt(input.hidingDelay, this.defaultValue.hidingDelay, 0, 600000),
2388
above: boolean(input.above, this.defaultValue.above),
2389
};
2390
}
2391
}
2392
2393
//#endregion
2394
2395
//#region layoutInfo
2396
2397
/**
2398
* A description for the overview ruler position.
2399
*/
2400
export interface OverviewRulerPosition {
2401
/**
2402
* Width of the overview ruler
2403
*/
2404
readonly width: number;
2405
/**
2406
* Height of the overview ruler
2407
*/
2408
readonly height: number;
2409
/**
2410
* Top position for the overview ruler
2411
*/
2412
readonly top: number;
2413
/**
2414
* Right position for the overview ruler
2415
*/
2416
readonly right: number;
2417
}
2418
2419
export const enum RenderMinimap {
2420
None = 0,
2421
Text = 1,
2422
Blocks = 2,
2423
}
2424
2425
/**
2426
* The internal layout details of the editor.
2427
*/
2428
export interface EditorLayoutInfo {
2429
2430
/**
2431
* Full editor width.
2432
*/
2433
readonly width: number;
2434
/**
2435
* Full editor height.
2436
*/
2437
readonly height: number;
2438
2439
/**
2440
* Left position for the glyph margin.
2441
*/
2442
readonly glyphMarginLeft: number;
2443
/**
2444
* The width of the glyph margin.
2445
*/
2446
readonly glyphMarginWidth: number;
2447
2448
/**
2449
* The number of decoration lanes to render in the glyph margin.
2450
*/
2451
readonly glyphMarginDecorationLaneCount: number;
2452
2453
/**
2454
* Left position for the line numbers.
2455
*/
2456
readonly lineNumbersLeft: number;
2457
/**
2458
* The width of the line numbers.
2459
*/
2460
readonly lineNumbersWidth: number;
2461
2462
/**
2463
* Left position for the line decorations.
2464
*/
2465
readonly decorationsLeft: number;
2466
/**
2467
* The width of the line decorations.
2468
*/
2469
readonly decorationsWidth: number;
2470
2471
/**
2472
* Left position for the content (actual text)
2473
*/
2474
readonly contentLeft: number;
2475
/**
2476
* The width of the content (actual text)
2477
*/
2478
readonly contentWidth: number;
2479
2480
/**
2481
* Layout information for the minimap
2482
*/
2483
readonly minimap: EditorMinimapLayoutInfo;
2484
2485
/**
2486
* The number of columns (of typical characters) fitting on a viewport line.
2487
*/
2488
readonly viewportColumn: number;
2489
2490
readonly isWordWrapMinified: boolean;
2491
readonly isViewportWrapping: boolean;
2492
readonly wrappingColumn: number;
2493
2494
/**
2495
* The width of the vertical scrollbar.
2496
*/
2497
readonly verticalScrollbarWidth: number;
2498
/**
2499
* The height of the horizontal scrollbar.
2500
*/
2501
readonly horizontalScrollbarHeight: number;
2502
2503
/**
2504
* The position of the overview ruler.
2505
*/
2506
readonly overviewRuler: OverviewRulerPosition;
2507
}
2508
2509
/**
2510
* The internal layout details of the editor.
2511
*/
2512
export interface EditorMinimapLayoutInfo {
2513
readonly renderMinimap: RenderMinimap;
2514
readonly minimapLeft: number;
2515
readonly minimapWidth: number;
2516
readonly minimapHeightIsEditorHeight: boolean;
2517
readonly minimapIsSampling: boolean;
2518
readonly minimapScale: number;
2519
readonly minimapLineHeight: number;
2520
readonly minimapCanvasInnerWidth: number;
2521
readonly minimapCanvasInnerHeight: number;
2522
readonly minimapCanvasOuterWidth: number;
2523
readonly minimapCanvasOuterHeight: number;
2524
}
2525
2526
/**
2527
* @internal
2528
*/
2529
export interface EditorLayoutInfoComputerEnv {
2530
readonly memory: ComputeOptionsMemory | null;
2531
readonly outerWidth: number;
2532
readonly outerHeight: number;
2533
readonly isDominatedByLongLines: boolean;
2534
readonly lineHeight: number;
2535
readonly viewLineCount: number;
2536
readonly lineNumbersDigitCount: number;
2537
readonly typicalHalfwidthCharacterWidth: number;
2538
readonly maxDigitWidth: number;
2539
readonly pixelRatio: number;
2540
readonly glyphMarginDecorationLaneCount: number;
2541
}
2542
2543
/**
2544
* @internal
2545
*/
2546
export interface IEditorLayoutComputerInput {
2547
readonly outerWidth: number;
2548
readonly outerHeight: number;
2549
readonly isDominatedByLongLines: boolean;
2550
readonly lineHeight: number;
2551
readonly lineNumbersDigitCount: number;
2552
readonly typicalHalfwidthCharacterWidth: number;
2553
readonly maxDigitWidth: number;
2554
readonly pixelRatio: number;
2555
readonly glyphMargin: boolean;
2556
readonly lineDecorationsWidth: string | number;
2557
readonly folding: boolean;
2558
readonly minimap: Readonly<Required<IEditorMinimapOptions>>;
2559
readonly scrollbar: InternalEditorScrollbarOptions;
2560
readonly lineNumbers: InternalEditorRenderLineNumbersOptions;
2561
readonly lineNumbersMinChars: number;
2562
readonly scrollBeyondLastLine: boolean;
2563
readonly wordWrap: 'wordWrapColumn' | 'on' | 'off' | 'bounded';
2564
readonly wordWrapColumn: number;
2565
readonly wordWrapMinified: boolean;
2566
readonly accessibilitySupport: AccessibilitySupport;
2567
}
2568
2569
/**
2570
* @internal
2571
*/
2572
export interface IMinimapLayoutInput {
2573
readonly outerWidth: number;
2574
readonly outerHeight: number;
2575
readonly lineHeight: number;
2576
readonly typicalHalfwidthCharacterWidth: number;
2577
readonly pixelRatio: number;
2578
readonly scrollBeyondLastLine: boolean;
2579
readonly paddingTop: number;
2580
readonly paddingBottom: number;
2581
readonly minimap: Readonly<Required<IEditorMinimapOptions>>;
2582
readonly verticalScrollbarWidth: number;
2583
readonly viewLineCount: number;
2584
readonly remainingWidth: number;
2585
readonly isViewportWrapping: boolean;
2586
}
2587
2588
/**
2589
* @internal
2590
*/
2591
export class EditorLayoutInfoComputer extends ComputedEditorOption<EditorOption.layoutInfo, EditorLayoutInfo> {
2592
2593
constructor() {
2594
super(EditorOption.layoutInfo, {
2595
width: 0,
2596
height: 0,
2597
glyphMarginLeft: 0,
2598
glyphMarginWidth: 0,
2599
glyphMarginDecorationLaneCount: 0,
2600
lineNumbersLeft: 0,
2601
lineNumbersWidth: 0,
2602
decorationsLeft: 0,
2603
decorationsWidth: 0,
2604
contentLeft: 0,
2605
contentWidth: 0,
2606
minimap: {
2607
renderMinimap: RenderMinimap.None,
2608
minimapLeft: 0,
2609
minimapWidth: 0,
2610
minimapHeightIsEditorHeight: false,
2611
minimapIsSampling: false,
2612
minimapScale: 1,
2613
minimapLineHeight: 1,
2614
minimapCanvasInnerWidth: 0,
2615
minimapCanvasInnerHeight: 0,
2616
minimapCanvasOuterWidth: 0,
2617
minimapCanvasOuterHeight: 0,
2618
},
2619
viewportColumn: 0,
2620
isWordWrapMinified: false,
2621
isViewportWrapping: false,
2622
wrappingColumn: -1,
2623
verticalScrollbarWidth: 0,
2624
horizontalScrollbarHeight: 0,
2625
overviewRuler: {
2626
top: 0,
2627
width: 0,
2628
height: 0,
2629
right: 0
2630
}
2631
});
2632
}
2633
2634
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: EditorLayoutInfo): EditorLayoutInfo {
2635
return EditorLayoutInfoComputer.computeLayout(options, {
2636
memory: env.memory,
2637
outerWidth: env.outerWidth,
2638
outerHeight: env.outerHeight,
2639
isDominatedByLongLines: env.isDominatedByLongLines,
2640
lineHeight: env.fontInfo.lineHeight,
2641
viewLineCount: env.viewLineCount,
2642
lineNumbersDigitCount: env.lineNumbersDigitCount,
2643
typicalHalfwidthCharacterWidth: env.fontInfo.typicalHalfwidthCharacterWidth,
2644
maxDigitWidth: env.fontInfo.maxDigitWidth,
2645
pixelRatio: env.pixelRatio,
2646
glyphMarginDecorationLaneCount: env.glyphMarginDecorationLaneCount
2647
});
2648
}
2649
2650
public static computeContainedMinimapLineCount(input: {
2651
viewLineCount: number;
2652
scrollBeyondLastLine: boolean;
2653
paddingTop: number;
2654
paddingBottom: number;
2655
height: number;
2656
lineHeight: number;
2657
pixelRatio: number;
2658
}): { typicalViewportLineCount: number; extraLinesBeforeFirstLine: number; extraLinesBeyondLastLine: number; desiredRatio: number; minimapLineCount: number } {
2659
const typicalViewportLineCount = input.height / input.lineHeight;
2660
const extraLinesBeforeFirstLine = Math.floor(input.paddingTop / input.lineHeight);
2661
let extraLinesBeyondLastLine = Math.floor(input.paddingBottom / input.lineHeight);
2662
if (input.scrollBeyondLastLine) {
2663
extraLinesBeyondLastLine = Math.max(extraLinesBeyondLastLine, typicalViewportLineCount - 1);
2664
}
2665
const desiredRatio = (extraLinesBeforeFirstLine + input.viewLineCount + extraLinesBeyondLastLine) / (input.pixelRatio * input.height);
2666
const minimapLineCount = Math.floor(input.viewLineCount / desiredRatio);
2667
return { typicalViewportLineCount, extraLinesBeforeFirstLine, extraLinesBeyondLastLine, desiredRatio, minimapLineCount };
2668
}
2669
2670
private static _computeMinimapLayout(input: IMinimapLayoutInput, memory: ComputeOptionsMemory): EditorMinimapLayoutInfo {
2671
const outerWidth = input.outerWidth;
2672
const outerHeight = input.outerHeight;
2673
const pixelRatio = input.pixelRatio;
2674
2675
if (!input.minimap.enabled) {
2676
return {
2677
renderMinimap: RenderMinimap.None,
2678
minimapLeft: 0,
2679
minimapWidth: 0,
2680
minimapHeightIsEditorHeight: false,
2681
minimapIsSampling: false,
2682
minimapScale: 1,
2683
minimapLineHeight: 1,
2684
minimapCanvasInnerWidth: 0,
2685
minimapCanvasInnerHeight: Math.floor(pixelRatio * outerHeight),
2686
minimapCanvasOuterWidth: 0,
2687
minimapCanvasOuterHeight: outerHeight,
2688
};
2689
}
2690
2691
// Can use memory if only the `viewLineCount` and `remainingWidth` have changed
2692
const stableMinimapLayoutInput = memory.stableMinimapLayoutInput;
2693
const couldUseMemory = (
2694
stableMinimapLayoutInput
2695
// && input.outerWidth === lastMinimapLayoutInput.outerWidth !!! INTENTIONAL OMITTED
2696
&& input.outerHeight === stableMinimapLayoutInput.outerHeight
2697
&& input.lineHeight === stableMinimapLayoutInput.lineHeight
2698
&& input.typicalHalfwidthCharacterWidth === stableMinimapLayoutInput.typicalHalfwidthCharacterWidth
2699
&& input.pixelRatio === stableMinimapLayoutInput.pixelRatio
2700
&& input.scrollBeyondLastLine === stableMinimapLayoutInput.scrollBeyondLastLine
2701
&& input.paddingTop === stableMinimapLayoutInput.paddingTop
2702
&& input.paddingBottom === stableMinimapLayoutInput.paddingBottom
2703
&& input.minimap.enabled === stableMinimapLayoutInput.minimap.enabled
2704
&& input.minimap.side === stableMinimapLayoutInput.minimap.side
2705
&& input.minimap.size === stableMinimapLayoutInput.minimap.size
2706
&& input.minimap.showSlider === stableMinimapLayoutInput.minimap.showSlider
2707
&& input.minimap.renderCharacters === stableMinimapLayoutInput.minimap.renderCharacters
2708
&& input.minimap.maxColumn === stableMinimapLayoutInput.minimap.maxColumn
2709
&& input.minimap.scale === stableMinimapLayoutInput.minimap.scale
2710
&& input.verticalScrollbarWidth === stableMinimapLayoutInput.verticalScrollbarWidth
2711
// && input.viewLineCount === lastMinimapLayoutInput.viewLineCount !!! INTENTIONAL OMITTED
2712
// && input.remainingWidth === lastMinimapLayoutInput.remainingWidth !!! INTENTIONAL OMITTED
2713
&& input.isViewportWrapping === stableMinimapLayoutInput.isViewportWrapping
2714
);
2715
2716
const lineHeight = input.lineHeight;
2717
const typicalHalfwidthCharacterWidth = input.typicalHalfwidthCharacterWidth;
2718
const scrollBeyondLastLine = input.scrollBeyondLastLine;
2719
const minimapRenderCharacters = input.minimap.renderCharacters;
2720
let minimapScale = (pixelRatio >= 2 ? Math.round(input.minimap.scale * 2) : input.minimap.scale);
2721
const minimapMaxColumn = input.minimap.maxColumn;
2722
const minimapSize = input.minimap.size;
2723
const minimapSide = input.minimap.side;
2724
const verticalScrollbarWidth = input.verticalScrollbarWidth;
2725
const viewLineCount = input.viewLineCount;
2726
const remainingWidth = input.remainingWidth;
2727
const isViewportWrapping = input.isViewportWrapping;
2728
2729
const baseCharHeight = minimapRenderCharacters ? 2 : 3;
2730
let minimapCanvasInnerHeight = Math.floor(pixelRatio * outerHeight);
2731
const minimapCanvasOuterHeight = minimapCanvasInnerHeight / pixelRatio;
2732
let minimapHeightIsEditorHeight = false;
2733
let minimapIsSampling = false;
2734
let minimapLineHeight = baseCharHeight * minimapScale;
2735
let minimapCharWidth = minimapScale / pixelRatio;
2736
let minimapWidthMultiplier: number = 1;
2737
2738
if (minimapSize === 'fill' || minimapSize === 'fit') {
2739
const { typicalViewportLineCount, extraLinesBeforeFirstLine, extraLinesBeyondLastLine, desiredRatio, minimapLineCount } = EditorLayoutInfoComputer.computeContainedMinimapLineCount({
2740
viewLineCount: viewLineCount,
2741
scrollBeyondLastLine: scrollBeyondLastLine,
2742
paddingTop: input.paddingTop,
2743
paddingBottom: input.paddingBottom,
2744
height: outerHeight,
2745
lineHeight: lineHeight,
2746
pixelRatio: pixelRatio
2747
});
2748
// ratio is intentionally not part of the layout to avoid the layout changing all the time
2749
// when doing sampling
2750
const ratio = viewLineCount / minimapLineCount;
2751
2752
if (ratio > 1) {
2753
minimapHeightIsEditorHeight = true;
2754
minimapIsSampling = true;
2755
minimapScale = 1;
2756
minimapLineHeight = 1;
2757
minimapCharWidth = minimapScale / pixelRatio;
2758
} else {
2759
let fitBecomesFill = false;
2760
let maxMinimapScale = minimapScale + 1;
2761
2762
if (minimapSize === 'fit') {
2763
const effectiveMinimapHeight = Math.ceil((extraLinesBeforeFirstLine + viewLineCount + extraLinesBeyondLastLine) * minimapLineHeight);
2764
if (isViewportWrapping && couldUseMemory && remainingWidth <= memory.stableFitRemainingWidth) {
2765
// There is a loop when using `fit` and viewport wrapping:
2766
// - view line count impacts minimap layout
2767
// - minimap layout impacts viewport width
2768
// - viewport width impacts view line count
2769
// To break the loop, once we go to a smaller minimap scale, we try to stick with it.
2770
fitBecomesFill = true;
2771
maxMinimapScale = memory.stableFitMaxMinimapScale;
2772
} else {
2773
fitBecomesFill = (effectiveMinimapHeight > minimapCanvasInnerHeight);
2774
}
2775
}
2776
2777
if (minimapSize === 'fill' || fitBecomesFill) {
2778
minimapHeightIsEditorHeight = true;
2779
const configuredMinimapScale = minimapScale;
2780
minimapLineHeight = Math.min(lineHeight * pixelRatio, Math.max(1, Math.floor(1 / desiredRatio)));
2781
if (isViewportWrapping && couldUseMemory && remainingWidth <= memory.stableFitRemainingWidth) {
2782
// There is a loop when using `fill` and viewport wrapping:
2783
// - view line count impacts minimap layout
2784
// - minimap layout impacts viewport width
2785
// - viewport width impacts view line count
2786
// To break the loop, once we go to a smaller minimap scale, we try to stick with it.
2787
maxMinimapScale = memory.stableFitMaxMinimapScale;
2788
}
2789
minimapScale = Math.min(maxMinimapScale, Math.max(1, Math.floor(minimapLineHeight / baseCharHeight)));
2790
if (minimapScale > configuredMinimapScale) {
2791
minimapWidthMultiplier = Math.min(2, minimapScale / configuredMinimapScale);
2792
}
2793
minimapCharWidth = minimapScale / pixelRatio / minimapWidthMultiplier;
2794
minimapCanvasInnerHeight = Math.ceil((Math.max(typicalViewportLineCount, extraLinesBeforeFirstLine + viewLineCount + extraLinesBeyondLastLine)) * minimapLineHeight);
2795
if (isViewportWrapping) {
2796
// remember for next time
2797
memory.stableMinimapLayoutInput = input;
2798
memory.stableFitRemainingWidth = remainingWidth;
2799
memory.stableFitMaxMinimapScale = minimapScale;
2800
} else {
2801
memory.stableMinimapLayoutInput = null;
2802
memory.stableFitRemainingWidth = 0;
2803
}
2804
}
2805
}
2806
}
2807
2808
// Given:
2809
// (leaving 2px for the cursor to have space after the last character)
2810
// viewportColumn = (contentWidth - verticalScrollbarWidth - 2) / typicalHalfwidthCharacterWidth
2811
// minimapWidth = viewportColumn * minimapCharWidth
2812
// contentWidth = remainingWidth - minimapWidth
2813
// What are good values for contentWidth and minimapWidth ?
2814
2815
// minimapWidth = ((contentWidth - verticalScrollbarWidth - 2) / typicalHalfwidthCharacterWidth) * minimapCharWidth
2816
// typicalHalfwidthCharacterWidth * minimapWidth = (contentWidth - verticalScrollbarWidth - 2) * minimapCharWidth
2817
// typicalHalfwidthCharacterWidth * minimapWidth = (remainingWidth - minimapWidth - verticalScrollbarWidth - 2) * minimapCharWidth
2818
// (typicalHalfwidthCharacterWidth + minimapCharWidth) * minimapWidth = (remainingWidth - verticalScrollbarWidth - 2) * minimapCharWidth
2819
// minimapWidth = ((remainingWidth - verticalScrollbarWidth - 2) * minimapCharWidth) / (typicalHalfwidthCharacterWidth + minimapCharWidth)
2820
2821
const minimapMaxWidth = Math.floor(minimapMaxColumn * minimapCharWidth);
2822
const minimapWidth = Math.min(minimapMaxWidth, Math.max(0, Math.floor(((remainingWidth - verticalScrollbarWidth - 2) * minimapCharWidth) / (typicalHalfwidthCharacterWidth + minimapCharWidth))) + MINIMAP_GUTTER_WIDTH);
2823
2824
let minimapCanvasInnerWidth = Math.floor(pixelRatio * minimapWidth);
2825
const minimapCanvasOuterWidth = minimapCanvasInnerWidth / pixelRatio;
2826
minimapCanvasInnerWidth = Math.floor(minimapCanvasInnerWidth * minimapWidthMultiplier);
2827
2828
const renderMinimap = (minimapRenderCharacters ? RenderMinimap.Text : RenderMinimap.Blocks);
2829
const minimapLeft = (minimapSide === 'left' ? 0 : (outerWidth - minimapWidth - verticalScrollbarWidth));
2830
2831
return {
2832
renderMinimap,
2833
minimapLeft,
2834
minimapWidth,
2835
minimapHeightIsEditorHeight,
2836
minimapIsSampling,
2837
minimapScale,
2838
minimapLineHeight,
2839
minimapCanvasInnerWidth,
2840
minimapCanvasInnerHeight,
2841
minimapCanvasOuterWidth,
2842
minimapCanvasOuterHeight,
2843
};
2844
}
2845
2846
public static computeLayout(options: IComputedEditorOptions, env: EditorLayoutInfoComputerEnv): EditorLayoutInfo {
2847
const outerWidth = env.outerWidth | 0;
2848
const outerHeight = env.outerHeight | 0;
2849
const lineHeight = env.lineHeight | 0;
2850
const lineNumbersDigitCount = env.lineNumbersDigitCount | 0;
2851
const typicalHalfwidthCharacterWidth = env.typicalHalfwidthCharacterWidth;
2852
const maxDigitWidth = env.maxDigitWidth;
2853
const pixelRatio = env.pixelRatio;
2854
const viewLineCount = env.viewLineCount;
2855
2856
const wordWrapOverride2 = options.get(EditorOption.wordWrapOverride2);
2857
const wordWrapOverride1 = (wordWrapOverride2 === 'inherit' ? options.get(EditorOption.wordWrapOverride1) : wordWrapOverride2);
2858
const wordWrap = (wordWrapOverride1 === 'inherit' ? options.get(EditorOption.wordWrap) : wordWrapOverride1);
2859
2860
const wordWrapColumn = options.get(EditorOption.wordWrapColumn);
2861
const isDominatedByLongLines = env.isDominatedByLongLines;
2862
2863
const showGlyphMargin = options.get(EditorOption.glyphMargin);
2864
const showLineNumbers = (options.get(EditorOption.lineNumbers).renderType !== RenderLineNumbersType.Off);
2865
const lineNumbersMinChars = options.get(EditorOption.lineNumbersMinChars);
2866
const scrollBeyondLastLine = options.get(EditorOption.scrollBeyondLastLine);
2867
const padding = options.get(EditorOption.padding);
2868
const minimap = options.get(EditorOption.minimap);
2869
2870
const scrollbar = options.get(EditorOption.scrollbar);
2871
const verticalScrollbarWidth = scrollbar.verticalScrollbarSize;
2872
const verticalScrollbarHasArrows = scrollbar.verticalHasArrows;
2873
const scrollbarArrowSize = scrollbar.arrowSize;
2874
const horizontalScrollbarHeight = scrollbar.horizontalScrollbarSize;
2875
2876
const folding = options.get(EditorOption.folding);
2877
const showFoldingDecoration = options.get(EditorOption.showFoldingControls) !== 'never';
2878
2879
let lineDecorationsWidth = options.get(EditorOption.lineDecorationsWidth);
2880
if (folding && showFoldingDecoration) {
2881
lineDecorationsWidth += 16;
2882
}
2883
2884
let lineNumbersWidth = 0;
2885
if (showLineNumbers) {
2886
const digitCount = Math.max(lineNumbersDigitCount, lineNumbersMinChars);
2887
lineNumbersWidth = Math.round(digitCount * maxDigitWidth);
2888
}
2889
2890
let glyphMarginWidth = 0;
2891
if (showGlyphMargin) {
2892
glyphMarginWidth = lineHeight * env.glyphMarginDecorationLaneCount;
2893
}
2894
2895
let glyphMarginLeft = 0;
2896
let lineNumbersLeft = glyphMarginLeft + glyphMarginWidth;
2897
let decorationsLeft = lineNumbersLeft + lineNumbersWidth;
2898
let contentLeft = decorationsLeft + lineDecorationsWidth;
2899
2900
const remainingWidth = outerWidth - glyphMarginWidth - lineNumbersWidth - lineDecorationsWidth;
2901
2902
let isWordWrapMinified = false;
2903
let isViewportWrapping = false;
2904
let wrappingColumn = -1;
2905
2906
if (options.get(EditorOption.accessibilitySupport) === AccessibilitySupport.Enabled && wordWrapOverride1 === 'inherit' && isDominatedByLongLines) {
2907
// Force viewport width wrapping if model is dominated by long lines
2908
isWordWrapMinified = true;
2909
isViewportWrapping = true;
2910
} else if (wordWrap === 'on' || wordWrap === 'bounded') {
2911
isViewportWrapping = true;
2912
} else if (wordWrap === 'wordWrapColumn') {
2913
wrappingColumn = wordWrapColumn;
2914
}
2915
2916
const minimapLayout = EditorLayoutInfoComputer._computeMinimapLayout({
2917
outerWidth: outerWidth,
2918
outerHeight: outerHeight,
2919
lineHeight: lineHeight,
2920
typicalHalfwidthCharacterWidth: typicalHalfwidthCharacterWidth,
2921
pixelRatio: pixelRatio,
2922
scrollBeyondLastLine: scrollBeyondLastLine,
2923
paddingTop: padding.top,
2924
paddingBottom: padding.bottom,
2925
minimap: minimap,
2926
verticalScrollbarWidth: verticalScrollbarWidth,
2927
viewLineCount: viewLineCount,
2928
remainingWidth: remainingWidth,
2929
isViewportWrapping: isViewportWrapping,
2930
}, env.memory || new ComputeOptionsMemory());
2931
2932
if (minimapLayout.renderMinimap !== RenderMinimap.None && minimapLayout.minimapLeft === 0) {
2933
// the minimap is rendered to the left, so move everything to the right
2934
glyphMarginLeft += minimapLayout.minimapWidth;
2935
lineNumbersLeft += minimapLayout.minimapWidth;
2936
decorationsLeft += minimapLayout.minimapWidth;
2937
contentLeft += minimapLayout.minimapWidth;
2938
}
2939
const contentWidth = remainingWidth - minimapLayout.minimapWidth;
2940
2941
// (leaving 2px for the cursor to have space after the last character)
2942
const viewportColumn = Math.max(1, Math.floor((contentWidth - verticalScrollbarWidth - 2) / typicalHalfwidthCharacterWidth));
2943
2944
const verticalArrowSize = (verticalScrollbarHasArrows ? scrollbarArrowSize : 0);
2945
2946
if (isViewportWrapping) {
2947
// compute the actual wrappingColumn
2948
wrappingColumn = Math.max(1, viewportColumn);
2949
if (wordWrap === 'bounded') {
2950
wrappingColumn = Math.min(wrappingColumn, wordWrapColumn);
2951
}
2952
}
2953
2954
return {
2955
width: outerWidth,
2956
height: outerHeight,
2957
2958
glyphMarginLeft: glyphMarginLeft,
2959
glyphMarginWidth: glyphMarginWidth,
2960
glyphMarginDecorationLaneCount: env.glyphMarginDecorationLaneCount,
2961
2962
lineNumbersLeft: lineNumbersLeft,
2963
lineNumbersWidth: lineNumbersWidth,
2964
2965
decorationsLeft: decorationsLeft,
2966
decorationsWidth: lineDecorationsWidth,
2967
2968
contentLeft: contentLeft,
2969
contentWidth: contentWidth,
2970
2971
minimap: minimapLayout,
2972
2973
viewportColumn: viewportColumn,
2974
2975
isWordWrapMinified: isWordWrapMinified,
2976
isViewportWrapping: isViewportWrapping,
2977
wrappingColumn: wrappingColumn,
2978
2979
verticalScrollbarWidth: verticalScrollbarWidth,
2980
horizontalScrollbarHeight: horizontalScrollbarHeight,
2981
2982
overviewRuler: {
2983
top: verticalArrowSize,
2984
width: verticalScrollbarWidth,
2985
height: (outerHeight - 2 * verticalArrowSize),
2986
right: 0
2987
}
2988
};
2989
}
2990
}
2991
2992
//#endregion
2993
2994
//#region WrappingStrategy
2995
class WrappingStrategy extends BaseEditorOption<EditorOption.wrappingStrategy, 'simple' | 'advanced', 'simple' | 'advanced'> {
2996
2997
constructor() {
2998
super(EditorOption.wrappingStrategy, 'wrappingStrategy', 'simple',
2999
{
3000
'editor.wrappingStrategy': {
3001
enumDescriptions: [
3002
nls.localize('wrappingStrategy.simple', "Assumes that all characters are of the same width. This is a fast algorithm that works correctly for monospace fonts and certain scripts (like Latin characters) where glyphs are of equal width."),
3003
nls.localize('wrappingStrategy.advanced', "Delegates wrapping points computation to the browser. This is a slow algorithm, that might cause freezes for large files, but it works correctly in all cases.")
3004
],
3005
type: 'string',
3006
enum: ['simple', 'advanced'],
3007
default: 'simple',
3008
description: nls.localize('wrappingStrategy', "Controls the algorithm that computes wrapping points. Note that when in accessibility mode, advanced will be used for the best experience.")
3009
}
3010
}
3011
);
3012
}
3013
3014
public validate(input: unknown): 'simple' | 'advanced' {
3015
return stringSet<'simple' | 'advanced'>(input, 'simple', ['simple', 'advanced']);
3016
}
3017
3018
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: 'simple' | 'advanced'): 'simple' | 'advanced' {
3019
const accessibilitySupport = options.get(EditorOption.accessibilitySupport);
3020
if (accessibilitySupport === AccessibilitySupport.Enabled) {
3021
// if we know for a fact that a screen reader is attached, we switch our strategy to advanced to
3022
// help that the editor's wrapping points match the textarea's wrapping points
3023
return 'advanced';
3024
}
3025
return value;
3026
}
3027
}
3028
//#endregion
3029
3030
//#region lightbulb
3031
3032
export enum ShowLightbulbIconMode {
3033
Off = 'off',
3034
OnCode = 'onCode',
3035
On = 'on'
3036
}
3037
3038
/**
3039
* Configuration options for editor lightbulb
3040
*/
3041
export interface IEditorLightbulbOptions {
3042
/**
3043
* Enable the lightbulb code action.
3044
* The three possible values are `off`, `on` and `onCode` and the default is `onCode`.
3045
* `off` disables the code action menu.
3046
* `on` shows the code action menu on code and on empty lines.
3047
* `onCode` shows the code action menu on code only.
3048
*/
3049
enabled?: ShowLightbulbIconMode;
3050
}
3051
3052
/**
3053
* @internal
3054
*/
3055
export type EditorLightbulbOptions = Readonly<Required<IEditorLightbulbOptions>>;
3056
3057
class EditorLightbulb extends BaseEditorOption<EditorOption.lightbulb, IEditorLightbulbOptions, EditorLightbulbOptions> {
3058
3059
constructor() {
3060
const defaults: EditorLightbulbOptions = { enabled: ShowLightbulbIconMode.OnCode };
3061
super(
3062
EditorOption.lightbulb, 'lightbulb', defaults,
3063
{
3064
'editor.lightbulb.enabled': {
3065
type: 'string',
3066
enum: [ShowLightbulbIconMode.Off, ShowLightbulbIconMode.OnCode, ShowLightbulbIconMode.On],
3067
default: defaults.enabled,
3068
enumDescriptions: [
3069
nls.localize('editor.lightbulb.enabled.off', 'Disable the code action menu.'),
3070
nls.localize('editor.lightbulb.enabled.onCode', 'Show the code action menu when the cursor is on lines with code.'),
3071
nls.localize('editor.lightbulb.enabled.on', 'Show the code action menu when the cursor is on lines with code or on empty lines.'),
3072
],
3073
description: nls.localize('enabled', "Enables the Code Action lightbulb in the editor.")
3074
}
3075
}
3076
);
3077
}
3078
3079
public validate(_input: unknown): EditorLightbulbOptions {
3080
if (!_input || typeof _input !== 'object') {
3081
return this.defaultValue;
3082
}
3083
const input = _input as Unknown<IEditorLightbulbOptions>;
3084
return {
3085
enabled: stringSet(input.enabled, this.defaultValue.enabled, [ShowLightbulbIconMode.Off, ShowLightbulbIconMode.OnCode, ShowLightbulbIconMode.On])
3086
};
3087
}
3088
}
3089
3090
//#endregion
3091
3092
//#region stickyScroll
3093
3094
export interface IEditorStickyScrollOptions {
3095
/**
3096
* Enable the sticky scroll
3097
*/
3098
enabled?: boolean;
3099
/**
3100
* Maximum number of sticky lines to show
3101
*/
3102
maxLineCount?: number;
3103
/**
3104
* Model to choose for sticky scroll by default
3105
*/
3106
defaultModel?: 'outlineModel' | 'foldingProviderModel' | 'indentationModel';
3107
/**
3108
* Define whether to scroll sticky scroll with editor horizontal scrollbae
3109
*/
3110
scrollWithEditor?: boolean;
3111
}
3112
3113
/**
3114
* @internal
3115
*/
3116
export type EditorStickyScrollOptions = Readonly<Required<IEditorStickyScrollOptions>>;
3117
3118
class EditorStickyScroll extends BaseEditorOption<EditorOption.stickyScroll, IEditorStickyScrollOptions, EditorStickyScrollOptions> {
3119
3120
constructor() {
3121
const defaults: EditorStickyScrollOptions = { enabled: true, maxLineCount: 5, defaultModel: 'outlineModel', scrollWithEditor: true };
3122
super(
3123
EditorOption.stickyScroll, 'stickyScroll', defaults,
3124
{
3125
'editor.stickyScroll.enabled': {
3126
type: 'boolean',
3127
default: defaults.enabled,
3128
description: nls.localize('editor.stickyScroll.enabled', "Shows the nested current scopes during the scroll at the top of the editor.")
3129
},
3130
'editor.stickyScroll.maxLineCount': {
3131
type: 'number',
3132
default: defaults.maxLineCount,
3133
minimum: 1,
3134
maximum: 20,
3135
description: nls.localize('editor.stickyScroll.maxLineCount', "Defines the maximum number of sticky lines to show.")
3136
},
3137
'editor.stickyScroll.defaultModel': {
3138
type: 'string',
3139
enum: ['outlineModel', 'foldingProviderModel', 'indentationModel'],
3140
default: defaults.defaultModel,
3141
description: nls.localize('editor.stickyScroll.defaultModel', "Defines the model to use for determining which lines to stick. If the outline model does not exist, it will fall back on the folding provider model which falls back on the indentation model. This order is respected in all three cases.")
3142
},
3143
'editor.stickyScroll.scrollWithEditor': {
3144
type: 'boolean',
3145
default: defaults.scrollWithEditor,
3146
description: nls.localize('editor.stickyScroll.scrollWithEditor', "Enable scrolling of Sticky Scroll with the editor's horizontal scrollbar.")
3147
},
3148
}
3149
);
3150
}
3151
3152
public validate(_input: unknown): EditorStickyScrollOptions {
3153
if (!_input || typeof _input !== 'object') {
3154
return this.defaultValue;
3155
}
3156
const input = _input as Unknown<IEditorStickyScrollOptions>;
3157
return {
3158
enabled: boolean(input.enabled, this.defaultValue.enabled),
3159
maxLineCount: EditorIntOption.clampedInt(input.maxLineCount, this.defaultValue.maxLineCount, 1, 20),
3160
defaultModel: stringSet<'outlineModel' | 'foldingProviderModel' | 'indentationModel'>(input.defaultModel, this.defaultValue.defaultModel, ['outlineModel', 'foldingProviderModel', 'indentationModel']),
3161
scrollWithEditor: boolean(input.scrollWithEditor, this.defaultValue.scrollWithEditor)
3162
};
3163
}
3164
}
3165
3166
//#endregion
3167
3168
//#region inlayHints
3169
3170
/**
3171
* Configuration options for editor inlayHints
3172
*/
3173
export interface IEditorInlayHintsOptions {
3174
/**
3175
* Enable the inline hints.
3176
* Defaults to true.
3177
*/
3178
enabled?: 'on' | 'off' | 'offUnlessPressed' | 'onUnlessPressed';
3179
3180
/**
3181
* Font size of inline hints.
3182
* Default to 90% of the editor font size.
3183
*/
3184
fontSize?: number;
3185
3186
/**
3187
* Font family of inline hints.
3188
* Defaults to editor font family.
3189
*/
3190
fontFamily?: string;
3191
3192
/**
3193
* Enables the padding around the inlay hint.
3194
* Defaults to false.
3195
*/
3196
padding?: boolean;
3197
3198
/**
3199
* Maximum length for inlay hints per line
3200
* Set to 0 to have an unlimited length.
3201
*/
3202
maximumLength?: number;
3203
}
3204
3205
/**
3206
* @internal
3207
*/
3208
export type EditorInlayHintsOptions = Readonly<Required<IEditorInlayHintsOptions>>;
3209
3210
class EditorInlayHints extends BaseEditorOption<EditorOption.inlayHints, IEditorInlayHintsOptions, EditorInlayHintsOptions> {
3211
3212
constructor() {
3213
const defaults: EditorInlayHintsOptions = { enabled: 'on', fontSize: 0, fontFamily: '', padding: false, maximumLength: 43 };
3214
super(
3215
EditorOption.inlayHints, 'inlayHints', defaults,
3216
{
3217
'editor.inlayHints.enabled': {
3218
type: 'string',
3219
default: defaults.enabled,
3220
description: nls.localize('inlayHints.enable', "Enables the inlay hints in the editor."),
3221
enum: ['on', 'onUnlessPressed', 'offUnlessPressed', 'off'],
3222
markdownEnumDescriptions: [
3223
nls.localize('editor.inlayHints.on', "Inlay hints are enabled"),
3224
nls.localize('editor.inlayHints.onUnlessPressed', "Inlay hints are showing by default and hide when holding {0}", platform.isMacintosh ? `Ctrl+Option` : `Ctrl+Alt`),
3225
nls.localize('editor.inlayHints.offUnlessPressed', "Inlay hints are hidden by default and show when holding {0}", platform.isMacintosh ? `Ctrl+Option` : `Ctrl+Alt`),
3226
nls.localize('editor.inlayHints.off', "Inlay hints are disabled"),
3227
],
3228
},
3229
'editor.inlayHints.fontSize': {
3230
type: 'number',
3231
default: defaults.fontSize,
3232
markdownDescription: nls.localize('inlayHints.fontSize', "Controls font size of inlay hints in the editor. As default the {0} is used when the configured value is less than {1} or greater than the editor font size.", '`#editor.fontSize#`', '`5`')
3233
},
3234
'editor.inlayHints.fontFamily': {
3235
type: 'string',
3236
default: defaults.fontFamily,
3237
markdownDescription: nls.localize('inlayHints.fontFamily', "Controls font family of inlay hints in the editor. When set to empty, the {0} is used.", '`#editor.fontFamily#`')
3238
},
3239
'editor.inlayHints.padding': {
3240
type: 'boolean',
3241
default: defaults.padding,
3242
description: nls.localize('inlayHints.padding', "Enables the padding around the inlay hints in the editor.")
3243
},
3244
'editor.inlayHints.maximumLength': {
3245
type: 'number',
3246
default: defaults.maximumLength,
3247
markdownDescription: nls.localize('inlayHints.maximumLength', "Maximum overall length of inlay hints, for a single line, before they get truncated by the editor. Set to `0` to never truncate")
3248
}
3249
}
3250
);
3251
}
3252
3253
public validate(_input: unknown): EditorInlayHintsOptions {
3254
if (!_input || typeof _input !== 'object') {
3255
return this.defaultValue;
3256
}
3257
const input = _input as Unknown<IEditorInlayHintsOptions>;
3258
if (typeof input.enabled === 'boolean') {
3259
input.enabled = input.enabled ? 'on' : 'off';
3260
}
3261
return {
3262
enabled: stringSet<'on' | 'off' | 'offUnlessPressed' | 'onUnlessPressed'>(input.enabled, this.defaultValue.enabled, ['on', 'off', 'offUnlessPressed', 'onUnlessPressed']),
3263
fontSize: EditorIntOption.clampedInt(input.fontSize, this.defaultValue.fontSize, 0, 100),
3264
fontFamily: EditorStringOption.string(input.fontFamily, this.defaultValue.fontFamily),
3265
padding: boolean(input.padding, this.defaultValue.padding),
3266
maximumLength: EditorIntOption.clampedInt(input.maximumLength, this.defaultValue.maximumLength, 0, Number.MAX_SAFE_INTEGER),
3267
};
3268
}
3269
}
3270
3271
//#endregion
3272
3273
//#region lineDecorationsWidth
3274
3275
class EditorLineDecorationsWidth extends BaseEditorOption<EditorOption.lineDecorationsWidth, number | string, number> {
3276
3277
constructor() {
3278
super(EditorOption.lineDecorationsWidth, 'lineDecorationsWidth', 10);
3279
}
3280
3281
public validate(input: unknown): number {
3282
if (typeof input === 'string' && /^\d+(\.\d+)?ch$/.test(input)) {
3283
const multiple = parseFloat(input.substring(0, input.length - 2));
3284
return -multiple; // negative numbers signal a multiple
3285
} else {
3286
return EditorIntOption.clampedInt(input, this.defaultValue, 0, 1000);
3287
}
3288
}
3289
3290
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: number): number {
3291
if (value < 0) {
3292
// negative numbers signal a multiple
3293
return EditorIntOption.clampedInt(-value * env.fontInfo.typicalHalfwidthCharacterWidth, this.defaultValue, 0, 1000);
3294
} else {
3295
return value;
3296
}
3297
}
3298
}
3299
3300
//#endregion
3301
3302
//#region lineHeight
3303
3304
class EditorLineHeight extends EditorFloatOption<EditorOption.lineHeight> {
3305
3306
constructor() {
3307
super(
3308
EditorOption.lineHeight, 'lineHeight',
3309
EDITOR_FONT_DEFAULTS.lineHeight,
3310
x => EditorFloatOption.clamp(x, 0, 150),
3311
{ markdownDescription: nls.localize('lineHeight', "Controls the line height. \n - Use 0 to automatically compute the line height from the font size.\n - Values between 0 and 8 will be used as a multiplier with the font size.\n - Values greater than or equal to 8 will be used as effective values.") },
3312
0,
3313
150
3314
);
3315
}
3316
3317
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: number): number {
3318
// The lineHeight is computed from the fontSize if it is 0.
3319
// Moreover, the final lineHeight respects the editor zoom level.
3320
// So take the result from env.fontInfo
3321
return env.fontInfo.lineHeight;
3322
}
3323
}
3324
3325
//#endregion
3326
3327
//#region minimap
3328
3329
/**
3330
* Configuration options for editor minimap
3331
*/
3332
export interface IEditorMinimapOptions {
3333
/**
3334
* Enable the rendering of the minimap.
3335
* Defaults to true.
3336
*/
3337
enabled?: boolean;
3338
/**
3339
* Control the rendering of minimap.
3340
*/
3341
autohide?: 'none' | 'mouseover' | 'scroll';
3342
/**
3343
* Control the side of the minimap in editor.
3344
* Defaults to 'right'.
3345
*/
3346
side?: 'right' | 'left';
3347
/**
3348
* Control the minimap rendering mode.
3349
* Defaults to 'actual'.
3350
*/
3351
size?: 'proportional' | 'fill' | 'fit';
3352
/**
3353
* Control the rendering of the minimap slider.
3354
* Defaults to 'mouseover'.
3355
*/
3356
showSlider?: 'always' | 'mouseover';
3357
/**
3358
* Render the actual text on a line (as opposed to color blocks).
3359
* Defaults to true.
3360
*/
3361
renderCharacters?: boolean;
3362
/**
3363
* Limit the width of the minimap to render at most a certain number of columns.
3364
* Defaults to 120.
3365
*/
3366
maxColumn?: number;
3367
/**
3368
* Relative size of the font in the minimap. Defaults to 1.
3369
*/
3370
scale?: number;
3371
/**
3372
* Whether to show named regions as section headers. Defaults to true.
3373
*/
3374
showRegionSectionHeaders?: boolean;
3375
/**
3376
* Whether to show MARK: comments as section headers. Defaults to true.
3377
*/
3378
showMarkSectionHeaders?: boolean;
3379
/**
3380
* When specified, is used to create a custom section header parser regexp.
3381
* Must contain a match group named 'label' (written as (?<label>.+)) that encapsulates the section header.
3382
* Optionally can include another match group named 'separator'.
3383
* To match multi-line headers like:
3384
* // ==========
3385
* // My Section
3386
* // ==========
3387
* Use a pattern like: ^={3,}\n^\/\/ *(?<label>[^\n]*?)\n^={3,}$
3388
*/
3389
markSectionHeaderRegex?: string;
3390
/**
3391
* Font size of section headers. Defaults to 9.
3392
*/
3393
sectionHeaderFontSize?: number;
3394
/**
3395
* Spacing between the section header characters (in CSS px). Defaults to 1.
3396
*/
3397
sectionHeaderLetterSpacing?: number;
3398
}
3399
3400
/**
3401
* @internal
3402
*/
3403
export type EditorMinimapOptions = Readonly<Required<IEditorMinimapOptions>>;
3404
3405
class EditorMinimap extends BaseEditorOption<EditorOption.minimap, IEditorMinimapOptions, EditorMinimapOptions> {
3406
3407
constructor() {
3408
const defaults: EditorMinimapOptions = {
3409
enabled: true,
3410
size: 'proportional',
3411
side: 'right',
3412
showSlider: 'mouseover',
3413
autohide: 'none',
3414
renderCharacters: true,
3415
maxColumn: 120,
3416
scale: 1,
3417
showRegionSectionHeaders: true,
3418
showMarkSectionHeaders: true,
3419
markSectionHeaderRegex: '\\bMARK:\\s*(?<separator>\-?)\\s*(?<label>.*)$',
3420
sectionHeaderFontSize: 9,
3421
sectionHeaderLetterSpacing: 1,
3422
};
3423
super(
3424
EditorOption.minimap, 'minimap', defaults,
3425
{
3426
'editor.minimap.enabled': {
3427
type: 'boolean',
3428
default: defaults.enabled,
3429
description: nls.localize('minimap.enabled', "Controls whether the minimap is shown.")
3430
},
3431
'editor.minimap.autohide': {
3432
type: 'string',
3433
enum: ['none', 'mouseover', 'scroll'],
3434
enumDescriptions: [
3435
nls.localize('minimap.autohide.none', "The minimap is always shown."),
3436
nls.localize('minimap.autohide.mouseover', "The minimap is hidden when mouse is not over the minimap and shown when mouse is over the minimap."),
3437
nls.localize('minimap.autohide.scroll', "The minimap is only shown when the editor is scrolled"),
3438
],
3439
default: defaults.autohide,
3440
description: nls.localize('minimap.autohide', "Controls whether the minimap is hidden automatically.")
3441
},
3442
'editor.minimap.size': {
3443
type: 'string',
3444
enum: ['proportional', 'fill', 'fit'],
3445
enumDescriptions: [
3446
nls.localize('minimap.size.proportional', "The minimap has the same size as the editor contents (and might scroll)."),
3447
nls.localize('minimap.size.fill', "The minimap will stretch or shrink as necessary to fill the height of the editor (no scrolling)."),
3448
nls.localize('minimap.size.fit', "The minimap will shrink as necessary to never be larger than the editor (no scrolling)."),
3449
],
3450
default: defaults.size,
3451
description: nls.localize('minimap.size', "Controls the size of the minimap.")
3452
},
3453
'editor.minimap.side': {
3454
type: 'string',
3455
enum: ['left', 'right'],
3456
default: defaults.side,
3457
description: nls.localize('minimap.side', "Controls the side where to render the minimap.")
3458
},
3459
'editor.minimap.showSlider': {
3460
type: 'string',
3461
enum: ['always', 'mouseover'],
3462
default: defaults.showSlider,
3463
description: nls.localize('minimap.showSlider', "Controls when the minimap slider is shown.")
3464
},
3465
'editor.minimap.scale': {
3466
type: 'number',
3467
default: defaults.scale,
3468
minimum: 1,
3469
maximum: 3,
3470
enum: [1, 2, 3],
3471
description: nls.localize('minimap.scale', "Scale of content drawn in the minimap: 1, 2 or 3.")
3472
},
3473
'editor.minimap.renderCharacters': {
3474
type: 'boolean',
3475
default: defaults.renderCharacters,
3476
description: nls.localize('minimap.renderCharacters', "Render the actual characters on a line as opposed to color blocks.")
3477
},
3478
'editor.minimap.maxColumn': {
3479
type: 'number',
3480
default: defaults.maxColumn,
3481
description: nls.localize('minimap.maxColumn', "Limit the width of the minimap to render at most a certain number of columns.")
3482
},
3483
'editor.minimap.showRegionSectionHeaders': {
3484
type: 'boolean',
3485
default: defaults.showRegionSectionHeaders,
3486
description: nls.localize('minimap.showRegionSectionHeaders', "Controls whether named regions are shown as section headers in the minimap.")
3487
},
3488
'editor.minimap.showMarkSectionHeaders': {
3489
type: 'boolean',
3490
default: defaults.showMarkSectionHeaders,
3491
description: nls.localize('minimap.showMarkSectionHeaders', "Controls whether MARK: comments are shown as section headers in the minimap.")
3492
},
3493
'editor.minimap.markSectionHeaderRegex': {
3494
type: 'string',
3495
default: defaults.markSectionHeaderRegex,
3496
description: nls.localize('minimap.markSectionHeaderRegex', "Defines the regular expression used to find section headers in comments. The regex must contain a named match group `label` (written as `(?<label>.+)`) that encapsulates the section header, otherwise it will not work. Optionally you can include another match group named `separator`. Use \\n in the pattern to match multi-line headers."),
3497
},
3498
'editor.minimap.sectionHeaderFontSize': {
3499
type: 'number',
3500
default: defaults.sectionHeaderFontSize,
3501
description: nls.localize('minimap.sectionHeaderFontSize', "Controls the font size of section headers in the minimap.")
3502
},
3503
'editor.minimap.sectionHeaderLetterSpacing': {
3504
type: 'number',
3505
default: defaults.sectionHeaderLetterSpacing,
3506
description: nls.localize('minimap.sectionHeaderLetterSpacing', "Controls the amount of space (in pixels) between characters of section header. This helps the readability of the header in small font sizes.")
3507
}
3508
}
3509
);
3510
}
3511
3512
public validate(_input: unknown): EditorMinimapOptions {
3513
if (!_input || typeof _input !== 'object') {
3514
return this.defaultValue;
3515
}
3516
const input = _input as Unknown<IEditorMinimapOptions>;
3517
3518
// Validate mark section header regex
3519
let markSectionHeaderRegex = this.defaultValue.markSectionHeaderRegex;
3520
const inputRegex = input.markSectionHeaderRegex;
3521
if (typeof inputRegex === 'string') {
3522
try {
3523
new RegExp(inputRegex, 'd');
3524
markSectionHeaderRegex = inputRegex;
3525
} catch { }
3526
}
3527
3528
return {
3529
enabled: boolean(input.enabled, this.defaultValue.enabled),
3530
autohide: stringSet<'none' | 'mouseover' | 'scroll'>(input.autohide, this.defaultValue.autohide, ['none', 'mouseover', 'scroll']),
3531
size: stringSet<'proportional' | 'fill' | 'fit'>(input.size, this.defaultValue.size, ['proportional', 'fill', 'fit']),
3532
side: stringSet<'right' | 'left'>(input.side, this.defaultValue.side, ['right', 'left']),
3533
showSlider: stringSet<'always' | 'mouseover'>(input.showSlider, this.defaultValue.showSlider, ['always', 'mouseover']),
3534
renderCharacters: boolean(input.renderCharacters, this.defaultValue.renderCharacters),
3535
scale: EditorIntOption.clampedInt(input.scale, 1, 1, 3),
3536
maxColumn: EditorIntOption.clampedInt(input.maxColumn, this.defaultValue.maxColumn, 1, 10000),
3537
showRegionSectionHeaders: boolean(input.showRegionSectionHeaders, this.defaultValue.showRegionSectionHeaders),
3538
showMarkSectionHeaders: boolean(input.showMarkSectionHeaders, this.defaultValue.showMarkSectionHeaders),
3539
markSectionHeaderRegex: markSectionHeaderRegex,
3540
sectionHeaderFontSize: EditorFloatOption.clamp(EditorFloatOption.float(input.sectionHeaderFontSize, this.defaultValue.sectionHeaderFontSize), 4, 32),
3541
sectionHeaderLetterSpacing: EditorFloatOption.clamp(EditorFloatOption.float(input.sectionHeaderLetterSpacing, this.defaultValue.sectionHeaderLetterSpacing), 0, 5),
3542
};
3543
}
3544
}
3545
3546
//#endregion
3547
3548
//#region multiCursorModifier
3549
3550
function _multiCursorModifierFromString(multiCursorModifier: 'ctrlCmd' | 'alt'): 'altKey' | 'metaKey' | 'ctrlKey' {
3551
if (multiCursorModifier === 'ctrlCmd') {
3552
return (platform.isMacintosh ? 'metaKey' : 'ctrlKey');
3553
}
3554
return 'altKey';
3555
}
3556
3557
//#endregion
3558
3559
//#region padding
3560
3561
/**
3562
* Configuration options for editor padding
3563
*/
3564
export interface IEditorPaddingOptions {
3565
/**
3566
* Spacing between top edge of editor and first line.
3567
*/
3568
top?: number;
3569
/**
3570
* Spacing between bottom edge of editor and last line.
3571
*/
3572
bottom?: number;
3573
}
3574
3575
/**
3576
* @internal
3577
*/
3578
export type InternalEditorPaddingOptions = Readonly<Required<IEditorPaddingOptions>>;
3579
3580
class EditorPadding extends BaseEditorOption<EditorOption.padding, IEditorPaddingOptions, InternalEditorPaddingOptions> {
3581
3582
constructor() {
3583
super(
3584
EditorOption.padding, 'padding', { top: 0, bottom: 0 },
3585
{
3586
'editor.padding.top': {
3587
type: 'number',
3588
default: 0,
3589
minimum: 0,
3590
maximum: 1000,
3591
description: nls.localize('padding.top', "Controls the amount of space between the top edge of the editor and the first line.")
3592
},
3593
'editor.padding.bottom': {
3594
type: 'number',
3595
default: 0,
3596
minimum: 0,
3597
maximum: 1000,
3598
description: nls.localize('padding.bottom', "Controls the amount of space between the bottom edge of the editor and the last line.")
3599
}
3600
}
3601
);
3602
}
3603
3604
public validate(_input: unknown): InternalEditorPaddingOptions {
3605
if (!_input || typeof _input !== 'object') {
3606
return this.defaultValue;
3607
}
3608
const input = _input as Unknown<IEditorPaddingOptions>;
3609
3610
return {
3611
top: EditorIntOption.clampedInt(input.top, 0, 0, 1000),
3612
bottom: EditorIntOption.clampedInt(input.bottom, 0, 0, 1000)
3613
};
3614
}
3615
}
3616
//#endregion
3617
3618
//#region parameterHints
3619
3620
/**
3621
* Configuration options for parameter hints
3622
*/
3623
export interface IEditorParameterHintOptions {
3624
/**
3625
* Enable parameter hints.
3626
* Defaults to true.
3627
*/
3628
enabled?: boolean;
3629
/**
3630
* Enable cycling of parameter hints.
3631
* Defaults to false.
3632
*/
3633
cycle?: boolean;
3634
}
3635
3636
/**
3637
* @internal
3638
*/
3639
export type InternalParameterHintOptions = Readonly<Required<IEditorParameterHintOptions>>;
3640
3641
class EditorParameterHints extends BaseEditorOption<EditorOption.parameterHints, IEditorParameterHintOptions, InternalParameterHintOptions> {
3642
3643
constructor() {
3644
const defaults: InternalParameterHintOptions = {
3645
enabled: true,
3646
cycle: true
3647
};
3648
super(
3649
EditorOption.parameterHints, 'parameterHints', defaults,
3650
{
3651
'editor.parameterHints.enabled': {
3652
type: 'boolean',
3653
default: defaults.enabled,
3654
description: nls.localize('parameterHints.enabled', "Enables a pop-up that shows parameter documentation and type information as you type.")
3655
},
3656
'editor.parameterHints.cycle': {
3657
type: 'boolean',
3658
default: defaults.cycle,
3659
description: nls.localize('parameterHints.cycle', "Controls whether the parameter hints menu cycles or closes when reaching the end of the list.")
3660
},
3661
}
3662
);
3663
}
3664
3665
public validate(_input: unknown): InternalParameterHintOptions {
3666
if (!_input || typeof _input !== 'object') {
3667
return this.defaultValue;
3668
}
3669
const input = _input as Unknown<IEditorParameterHintOptions>;
3670
return {
3671
enabled: boolean(input.enabled, this.defaultValue.enabled),
3672
cycle: boolean(input.cycle, this.defaultValue.cycle)
3673
};
3674
}
3675
}
3676
3677
//#endregion
3678
3679
//#region pixelRatio
3680
3681
class EditorPixelRatio extends ComputedEditorOption<EditorOption.pixelRatio, number> {
3682
3683
constructor() {
3684
super(EditorOption.pixelRatio, 1);
3685
}
3686
3687
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: number): number {
3688
return env.pixelRatio;
3689
}
3690
}
3691
3692
//#endregion
3693
3694
//#region
3695
3696
class PlaceholderOption extends BaseEditorOption<EditorOption.placeholder, string | undefined, string | undefined> {
3697
constructor() {
3698
super(EditorOption.placeholder, 'placeholder', undefined);
3699
}
3700
3701
public validate(input: unknown): string | undefined {
3702
if (typeof input === 'undefined') {
3703
return this.defaultValue;
3704
}
3705
if (typeof input === 'string') {
3706
return input;
3707
}
3708
return this.defaultValue;
3709
}
3710
}
3711
//#endregion
3712
3713
//#region quickSuggestions
3714
3715
export type QuickSuggestionsValue = 'on' | 'inline' | 'off';
3716
3717
/**
3718
* Configuration options for quick suggestions
3719
*/
3720
export interface IQuickSuggestionsOptions {
3721
other?: boolean | QuickSuggestionsValue;
3722
comments?: boolean | QuickSuggestionsValue;
3723
strings?: boolean | QuickSuggestionsValue;
3724
}
3725
3726
export interface InternalQuickSuggestionsOptions {
3727
readonly other: QuickSuggestionsValue;
3728
readonly comments: QuickSuggestionsValue;
3729
readonly strings: QuickSuggestionsValue;
3730
}
3731
3732
class EditorQuickSuggestions extends BaseEditorOption<EditorOption.quickSuggestions, boolean | IQuickSuggestionsOptions, InternalQuickSuggestionsOptions> {
3733
3734
public override readonly defaultValue: InternalQuickSuggestionsOptions;
3735
3736
constructor() {
3737
const defaults: InternalQuickSuggestionsOptions = {
3738
other: 'on',
3739
comments: 'off',
3740
strings: 'off'
3741
};
3742
const types: IJSONSchema[] = [
3743
{ type: 'boolean' },
3744
{
3745
type: 'string',
3746
enum: ['on', 'inline', 'off'],
3747
enumDescriptions: [nls.localize('on', "Quick suggestions show inside the suggest widget"), nls.localize('inline', "Quick suggestions show as ghost text"), nls.localize('off', "Quick suggestions are disabled")]
3748
}
3749
];
3750
super(EditorOption.quickSuggestions, 'quickSuggestions', defaults, {
3751
type: 'object',
3752
additionalProperties: false,
3753
properties: {
3754
strings: {
3755
anyOf: types,
3756
default: defaults.strings,
3757
description: nls.localize('quickSuggestions.strings', "Enable quick suggestions inside strings.")
3758
},
3759
comments: {
3760
anyOf: types,
3761
default: defaults.comments,
3762
description: nls.localize('quickSuggestions.comments', "Enable quick suggestions inside comments.")
3763
},
3764
other: {
3765
anyOf: types,
3766
default: defaults.other,
3767
description: nls.localize('quickSuggestions.other', "Enable quick suggestions outside of strings and comments.")
3768
},
3769
},
3770
default: defaults,
3771
markdownDescription: nls.localize('quickSuggestions', "Controls whether suggestions should automatically show up while typing. This can be controlled for typing in comments, strings, and other code. Quick suggestion can be configured to show as ghost text or with the suggest widget. Also be aware of the {0}-setting which controls if suggestions are triggered by special characters.", '`#editor.suggestOnTriggerCharacters#`')
3772
});
3773
this.defaultValue = defaults;
3774
}
3775
3776
public validate(input: unknown): InternalQuickSuggestionsOptions {
3777
if (typeof input === 'boolean') {
3778
// boolean -> all on/off
3779
const value = input ? 'on' : 'off';
3780
return { comments: value, strings: value, other: value };
3781
}
3782
if (!input || typeof input !== 'object') {
3783
// invalid object
3784
return this.defaultValue;
3785
}
3786
3787
const { other, comments, strings } = (<IQuickSuggestionsOptions>input);
3788
const allowedValues: QuickSuggestionsValue[] = ['on', 'inline', 'off'];
3789
let validatedOther: QuickSuggestionsValue;
3790
let validatedComments: QuickSuggestionsValue;
3791
let validatedStrings: QuickSuggestionsValue;
3792
3793
if (typeof other === 'boolean') {
3794
validatedOther = other ? 'on' : 'off';
3795
} else {
3796
validatedOther = stringSet(other, this.defaultValue.other, allowedValues);
3797
}
3798
if (typeof comments === 'boolean') {
3799
validatedComments = comments ? 'on' : 'off';
3800
} else {
3801
validatedComments = stringSet(comments, this.defaultValue.comments, allowedValues);
3802
}
3803
if (typeof strings === 'boolean') {
3804
validatedStrings = strings ? 'on' : 'off';
3805
} else {
3806
validatedStrings = stringSet(strings, this.defaultValue.strings, allowedValues);
3807
}
3808
return {
3809
other: validatedOther,
3810
comments: validatedComments,
3811
strings: validatedStrings
3812
};
3813
}
3814
}
3815
3816
//#endregion
3817
3818
//#region renderLineNumbers
3819
3820
export type LineNumbersType = 'on' | 'off' | 'relative' | 'interval' | ((lineNumber: number) => string);
3821
3822
export const enum RenderLineNumbersType {
3823
Off = 0,
3824
On = 1,
3825
Relative = 2,
3826
Interval = 3,
3827
Custom = 4
3828
}
3829
3830
export interface InternalEditorRenderLineNumbersOptions {
3831
readonly renderType: RenderLineNumbersType;
3832
readonly renderFn: ((lineNumber: number) => string) | null;
3833
}
3834
3835
class EditorRenderLineNumbersOption extends BaseEditorOption<EditorOption.lineNumbers, LineNumbersType, InternalEditorRenderLineNumbersOptions> {
3836
3837
constructor() {
3838
super(
3839
EditorOption.lineNumbers, 'lineNumbers', { renderType: RenderLineNumbersType.On, renderFn: null },
3840
{
3841
type: 'string',
3842
enum: ['off', 'on', 'relative', 'interval'],
3843
enumDescriptions: [
3844
nls.localize('lineNumbers.off', "Line numbers are not rendered."),
3845
nls.localize('lineNumbers.on', "Line numbers are rendered as absolute number."),
3846
nls.localize('lineNumbers.relative', "Line numbers are rendered as distance in lines to cursor position."),
3847
nls.localize('lineNumbers.interval', "Line numbers are rendered every 10 lines.")
3848
],
3849
default: 'on',
3850
description: nls.localize('lineNumbers', "Controls the display of line numbers.")
3851
}
3852
);
3853
}
3854
3855
public validate(lineNumbers: unknown): InternalEditorRenderLineNumbersOptions {
3856
let renderType: RenderLineNumbersType = this.defaultValue.renderType;
3857
let renderFn: ((lineNumber: number) => string) | null = this.defaultValue.renderFn;
3858
3859
if (typeof lineNumbers !== 'undefined') {
3860
if (typeof lineNumbers === 'function') {
3861
renderType = RenderLineNumbersType.Custom;
3862
renderFn = lineNumbers as ((lineNumber: number) => string);
3863
} else if (lineNumbers === 'interval') {
3864
renderType = RenderLineNumbersType.Interval;
3865
} else if (lineNumbers === 'relative') {
3866
renderType = RenderLineNumbersType.Relative;
3867
} else if (lineNumbers === 'on') {
3868
renderType = RenderLineNumbersType.On;
3869
} else {
3870
renderType = RenderLineNumbersType.Off;
3871
}
3872
}
3873
3874
return {
3875
renderType,
3876
renderFn
3877
};
3878
}
3879
}
3880
3881
//#endregion
3882
3883
//#region renderValidationDecorations
3884
3885
/**
3886
* @internal
3887
*/
3888
export function filterValidationDecorations(options: IComputedEditorOptions): boolean {
3889
const renderValidationDecorations = options.get(EditorOption.renderValidationDecorations);
3890
if (renderValidationDecorations === 'editable') {
3891
return options.get(EditorOption.readOnly);
3892
}
3893
return renderValidationDecorations === 'on' ? false : true;
3894
}
3895
3896
//#endregion
3897
3898
//#region filterFontDecorations
3899
3900
/**
3901
* @internal
3902
*/
3903
export function filterFontDecorations(options: IComputedEditorOptions): boolean {
3904
return !options.get(EditorOption.effectiveAllowVariableFonts);
3905
}
3906
3907
//#endregion
3908
3909
//#region rulers
3910
3911
export interface IRulerOption {
3912
readonly column: number;
3913
readonly color: string | null;
3914
}
3915
3916
class EditorRulers extends BaseEditorOption<EditorOption.rulers, (number | IRulerOption)[], IRulerOption[]> {
3917
3918
constructor() {
3919
const defaults: IRulerOption[] = [];
3920
const columnSchema: IJSONSchema = { type: 'number', description: nls.localize('rulers.size', "Number of monospace characters at which this editor ruler will render.") };
3921
super(
3922
EditorOption.rulers, 'rulers', defaults,
3923
{
3924
type: 'array',
3925
items: {
3926
anyOf: [
3927
columnSchema,
3928
{
3929
type: [
3930
'object'
3931
],
3932
properties: {
3933
column: columnSchema,
3934
color: {
3935
type: 'string',
3936
description: nls.localize('rulers.color', "Color of this editor ruler."),
3937
format: 'color-hex'
3938
}
3939
}
3940
}
3941
]
3942
},
3943
default: defaults,
3944
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.")
3945
}
3946
);
3947
}
3948
3949
public validate(input: unknown): IRulerOption[] {
3950
if (Array.isArray(input)) {
3951
const rulers: IRulerOption[] = [];
3952
for (const _element of input) {
3953
if (typeof _element === 'number') {
3954
rulers.push({
3955
column: EditorIntOption.clampedInt(_element, 0, 0, 10000),
3956
color: null
3957
});
3958
} else if (_element && typeof _element === 'object') {
3959
const element = _element as IRulerOption;
3960
rulers.push({
3961
column: EditorIntOption.clampedInt(element.column, 0, 0, 10000),
3962
color: element.color
3963
});
3964
}
3965
}
3966
rulers.sort((a, b) => a.column - b.column);
3967
return rulers;
3968
}
3969
return this.defaultValue;
3970
}
3971
}
3972
3973
//#endregion
3974
3975
//#region readonly
3976
3977
/**
3978
* Configuration options for readonly message
3979
*/
3980
class ReadonlyMessage extends BaseEditorOption<EditorOption.readOnlyMessage, IMarkdownString | undefined, IMarkdownString | undefined> {
3981
constructor() {
3982
const defaults = undefined;
3983
3984
super(
3985
EditorOption.readOnlyMessage, 'readOnlyMessage', defaults
3986
);
3987
}
3988
3989
public validate(_input: unknown): IMarkdownString | undefined {
3990
if (!_input || typeof _input !== 'object') {
3991
return this.defaultValue;
3992
}
3993
return _input as IMarkdownString;
3994
}
3995
}
3996
3997
//#endregion
3998
3999
//#region scrollbar
4000
4001
/**
4002
* Configuration options for editor scrollbars
4003
*/
4004
export interface IEditorScrollbarOptions {
4005
/**
4006
* The size of arrows (if displayed).
4007
* Defaults to 11.
4008
* **NOTE**: This option cannot be updated using `updateOptions()`
4009
*/
4010
arrowSize?: number;
4011
/**
4012
* Render vertical scrollbar.
4013
* Defaults to 'auto'.
4014
*/
4015
vertical?: 'auto' | 'visible' | 'hidden';
4016
/**
4017
* Render horizontal scrollbar.
4018
* Defaults to 'auto'.
4019
*/
4020
horizontal?: 'auto' | 'visible' | 'hidden';
4021
/**
4022
* Cast horizontal and vertical shadows when the content is scrolled.
4023
* Defaults to true.
4024
* **NOTE**: This option cannot be updated using `updateOptions()`
4025
*/
4026
useShadows?: boolean;
4027
/**
4028
* Render arrows at the top and bottom of the vertical scrollbar.
4029
* Defaults to false.
4030
* **NOTE**: This option cannot be updated using `updateOptions()`
4031
*/
4032
verticalHasArrows?: boolean;
4033
/**
4034
* Render arrows at the left and right of the horizontal scrollbar.
4035
* Defaults to false.
4036
* **NOTE**: This option cannot be updated using `updateOptions()`
4037
*/
4038
horizontalHasArrows?: boolean;
4039
/**
4040
* Listen to mouse wheel events and react to them by scrolling.
4041
* Defaults to true.
4042
*/
4043
handleMouseWheel?: boolean;
4044
/**
4045
* Always consume mouse wheel events (always call preventDefault() and stopPropagation() on the browser events).
4046
* Defaults to true.
4047
* **NOTE**: This option cannot be updated using `updateOptions()`
4048
*/
4049
alwaysConsumeMouseWheel?: boolean;
4050
/**
4051
* Height in pixels for the horizontal scrollbar.
4052
* Defaults to 12 (px).
4053
*/
4054
horizontalScrollbarSize?: number;
4055
/**
4056
* Width in pixels for the vertical scrollbar.
4057
* Defaults to 14 (px).
4058
*/
4059
verticalScrollbarSize?: number;
4060
/**
4061
* Width in pixels for the vertical slider.
4062
* Defaults to `verticalScrollbarSize`.
4063
* **NOTE**: This option cannot be updated using `updateOptions()`
4064
*/
4065
verticalSliderSize?: number;
4066
/**
4067
* Height in pixels for the horizontal slider.
4068
* Defaults to `horizontalScrollbarSize`.
4069
* **NOTE**: This option cannot be updated using `updateOptions()`
4070
*/
4071
horizontalSliderSize?: number;
4072
/**
4073
* Scroll gutter clicks move by page vs jump to position.
4074
* Defaults to false.
4075
*/
4076
scrollByPage?: boolean;
4077
4078
/**
4079
* When set, the horizontal scrollbar will not increase content height.
4080
* Defaults to false.
4081
*/
4082
ignoreHorizontalScrollbarInContentHeight?: boolean;
4083
}
4084
4085
export interface InternalEditorScrollbarOptions {
4086
readonly arrowSize: number;
4087
readonly vertical: ScrollbarVisibility;
4088
readonly horizontal: ScrollbarVisibility;
4089
readonly useShadows: boolean;
4090
readonly verticalHasArrows: boolean;
4091
readonly horizontalHasArrows: boolean;
4092
readonly handleMouseWheel: boolean;
4093
readonly alwaysConsumeMouseWheel: boolean;
4094
readonly horizontalScrollbarSize: number;
4095
readonly horizontalSliderSize: number;
4096
readonly verticalScrollbarSize: number;
4097
readonly verticalSliderSize: number;
4098
readonly scrollByPage: boolean;
4099
readonly ignoreHorizontalScrollbarInContentHeight: boolean;
4100
}
4101
4102
function _scrollbarVisibilityFromString(visibility: unknown, defaultValue: ScrollbarVisibility): ScrollbarVisibility {
4103
if (typeof visibility !== 'string') {
4104
return defaultValue;
4105
}
4106
switch (visibility) {
4107
case 'hidden': return ScrollbarVisibility.Hidden;
4108
case 'visible': return ScrollbarVisibility.Visible;
4109
default: return ScrollbarVisibility.Auto;
4110
}
4111
}
4112
4113
class EditorScrollbar extends BaseEditorOption<EditorOption.scrollbar, IEditorScrollbarOptions, InternalEditorScrollbarOptions> {
4114
4115
constructor() {
4116
const defaults: InternalEditorScrollbarOptions = {
4117
vertical: ScrollbarVisibility.Auto,
4118
horizontal: ScrollbarVisibility.Auto,
4119
arrowSize: 11,
4120
useShadows: true,
4121
verticalHasArrows: false,
4122
horizontalHasArrows: false,
4123
horizontalScrollbarSize: 12,
4124
horizontalSliderSize: 12,
4125
verticalScrollbarSize: 14,
4126
verticalSliderSize: 14,
4127
handleMouseWheel: true,
4128
alwaysConsumeMouseWheel: true,
4129
scrollByPage: false,
4130
ignoreHorizontalScrollbarInContentHeight: false,
4131
};
4132
super(
4133
EditorOption.scrollbar, 'scrollbar', defaults,
4134
{
4135
'editor.scrollbar.vertical': {
4136
type: 'string',
4137
enum: ['auto', 'visible', 'hidden'],
4138
enumDescriptions: [
4139
nls.localize('scrollbar.vertical.auto', "The vertical scrollbar will be visible only when necessary."),
4140
nls.localize('scrollbar.vertical.visible', "The vertical scrollbar will always be visible."),
4141
nls.localize('scrollbar.vertical.fit', "The vertical scrollbar will always be hidden."),
4142
],
4143
default: 'auto',
4144
description: nls.localize('scrollbar.vertical', "Controls the visibility of the vertical scrollbar.")
4145
},
4146
'editor.scrollbar.horizontal': {
4147
type: 'string',
4148
enum: ['auto', 'visible', 'hidden'],
4149
enumDescriptions: [
4150
nls.localize('scrollbar.horizontal.auto', "The horizontal scrollbar will be visible only when necessary."),
4151
nls.localize('scrollbar.horizontal.visible', "The horizontal scrollbar will always be visible."),
4152
nls.localize('scrollbar.horizontal.fit', "The horizontal scrollbar will always be hidden."),
4153
],
4154
default: 'auto',
4155
description: nls.localize('scrollbar.horizontal', "Controls the visibility of the horizontal scrollbar.")
4156
},
4157
'editor.scrollbar.verticalScrollbarSize': {
4158
type: 'number',
4159
default: defaults.verticalScrollbarSize,
4160
description: nls.localize('scrollbar.verticalScrollbarSize', "The width of the vertical scrollbar.")
4161
},
4162
'editor.scrollbar.horizontalScrollbarSize': {
4163
type: 'number',
4164
default: defaults.horizontalScrollbarSize,
4165
description: nls.localize('scrollbar.horizontalScrollbarSize', "The height of the horizontal scrollbar.")
4166
},
4167
'editor.scrollbar.scrollByPage': {
4168
type: 'boolean',
4169
default: defaults.scrollByPage,
4170
description: nls.localize('scrollbar.scrollByPage', "Controls whether clicks scroll by page or jump to click position.")
4171
},
4172
'editor.scrollbar.ignoreHorizontalScrollbarInContentHeight': {
4173
type: 'boolean',
4174
default: defaults.ignoreHorizontalScrollbarInContentHeight,
4175
description: nls.localize('scrollbar.ignoreHorizontalScrollbarInContentHeight', "When set, the horizontal scrollbar will not increase the size of the editor's content.")
4176
}
4177
}
4178
);
4179
}
4180
4181
public validate(_input: unknown): InternalEditorScrollbarOptions {
4182
if (!_input || typeof _input !== 'object') {
4183
return this.defaultValue;
4184
}
4185
const input = _input as Unknown<IEditorScrollbarOptions>;
4186
const horizontalScrollbarSize = EditorIntOption.clampedInt(input.horizontalScrollbarSize, this.defaultValue.horizontalScrollbarSize, 0, 1000);
4187
const verticalScrollbarSize = EditorIntOption.clampedInt(input.verticalScrollbarSize, this.defaultValue.verticalScrollbarSize, 0, 1000);
4188
return {
4189
arrowSize: EditorIntOption.clampedInt(input.arrowSize, this.defaultValue.arrowSize, 0, 1000),
4190
vertical: _scrollbarVisibilityFromString(input.vertical, this.defaultValue.vertical),
4191
horizontal: _scrollbarVisibilityFromString(input.horizontal, this.defaultValue.horizontal),
4192
useShadows: boolean(input.useShadows, this.defaultValue.useShadows),
4193
verticalHasArrows: boolean(input.verticalHasArrows, this.defaultValue.verticalHasArrows),
4194
horizontalHasArrows: boolean(input.horizontalHasArrows, this.defaultValue.horizontalHasArrows),
4195
handleMouseWheel: boolean(input.handleMouseWheel, this.defaultValue.handleMouseWheel),
4196
alwaysConsumeMouseWheel: boolean(input.alwaysConsumeMouseWheel, this.defaultValue.alwaysConsumeMouseWheel),
4197
horizontalScrollbarSize: horizontalScrollbarSize,
4198
horizontalSliderSize: EditorIntOption.clampedInt(input.horizontalSliderSize, horizontalScrollbarSize, 0, 1000),
4199
verticalScrollbarSize: verticalScrollbarSize,
4200
verticalSliderSize: EditorIntOption.clampedInt(input.verticalSliderSize, verticalScrollbarSize, 0, 1000),
4201
scrollByPage: boolean(input.scrollByPage, this.defaultValue.scrollByPage),
4202
ignoreHorizontalScrollbarInContentHeight: boolean(input.ignoreHorizontalScrollbarInContentHeight, this.defaultValue.ignoreHorizontalScrollbarInContentHeight),
4203
};
4204
}
4205
}
4206
4207
//#endregion
4208
4209
//#region UnicodeHighlight
4210
4211
export type InUntrustedWorkspace = 'inUntrustedWorkspace';
4212
4213
/**
4214
* @internal
4215
*/
4216
export const inUntrustedWorkspace: InUntrustedWorkspace = 'inUntrustedWorkspace';
4217
4218
/**
4219
* Configuration options for unicode highlighting.
4220
*/
4221
export interface IUnicodeHighlightOptions {
4222
4223
/**
4224
* Controls whether all non-basic ASCII characters are highlighted. Only characters between U+0020 and U+007E, tab, line-feed and carriage-return are considered basic ASCII.
4225
*/
4226
nonBasicASCII?: boolean | InUntrustedWorkspace;
4227
4228
/**
4229
* Controls whether characters that just reserve space or have no width at all are highlighted.
4230
*/
4231
invisibleCharacters?: boolean;
4232
4233
/**
4234
* Controls whether characters are highlighted that can be confused with basic ASCII characters, except those that are common in the current user locale.
4235
*/
4236
ambiguousCharacters?: boolean;
4237
4238
/**
4239
* Controls whether characters in comments should also be subject to unicode highlighting.
4240
*/
4241
includeComments?: boolean | InUntrustedWorkspace;
4242
4243
/**
4244
* Controls whether characters in strings should also be subject to unicode highlighting.
4245
*/
4246
includeStrings?: boolean | InUntrustedWorkspace;
4247
4248
/**
4249
* Defines allowed characters that are not being highlighted.
4250
*/
4251
allowedCharacters?: Record<string, true>;
4252
4253
/**
4254
* Unicode characters that are common in allowed locales are not being highlighted.
4255
*/
4256
allowedLocales?: Record<string | '_os' | '_vscode', true>;
4257
}
4258
4259
/**
4260
* @internal
4261
*/
4262
export type InternalUnicodeHighlightOptions = Required<Readonly<IUnicodeHighlightOptions>>;
4263
4264
/**
4265
* @internal
4266
*/
4267
export const unicodeHighlightConfigKeys = {
4268
allowedCharacters: 'editor.unicodeHighlight.allowedCharacters',
4269
invisibleCharacters: 'editor.unicodeHighlight.invisibleCharacters',
4270
nonBasicASCII: 'editor.unicodeHighlight.nonBasicASCII',
4271
ambiguousCharacters: 'editor.unicodeHighlight.ambiguousCharacters',
4272
includeComments: 'editor.unicodeHighlight.includeComments',
4273
includeStrings: 'editor.unicodeHighlight.includeStrings',
4274
allowedLocales: 'editor.unicodeHighlight.allowedLocales',
4275
};
4276
4277
class UnicodeHighlight extends BaseEditorOption<EditorOption.unicodeHighlighting, IUnicodeHighlightOptions, InternalUnicodeHighlightOptions> {
4278
constructor() {
4279
const defaults: InternalUnicodeHighlightOptions = {
4280
nonBasicASCII: inUntrustedWorkspace,
4281
invisibleCharacters: true,
4282
ambiguousCharacters: true,
4283
includeComments: inUntrustedWorkspace,
4284
includeStrings: true,
4285
allowedCharacters: {},
4286
allowedLocales: { _os: true, _vscode: true },
4287
};
4288
4289
super(
4290
EditorOption.unicodeHighlighting, 'unicodeHighlight', defaults,
4291
{
4292
[unicodeHighlightConfigKeys.nonBasicASCII]: {
4293
restricted: true,
4294
type: ['boolean', 'string'],
4295
enum: [true, false, inUntrustedWorkspace],
4296
default: defaults.nonBasicASCII,
4297
description: nls.localize('unicodeHighlight.nonBasicASCII', "Controls whether all non-basic ASCII characters are highlighted. Only characters between U+0020 and U+007E, tab, line-feed and carriage-return are considered basic ASCII.")
4298
},
4299
[unicodeHighlightConfigKeys.invisibleCharacters]: {
4300
restricted: true,
4301
type: 'boolean',
4302
default: defaults.invisibleCharacters,
4303
description: nls.localize('unicodeHighlight.invisibleCharacters', "Controls whether characters that just reserve space or have no width at all are highlighted.")
4304
},
4305
[unicodeHighlightConfigKeys.ambiguousCharacters]: {
4306
restricted: true,
4307
type: 'boolean',
4308
default: defaults.ambiguousCharacters,
4309
description: nls.localize('unicodeHighlight.ambiguousCharacters', "Controls whether characters are highlighted that can be confused with basic ASCII characters, except those that are common in the current user locale.")
4310
},
4311
[unicodeHighlightConfigKeys.includeComments]: {
4312
restricted: true,
4313
type: ['boolean', 'string'],
4314
enum: [true, false, inUntrustedWorkspace],
4315
default: defaults.includeComments,
4316
description: nls.localize('unicodeHighlight.includeComments', "Controls whether characters in comments should also be subject to Unicode highlighting.")
4317
},
4318
[unicodeHighlightConfigKeys.includeStrings]: {
4319
restricted: true,
4320
type: ['boolean', 'string'],
4321
enum: [true, false, inUntrustedWorkspace],
4322
default: defaults.includeStrings,
4323
description: nls.localize('unicodeHighlight.includeStrings', "Controls whether characters in strings should also be subject to Unicode highlighting.")
4324
},
4325
[unicodeHighlightConfigKeys.allowedCharacters]: {
4326
restricted: true,
4327
type: 'object',
4328
default: defaults.allowedCharacters,
4329
description: nls.localize('unicodeHighlight.allowedCharacters', "Defines allowed characters that are not being highlighted."),
4330
additionalProperties: {
4331
type: 'boolean'
4332
}
4333
},
4334
[unicodeHighlightConfigKeys.allowedLocales]: {
4335
restricted: true,
4336
type: 'object',
4337
additionalProperties: {
4338
type: 'boolean'
4339
},
4340
default: defaults.allowedLocales,
4341
description: nls.localize('unicodeHighlight.allowedLocales', "Unicode characters that are common in allowed locales are not being highlighted.")
4342
},
4343
}
4344
);
4345
}
4346
4347
public override applyUpdate(value: Required<Readonly<IUnicodeHighlightOptions>> | undefined, update: Required<Readonly<IUnicodeHighlightOptions>>): ApplyUpdateResult<Required<Readonly<IUnicodeHighlightOptions>>> {
4348
let didChange = false;
4349
if (update.allowedCharacters && value) {
4350
// Treat allowedCharacters atomically
4351
if (!objects.equals(value.allowedCharacters, update.allowedCharacters)) {
4352
value = { ...value, allowedCharacters: update.allowedCharacters };
4353
didChange = true;
4354
}
4355
}
4356
if (update.allowedLocales && value) {
4357
// Treat allowedLocales atomically
4358
if (!objects.equals(value.allowedLocales, update.allowedLocales)) {
4359
value = { ...value, allowedLocales: update.allowedLocales };
4360
didChange = true;
4361
}
4362
}
4363
4364
const result = super.applyUpdate(value, update);
4365
if (didChange) {
4366
return new ApplyUpdateResult(result.newValue, true);
4367
}
4368
return result;
4369
}
4370
4371
public validate(_input: unknown): InternalUnicodeHighlightOptions {
4372
if (!_input || typeof _input !== 'object') {
4373
return this.defaultValue;
4374
}
4375
const input = _input as Unknown<IUnicodeHighlightOptions>;
4376
return {
4377
nonBasicASCII: primitiveSet<boolean | InUntrustedWorkspace>(input.nonBasicASCII, inUntrustedWorkspace, [true, false, inUntrustedWorkspace]),
4378
invisibleCharacters: boolean(input.invisibleCharacters, this.defaultValue.invisibleCharacters),
4379
ambiguousCharacters: boolean(input.ambiguousCharacters, this.defaultValue.ambiguousCharacters),
4380
includeComments: primitiveSet<boolean | InUntrustedWorkspace>(input.includeComments, inUntrustedWorkspace, [true, false, inUntrustedWorkspace]),
4381
includeStrings: primitiveSet<boolean | InUntrustedWorkspace>(input.includeStrings, inUntrustedWorkspace, [true, false, inUntrustedWorkspace]),
4382
allowedCharacters: this.validateBooleanMap(input.allowedCharacters, this.defaultValue.allowedCharacters),
4383
allowedLocales: this.validateBooleanMap(input.allowedLocales, this.defaultValue.allowedLocales),
4384
};
4385
}
4386
4387
private validateBooleanMap(map: unknown, defaultValue: Record<string, true>): Record<string, true> {
4388
if ((typeof map !== 'object') || !map) {
4389
return defaultValue;
4390
}
4391
const result: Record<string, true> = {};
4392
for (const [key, value] of Object.entries(map)) {
4393
if (value === true) {
4394
result[key] = true;
4395
}
4396
}
4397
return result;
4398
}
4399
}
4400
4401
//#endregion
4402
4403
//#region inlineSuggest
4404
4405
export interface IInlineSuggestOptions {
4406
/**
4407
* Enable or disable the rendering of automatic inline completions.
4408
*/
4409
enabled?: boolean;
4410
4411
/**
4412
* Configures the mode.
4413
* Use `prefix` to only show ghost text if the text to replace is a prefix of the suggestion text.
4414
* Use `subword` to only show ghost text if the replace text is a subword of the suggestion text.
4415
* Use `subwordSmart` to only show ghost text if the replace text is a subword of the suggestion text, but the subword must start after the cursor position.
4416
* Defaults to `prefix`.
4417
*/
4418
mode?: 'prefix' | 'subword' | 'subwordSmart';
4419
4420
showToolbar?: 'always' | 'onHover' | 'never';
4421
4422
syntaxHighlightingEnabled?: boolean;
4423
4424
suppressSuggestions?: boolean;
4425
4426
minShowDelay?: number;
4427
suppressInSnippetMode?: boolean;
4428
/**
4429
* Does not clear active inline suggestions when the editor loses focus.
4430
*/
4431
keepOnBlur?: boolean;
4432
4433
/**
4434
* Font family for inline suggestions.
4435
*/
4436
fontFamily?: string | 'default';
4437
4438
edits?: {
4439
allowCodeShifting?: 'always' | 'horizontal' | 'never';
4440
4441
renderSideBySide?: 'never' | 'auto';
4442
4443
showCollapsed?: boolean;
4444
4445
showLongDistanceHint?: boolean;
4446
4447
/**
4448
* @internal
4449
*/
4450
enabled?: boolean;
4451
};
4452
4453
/**
4454
* @internal
4455
*/
4456
triggerCommandOnProviderChange?: boolean;
4457
4458
/**
4459
* @internal
4460
*/
4461
experimental?: {
4462
/**
4463
* @internal
4464
*/
4465
suppressInlineSuggestions?: string;
4466
4467
/**
4468
* @internal
4469
*/
4470
emptyResponseInformation?: boolean;
4471
4472
showOnSuggestConflict?: 'always' | 'never' | 'whenSuggestListIsIncomplete';
4473
};
4474
}
4475
4476
type RequiredRecursive<T> = {
4477
[P in keyof T]-?: T[P] extends object | undefined ? RequiredRecursive<T[P]> : T[P];
4478
};
4479
4480
/**
4481
* @internal
4482
*/
4483
export type InternalInlineSuggestOptions = Readonly<RequiredRecursive<IInlineSuggestOptions>>;
4484
4485
/**
4486
* Configuration options for inline suggestions
4487
*/
4488
class InlineEditorSuggest extends BaseEditorOption<EditorOption.inlineSuggest, IInlineSuggestOptions, InternalInlineSuggestOptions> {
4489
constructor() {
4490
const defaults: InternalInlineSuggestOptions = {
4491
enabled: true,
4492
mode: 'subwordSmart',
4493
showToolbar: 'onHover',
4494
suppressSuggestions: false,
4495
keepOnBlur: false,
4496
fontFamily: 'default',
4497
syntaxHighlightingEnabled: true,
4498
minShowDelay: 0,
4499
suppressInSnippetMode: true,
4500
edits: {
4501
enabled: true,
4502
showCollapsed: false,
4503
renderSideBySide: 'auto',
4504
allowCodeShifting: 'always',
4505
showLongDistanceHint: true,
4506
},
4507
triggerCommandOnProviderChange: false,
4508
experimental: {
4509
suppressInlineSuggestions: '',
4510
showOnSuggestConflict: 'never',
4511
emptyResponseInformation: true,
4512
},
4513
};
4514
4515
super(
4516
EditorOption.inlineSuggest, 'inlineSuggest', defaults,
4517
{
4518
'editor.inlineSuggest.enabled': {
4519
type: 'boolean',
4520
default: defaults.enabled,
4521
description: nls.localize('inlineSuggest.enabled', "Controls whether to automatically show inline suggestions in the editor.")
4522
},
4523
'editor.inlineSuggest.showToolbar': {
4524
type: 'string',
4525
default: defaults.showToolbar,
4526
enum: ['always', 'onHover', 'never'],
4527
enumDescriptions: [
4528
nls.localize('inlineSuggest.showToolbar.always', "Show the inline suggestion toolbar whenever an inline suggestion is shown."),
4529
nls.localize('inlineSuggest.showToolbar.onHover', "Show the inline suggestion toolbar when hovering over an inline suggestion."),
4530
nls.localize('inlineSuggest.showToolbar.never', "Never show the inline suggestion toolbar."),
4531
],
4532
description: nls.localize('inlineSuggest.showToolbar', "Controls when to show the inline suggestion toolbar."),
4533
},
4534
'editor.inlineSuggest.syntaxHighlightingEnabled': {
4535
type: 'boolean',
4536
default: defaults.syntaxHighlightingEnabled,
4537
description: nls.localize('inlineSuggest.syntaxHighlightingEnabled', "Controls whether to show syntax highlighting for inline suggestions in the editor."),
4538
},
4539
'editor.inlineSuggest.suppressSuggestions': {
4540
type: 'boolean',
4541
default: defaults.suppressSuggestions,
4542
description: nls.localize('inlineSuggest.suppressSuggestions', "Controls how inline suggestions interact with the suggest widget. If enabled, the suggest widget is not shown automatically when inline suggestions are available.")
4543
},
4544
'editor.inlineSuggest.suppressInSnippetMode': {
4545
type: 'boolean',
4546
default: defaults.suppressInSnippetMode,
4547
description: nls.localize('inlineSuggest.suppressInSnippetMode', "Controls whether inline suggestions are suppressed when in snippet mode."),
4548
},
4549
'editor.inlineSuggest.minShowDelay': {
4550
type: 'number',
4551
default: 0,
4552
minimum: 0,
4553
maximum: 10000,
4554
description: nls.localize('inlineSuggest.minShowDelay', "Controls the minimal delay in milliseconds after which inline suggestions are shown after typing."),
4555
},
4556
'editor.inlineSuggest.experimental.suppressInlineSuggestions': {
4557
type: 'string',
4558
default: defaults.experimental.suppressInlineSuggestions,
4559
tags: ['experimental'],
4560
description: nls.localize('inlineSuggest.suppressInlineSuggestions', "Suppresses inline completions for specified extension IDs -- comma separated."),
4561
experiment: {
4562
mode: 'auto'
4563
}
4564
},
4565
'editor.inlineSuggest.experimental.emptyResponseInformation': {
4566
type: 'boolean',
4567
default: defaults.experimental.emptyResponseInformation,
4568
tags: ['experimental'],
4569
description: nls.localize('inlineSuggest.emptyResponseInformation', "Controls whether to send request information from the inline suggestion provider."),
4570
experiment: {
4571
mode: 'auto'
4572
}
4573
},
4574
'editor.inlineSuggest.triggerCommandOnProviderChange': {
4575
type: 'boolean',
4576
default: defaults.triggerCommandOnProviderChange,
4577
tags: ['experimental'],
4578
description: nls.localize('inlineSuggest.triggerCommandOnProviderChange', "Controls whether to trigger a command when the inline suggestion provider changes."),
4579
experiment: {
4580
mode: 'auto'
4581
}
4582
},
4583
'editor.inlineSuggest.experimental.showOnSuggestConflict': {
4584
type: 'string',
4585
default: defaults.experimental.showOnSuggestConflict,
4586
tags: ['experimental'],
4587
enum: ['always', 'never', 'whenSuggestListIsIncomplete'],
4588
description: nls.localize('inlineSuggest.showOnSuggestConflict', "Controls whether to show inline suggestions when there is a suggest conflict."),
4589
experiment: {
4590
mode: 'auto'
4591
}
4592
},
4593
'editor.inlineSuggest.fontFamily': {
4594
type: 'string',
4595
default: defaults.fontFamily,
4596
description: nls.localize('inlineSuggest.fontFamily', "Controls the font family of the inline suggestions.")
4597
},
4598
'editor.inlineSuggest.edits.allowCodeShifting': {
4599
type: 'string',
4600
default: defaults.edits.allowCodeShifting,
4601
description: nls.localize('inlineSuggest.edits.allowCodeShifting', "Controls whether showing a suggestion will shift the code to make space for the suggestion inline."),
4602
enum: ['always', 'horizontal', 'never'],
4603
tags: ['nextEditSuggestions']
4604
},
4605
'editor.inlineSuggest.edits.showLongDistanceHint': {
4606
type: 'boolean',
4607
default: defaults.edits.showLongDistanceHint,
4608
description: nls.localize('inlineSuggest.edits.showLongDistanceHint', "Controls whether long distance inline suggestions are shown."),
4609
tags: ['nextEditSuggestions', 'experimental']
4610
},
4611
'editor.inlineSuggest.edits.renderSideBySide': {
4612
type: 'string',
4613
default: defaults.edits.renderSideBySide,
4614
description: nls.localize('inlineSuggest.edits.renderSideBySide', "Controls whether larger suggestions can be shown side by side."),
4615
enum: ['auto', 'never'],
4616
enumDescriptions: [
4617
nls.localize('editor.inlineSuggest.edits.renderSideBySide.auto', "Larger suggestions will show side by side if there is enough space, otherwise they will be shown below."),
4618
nls.localize('editor.inlineSuggest.edits.renderSideBySide.never', "Larger suggestions are never shown side by side and will always be shown below."),
4619
],
4620
tags: ['nextEditSuggestions']
4621
},
4622
'editor.inlineSuggest.edits.showCollapsed': {
4623
type: 'boolean',
4624
default: defaults.edits.showCollapsed,
4625
description: nls.localize('inlineSuggest.edits.showCollapsed', "Controls whether the suggestion will show as collapsed until jumping to it."),
4626
tags: ['nextEditSuggestions']
4627
},
4628
}
4629
);
4630
}
4631
4632
public validate(_input: unknown): InternalInlineSuggestOptions {
4633
if (!_input || typeof _input !== 'object') {
4634
return this.defaultValue;
4635
}
4636
const input = _input as Unknown<IInlineSuggestOptions>;
4637
return {
4638
enabled: boolean(input.enabled, this.defaultValue.enabled),
4639
mode: stringSet(input.mode, this.defaultValue.mode, ['prefix', 'subword', 'subwordSmart']),
4640
showToolbar: stringSet(input.showToolbar, this.defaultValue.showToolbar, ['always', 'onHover', 'never']),
4641
suppressSuggestions: boolean(input.suppressSuggestions, this.defaultValue.suppressSuggestions),
4642
keepOnBlur: boolean(input.keepOnBlur, this.defaultValue.keepOnBlur),
4643
fontFamily: EditorStringOption.string(input.fontFamily, this.defaultValue.fontFamily),
4644
syntaxHighlightingEnabled: boolean(input.syntaxHighlightingEnabled, this.defaultValue.syntaxHighlightingEnabled),
4645
minShowDelay: EditorIntOption.clampedInt(input.minShowDelay, 0, 0, 10000),
4646
suppressInSnippetMode: boolean(input.suppressInSnippetMode, this.defaultValue.suppressInSnippetMode),
4647
edits: this._validateEdits(input.edits),
4648
triggerCommandOnProviderChange: boolean(input.triggerCommandOnProviderChange, this.defaultValue.triggerCommandOnProviderChange),
4649
experimental: this._validateExperimental(input.experimental),
4650
};
4651
}
4652
4653
private _validateEdits(_input: unknown): InternalInlineSuggestOptions['edits'] {
4654
if (!_input || typeof _input !== 'object') {
4655
return this.defaultValue.edits;
4656
}
4657
const input = _input as Unknown<InternalInlineSuggestOptions['edits']>;
4658
return {
4659
enabled: boolean(input.enabled, this.defaultValue.edits.enabled),
4660
showCollapsed: boolean(input.showCollapsed, this.defaultValue.edits.showCollapsed),
4661
allowCodeShifting: stringSet(input.allowCodeShifting, this.defaultValue.edits.allowCodeShifting, ['always', 'horizontal', 'never']),
4662
showLongDistanceHint: boolean(input.showLongDistanceHint, this.defaultValue.edits.showLongDistanceHint),
4663
renderSideBySide: stringSet(input.renderSideBySide, this.defaultValue.edits.renderSideBySide, ['never', 'auto']),
4664
};
4665
}
4666
4667
private _validateExperimental(_input: unknown): InternalInlineSuggestOptions['experimental'] {
4668
if (!_input || typeof _input !== 'object') {
4669
return this.defaultValue.experimental;
4670
}
4671
const input = _input as Unknown<InternalInlineSuggestOptions['experimental']>;
4672
return {
4673
suppressInlineSuggestions: EditorStringOption.string(input.suppressInlineSuggestions, this.defaultValue.experimental.suppressInlineSuggestions),
4674
showOnSuggestConflict: stringSet(input.showOnSuggestConflict, this.defaultValue.experimental.showOnSuggestConflict, ['always', 'never', 'whenSuggestListIsIncomplete']),
4675
emptyResponseInformation: boolean(input.emptyResponseInformation, this.defaultValue.experimental.emptyResponseInformation),
4676
};
4677
}
4678
}
4679
4680
//#endregion
4681
4682
//#region bracketPairColorization
4683
4684
export interface IBracketPairColorizationOptions {
4685
/**
4686
* Enable or disable bracket pair colorization.
4687
*/
4688
enabled?: boolean;
4689
4690
/**
4691
* Use independent color pool per bracket type.
4692
*/
4693
independentColorPoolPerBracketType?: boolean;
4694
}
4695
4696
/**
4697
* @internal
4698
*/
4699
export type InternalBracketPairColorizationOptions = Readonly<Required<IBracketPairColorizationOptions>>;
4700
4701
/**
4702
* Configuration options for inline suggestions
4703
*/
4704
class BracketPairColorization extends BaseEditorOption<EditorOption.bracketPairColorization, IBracketPairColorizationOptions, InternalBracketPairColorizationOptions> {
4705
constructor() {
4706
const defaults: InternalBracketPairColorizationOptions = {
4707
enabled: EDITOR_MODEL_DEFAULTS.bracketPairColorizationOptions.enabled,
4708
independentColorPoolPerBracketType: EDITOR_MODEL_DEFAULTS.bracketPairColorizationOptions.independentColorPoolPerBracketType,
4709
};
4710
4711
super(
4712
EditorOption.bracketPairColorization, 'bracketPairColorization', defaults,
4713
{
4714
'editor.bracketPairColorization.enabled': {
4715
type: 'boolean',
4716
default: defaults.enabled,
4717
markdownDescription: nls.localize('bracketPairColorization.enabled', "Controls whether bracket pair colorization is enabled or not. Use {0} to override the bracket highlight colors.", '`#workbench.colorCustomizations#`')
4718
},
4719
'editor.bracketPairColorization.independentColorPoolPerBracketType': {
4720
type: 'boolean',
4721
default: defaults.independentColorPoolPerBracketType,
4722
description: nls.localize('bracketPairColorization.independentColorPoolPerBracketType', "Controls whether each bracket type has its own independent color pool.")
4723
},
4724
}
4725
);
4726
}
4727
4728
public validate(_input: unknown): InternalBracketPairColorizationOptions {
4729
if (!_input || typeof _input !== 'object') {
4730
return this.defaultValue;
4731
}
4732
const input = _input as Unknown<IBracketPairColorizationOptions>;
4733
return {
4734
enabled: boolean(input.enabled, this.defaultValue.enabled),
4735
independentColorPoolPerBracketType: boolean(input.independentColorPoolPerBracketType, this.defaultValue.independentColorPoolPerBracketType),
4736
};
4737
}
4738
}
4739
4740
//#endregion
4741
4742
//#region guides
4743
4744
export interface IGuidesOptions {
4745
/**
4746
* Enable rendering of bracket pair guides.
4747
* Defaults to false.
4748
*/
4749
bracketPairs?: boolean | 'active';
4750
4751
/**
4752
* Enable rendering of vertical bracket pair guides.
4753
* Defaults to 'active'.
4754
*/
4755
bracketPairsHorizontal?: boolean | 'active';
4756
4757
/**
4758
* Enable highlighting of the active bracket pair.
4759
* Defaults to true.
4760
*/
4761
highlightActiveBracketPair?: boolean;
4762
4763
/**
4764
* Enable rendering of indent guides.
4765
* Defaults to true.
4766
*/
4767
indentation?: boolean;
4768
4769
/**
4770
* Enable highlighting of the active indent guide.
4771
* Defaults to true.
4772
*/
4773
highlightActiveIndentation?: boolean | 'always';
4774
}
4775
4776
/**
4777
* @internal
4778
*/
4779
export type InternalGuidesOptions = Readonly<Required<IGuidesOptions>>;
4780
4781
/**
4782
* Configuration options for inline suggestions
4783
*/
4784
class GuideOptions extends BaseEditorOption<EditorOption.guides, IGuidesOptions, InternalGuidesOptions> {
4785
constructor() {
4786
const defaults: InternalGuidesOptions = {
4787
bracketPairs: false,
4788
bracketPairsHorizontal: 'active',
4789
highlightActiveBracketPair: true,
4790
4791
indentation: true,
4792
highlightActiveIndentation: true
4793
};
4794
4795
super(
4796
EditorOption.guides, 'guides', defaults,
4797
{
4798
'editor.guides.bracketPairs': {
4799
type: ['boolean', 'string'],
4800
enum: [true, 'active', false],
4801
enumDescriptions: [
4802
nls.localize('editor.guides.bracketPairs.true', "Enables bracket pair guides."),
4803
nls.localize('editor.guides.bracketPairs.active', "Enables bracket pair guides only for the active bracket pair."),
4804
nls.localize('editor.guides.bracketPairs.false', "Disables bracket pair guides."),
4805
],
4806
default: defaults.bracketPairs,
4807
description: nls.localize('editor.guides.bracketPairs', "Controls whether bracket pair guides are enabled or not.")
4808
},
4809
'editor.guides.bracketPairsHorizontal': {
4810
type: ['boolean', 'string'],
4811
enum: [true, 'active', false],
4812
enumDescriptions: [
4813
nls.localize('editor.guides.bracketPairsHorizontal.true', "Enables horizontal guides as addition to vertical bracket pair guides."),
4814
nls.localize('editor.guides.bracketPairsHorizontal.active', "Enables horizontal guides only for the active bracket pair."),
4815
nls.localize('editor.guides.bracketPairsHorizontal.false', "Disables horizontal bracket pair guides."),
4816
],
4817
default: defaults.bracketPairsHorizontal,
4818
description: nls.localize('editor.guides.bracketPairsHorizontal', "Controls whether horizontal bracket pair guides are enabled or not.")
4819
},
4820
'editor.guides.highlightActiveBracketPair': {
4821
type: 'boolean',
4822
default: defaults.highlightActiveBracketPair,
4823
description: nls.localize('editor.guides.highlightActiveBracketPair', "Controls whether the editor should highlight the active bracket pair.")
4824
},
4825
'editor.guides.indentation': {
4826
type: 'boolean',
4827
default: defaults.indentation,
4828
description: nls.localize('editor.guides.indentation', "Controls whether the editor should render indent guides.")
4829
},
4830
'editor.guides.highlightActiveIndentation': {
4831
type: ['boolean', 'string'],
4832
enum: [true, 'always', false],
4833
enumDescriptions: [
4834
nls.localize('editor.guides.highlightActiveIndentation.true', "Highlights the active indent guide."),
4835
nls.localize('editor.guides.highlightActiveIndentation.always', "Highlights the active indent guide even if bracket guides are highlighted."),
4836
nls.localize('editor.guides.highlightActiveIndentation.false', "Do not highlight the active indent guide."),
4837
],
4838
default: defaults.highlightActiveIndentation,
4839
4840
description: nls.localize('editor.guides.highlightActiveIndentation', "Controls whether the editor should highlight the active indent guide.")
4841
}
4842
}
4843
);
4844
}
4845
4846
public validate(_input: unknown): InternalGuidesOptions {
4847
if (!_input || typeof _input !== 'object') {
4848
return this.defaultValue;
4849
}
4850
const input = _input as Unknown<IGuidesOptions>;
4851
return {
4852
bracketPairs: primitiveSet(input.bracketPairs, this.defaultValue.bracketPairs, [true, false, 'active']),
4853
bracketPairsHorizontal: primitiveSet(input.bracketPairsHorizontal, this.defaultValue.bracketPairsHorizontal, [true, false, 'active']),
4854
highlightActiveBracketPair: boolean(input.highlightActiveBracketPair, this.defaultValue.highlightActiveBracketPair),
4855
4856
indentation: boolean(input.indentation, this.defaultValue.indentation),
4857
highlightActiveIndentation: primitiveSet(input.highlightActiveIndentation, this.defaultValue.highlightActiveIndentation, [true, false, 'always']),
4858
};
4859
}
4860
}
4861
4862
function primitiveSet<T extends string | boolean>(value: unknown, defaultValue: T, allowedValues: T[]): T {
4863
const idx = allowedValues.indexOf(value as T);
4864
if (idx === -1) {
4865
return defaultValue;
4866
}
4867
return allowedValues[idx];
4868
}
4869
4870
//#endregion
4871
4872
//#region suggest
4873
4874
/**
4875
* Configuration options for editor suggest widget
4876
*/
4877
export interface ISuggestOptions {
4878
/**
4879
* Overwrite word ends on accept. Default to false.
4880
*/
4881
insertMode?: 'insert' | 'replace';
4882
/**
4883
* Enable graceful matching. Defaults to true.
4884
*/
4885
filterGraceful?: boolean;
4886
/**
4887
* Prevent quick suggestions when a snippet is active. Defaults to true.
4888
*/
4889
snippetsPreventQuickSuggestions?: boolean;
4890
/**
4891
* Favors words that appear close to the cursor.
4892
*/
4893
localityBonus?: boolean;
4894
/**
4895
* Enable using global storage for remembering suggestions.
4896
*/
4897
shareSuggestSelections?: boolean;
4898
/**
4899
* Select suggestions when triggered via quick suggest or trigger characters
4900
*/
4901
selectionMode?: 'always' | 'never' | 'whenTriggerCharacter' | 'whenQuickSuggestion';
4902
/**
4903
* Enable or disable icons in suggestions. Defaults to true.
4904
*/
4905
showIcons?: boolean;
4906
/**
4907
* Enable or disable the suggest status bar.
4908
*/
4909
showStatusBar?: boolean;
4910
/**
4911
* Enable or disable the rendering of the suggestion preview.
4912
*/
4913
preview?: boolean;
4914
/**
4915
* Configures the mode of the preview.
4916
*/
4917
previewMode?: 'prefix' | 'subword' | 'subwordSmart';
4918
/**
4919
* Show details inline with the label. Defaults to true.
4920
*/
4921
showInlineDetails?: boolean;
4922
/**
4923
* Show method-suggestions.
4924
*/
4925
showMethods?: boolean;
4926
/**
4927
* Show function-suggestions.
4928
*/
4929
showFunctions?: boolean;
4930
/**
4931
* Show constructor-suggestions.
4932
*/
4933
showConstructors?: boolean;
4934
/**
4935
* Show deprecated-suggestions.
4936
*/
4937
showDeprecated?: boolean;
4938
/**
4939
* Controls whether suggestions allow matches in the middle of the word instead of only at the beginning
4940
*/
4941
matchOnWordStartOnly?: boolean;
4942
/**
4943
* Show field-suggestions.
4944
*/
4945
showFields?: boolean;
4946
/**
4947
* Show variable-suggestions.
4948
*/
4949
showVariables?: boolean;
4950
/**
4951
* Show class-suggestions.
4952
*/
4953
showClasses?: boolean;
4954
/**
4955
* Show struct-suggestions.
4956
*/
4957
showStructs?: boolean;
4958
/**
4959
* Show interface-suggestions.
4960
*/
4961
showInterfaces?: boolean;
4962
/**
4963
* Show module-suggestions.
4964
*/
4965
showModules?: boolean;
4966
/**
4967
* Show property-suggestions.
4968
*/
4969
showProperties?: boolean;
4970
/**
4971
* Show event-suggestions.
4972
*/
4973
showEvents?: boolean;
4974
/**
4975
* Show operator-suggestions.
4976
*/
4977
showOperators?: boolean;
4978
/**
4979
* Show unit-suggestions.
4980
*/
4981
showUnits?: boolean;
4982
/**
4983
* Show value-suggestions.
4984
*/
4985
showValues?: boolean;
4986
/**
4987
* Show constant-suggestions.
4988
*/
4989
showConstants?: boolean;
4990
/**
4991
* Show enum-suggestions.
4992
*/
4993
showEnums?: boolean;
4994
/**
4995
* Show enumMember-suggestions.
4996
*/
4997
showEnumMembers?: boolean;
4998
/**
4999
* Show keyword-suggestions.
5000
*/
5001
showKeywords?: boolean;
5002
/**
5003
* Show text-suggestions.
5004
*/
5005
showWords?: boolean;
5006
/**
5007
* Show color-suggestions.
5008
*/
5009
showColors?: boolean;
5010
/**
5011
* Show file-suggestions.
5012
*/
5013
showFiles?: boolean;
5014
/**
5015
* Show reference-suggestions.
5016
*/
5017
showReferences?: boolean;
5018
/**
5019
* Show folder-suggestions.
5020
*/
5021
showFolders?: boolean;
5022
/**
5023
* Show typeParameter-suggestions.
5024
*/
5025
showTypeParameters?: boolean;
5026
/**
5027
* Show issue-suggestions.
5028
*/
5029
showIssues?: boolean;
5030
/**
5031
* Show user-suggestions.
5032
*/
5033
showUsers?: boolean;
5034
/**
5035
* Show snippet-suggestions.
5036
*/
5037
showSnippets?: boolean;
5038
}
5039
5040
/**
5041
* @internal
5042
*/
5043
export type InternalSuggestOptions = Readonly<Required<ISuggestOptions>>;
5044
5045
class EditorSuggest extends BaseEditorOption<EditorOption.suggest, ISuggestOptions, InternalSuggestOptions> {
5046
5047
constructor() {
5048
const defaults: InternalSuggestOptions = {
5049
insertMode: 'insert',
5050
filterGraceful: true,
5051
snippetsPreventQuickSuggestions: false,
5052
localityBonus: false,
5053
shareSuggestSelections: false,
5054
selectionMode: 'always',
5055
showIcons: true,
5056
showStatusBar: false,
5057
preview: false,
5058
previewMode: 'subwordSmart',
5059
showInlineDetails: true,
5060
showMethods: true,
5061
showFunctions: true,
5062
showConstructors: true,
5063
showDeprecated: true,
5064
matchOnWordStartOnly: true,
5065
showFields: true,
5066
showVariables: true,
5067
showClasses: true,
5068
showStructs: true,
5069
showInterfaces: true,
5070
showModules: true,
5071
showProperties: true,
5072
showEvents: true,
5073
showOperators: true,
5074
showUnits: true,
5075
showValues: true,
5076
showConstants: true,
5077
showEnums: true,
5078
showEnumMembers: true,
5079
showKeywords: true,
5080
showWords: true,
5081
showColors: true,
5082
showFiles: true,
5083
showReferences: true,
5084
showFolders: true,
5085
showTypeParameters: true,
5086
showSnippets: true,
5087
showUsers: true,
5088
showIssues: true,
5089
};
5090
super(
5091
EditorOption.suggest, 'suggest', defaults,
5092
{
5093
'editor.suggest.insertMode': {
5094
type: 'string',
5095
enum: ['insert', 'replace'],
5096
enumDescriptions: [
5097
nls.localize('suggest.insertMode.insert', "Insert suggestion without overwriting text right of the cursor."),
5098
nls.localize('suggest.insertMode.replace', "Insert suggestion and overwrite text right of the cursor."),
5099
],
5100
default: defaults.insertMode,
5101
description: nls.localize('suggest.insertMode', "Controls whether words are overwritten when accepting completions. Note that this depends on extensions opting into this feature.")
5102
},
5103
'editor.suggest.filterGraceful': {
5104
type: 'boolean',
5105
default: defaults.filterGraceful,
5106
description: nls.localize('suggest.filterGraceful', "Controls whether filtering and sorting suggestions accounts for small typos.")
5107
},
5108
'editor.suggest.localityBonus': {
5109
type: 'boolean',
5110
default: defaults.localityBonus,
5111
description: nls.localize('suggest.localityBonus', "Controls whether sorting favors words that appear close to the cursor.")
5112
},
5113
'editor.suggest.shareSuggestSelections': {
5114
type: 'boolean',
5115
default: defaults.shareSuggestSelections,
5116
markdownDescription: nls.localize('suggest.shareSuggestSelections', "Controls whether remembered suggestion selections are shared between multiple workspaces and windows (needs `#editor.suggestSelection#`).")
5117
},
5118
'editor.suggest.selectionMode': {
5119
type: 'string',
5120
enum: ['always', 'never', 'whenTriggerCharacter', 'whenQuickSuggestion'],
5121
enumDescriptions: [
5122
nls.localize('suggest.insertMode.always', "Always select a suggestion when automatically triggering IntelliSense."),
5123
nls.localize('suggest.insertMode.never', "Never select a suggestion when automatically triggering IntelliSense."),
5124
nls.localize('suggest.insertMode.whenTriggerCharacter', "Select a suggestion only when triggering IntelliSense from a trigger character."),
5125
nls.localize('suggest.insertMode.whenQuickSuggestion', "Select a suggestion only when triggering IntelliSense as you type."),
5126
],
5127
default: defaults.selectionMode,
5128
markdownDescription: nls.localize('suggest.selectionMode', "Controls whether a suggestion is selected when the widget shows. Note that this only applies to automatically triggered suggestions ({0} and {1}) and that a suggestion is always selected when explicitly invoked, e.g via `Ctrl+Space`.", '`#editor.quickSuggestions#`', '`#editor.suggestOnTriggerCharacters#`')
5129
},
5130
'editor.suggest.snippetsPreventQuickSuggestions': {
5131
type: 'boolean',
5132
default: defaults.snippetsPreventQuickSuggestions,
5133
description: nls.localize('suggest.snippetsPreventQuickSuggestions', "Controls whether an active snippet prevents quick suggestions.")
5134
},
5135
'editor.suggest.showIcons': {
5136
type: 'boolean',
5137
default: defaults.showIcons,
5138
description: nls.localize('suggest.showIcons', "Controls whether to show or hide icons in suggestions.")
5139
},
5140
'editor.suggest.showStatusBar': {
5141
type: 'boolean',
5142
default: defaults.showStatusBar,
5143
description: nls.localize('suggest.showStatusBar', "Controls the visibility of the status bar at the bottom of the suggest widget.")
5144
},
5145
'editor.suggest.preview': {
5146
type: 'boolean',
5147
default: defaults.preview,
5148
description: nls.localize('suggest.preview', "Controls whether to preview the suggestion outcome in the editor.")
5149
},
5150
'editor.suggest.showInlineDetails': {
5151
type: 'boolean',
5152
default: defaults.showInlineDetails,
5153
description: nls.localize('suggest.showInlineDetails', "Controls whether suggest details show inline with the label or only in the details widget.")
5154
},
5155
'editor.suggest.maxVisibleSuggestions': {
5156
type: 'number',
5157
deprecationMessage: nls.localize('suggest.maxVisibleSuggestions.dep', "This setting is deprecated. The suggest widget can now be resized."),
5158
},
5159
'editor.suggest.filteredTypes': {
5160
type: 'object',
5161
deprecationMessage: nls.localize('deprecated', "This setting is deprecated, please use separate settings like 'editor.suggest.showKeywords' or 'editor.suggest.showSnippets' instead.")
5162
},
5163
'editor.suggest.showMethods': {
5164
type: 'boolean',
5165
default: true,
5166
markdownDescription: nls.localize('editor.suggest.showMethods', "When enabled IntelliSense shows `method`-suggestions.")
5167
},
5168
'editor.suggest.showFunctions': {
5169
type: 'boolean',
5170
default: true,
5171
markdownDescription: nls.localize('editor.suggest.showFunctions', "When enabled IntelliSense shows `function`-suggestions.")
5172
},
5173
'editor.suggest.showConstructors': {
5174
type: 'boolean',
5175
default: true,
5176
markdownDescription: nls.localize('editor.suggest.showConstructors', "When enabled IntelliSense shows `constructor`-suggestions.")
5177
},
5178
'editor.suggest.showDeprecated': {
5179
type: 'boolean',
5180
default: true,
5181
markdownDescription: nls.localize('editor.suggest.showDeprecated', "When enabled IntelliSense shows `deprecated`-suggestions.")
5182
},
5183
'editor.suggest.matchOnWordStartOnly': {
5184
type: 'boolean',
5185
default: true,
5186
markdownDescription: nls.localize('editor.suggest.matchOnWordStartOnly', "When enabled IntelliSense filtering requires that the first character matches on a word start. For example, `c` on `Console` or `WebContext` but _not_ on `description`. When disabled IntelliSense will show more results but still sorts them by match quality.")
5187
},
5188
'editor.suggest.showFields': {
5189
type: 'boolean',
5190
default: true,
5191
markdownDescription: nls.localize('editor.suggest.showFields', "When enabled IntelliSense shows `field`-suggestions.")
5192
},
5193
'editor.suggest.showVariables': {
5194
type: 'boolean',
5195
default: true,
5196
markdownDescription: nls.localize('editor.suggest.showVariables', "When enabled IntelliSense shows `variable`-suggestions.")
5197
},
5198
'editor.suggest.showClasses': {
5199
type: 'boolean',
5200
default: true,
5201
markdownDescription: nls.localize('editor.suggest.showClasss', "When enabled IntelliSense shows `class`-suggestions.")
5202
},
5203
'editor.suggest.showStructs': {
5204
type: 'boolean',
5205
default: true,
5206
markdownDescription: nls.localize('editor.suggest.showStructs', "When enabled IntelliSense shows `struct`-suggestions.")
5207
},
5208
'editor.suggest.showInterfaces': {
5209
type: 'boolean',
5210
default: true,
5211
markdownDescription: nls.localize('editor.suggest.showInterfaces', "When enabled IntelliSense shows `interface`-suggestions.")
5212
},
5213
'editor.suggest.showModules': {
5214
type: 'boolean',
5215
default: true,
5216
markdownDescription: nls.localize('editor.suggest.showModules', "When enabled IntelliSense shows `module`-suggestions.")
5217
},
5218
'editor.suggest.showProperties': {
5219
type: 'boolean',
5220
default: true,
5221
markdownDescription: nls.localize('editor.suggest.showPropertys', "When enabled IntelliSense shows `property`-suggestions.")
5222
},
5223
'editor.suggest.showEvents': {
5224
type: 'boolean',
5225
default: true,
5226
markdownDescription: nls.localize('editor.suggest.showEvents', "When enabled IntelliSense shows `event`-suggestions.")
5227
},
5228
'editor.suggest.showOperators': {
5229
type: 'boolean',
5230
default: true,
5231
markdownDescription: nls.localize('editor.suggest.showOperators', "When enabled IntelliSense shows `operator`-suggestions.")
5232
},
5233
'editor.suggest.showUnits': {
5234
type: 'boolean',
5235
default: true,
5236
markdownDescription: nls.localize('editor.suggest.showUnits', "When enabled IntelliSense shows `unit`-suggestions.")
5237
},
5238
'editor.suggest.showValues': {
5239
type: 'boolean',
5240
default: true,
5241
markdownDescription: nls.localize('editor.suggest.showValues', "When enabled IntelliSense shows `value`-suggestions.")
5242
},
5243
'editor.suggest.showConstants': {
5244
type: 'boolean',
5245
default: true,
5246
markdownDescription: nls.localize('editor.suggest.showConstants', "When enabled IntelliSense shows `constant`-suggestions.")
5247
},
5248
'editor.suggest.showEnums': {
5249
type: 'boolean',
5250
default: true,
5251
markdownDescription: nls.localize('editor.suggest.showEnums', "When enabled IntelliSense shows `enum`-suggestions.")
5252
},
5253
'editor.suggest.showEnumMembers': {
5254
type: 'boolean',
5255
default: true,
5256
markdownDescription: nls.localize('editor.suggest.showEnumMembers', "When enabled IntelliSense shows `enumMember`-suggestions.")
5257
},
5258
'editor.suggest.showKeywords': {
5259
type: 'boolean',
5260
default: true,
5261
markdownDescription: nls.localize('editor.suggest.showKeywords', "When enabled IntelliSense shows `keyword`-suggestions.")
5262
},
5263
'editor.suggest.showWords': {
5264
type: 'boolean',
5265
default: true,
5266
markdownDescription: nls.localize('editor.suggest.showTexts', "When enabled IntelliSense shows `text`-suggestions.")
5267
},
5268
'editor.suggest.showColors': {
5269
type: 'boolean',
5270
default: true,
5271
markdownDescription: nls.localize('editor.suggest.showColors', "When enabled IntelliSense shows `color`-suggestions.")
5272
},
5273
'editor.suggest.showFiles': {
5274
type: 'boolean',
5275
default: true,
5276
markdownDescription: nls.localize('editor.suggest.showFiles', "When enabled IntelliSense shows `file`-suggestions.")
5277
},
5278
'editor.suggest.showReferences': {
5279
type: 'boolean',
5280
default: true,
5281
markdownDescription: nls.localize('editor.suggest.showReferences', "When enabled IntelliSense shows `reference`-suggestions.")
5282
},
5283
'editor.suggest.showCustomcolors': {
5284
type: 'boolean',
5285
default: true,
5286
markdownDescription: nls.localize('editor.suggest.showCustomcolors', "When enabled IntelliSense shows `customcolor`-suggestions.")
5287
},
5288
'editor.suggest.showFolders': {
5289
type: 'boolean',
5290
default: true,
5291
markdownDescription: nls.localize('editor.suggest.showFolders', "When enabled IntelliSense shows `folder`-suggestions.")
5292
},
5293
'editor.suggest.showTypeParameters': {
5294
type: 'boolean',
5295
default: true,
5296
markdownDescription: nls.localize('editor.suggest.showTypeParameters', "When enabled IntelliSense shows `typeParameter`-suggestions.")
5297
},
5298
'editor.suggest.showSnippets': {
5299
type: 'boolean',
5300
default: true,
5301
markdownDescription: nls.localize('editor.suggest.showSnippets', "When enabled IntelliSense shows `snippet`-suggestions.")
5302
},
5303
'editor.suggest.showUsers': {
5304
type: 'boolean',
5305
default: true,
5306
markdownDescription: nls.localize('editor.suggest.showUsers', "When enabled IntelliSense shows `user`-suggestions.")
5307
},
5308
'editor.suggest.showIssues': {
5309
type: 'boolean',
5310
default: true,
5311
markdownDescription: nls.localize('editor.suggest.showIssues', "When enabled IntelliSense shows `issues`-suggestions.")
5312
}
5313
}
5314
);
5315
}
5316
5317
public validate(_input: unknown): InternalSuggestOptions {
5318
if (!_input || typeof _input !== 'object') {
5319
return this.defaultValue;
5320
}
5321
const input = _input as Unknown<ISuggestOptions>;
5322
return {
5323
insertMode: stringSet(input.insertMode, this.defaultValue.insertMode, ['insert', 'replace']),
5324
filterGraceful: boolean(input.filterGraceful, this.defaultValue.filterGraceful),
5325
snippetsPreventQuickSuggestions: boolean(input.snippetsPreventQuickSuggestions, this.defaultValue.filterGraceful),
5326
localityBonus: boolean(input.localityBonus, this.defaultValue.localityBonus),
5327
shareSuggestSelections: boolean(input.shareSuggestSelections, this.defaultValue.shareSuggestSelections),
5328
selectionMode: stringSet(input.selectionMode, this.defaultValue.selectionMode, ['always', 'never', 'whenQuickSuggestion', 'whenTriggerCharacter']),
5329
showIcons: boolean(input.showIcons, this.defaultValue.showIcons),
5330
showStatusBar: boolean(input.showStatusBar, this.defaultValue.showStatusBar),
5331
preview: boolean(input.preview, this.defaultValue.preview),
5332
previewMode: stringSet(input.previewMode, this.defaultValue.previewMode, ['prefix', 'subword', 'subwordSmart']),
5333
showInlineDetails: boolean(input.showInlineDetails, this.defaultValue.showInlineDetails),
5334
showMethods: boolean(input.showMethods, this.defaultValue.showMethods),
5335
showFunctions: boolean(input.showFunctions, this.defaultValue.showFunctions),
5336
showConstructors: boolean(input.showConstructors, this.defaultValue.showConstructors),
5337
showDeprecated: boolean(input.showDeprecated, this.defaultValue.showDeprecated),
5338
matchOnWordStartOnly: boolean(input.matchOnWordStartOnly, this.defaultValue.matchOnWordStartOnly),
5339
showFields: boolean(input.showFields, this.defaultValue.showFields),
5340
showVariables: boolean(input.showVariables, this.defaultValue.showVariables),
5341
showClasses: boolean(input.showClasses, this.defaultValue.showClasses),
5342
showStructs: boolean(input.showStructs, this.defaultValue.showStructs),
5343
showInterfaces: boolean(input.showInterfaces, this.defaultValue.showInterfaces),
5344
showModules: boolean(input.showModules, this.defaultValue.showModules),
5345
showProperties: boolean(input.showProperties, this.defaultValue.showProperties),
5346
showEvents: boolean(input.showEvents, this.defaultValue.showEvents),
5347
showOperators: boolean(input.showOperators, this.defaultValue.showOperators),
5348
showUnits: boolean(input.showUnits, this.defaultValue.showUnits),
5349
showValues: boolean(input.showValues, this.defaultValue.showValues),
5350
showConstants: boolean(input.showConstants, this.defaultValue.showConstants),
5351
showEnums: boolean(input.showEnums, this.defaultValue.showEnums),
5352
showEnumMembers: boolean(input.showEnumMembers, this.defaultValue.showEnumMembers),
5353
showKeywords: boolean(input.showKeywords, this.defaultValue.showKeywords),
5354
showWords: boolean(input.showWords, this.defaultValue.showWords),
5355
showColors: boolean(input.showColors, this.defaultValue.showColors),
5356
showFiles: boolean(input.showFiles, this.defaultValue.showFiles),
5357
showReferences: boolean(input.showReferences, this.defaultValue.showReferences),
5358
showFolders: boolean(input.showFolders, this.defaultValue.showFolders),
5359
showTypeParameters: boolean(input.showTypeParameters, this.defaultValue.showTypeParameters),
5360
showSnippets: boolean(input.showSnippets, this.defaultValue.showSnippets),
5361
showUsers: boolean(input.showUsers, this.defaultValue.showUsers),
5362
showIssues: boolean(input.showIssues, this.defaultValue.showIssues),
5363
};
5364
}
5365
}
5366
5367
//#endregion
5368
5369
//#region smart select
5370
5371
export interface ISmartSelectOptions {
5372
selectLeadingAndTrailingWhitespace?: boolean;
5373
selectSubwords?: boolean;
5374
}
5375
5376
/**
5377
* @internal
5378
*/
5379
export type SmartSelectOptions = Readonly<Required<ISmartSelectOptions>>;
5380
5381
class SmartSelect extends BaseEditorOption<EditorOption.smartSelect, ISmartSelectOptions, SmartSelectOptions> {
5382
5383
constructor() {
5384
super(
5385
EditorOption.smartSelect, 'smartSelect',
5386
{
5387
selectLeadingAndTrailingWhitespace: true,
5388
selectSubwords: true,
5389
},
5390
{
5391
'editor.smartSelect.selectLeadingAndTrailingWhitespace': {
5392
description: nls.localize('selectLeadingAndTrailingWhitespace', "Whether leading and trailing whitespace should always be selected."),
5393
default: true,
5394
type: 'boolean'
5395
},
5396
'editor.smartSelect.selectSubwords': {
5397
description: nls.localize('selectSubwords', "Whether subwords (like 'foo' in 'fooBar' or 'foo_bar') should be selected."),
5398
default: true,
5399
type: 'boolean'
5400
}
5401
}
5402
);
5403
}
5404
5405
public validate(input: unknown): Readonly<Required<ISmartSelectOptions>> {
5406
if (!input || typeof input !== 'object') {
5407
return this.defaultValue;
5408
}
5409
return {
5410
selectLeadingAndTrailingWhitespace: boolean((input as ISmartSelectOptions).selectLeadingAndTrailingWhitespace, this.defaultValue.selectLeadingAndTrailingWhitespace),
5411
selectSubwords: boolean((input as ISmartSelectOptions).selectSubwords, this.defaultValue.selectSubwords),
5412
};
5413
}
5414
}
5415
5416
//#endregion
5417
5418
//#region wordSegmenterLocales
5419
5420
/**
5421
* Locales used for segmenting lines into words when doing word related navigations or operations.
5422
*
5423
* Specify the BCP 47 language tag of the word you wish to recognize (e.g., ja, zh-CN, zh-Hant-TW, etc.).
5424
*/
5425
class WordSegmenterLocales extends BaseEditorOption<EditorOption.wordSegmenterLocales, string | string[], string[]> {
5426
constructor() {
5427
const defaults: string[] = [];
5428
5429
super(
5430
EditorOption.wordSegmenterLocales, 'wordSegmenterLocales', defaults,
5431
{
5432
anyOf: [
5433
{
5434
type: 'string',
5435
}, {
5436
type: 'array',
5437
items: {
5438
type: 'string'
5439
}
5440
}
5441
],
5442
description: nls.localize('wordSegmenterLocales', "Locales to be used for word segmentation when doing word related navigations or operations. Specify the BCP 47 language tag of the word you wish to recognize (e.g., ja, zh-CN, zh-Hant-TW, etc.)."),
5443
type: 'array',
5444
items: {
5445
type: 'string',
5446
},
5447
default: defaults,
5448
},
5449
);
5450
}
5451
5452
public validate(input: unknown): string[] {
5453
if (typeof input === 'string') {
5454
input = [input];
5455
}
5456
if (Array.isArray(input)) {
5457
const validLocales: string[] = [];
5458
for (const locale of input) {
5459
if (typeof locale === 'string') {
5460
try {
5461
if (Intl.Segmenter.supportedLocalesOf(locale).length > 0) {
5462
validLocales.push(locale);
5463
}
5464
} catch {
5465
// ignore invalid locales
5466
}
5467
}
5468
}
5469
return validLocales;
5470
}
5471
5472
return this.defaultValue;
5473
}
5474
}
5475
5476
5477
//#endregion
5478
5479
//#region wrappingIndent
5480
5481
/**
5482
* Describes how to indent wrapped lines.
5483
*/
5484
export const enum WrappingIndent {
5485
/**
5486
* No indentation => wrapped lines begin at column 1.
5487
*/
5488
None = 0,
5489
/**
5490
* Same => wrapped lines get the same indentation as the parent.
5491
*/
5492
Same = 1,
5493
/**
5494
* Indent => wrapped lines get +1 indentation toward the parent.
5495
*/
5496
Indent = 2,
5497
/**
5498
* DeepIndent => wrapped lines get +2 indentation toward the parent.
5499
*/
5500
DeepIndent = 3
5501
}
5502
5503
class WrappingIndentOption extends BaseEditorOption<EditorOption.wrappingIndent, 'none' | 'same' | 'indent' | 'deepIndent', WrappingIndent> {
5504
5505
constructor() {
5506
super(EditorOption.wrappingIndent, 'wrappingIndent', WrappingIndent.Same,
5507
{
5508
'editor.wrappingIndent': {
5509
type: 'string',
5510
enum: ['none', 'same', 'indent', 'deepIndent'],
5511
enumDescriptions: [
5512
nls.localize('wrappingIndent.none', "No indentation. Wrapped lines begin at column 1."),
5513
nls.localize('wrappingIndent.same', "Wrapped lines get the same indentation as the parent."),
5514
nls.localize('wrappingIndent.indent', "Wrapped lines get +1 indentation toward the parent."),
5515
nls.localize('wrappingIndent.deepIndent', "Wrapped lines get +2 indentation toward the parent."),
5516
],
5517
description: nls.localize('wrappingIndent', "Controls the indentation of wrapped lines."),
5518
default: 'same'
5519
}
5520
}
5521
);
5522
}
5523
5524
public validate(input: unknown): WrappingIndent {
5525
switch (input) {
5526
case 'none': return WrappingIndent.None;
5527
case 'same': return WrappingIndent.Same;
5528
case 'indent': return WrappingIndent.Indent;
5529
case 'deepIndent': return WrappingIndent.DeepIndent;
5530
}
5531
return WrappingIndent.Same;
5532
}
5533
5534
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: WrappingIndent): WrappingIndent {
5535
const accessibilitySupport = options.get(EditorOption.accessibilitySupport);
5536
if (accessibilitySupport === AccessibilitySupport.Enabled) {
5537
// if we know for a fact that a screen reader is attached, we use no indent wrapping to
5538
// help that the editor's wrapping points match the textarea's wrapping points
5539
return WrappingIndent.None;
5540
}
5541
return value;
5542
}
5543
}
5544
5545
//#endregion
5546
5547
//#region wrappingInfo
5548
5549
export interface EditorWrappingInfo {
5550
readonly isDominatedByLongLines: boolean;
5551
readonly isWordWrapMinified: boolean;
5552
readonly isViewportWrapping: boolean;
5553
readonly wrappingColumn: number;
5554
}
5555
5556
class EditorWrappingInfoComputer extends ComputedEditorOption<EditorOption.wrappingInfo, EditorWrappingInfo> {
5557
5558
constructor() {
5559
super(EditorOption.wrappingInfo, {
5560
isDominatedByLongLines: false,
5561
isWordWrapMinified: false,
5562
isViewportWrapping: false,
5563
wrappingColumn: -1
5564
});
5565
}
5566
5567
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, _: EditorWrappingInfo): EditorWrappingInfo {
5568
const layoutInfo = options.get(EditorOption.layoutInfo);
5569
5570
return {
5571
isDominatedByLongLines: env.isDominatedByLongLines,
5572
isWordWrapMinified: layoutInfo.isWordWrapMinified,
5573
isViewportWrapping: layoutInfo.isViewportWrapping,
5574
wrappingColumn: layoutInfo.wrappingColumn,
5575
};
5576
}
5577
}
5578
5579
//#endregion
5580
5581
//#region dropIntoEditor
5582
5583
/**
5584
* Configuration options for editor drop into behavior
5585
*/
5586
export interface IDropIntoEditorOptions {
5587
/**
5588
* Enable dropping into editor.
5589
* Defaults to true.
5590
*/
5591
enabled?: boolean;
5592
5593
/**
5594
* Controls if a widget is shown after a drop.
5595
* Defaults to 'afterDrop'.
5596
*/
5597
showDropSelector?: 'afterDrop' | 'never';
5598
}
5599
5600
/**
5601
* @internal
5602
*/
5603
export type EditorDropIntoEditorOptions = Readonly<Required<IDropIntoEditorOptions>>;
5604
5605
class EditorDropIntoEditor extends BaseEditorOption<EditorOption.dropIntoEditor, IDropIntoEditorOptions, EditorDropIntoEditorOptions> {
5606
5607
constructor() {
5608
const defaults: EditorDropIntoEditorOptions = { enabled: true, showDropSelector: 'afterDrop' };
5609
super(
5610
EditorOption.dropIntoEditor, 'dropIntoEditor', defaults,
5611
{
5612
'editor.dropIntoEditor.enabled': {
5613
type: 'boolean',
5614
default: defaults.enabled,
5615
markdownDescription: nls.localize('dropIntoEditor.enabled', "Controls whether you can drag and drop a file into a text editor by holding down the `Shift` key (instead of opening the file in an editor)."),
5616
},
5617
'editor.dropIntoEditor.showDropSelector': {
5618
type: 'string',
5619
markdownDescription: nls.localize('dropIntoEditor.showDropSelector', "Controls if a widget is shown when dropping files into the editor. This widget lets you control how the file is dropped."),
5620
enum: [
5621
'afterDrop',
5622
'never'
5623
],
5624
enumDescriptions: [
5625
nls.localize('dropIntoEditor.showDropSelector.afterDrop', "Show the drop selector widget after a file is dropped into the editor."),
5626
nls.localize('dropIntoEditor.showDropSelector.never', "Never show the drop selector widget. Instead the default drop provider is always used."),
5627
],
5628
default: 'afterDrop',
5629
},
5630
}
5631
);
5632
}
5633
5634
public validate(_input: unknown): EditorDropIntoEditorOptions {
5635
if (!_input || typeof _input !== 'object') {
5636
return this.defaultValue;
5637
}
5638
const input = _input as Unknown<IDropIntoEditorOptions>;
5639
return {
5640
enabled: boolean(input.enabled, this.defaultValue.enabled),
5641
showDropSelector: stringSet(input.showDropSelector, this.defaultValue.showDropSelector, ['afterDrop', 'never']),
5642
};
5643
}
5644
}
5645
5646
//#endregion
5647
5648
//#region pasteAs
5649
5650
/**
5651
* Configuration options for editor pasting as into behavior
5652
*/
5653
export interface IPasteAsOptions {
5654
/**
5655
* Enable paste as functionality in editors.
5656
* Defaults to true.
5657
*/
5658
enabled?: boolean;
5659
5660
/**
5661
* Controls if a widget is shown after a drop.
5662
* Defaults to 'afterPaste'.
5663
*/
5664
showPasteSelector?: 'afterPaste' | 'never';
5665
}
5666
5667
/**
5668
* @internal
5669
*/
5670
export type EditorPasteAsOptions = Readonly<Required<IPasteAsOptions>>;
5671
5672
class EditorPasteAs extends BaseEditorOption<EditorOption.pasteAs, IPasteAsOptions, EditorPasteAsOptions> {
5673
5674
constructor() {
5675
const defaults: EditorPasteAsOptions = { enabled: true, showPasteSelector: 'afterPaste' };
5676
super(
5677
EditorOption.pasteAs, 'pasteAs', defaults,
5678
{
5679
'editor.pasteAs.enabled': {
5680
type: 'boolean',
5681
default: defaults.enabled,
5682
markdownDescription: nls.localize('pasteAs.enabled', "Controls whether you can paste content in different ways."),
5683
},
5684
'editor.pasteAs.showPasteSelector': {
5685
type: 'string',
5686
markdownDescription: nls.localize('pasteAs.showPasteSelector', "Controls if a widget is shown when pasting content in to the editor. This widget lets you control how the file is pasted."),
5687
enum: [
5688
'afterPaste',
5689
'never'
5690
],
5691
enumDescriptions: [
5692
nls.localize('pasteAs.showPasteSelector.afterPaste', "Show the paste selector widget after content is pasted into the editor."),
5693
nls.localize('pasteAs.showPasteSelector.never', "Never show the paste selector widget. Instead the default pasting behavior is always used."),
5694
],
5695
default: 'afterPaste',
5696
},
5697
}
5698
);
5699
}
5700
5701
public validate(_input: unknown): EditorPasteAsOptions {
5702
if (!_input || typeof _input !== 'object') {
5703
return this.defaultValue;
5704
}
5705
const input = _input as Unknown<IPasteAsOptions>;
5706
return {
5707
enabled: boolean(input.enabled, this.defaultValue.enabled),
5708
showPasteSelector: stringSet(input.showPasteSelector, this.defaultValue.showPasteSelector, ['afterPaste', 'never']),
5709
};
5710
}
5711
}
5712
5713
//#endregion
5714
5715
/**
5716
* @internal
5717
*/
5718
export const editorOptionsRegistry: IEditorOption<EditorOption, unknown>[] = [];
5719
5720
function register<K extends EditorOption, V>(option: IEditorOption<K, V>): IEditorOption<K, V> {
5721
editorOptionsRegistry[option.id] = option;
5722
return option;
5723
}
5724
5725
export const enum EditorOption {
5726
acceptSuggestionOnCommitCharacter,
5727
acceptSuggestionOnEnter,
5728
accessibilitySupport,
5729
accessibilityPageSize,
5730
allowOverflow,
5731
allowVariableLineHeights,
5732
allowVariableFonts,
5733
allowVariableFontsInAccessibilityMode,
5734
ariaLabel,
5735
ariaRequired,
5736
autoClosingBrackets,
5737
autoClosingComments,
5738
screenReaderAnnounceInlineSuggestion,
5739
autoClosingDelete,
5740
autoClosingOvertype,
5741
autoClosingQuotes,
5742
autoIndent,
5743
autoIndentOnPaste,
5744
autoIndentOnPasteWithinString,
5745
automaticLayout,
5746
autoSurround,
5747
bracketPairColorization,
5748
guides,
5749
codeLens,
5750
codeLensFontFamily,
5751
codeLensFontSize,
5752
colorDecorators,
5753
colorDecoratorsLimit,
5754
columnSelection,
5755
comments,
5756
contextmenu,
5757
copyWithSyntaxHighlighting,
5758
cursorBlinking,
5759
cursorSmoothCaretAnimation,
5760
cursorStyle,
5761
cursorSurroundingLines,
5762
cursorSurroundingLinesStyle,
5763
cursorWidth,
5764
cursorHeight,
5765
disableLayerHinting,
5766
disableMonospaceOptimizations,
5767
domReadOnly,
5768
dragAndDrop,
5769
dropIntoEditor,
5770
editContext,
5771
emptySelectionClipboard,
5772
experimentalGpuAcceleration,
5773
experimentalWhitespaceRendering,
5774
extraEditorClassName,
5775
fastScrollSensitivity,
5776
find,
5777
fixedOverflowWidgets,
5778
folding,
5779
foldingStrategy,
5780
foldingHighlight,
5781
foldingImportsByDefault,
5782
foldingMaximumRegions,
5783
unfoldOnClickAfterEndOfLine,
5784
fontFamily,
5785
fontInfo,
5786
fontLigatures,
5787
fontSize,
5788
fontWeight,
5789
fontVariations,
5790
formatOnPaste,
5791
formatOnType,
5792
glyphMargin,
5793
gotoLocation,
5794
hideCursorInOverviewRuler,
5795
hover,
5796
inDiffEditor,
5797
inlineSuggest,
5798
letterSpacing,
5799
lightbulb,
5800
lineDecorationsWidth,
5801
lineHeight,
5802
lineNumbers,
5803
lineNumbersMinChars,
5804
linkedEditing,
5805
links,
5806
matchBrackets,
5807
minimap,
5808
mouseStyle,
5809
mouseWheelScrollSensitivity,
5810
mouseWheelZoom,
5811
multiCursorMergeOverlapping,
5812
multiCursorModifier,
5813
mouseMiddleClickAction,
5814
multiCursorPaste,
5815
multiCursorLimit,
5816
occurrencesHighlight,
5817
occurrencesHighlightDelay,
5818
overtypeCursorStyle,
5819
overtypeOnPaste,
5820
overviewRulerBorder,
5821
overviewRulerLanes,
5822
padding,
5823
pasteAs,
5824
parameterHints,
5825
peekWidgetDefaultFocus,
5826
placeholder,
5827
definitionLinkOpensInPeek,
5828
quickSuggestions,
5829
quickSuggestionsDelay,
5830
readOnly,
5831
readOnlyMessage,
5832
renameOnType,
5833
renderRichScreenReaderContent,
5834
renderControlCharacters,
5835
renderFinalNewline,
5836
renderLineHighlight,
5837
renderLineHighlightOnlyWhenFocus,
5838
renderValidationDecorations,
5839
renderWhitespace,
5840
revealHorizontalRightPadding,
5841
roundedSelection,
5842
rulers,
5843
scrollbar,
5844
scrollBeyondLastColumn,
5845
scrollBeyondLastLine,
5846
scrollPredominantAxis,
5847
selectionClipboard,
5848
selectionHighlight,
5849
selectionHighlightMaxLength,
5850
selectionHighlightMultiline,
5851
selectOnLineNumbers,
5852
showFoldingControls,
5853
showUnused,
5854
snippetSuggestions,
5855
smartSelect,
5856
smoothScrolling,
5857
stickyScroll,
5858
stickyTabStops,
5859
stopRenderingLineAfter,
5860
suggest,
5861
suggestFontSize,
5862
suggestLineHeight,
5863
suggestOnTriggerCharacters,
5864
suggestSelection,
5865
tabCompletion,
5866
tabIndex,
5867
trimWhitespaceOnDelete,
5868
unicodeHighlighting,
5869
unusualLineTerminators,
5870
useShadowDOM,
5871
useTabStops,
5872
wordBreak,
5873
wordSegmenterLocales,
5874
wordSeparators,
5875
wordWrap,
5876
wordWrapBreakAfterCharacters,
5877
wordWrapBreakBeforeCharacters,
5878
wordWrapColumn,
5879
wordWrapOverride1,
5880
wordWrapOverride2,
5881
wrappingIndent,
5882
wrappingStrategy,
5883
showDeprecated,
5884
inertialScroll,
5885
inlayHints,
5886
wrapOnEscapedLineFeeds,
5887
// Leave these at the end (because they have dependencies!)
5888
effectiveCursorStyle,
5889
editorClassName,
5890
pixelRatio,
5891
tabFocusMode,
5892
layoutInfo,
5893
wrappingInfo,
5894
defaultColorDecorators,
5895
colorDecoratorsActivatedOn,
5896
inlineCompletionsAccessibilityVerbose,
5897
effectiveEditContext,
5898
scrollOnMiddleClick,
5899
effectiveAllowVariableFonts
5900
}
5901
5902
export const EditorOptions = {
5903
acceptSuggestionOnCommitCharacter: register(new EditorBooleanOption(
5904
EditorOption.acceptSuggestionOnCommitCharacter, 'acceptSuggestionOnCommitCharacter', true,
5905
{ 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.") }
5906
)),
5907
acceptSuggestionOnEnter: register(new EditorStringEnumOption(
5908
EditorOption.acceptSuggestionOnEnter, 'acceptSuggestionOnEnter',
5909
'on' as 'on' | 'smart' | 'off',
5910
['on', 'smart', 'off'] as const,
5911
{
5912
markdownEnumDescriptions: [
5913
'',
5914
nls.localize('acceptSuggestionOnEnterSmart', "Only accept a suggestion with `Enter` when it makes a textual change."),
5915
''
5916
],
5917
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.")
5918
}
5919
)),
5920
accessibilitySupport: register(new EditorAccessibilitySupport()),
5921
accessibilityPageSize: register(new EditorIntOption(EditorOption.accessibilityPageSize, 'accessibilityPageSize', 500, 1, Constants.MAX_SAFE_SMALL_INTEGER,
5922
{
5923
description: nls.localize('accessibilityPageSize', "Controls the number of lines in the editor that can be read out by a screen reader at once. When we detect a screen reader we automatically set the default to be 500. Warning: this has a performance implication for numbers larger than the default."),
5924
tags: ['accessibility']
5925
}
5926
)),
5927
allowOverflow: register(new EditorBooleanOption(
5928
EditorOption.allowOverflow, 'allowOverflow', true,
5929
)),
5930
allowVariableLineHeights: register(new EditorBooleanOption(
5931
EditorOption.allowVariableLineHeights, 'allowVariableLineHeights', true,
5932
{
5933
description: nls.localize('allowVariableLineHeights', "Controls whether to allow using variable line heights in the editor.")
5934
}
5935
)),
5936
allowVariableFonts: register(new EditorBooleanOption(
5937
EditorOption.allowVariableFonts, 'allowVariableFonts', true,
5938
{
5939
description: nls.localize('allowVariableFonts', "Controls whether to allow using variable fonts in the editor.")
5940
}
5941
)),
5942
allowVariableFontsInAccessibilityMode: register(new EditorBooleanOption(
5943
EditorOption.allowVariableFontsInAccessibilityMode, 'allowVariableFontsInAccessibilityMode', false,
5944
{
5945
description: nls.localize('allowVariableFontsInAccessibilityMode', "Controls whether to allow using variable fonts in the editor in the accessibility mode."),
5946
tags: ['accessibility']
5947
}
5948
)),
5949
ariaLabel: register(new EditorStringOption(
5950
EditorOption.ariaLabel, 'ariaLabel', nls.localize('editorViewAccessibleLabel', "Editor content")
5951
)),
5952
ariaRequired: register(new EditorBooleanOption(
5953
EditorOption.ariaRequired, 'ariaRequired', false, undefined
5954
)),
5955
screenReaderAnnounceInlineSuggestion: register(new EditorBooleanOption(
5956
EditorOption.screenReaderAnnounceInlineSuggestion, 'screenReaderAnnounceInlineSuggestion', true,
5957
{
5958
description: nls.localize('screenReaderAnnounceInlineSuggestion', "Control whether inline suggestions are announced by a screen reader."),
5959
tags: ['accessibility']
5960
}
5961
)),
5962
autoClosingBrackets: register(new EditorStringEnumOption(
5963
EditorOption.autoClosingBrackets, 'autoClosingBrackets',
5964
'languageDefined' as 'always' | 'languageDefined' | 'beforeWhitespace' | 'never',
5965
['always', 'languageDefined', 'beforeWhitespace', 'never'] as const,
5966
{
5967
enumDescriptions: [
5968
'',
5969
nls.localize('editor.autoClosingBrackets.languageDefined', "Use language configurations to determine when to autoclose brackets."),
5970
nls.localize('editor.autoClosingBrackets.beforeWhitespace', "Autoclose brackets only when the cursor is to the left of whitespace."),
5971
'',
5972
],
5973
description: nls.localize('autoClosingBrackets', "Controls whether the editor should automatically close brackets after the user adds an opening bracket.")
5974
}
5975
)),
5976
autoClosingComments: register(new EditorStringEnumOption(
5977
EditorOption.autoClosingComments, 'autoClosingComments',
5978
'languageDefined' as 'always' | 'languageDefined' | 'beforeWhitespace' | 'never',
5979
['always', 'languageDefined', 'beforeWhitespace', 'never'] as const,
5980
{
5981
enumDescriptions: [
5982
'',
5983
nls.localize('editor.autoClosingComments.languageDefined', "Use language configurations to determine when to autoclose comments."),
5984
nls.localize('editor.autoClosingComments.beforeWhitespace', "Autoclose comments only when the cursor is to the left of whitespace."),
5985
'',
5986
],
5987
description: nls.localize('autoClosingComments', "Controls whether the editor should automatically close comments after the user adds an opening comment.")
5988
}
5989
)),
5990
autoClosingDelete: register(new EditorStringEnumOption(
5991
EditorOption.autoClosingDelete, 'autoClosingDelete',
5992
'auto' as 'always' | 'auto' | 'never',
5993
['always', 'auto', 'never'] as const,
5994
{
5995
enumDescriptions: [
5996
'',
5997
nls.localize('editor.autoClosingDelete.auto', "Remove adjacent closing quotes or brackets only if they were automatically inserted."),
5998
'',
5999
],
6000
description: nls.localize('autoClosingDelete', "Controls whether the editor should remove adjacent closing quotes or brackets when deleting.")
6001
}
6002
)),
6003
autoClosingOvertype: register(new EditorStringEnumOption(
6004
EditorOption.autoClosingOvertype, 'autoClosingOvertype',
6005
'auto' as 'always' | 'auto' | 'never',
6006
['always', 'auto', 'never'] as const,
6007
{
6008
enumDescriptions: [
6009
'',
6010
nls.localize('editor.autoClosingOvertype.auto', "Type over closing quotes or brackets only if they were automatically inserted."),
6011
'',
6012
],
6013
description: nls.localize('autoClosingOvertype', "Controls whether the editor should type over closing quotes or brackets.")
6014
}
6015
)),
6016
autoClosingQuotes: register(new EditorStringEnumOption(
6017
EditorOption.autoClosingQuotes, 'autoClosingQuotes',
6018
'languageDefined' as 'always' | 'languageDefined' | 'beforeWhitespace' | 'never',
6019
['always', 'languageDefined', 'beforeWhitespace', 'never'] as const,
6020
{
6021
enumDescriptions: [
6022
'',
6023
nls.localize('editor.autoClosingQuotes.languageDefined', "Use language configurations to determine when to autoclose quotes."),
6024
nls.localize('editor.autoClosingQuotes.beforeWhitespace', "Autoclose quotes only when the cursor is to the left of whitespace."),
6025
'',
6026
],
6027
description: nls.localize('autoClosingQuotes', "Controls whether the editor should automatically close quotes after the user adds an opening quote.")
6028
}
6029
)),
6030
autoIndent: register(new EditorEnumOption(
6031
EditorOption.autoIndent, 'autoIndent',
6032
EditorAutoIndentStrategy.Full, 'full',
6033
['none', 'keep', 'brackets', 'advanced', 'full'],
6034
_autoIndentFromString,
6035
{
6036
enumDescriptions: [
6037
nls.localize('editor.autoIndent.none', "The editor will not insert indentation automatically."),
6038
nls.localize('editor.autoIndent.keep', "The editor will keep the current line's indentation."),
6039
nls.localize('editor.autoIndent.brackets', "The editor will keep the current line's indentation and honor language defined brackets."),
6040
nls.localize('editor.autoIndent.advanced', "The editor will keep the current line's indentation, honor language defined brackets and invoke special onEnterRules defined by languages."),
6041
nls.localize('editor.autoIndent.full', "The editor will keep the current line's indentation, honor language defined brackets, invoke special onEnterRules defined by languages, and honor indentationRules defined by languages."),
6042
],
6043
description: nls.localize('autoIndent', "Controls whether the editor should automatically adjust the indentation when users type, paste, move or indent lines.")
6044
}
6045
)),
6046
autoIndentOnPaste: register(new EditorBooleanOption(
6047
EditorOption.autoIndentOnPaste, 'autoIndentOnPaste', false,
6048
{ description: nls.localize('autoIndentOnPaste', "Controls whether the editor should automatically auto-indent the pasted content.") }
6049
)),
6050
autoIndentOnPasteWithinString: register(new EditorBooleanOption(
6051
EditorOption.autoIndentOnPasteWithinString, 'autoIndentOnPasteWithinString', true,
6052
{ description: nls.localize('autoIndentOnPasteWithinString', "Controls whether the editor should automatically auto-indent the pasted content when pasted within a string. This takes effect when autoIndentOnPaste is true.") }
6053
)),
6054
automaticLayout: register(new EditorBooleanOption(
6055
EditorOption.automaticLayout, 'automaticLayout', false,
6056
)),
6057
autoSurround: register(new EditorStringEnumOption(
6058
EditorOption.autoSurround, 'autoSurround',
6059
'languageDefined' as 'languageDefined' | 'quotes' | 'brackets' | 'never',
6060
['languageDefined', 'quotes', 'brackets', 'never'] as const,
6061
{
6062
enumDescriptions: [
6063
nls.localize('editor.autoSurround.languageDefined', "Use language configurations to determine when to automatically surround selections."),
6064
nls.localize('editor.autoSurround.quotes', "Surround with quotes but not brackets."),
6065
nls.localize('editor.autoSurround.brackets', "Surround with brackets but not quotes."),
6066
''
6067
],
6068
description: nls.localize('autoSurround', "Controls whether the editor should automatically surround selections when typing quotes or brackets.")
6069
}
6070
)),
6071
bracketPairColorization: register(new BracketPairColorization()),
6072
bracketPairGuides: register(new GuideOptions()),
6073
stickyTabStops: register(new EditorBooleanOption(
6074
EditorOption.stickyTabStops, 'stickyTabStops', false,
6075
{ description: nls.localize('stickyTabStops', "Emulate selection behavior of tab characters when using spaces for indentation. Selection will stick to tab stops.") }
6076
)),
6077
codeLens: register(new EditorBooleanOption(
6078
EditorOption.codeLens, 'codeLens', true,
6079
{ description: nls.localize('codeLens', "Controls whether the editor shows CodeLens.") }
6080
)),
6081
codeLensFontFamily: register(new EditorStringOption(
6082
EditorOption.codeLensFontFamily, 'codeLensFontFamily', '',
6083
{ description: nls.localize('codeLensFontFamily', "Controls the font family for CodeLens.") }
6084
)),
6085
codeLensFontSize: register(new EditorIntOption(EditorOption.codeLensFontSize, 'codeLensFontSize', 0, 0, 100, {
6086
type: 'number',
6087
default: 0,
6088
minimum: 0,
6089
maximum: 100,
6090
markdownDescription: nls.localize('codeLensFontSize', "Controls the font size in pixels for CodeLens. When set to 0, 90% of `#editor.fontSize#` is used.")
6091
})),
6092
colorDecorators: register(new EditorBooleanOption(
6093
EditorOption.colorDecorators, 'colorDecorators', true,
6094
{ description: nls.localize('colorDecorators', "Controls whether the editor should render the inline color decorators and color picker.") }
6095
)),
6096
colorDecoratorActivatedOn: register(new EditorStringEnumOption(EditorOption.colorDecoratorsActivatedOn, 'colorDecoratorsActivatedOn', 'clickAndHover' as 'clickAndHover' | 'hover' | 'click', ['clickAndHover', 'hover', 'click'] as const, {
6097
enumDescriptions: [
6098
nls.localize('editor.colorDecoratorActivatedOn.clickAndHover', "Make the color picker appear both on click and hover of the color decorator"),
6099
nls.localize('editor.colorDecoratorActivatedOn.hover', "Make the color picker appear on hover of the color decorator"),
6100
nls.localize('editor.colorDecoratorActivatedOn.click', "Make the color picker appear on click of the color decorator")
6101
],
6102
description: nls.localize('colorDecoratorActivatedOn', "Controls the condition to make a color picker appear from a color decorator.")
6103
})),
6104
colorDecoratorsLimit: register(new EditorIntOption(
6105
EditorOption.colorDecoratorsLimit, 'colorDecoratorsLimit', 500, 1, 1000000,
6106
{
6107
markdownDescription: nls.localize('colorDecoratorsLimit', "Controls the max number of color decorators that can be rendered in an editor at once.")
6108
}
6109
)),
6110
columnSelection: register(new EditorBooleanOption(
6111
EditorOption.columnSelection, 'columnSelection', false,
6112
{ description: nls.localize('columnSelection', "Enable that the selection with the mouse and keys is doing column selection.") }
6113
)),
6114
comments: register(new EditorComments()),
6115
contextmenu: register(new EditorBooleanOption(
6116
EditorOption.contextmenu, 'contextmenu', true,
6117
)),
6118
copyWithSyntaxHighlighting: register(new EditorBooleanOption(
6119
EditorOption.copyWithSyntaxHighlighting, 'copyWithSyntaxHighlighting', true,
6120
{ description: nls.localize('copyWithSyntaxHighlighting', "Controls whether syntax highlighting should be copied into the clipboard.") }
6121
)),
6122
cursorBlinking: register(new EditorEnumOption(
6123
EditorOption.cursorBlinking, 'cursorBlinking',
6124
TextEditorCursorBlinkingStyle.Blink, 'blink',
6125
['blink', 'smooth', 'phase', 'expand', 'solid'],
6126
cursorBlinkingStyleFromString,
6127
{ description: nls.localize('cursorBlinking', "Control the cursor animation style.") }
6128
)),
6129
cursorSmoothCaretAnimation: register(new EditorStringEnumOption(
6130
EditorOption.cursorSmoothCaretAnimation, 'cursorSmoothCaretAnimation',
6131
'off' as 'off' | 'explicit' | 'on',
6132
['off', 'explicit', 'on'] as const,
6133
{
6134
enumDescriptions: [
6135
nls.localize('cursorSmoothCaretAnimation.off', "Smooth caret animation is disabled."),
6136
nls.localize('cursorSmoothCaretAnimation.explicit', "Smooth caret animation is enabled only when the user moves the cursor with an explicit gesture."),
6137
nls.localize('cursorSmoothCaretAnimation.on', "Smooth caret animation is always enabled.")
6138
],
6139
description: nls.localize('cursorSmoothCaretAnimation', "Controls whether the smooth caret animation should be enabled.")
6140
}
6141
)),
6142
cursorStyle: register(new EditorEnumOption(
6143
EditorOption.cursorStyle, 'cursorStyle',
6144
TextEditorCursorStyle.Line, 'line',
6145
['line', 'block', 'underline', 'line-thin', 'block-outline', 'underline-thin'],
6146
cursorStyleFromString,
6147
{ description: nls.localize('cursorStyle', "Controls the cursor style in insert input mode.") }
6148
)),
6149
overtypeCursorStyle: register(new EditorEnumOption(
6150
EditorOption.overtypeCursorStyle, 'overtypeCursorStyle',
6151
TextEditorCursorStyle.Block, 'block',
6152
['line', 'block', 'underline', 'line-thin', 'block-outline', 'underline-thin'],
6153
cursorStyleFromString,
6154
{ description: nls.localize('overtypeCursorStyle', "Controls the cursor style in overtype input mode.") }
6155
)),
6156
cursorSurroundingLines: register(new EditorIntOption(
6157
EditorOption.cursorSurroundingLines, 'cursorSurroundingLines',
6158
0, 0, Constants.MAX_SAFE_SMALL_INTEGER,
6159
{ description: nls.localize('cursorSurroundingLines', "Controls the minimal number of visible leading lines (minimum 0) and trailing lines (minimum 1) surrounding the cursor. Known as 'scrollOff' or 'scrollOffset' in some other editors.") }
6160
)),
6161
cursorSurroundingLinesStyle: register(new EditorStringEnumOption(
6162
EditorOption.cursorSurroundingLinesStyle, 'cursorSurroundingLinesStyle',
6163
'default' as 'default' | 'all',
6164
['default', 'all'] as const,
6165
{
6166
enumDescriptions: [
6167
nls.localize('cursorSurroundingLinesStyle.default', "`cursorSurroundingLines` is enforced only when triggered via the keyboard or API."),
6168
nls.localize('cursorSurroundingLinesStyle.all', "`cursorSurroundingLines` is enforced always.")
6169
],
6170
markdownDescription: nls.localize('cursorSurroundingLinesStyle', "Controls when `#editor.cursorSurroundingLines#` should be enforced.")
6171
}
6172
)),
6173
cursorWidth: register(new EditorIntOption(
6174
EditorOption.cursorWidth, 'cursorWidth',
6175
0, 0, Constants.MAX_SAFE_SMALL_INTEGER,
6176
{ markdownDescription: nls.localize('cursorWidth', "Controls the width of the cursor when `#editor.cursorStyle#` is set to `line`.") }
6177
)),
6178
cursorHeight: register(new EditorIntOption(
6179
EditorOption.cursorHeight, 'cursorHeight',
6180
0, 0, Constants.MAX_SAFE_SMALL_INTEGER,
6181
{ markdownDescription: nls.localize('cursorHeight', "Controls the height of the cursor when `#editor.cursorStyle#` is set to `line`. Cursor's max height depends on line height.") }
6182
)),
6183
disableLayerHinting: register(new EditorBooleanOption(
6184
EditorOption.disableLayerHinting, 'disableLayerHinting', false,
6185
)),
6186
disableMonospaceOptimizations: register(new EditorBooleanOption(
6187
EditorOption.disableMonospaceOptimizations, 'disableMonospaceOptimizations', false
6188
)),
6189
domReadOnly: register(new EditorBooleanOption(
6190
EditorOption.domReadOnly, 'domReadOnly', false,
6191
)),
6192
dragAndDrop: register(new EditorBooleanOption(
6193
EditorOption.dragAndDrop, 'dragAndDrop', true,
6194
{ description: nls.localize('dragAndDrop', "Controls whether the editor should allow moving selections via drag and drop.") }
6195
)),
6196
emptySelectionClipboard: register(new EditorEmptySelectionClipboard()),
6197
dropIntoEditor: register(new EditorDropIntoEditor()),
6198
editContext: register(new EditorBooleanOption(
6199
EditorOption.editContext, 'editContext', true,
6200
{
6201
description: nls.localize('editContext', "Sets whether the EditContext API should be used instead of the text area to power input in the editor."),
6202
included: platform.isChrome || platform.isEdge || platform.isNative
6203
}
6204
)),
6205
renderRichScreenReaderContent: register(new EditorBooleanOption(
6206
EditorOption.renderRichScreenReaderContent, 'renderRichScreenReaderContent', false,
6207
{
6208
markdownDescription: nls.localize('renderRichScreenReaderContent', "Whether to render rich screen reader content when the `#editor.editContext#` setting is enabled."),
6209
}
6210
)),
6211
stickyScroll: register(new EditorStickyScroll()),
6212
experimentalGpuAcceleration: register(new EditorStringEnumOption(
6213
EditorOption.experimentalGpuAcceleration, 'experimentalGpuAcceleration',
6214
'off' as 'off' | 'on',
6215
['off', 'on'] as const,
6216
{
6217
tags: ['experimental'],
6218
enumDescriptions: [
6219
nls.localize('experimentalGpuAcceleration.off', "Use regular DOM-based rendering."),
6220
nls.localize('experimentalGpuAcceleration.on', "Use GPU acceleration."),
6221
],
6222
description: nls.localize('experimentalGpuAcceleration', "Controls whether to use the experimental GPU acceleration to render the editor.")
6223
}
6224
)),
6225
experimentalWhitespaceRendering: register(new EditorStringEnumOption(
6226
EditorOption.experimentalWhitespaceRendering, 'experimentalWhitespaceRendering',
6227
'svg' as 'svg' | 'font' | 'off',
6228
['svg', 'font', 'off'] as const,
6229
{
6230
enumDescriptions: [
6231
nls.localize('experimentalWhitespaceRendering.svg', "Use a new rendering method with svgs."),
6232
nls.localize('experimentalWhitespaceRendering.font', "Use a new rendering method with font characters."),
6233
nls.localize('experimentalWhitespaceRendering.off', "Use the stable rendering method."),
6234
],
6235
description: nls.localize('experimentalWhitespaceRendering', "Controls whether whitespace is rendered with a new, experimental method.")
6236
}
6237
)),
6238
extraEditorClassName: register(new EditorStringOption(
6239
EditorOption.extraEditorClassName, 'extraEditorClassName', '',
6240
)),
6241
fastScrollSensitivity: register(new EditorFloatOption(
6242
EditorOption.fastScrollSensitivity, 'fastScrollSensitivity',
6243
5, x => (x <= 0 ? 5 : x),
6244
{ markdownDescription: nls.localize('fastScrollSensitivity', "Scrolling speed multiplier when pressing `Alt`.") }
6245
)),
6246
find: register(new EditorFind()),
6247
fixedOverflowWidgets: register(new EditorBooleanOption(
6248
EditorOption.fixedOverflowWidgets, 'fixedOverflowWidgets', false,
6249
)),
6250
folding: register(new EditorBooleanOption(
6251
EditorOption.folding, 'folding', true,
6252
{ description: nls.localize('folding', "Controls whether the editor has code folding enabled.") }
6253
)),
6254
foldingStrategy: register(new EditorStringEnumOption(
6255
EditorOption.foldingStrategy, 'foldingStrategy',
6256
'auto' as 'auto' | 'indentation',
6257
['auto', 'indentation'] as const,
6258
{
6259
enumDescriptions: [
6260
nls.localize('foldingStrategy.auto', "Use a language-specific folding strategy if available, else the indentation-based one."),
6261
nls.localize('foldingStrategy.indentation', "Use the indentation-based folding strategy."),
6262
],
6263
description: nls.localize('foldingStrategy', "Controls the strategy for computing folding ranges.")
6264
}
6265
)),
6266
foldingHighlight: register(new EditorBooleanOption(
6267
EditorOption.foldingHighlight, 'foldingHighlight', true,
6268
{ description: nls.localize('foldingHighlight', "Controls whether the editor should highlight folded ranges.") }
6269
)),
6270
foldingImportsByDefault: register(new EditorBooleanOption(
6271
EditorOption.foldingImportsByDefault, 'foldingImportsByDefault', false,
6272
{ description: nls.localize('foldingImportsByDefault', "Controls whether the editor automatically collapses import ranges.") }
6273
)),
6274
foldingMaximumRegions: register(new EditorIntOption(
6275
EditorOption.foldingMaximumRegions, 'foldingMaximumRegions',
6276
5000, 10, 65000, // limit must be less than foldingRanges MAX_FOLDING_REGIONS
6277
{ description: nls.localize('foldingMaximumRegions', "The maximum number of foldable regions. Increasing this value may result in the editor becoming less responsive when the current source has a large number of foldable regions.") }
6278
)),
6279
unfoldOnClickAfterEndOfLine: register(new EditorBooleanOption(
6280
EditorOption.unfoldOnClickAfterEndOfLine, 'unfoldOnClickAfterEndOfLine', false,
6281
{ description: nls.localize('unfoldOnClickAfterEndOfLine', "Controls whether clicking on the empty content after a folded line will unfold the line.") }
6282
)),
6283
fontFamily: register(new EditorStringOption(
6284
EditorOption.fontFamily, 'fontFamily', EDITOR_FONT_DEFAULTS.fontFamily,
6285
{ description: nls.localize('fontFamily', "Controls the font family.") }
6286
)),
6287
fontInfo: register(new EditorFontInfo()),
6288
fontLigatures2: register(new EditorFontLigatures()),
6289
fontSize: register(new EditorFontSize()),
6290
fontWeight: register(new EditorFontWeight()),
6291
fontVariations: register(new EditorFontVariations()),
6292
formatOnPaste: register(new EditorBooleanOption(
6293
EditorOption.formatOnPaste, 'formatOnPaste', false,
6294
{ 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.") }
6295
)),
6296
formatOnType: register(new EditorBooleanOption(
6297
EditorOption.formatOnType, 'formatOnType', false,
6298
{ description: nls.localize('formatOnType', "Controls whether the editor should automatically format the line after typing.") }
6299
)),
6300
glyphMargin: register(new EditorBooleanOption(
6301
EditorOption.glyphMargin, 'glyphMargin', true,
6302
{ description: nls.localize('glyphMargin', "Controls whether the editor should render the vertical glyph margin. Glyph margin is mostly used for debugging.") }
6303
)),
6304
gotoLocation: register(new EditorGoToLocation()),
6305
hideCursorInOverviewRuler: register(new EditorBooleanOption(
6306
EditorOption.hideCursorInOverviewRuler, 'hideCursorInOverviewRuler', false,
6307
{ description: nls.localize('hideCursorInOverviewRuler', "Controls whether the cursor should be hidden in the overview ruler.") }
6308
)),
6309
hover: register(new EditorHover()),
6310
inDiffEditor: register(new EditorBooleanOption(
6311
EditorOption.inDiffEditor, 'inDiffEditor', false
6312
)),
6313
inertialScroll: register(new EditorBooleanOption(
6314
EditorOption.inertialScroll, 'inertialScroll', false,
6315
{ description: nls.localize('inertialScroll', "Make scrolling inertial - mostly useful with touchpad on linux.") }
6316
)),
6317
letterSpacing: register(new EditorFloatOption(
6318
EditorOption.letterSpacing, 'letterSpacing',
6319
EDITOR_FONT_DEFAULTS.letterSpacing, x => EditorFloatOption.clamp(x, -5, 20),
6320
{ description: nls.localize('letterSpacing', "Controls the letter spacing in pixels.") }
6321
)),
6322
lightbulb: register(new EditorLightbulb()),
6323
lineDecorationsWidth: register(new EditorLineDecorationsWidth()),
6324
lineHeight: register(new EditorLineHeight()),
6325
lineNumbers: register(new EditorRenderLineNumbersOption()),
6326
lineNumbersMinChars: register(new EditorIntOption(
6327
EditorOption.lineNumbersMinChars, 'lineNumbersMinChars',
6328
5, 1, 300
6329
)),
6330
linkedEditing: register(new EditorBooleanOption(
6331
EditorOption.linkedEditing, 'linkedEditing', false,
6332
{ description: nls.localize('linkedEditing', "Controls whether the editor has linked editing enabled. Depending on the language, related symbols such as HTML tags, are updated while editing.") }
6333
)),
6334
links: register(new EditorBooleanOption(
6335
EditorOption.links, 'links', true,
6336
{ description: nls.localize('links', "Controls whether the editor should detect links and make them clickable.") }
6337
)),
6338
matchBrackets: register(new EditorStringEnumOption(
6339
EditorOption.matchBrackets, 'matchBrackets',
6340
'always' as 'never' | 'near' | 'always',
6341
['always', 'near', 'never'] as const,
6342
{ description: nls.localize('matchBrackets', "Highlight matching brackets.") }
6343
)),
6344
minimap: register(new EditorMinimap()),
6345
mouseStyle: register(new EditorStringEnumOption(
6346
EditorOption.mouseStyle, 'mouseStyle',
6347
'text' as 'text' | 'default' | 'copy',
6348
['text', 'default', 'copy'] as const,
6349
)),
6350
mouseWheelScrollSensitivity: register(new EditorFloatOption(
6351
EditorOption.mouseWheelScrollSensitivity, 'mouseWheelScrollSensitivity',
6352
1, x => (x === 0 ? 1 : x),
6353
{ markdownDescription: nls.localize('mouseWheelScrollSensitivity', "A multiplier to be used on the `deltaX` and `deltaY` of mouse wheel scroll events.") }
6354
)),
6355
mouseWheelZoom: register(new EditorBooleanOption(
6356
EditorOption.mouseWheelZoom, 'mouseWheelZoom', false,
6357
{
6358
markdownDescription: platform.isMacintosh
6359
? nls.localize('mouseWheelZoom.mac', "Zoom the font of the editor when using mouse wheel and holding `Cmd`.")
6360
: nls.localize('mouseWheelZoom', "Zoom the font of the editor when using mouse wheel and holding `Ctrl`.")
6361
}
6362
)),
6363
multiCursorMergeOverlapping: register(new EditorBooleanOption(
6364
EditorOption.multiCursorMergeOverlapping, 'multiCursorMergeOverlapping', true,
6365
{ description: nls.localize('multiCursorMergeOverlapping', "Merge multiple cursors when they are overlapping.") }
6366
)),
6367
multiCursorModifier: register(new EditorEnumOption(
6368
EditorOption.multiCursorModifier, 'multiCursorModifier',
6369
'altKey', 'alt',
6370
['ctrlCmd', 'alt'],
6371
_multiCursorModifierFromString,
6372
{
6373
markdownEnumDescriptions: [
6374
nls.localize('multiCursorModifier.ctrlCmd', "Maps to `Control` on Windows and Linux and to `Command` on macOS."),
6375
nls.localize('multiCursorModifier.alt', "Maps to `Alt` on Windows and Linux and to `Option` on macOS.")
6376
],
6377
markdownDescription: nls.localize({
6378
key: 'multiCursorModifier',
6379
comment: [
6380
'- `ctrlCmd` refers to a value the setting can take and should not be localized.',
6381
'- `Control` and `Command` refer to the modifier keys Ctrl or Cmd on the keyboard and can be localized.'
6382
]
6383
}, "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](https://code.visualstudio.com/docs/editor/codebasics#_multicursor-modifier).")
6384
}
6385
)),
6386
mouseMiddleClickAction: register(new EditorStringEnumOption(
6387
EditorOption.mouseMiddleClickAction, 'mouseMiddleClickAction', 'default' as MouseMiddleClickAction,
6388
['default', 'openLink', 'ctrlLeftClick'] as MouseMiddleClickAction[],
6389
{ description: nls.localize('mouseMiddleClickAction', "Controls what happens when middle mouse button is clicked in the editor.") }
6390
)),
6391
multiCursorPaste: register(new EditorStringEnumOption(
6392
EditorOption.multiCursorPaste, 'multiCursorPaste',
6393
'spread' as 'spread' | 'full',
6394
['spread', 'full'] as const,
6395
{
6396
markdownEnumDescriptions: [
6397
nls.localize('multiCursorPaste.spread', "Each cursor pastes a single line of the text."),
6398
nls.localize('multiCursorPaste.full', "Each cursor pastes the full text.")
6399
],
6400
markdownDescription: nls.localize('multiCursorPaste', "Controls pasting when the line count of the pasted text matches the cursor count.")
6401
}
6402
)),
6403
multiCursorLimit: register(new EditorIntOption(
6404
EditorOption.multiCursorLimit, 'multiCursorLimit', 10000, 1, 100000,
6405
{
6406
markdownDescription: nls.localize('multiCursorLimit', "Controls the max number of cursors that can be in an active editor at once.")
6407
}
6408
)),
6409
occurrencesHighlight: register(new EditorStringEnumOption(
6410
EditorOption.occurrencesHighlight, 'occurrencesHighlight',
6411
'singleFile' as 'off' | 'singleFile' | 'multiFile',
6412
['off', 'singleFile', 'multiFile'] as const,
6413
{
6414
markdownEnumDescriptions: [
6415
nls.localize('occurrencesHighlight.off', "Does not highlight occurrences."),
6416
nls.localize('occurrencesHighlight.singleFile', "Highlights occurrences only in the current file."),
6417
nls.localize('occurrencesHighlight.multiFile', "Experimental: Highlights occurrences across all valid open files.")
6418
],
6419
markdownDescription: nls.localize('occurrencesHighlight', "Controls whether occurrences should be highlighted across open files.")
6420
}
6421
)),
6422
occurrencesHighlightDelay: register(new EditorIntOption(
6423
EditorOption.occurrencesHighlightDelay, 'occurrencesHighlightDelay',
6424
0, 0, 2000,
6425
{
6426
description: nls.localize('occurrencesHighlightDelay', "Controls the delay in milliseconds after which occurrences are highlighted."),
6427
tags: ['preview']
6428
}
6429
)),
6430
overtypeOnPaste: register(new EditorBooleanOption(
6431
EditorOption.overtypeOnPaste, 'overtypeOnPaste', true,
6432
{ description: nls.localize('overtypeOnPaste', "Controls whether pasting should overtype.") }
6433
)),
6434
overviewRulerBorder: register(new EditorBooleanOption(
6435
EditorOption.overviewRulerBorder, 'overviewRulerBorder', true,
6436
{ description: nls.localize('overviewRulerBorder', "Controls whether a border should be drawn around the overview ruler.") }
6437
)),
6438
overviewRulerLanes: register(new EditorIntOption(
6439
EditorOption.overviewRulerLanes, 'overviewRulerLanes',
6440
3, 0, 3
6441
)),
6442
padding: register(new EditorPadding()),
6443
pasteAs: register(new EditorPasteAs()),
6444
parameterHints: register(new EditorParameterHints()),
6445
peekWidgetDefaultFocus: register(new EditorStringEnumOption(
6446
EditorOption.peekWidgetDefaultFocus, 'peekWidgetDefaultFocus',
6447
'tree' as 'tree' | 'editor',
6448
['tree', 'editor'] as const,
6449
{
6450
enumDescriptions: [
6451
nls.localize('peekWidgetDefaultFocus.tree', "Focus the tree when opening peek"),
6452
nls.localize('peekWidgetDefaultFocus.editor', "Focus the editor when opening peek")
6453
],
6454
description: nls.localize('peekWidgetDefaultFocus', "Controls whether to focus the inline editor or the tree in the peek widget.")
6455
}
6456
)),
6457
placeholder: register(new PlaceholderOption()),
6458
definitionLinkOpensInPeek: register(new EditorBooleanOption(
6459
EditorOption.definitionLinkOpensInPeek, 'definitionLinkOpensInPeek', false,
6460
{ description: nls.localize('definitionLinkOpensInPeek', "Controls whether the Go to Definition mouse gesture always opens the peek widget.") }
6461
)),
6462
quickSuggestions: register(new EditorQuickSuggestions()),
6463
quickSuggestionsDelay: register(new EditorIntOption(
6464
EditorOption.quickSuggestionsDelay, 'quickSuggestionsDelay',
6465
10, 0, Constants.MAX_SAFE_SMALL_INTEGER,
6466
{
6467
description: nls.localize('quickSuggestionsDelay', "Controls the delay in milliseconds after which quick suggestions will show up."),
6468
experiment: {
6469
mode: 'auto'
6470
}
6471
}
6472
)),
6473
readOnly: register(new EditorBooleanOption(
6474
EditorOption.readOnly, 'readOnly', false,
6475
)),
6476
readOnlyMessage: register(new ReadonlyMessage()),
6477
renameOnType: register(new EditorBooleanOption(
6478
EditorOption.renameOnType, 'renameOnType', false,
6479
{ description: nls.localize('renameOnType', "Controls whether the editor auto renames on type."), markdownDeprecationMessage: nls.localize('renameOnTypeDeprecate', "Deprecated, use `#editor.linkedEditing#` instead.") }
6480
)),
6481
renderControlCharacters: register(new EditorBooleanOption(
6482
EditorOption.renderControlCharacters, 'renderControlCharacters', true,
6483
{ description: nls.localize('renderControlCharacters', "Controls whether the editor should render control characters."), restricted: true }
6484
)),
6485
renderFinalNewline: register(new EditorStringEnumOption(
6486
EditorOption.renderFinalNewline, 'renderFinalNewline',
6487
(platform.isLinux ? 'dimmed' : 'on') as 'off' | 'on' | 'dimmed',
6488
['off', 'on', 'dimmed'] as const,
6489
{ description: nls.localize('renderFinalNewline', "Render last line number when the file ends with a newline.") }
6490
)),
6491
renderLineHighlight: register(new EditorStringEnumOption(
6492
EditorOption.renderLineHighlight, 'renderLineHighlight',
6493
'line' as 'none' | 'gutter' | 'line' | 'all',
6494
['none', 'gutter', 'line', 'all'] as const,
6495
{
6496
enumDescriptions: [
6497
'',
6498
'',
6499
'',
6500
nls.localize('renderLineHighlight.all', "Highlights both the gutter and the current line."),
6501
],
6502
description: nls.localize('renderLineHighlight', "Controls how the editor should render the current line highlight.")
6503
}
6504
)),
6505
renderLineHighlightOnlyWhenFocus: register(new EditorBooleanOption(
6506
EditorOption.renderLineHighlightOnlyWhenFocus, 'renderLineHighlightOnlyWhenFocus', false,
6507
{ description: nls.localize('renderLineHighlightOnlyWhenFocus', "Controls if the editor should render the current line highlight only when the editor is focused.") }
6508
)),
6509
renderValidationDecorations: register(new EditorStringEnumOption(
6510
EditorOption.renderValidationDecorations, 'renderValidationDecorations',
6511
'editable' as 'editable' | 'on' | 'off',
6512
['editable', 'on', 'off'] as const
6513
)),
6514
renderWhitespace: register(new EditorStringEnumOption(
6515
EditorOption.renderWhitespace, 'renderWhitespace',
6516
'selection' as 'selection' | 'none' | 'boundary' | 'trailing' | 'all',
6517
['none', 'boundary', 'selection', 'trailing', 'all'] as const,
6518
{
6519
enumDescriptions: [
6520
'',
6521
nls.localize('renderWhitespace.boundary', "Render whitespace characters except for single spaces between words."),
6522
nls.localize('renderWhitespace.selection', "Render whitespace characters only on selected text."),
6523
nls.localize('renderWhitespace.trailing', "Render only trailing whitespace characters."),
6524
''
6525
],
6526
description: nls.localize('renderWhitespace', "Controls how the editor should render whitespace characters.")
6527
}
6528
)),
6529
revealHorizontalRightPadding: register(new EditorIntOption(
6530
EditorOption.revealHorizontalRightPadding, 'revealHorizontalRightPadding',
6531
15, 0, 1000,
6532
)),
6533
roundedSelection: register(new EditorBooleanOption(
6534
EditorOption.roundedSelection, 'roundedSelection', true,
6535
{ description: nls.localize('roundedSelection', "Controls whether selections should have rounded corners.") }
6536
)),
6537
rulers: register(new EditorRulers()),
6538
scrollbar: register(new EditorScrollbar()),
6539
scrollBeyondLastColumn: register(new EditorIntOption(
6540
EditorOption.scrollBeyondLastColumn, 'scrollBeyondLastColumn',
6541
4, 0, Constants.MAX_SAFE_SMALL_INTEGER,
6542
{ description: nls.localize('scrollBeyondLastColumn', "Controls the number of extra characters beyond which the editor will scroll horizontally.") }
6543
)),
6544
scrollBeyondLastLine: register(new EditorBooleanOption(
6545
EditorOption.scrollBeyondLastLine, 'scrollBeyondLastLine', true,
6546
{ description: nls.localize('scrollBeyondLastLine', "Controls whether the editor will scroll beyond the last line.") }
6547
)),
6548
scrollOnMiddleClick: register(new EditorBooleanOption(
6549
EditorOption.scrollOnMiddleClick, 'scrollOnMiddleClick', false,
6550
{ description: nls.localize('scrollOnMiddleClick', "Controls whether the editor will scroll when the middle button is pressed.") }
6551
)),
6552
scrollPredominantAxis: register(new EditorBooleanOption(
6553
EditorOption.scrollPredominantAxis, 'scrollPredominantAxis', true,
6554
{ description: nls.localize('scrollPredominantAxis', "Scroll only along the predominant axis when scrolling both vertically and horizontally at the same time. Prevents horizontal drift when scrolling vertically on a trackpad.") }
6555
)),
6556
selectionClipboard: register(new EditorBooleanOption(
6557
EditorOption.selectionClipboard, 'selectionClipboard', true,
6558
{
6559
description: nls.localize('selectionClipboard', "Controls whether the Linux primary clipboard should be supported."),
6560
included: platform.isLinux
6561
}
6562
)),
6563
selectionHighlight: register(new EditorBooleanOption(
6564
EditorOption.selectionHighlight, 'selectionHighlight', true,
6565
{ description: nls.localize('selectionHighlight', "Controls whether the editor should highlight matches similar to the selection.") }
6566
)),
6567
selectionHighlightMaxLength: register(new EditorIntOption(
6568
EditorOption.selectionHighlightMaxLength, 'selectionHighlightMaxLength',
6569
200, 0, Constants.MAX_SAFE_SMALL_INTEGER,
6570
{ description: nls.localize('selectionHighlightMaxLength', "Controls how many characters can be in the selection before similiar matches are not highlighted. Set to zero for unlimited.") }
6571
)),
6572
selectionHighlightMultiline: register(new EditorBooleanOption(
6573
EditorOption.selectionHighlightMultiline, 'selectionHighlightMultiline', false,
6574
{ description: nls.localize('selectionHighlightMultiline', "Controls whether the editor should highlight selection matches that span multiple lines.") }
6575
)),
6576
selectOnLineNumbers: register(new EditorBooleanOption(
6577
EditorOption.selectOnLineNumbers, 'selectOnLineNumbers', true,
6578
)),
6579
showFoldingControls: register(new EditorStringEnumOption(
6580
EditorOption.showFoldingControls, 'showFoldingControls',
6581
'mouseover' as 'always' | 'never' | 'mouseover',
6582
['always', 'never', 'mouseover'] as const,
6583
{
6584
enumDescriptions: [
6585
nls.localize('showFoldingControls.always', "Always show the folding controls."),
6586
nls.localize('showFoldingControls.never', "Never show the folding controls and reduce the gutter size."),
6587
nls.localize('showFoldingControls.mouseover', "Only show the folding controls when the mouse is over the gutter."),
6588
],
6589
description: nls.localize('showFoldingControls', "Controls when the folding controls on the gutter are shown.")
6590
}
6591
)),
6592
showUnused: register(new EditorBooleanOption(
6593
EditorOption.showUnused, 'showUnused', true,
6594
{ description: nls.localize('showUnused', "Controls fading out of unused code.") }
6595
)),
6596
showDeprecated: register(new EditorBooleanOption(
6597
EditorOption.showDeprecated, 'showDeprecated', true,
6598
{ description: nls.localize('showDeprecated', "Controls strikethrough deprecated variables.") }
6599
)),
6600
inlayHints: register(new EditorInlayHints()),
6601
snippetSuggestions: register(new EditorStringEnumOption(
6602
EditorOption.snippetSuggestions, 'snippetSuggestions',
6603
'inline' as 'top' | 'bottom' | 'inline' | 'none',
6604
['top', 'bottom', 'inline', 'none'] as const,
6605
{
6606
enumDescriptions: [
6607
nls.localize('snippetSuggestions.top', "Show snippet suggestions on top of other suggestions."),
6608
nls.localize('snippetSuggestions.bottom', "Show snippet suggestions below other suggestions."),
6609
nls.localize('snippetSuggestions.inline', "Show snippets suggestions with other suggestions."),
6610
nls.localize('snippetSuggestions.none', "Do not show snippet suggestions."),
6611
],
6612
description: nls.localize('snippetSuggestions', "Controls whether snippets are shown with other suggestions and how they are sorted.")
6613
}
6614
)),
6615
smartSelect: register(new SmartSelect()),
6616
smoothScrolling: register(new EditorBooleanOption(
6617
EditorOption.smoothScrolling, 'smoothScrolling', false,
6618
{ description: nls.localize('smoothScrolling', "Controls whether the editor will scroll using an animation.") }
6619
)),
6620
stopRenderingLineAfter: register(new EditorIntOption(
6621
EditorOption.stopRenderingLineAfter, 'stopRenderingLineAfter',
6622
10000, -1, Constants.MAX_SAFE_SMALL_INTEGER,
6623
)),
6624
suggest: register(new EditorSuggest()),
6625
inlineSuggest: register(new InlineEditorSuggest()),
6626
inlineCompletionsAccessibilityVerbose: register(new EditorBooleanOption(EditorOption.inlineCompletionsAccessibilityVerbose, 'inlineCompletionsAccessibilityVerbose', false,
6627
{ description: nls.localize('inlineCompletionsAccessibilityVerbose', "Controls whether the accessibility hint should be provided to screen reader users when an inline completion is shown.") })),
6628
suggestFontSize: register(new EditorIntOption(
6629
EditorOption.suggestFontSize, 'suggestFontSize',
6630
0, 0, 1000,
6631
{ markdownDescription: nls.localize('suggestFontSize', "Font size for the suggest widget. When set to {0}, the value of {1} is used.", '`0`', '`#editor.fontSize#`') }
6632
)),
6633
suggestLineHeight: register(new EditorIntOption(
6634
EditorOption.suggestLineHeight, 'suggestLineHeight',
6635
0, 0, 1000,
6636
{ markdownDescription: nls.localize('suggestLineHeight', "Line height for the suggest widget. When set to {0}, the value of {1} is used. The minimum value is 8.", '`0`', '`#editor.lineHeight#`') }
6637
)),
6638
suggestOnTriggerCharacters: register(new EditorBooleanOption(
6639
EditorOption.suggestOnTriggerCharacters, 'suggestOnTriggerCharacters', true,
6640
{ description: nls.localize('suggestOnTriggerCharacters', "Controls whether suggestions should automatically show up when typing trigger characters.") }
6641
)),
6642
suggestSelection: register(new EditorStringEnumOption(
6643
EditorOption.suggestSelection, 'suggestSelection',
6644
'first' as 'first' | 'recentlyUsed' | 'recentlyUsedByPrefix',
6645
['first', 'recentlyUsed', 'recentlyUsedByPrefix'] as const,
6646
{
6647
markdownEnumDescriptions: [
6648
nls.localize('suggestSelection.first', "Always select the first suggestion."),
6649
nls.localize('suggestSelection.recentlyUsed', "Select recent suggestions unless further typing selects one, e.g. `console.| -> console.log` because `log` has been completed recently."),
6650
nls.localize('suggestSelection.recentlyUsedByPrefix', "Select suggestions based on previous prefixes that have completed those suggestions, e.g. `co -> console` and `con -> const`."),
6651
],
6652
description: nls.localize('suggestSelection', "Controls how suggestions are pre-selected when showing the suggest list.")
6653
}
6654
)),
6655
tabCompletion: register(new EditorStringEnumOption(
6656
EditorOption.tabCompletion, 'tabCompletion',
6657
'off' as 'on' | 'off' | 'onlySnippets',
6658
['on', 'off', 'onlySnippets'] as const,
6659
{
6660
enumDescriptions: [
6661
nls.localize('tabCompletion.on', "Tab complete will insert the best matching suggestion when pressing tab."),
6662
nls.localize('tabCompletion.off', "Disable tab completions."),
6663
nls.localize('tabCompletion.onlySnippets', "Tab complete snippets when their prefix match. Works best when 'quickSuggestions' aren't enabled."),
6664
],
6665
description: nls.localize('tabCompletion', "Enables tab completions.")
6666
}
6667
)),
6668
tabIndex: register(new EditorIntOption(
6669
EditorOption.tabIndex, 'tabIndex',
6670
0, -1, Constants.MAX_SAFE_SMALL_INTEGER
6671
)),
6672
trimWhitespaceOnDelete: register(new EditorBooleanOption(
6673
EditorOption.trimWhitespaceOnDelete, 'trimWhitespaceOnDelete', false,
6674
{ description: nls.localize('trimWhitespaceOnDelete', "Controls whether the editor will also delete the next line's indentation whitespace when deleting a newline.") }
6675
)),
6676
unicodeHighlight: register(new UnicodeHighlight()),
6677
unusualLineTerminators: register(new EditorStringEnumOption(
6678
EditorOption.unusualLineTerminators, 'unusualLineTerminators',
6679
'prompt' as 'auto' | 'off' | 'prompt',
6680
['auto', 'off', 'prompt'] as const,
6681
{
6682
enumDescriptions: [
6683
nls.localize('unusualLineTerminators.auto', "Unusual line terminators are automatically removed."),
6684
nls.localize('unusualLineTerminators.off', "Unusual line terminators are ignored."),
6685
nls.localize('unusualLineTerminators.prompt', "Unusual line terminators prompt to be removed."),
6686
],
6687
description: nls.localize('unusualLineTerminators', "Remove unusual line terminators that might cause problems.")
6688
}
6689
)),
6690
useShadowDOM: register(new EditorBooleanOption(
6691
EditorOption.useShadowDOM, 'useShadowDOM', true
6692
)),
6693
useTabStops: register(new EditorBooleanOption(
6694
EditorOption.useTabStops, 'useTabStops', true,
6695
{ description: nls.localize('useTabStops', "Spaces and tabs are inserted and deleted in alignment with tab stops.") }
6696
)),
6697
wordBreak: register(new EditorStringEnumOption(
6698
EditorOption.wordBreak, 'wordBreak',
6699
'normal' as 'normal' | 'keepAll',
6700
['normal', 'keepAll'] as const,
6701
{
6702
markdownEnumDescriptions: [
6703
nls.localize('wordBreak.normal', "Use the default line break rule."),
6704
nls.localize('wordBreak.keepAll', "Word breaks should not be used for Chinese/Japanese/Korean (CJK) text. Non-CJK text behavior is the same as for normal."),
6705
],
6706
description: nls.localize('wordBreak', "Controls the word break rules used for Chinese/Japanese/Korean (CJK) text.")
6707
}
6708
)),
6709
wordSegmenterLocales: register(new WordSegmenterLocales()),
6710
wordSeparators: register(new EditorStringOption(
6711
EditorOption.wordSeparators, 'wordSeparators', USUAL_WORD_SEPARATORS,
6712
{ description: nls.localize('wordSeparators', "Characters that will be used as word separators when doing word related navigations or operations.") }
6713
)),
6714
wordWrap: register(new EditorStringEnumOption(
6715
EditorOption.wordWrap, 'wordWrap',
6716
'off' as 'off' | 'on' | 'wordWrapColumn' | 'bounded',
6717
['off', 'on', 'wordWrapColumn', 'bounded'] as const,
6718
{
6719
markdownEnumDescriptions: [
6720
nls.localize('wordWrap.off', "Lines will never wrap."),
6721
nls.localize('wordWrap.on', "Lines will wrap at the viewport width."),
6722
nls.localize({
6723
key: 'wordWrap.wordWrapColumn',
6724
comment: [
6725
'- `editor.wordWrapColumn` refers to a different setting and should not be localized.'
6726
]
6727
}, "Lines will wrap at `#editor.wordWrapColumn#`."),
6728
nls.localize({
6729
key: 'wordWrap.bounded',
6730
comment: [
6731
'- viewport means the edge of the visible window size.',
6732
'- `editor.wordWrapColumn` refers to a different setting and should not be localized.'
6733
]
6734
}, "Lines will wrap at the minimum of viewport and `#editor.wordWrapColumn#`."),
6735
],
6736
description: nls.localize({
6737
key: 'wordWrap',
6738
comment: [
6739
'- \'off\', \'on\', \'wordWrapColumn\' and \'bounded\' refer to values the setting can take and should not be localized.',
6740
'- `editor.wordWrapColumn` refers to a different setting and should not be localized.'
6741
]
6742
}, "Controls how lines should wrap.")
6743
}
6744
)),
6745
wordWrapBreakAfterCharacters: register(new EditorStringOption(
6746
EditorOption.wordWrapBreakAfterCharacters, 'wordWrapBreakAfterCharacters',
6747
// allow-any-unicode-next-line
6748
' \t})]?|/&.,;¢°′″‰℃、。。、¢,.:;?!%・・ゝゞヽヾーァィゥェォッャュョヮヵヶぁぃぅぇぉっゃゅょゎゕゖㇰㇱㇲㇳㇴㇵㇶㇷㇸㇹㇺㇻㇼㇽㇾㇿ々〻ァィゥェォャュョッー”〉》」』】〕)]}」',
6749
)),
6750
wordWrapBreakBeforeCharacters: register(new EditorStringOption(
6751
EditorOption.wordWrapBreakBeforeCharacters, 'wordWrapBreakBeforeCharacters',
6752
// allow-any-unicode-next-line
6753
'([{‘“〈《「『【〔([{「£¥$£¥++'
6754
)),
6755
wordWrapColumn: register(new EditorIntOption(
6756
EditorOption.wordWrapColumn, 'wordWrapColumn',
6757
80, 1, Constants.MAX_SAFE_SMALL_INTEGER,
6758
{
6759
markdownDescription: nls.localize({
6760
key: 'wordWrapColumn',
6761
comment: [
6762
'- `editor.wordWrap` refers to a different setting and should not be localized.',
6763
'- \'wordWrapColumn\' and \'bounded\' refer to values the different setting can take and should not be localized.'
6764
]
6765
}, "Controls the wrapping column of the editor when `#editor.wordWrap#` is `wordWrapColumn` or `bounded`.")
6766
}
6767
)),
6768
wordWrapOverride1: register(new EditorStringEnumOption(
6769
EditorOption.wordWrapOverride1, 'wordWrapOverride1',
6770
'inherit' as 'off' | 'on' | 'inherit',
6771
['off', 'on', 'inherit'] as const
6772
)),
6773
wordWrapOverride2: register(new EditorStringEnumOption(
6774
EditorOption.wordWrapOverride2, 'wordWrapOverride2',
6775
'inherit' as 'off' | 'on' | 'inherit',
6776
['off', 'on', 'inherit'] as const
6777
)),
6778
wrapOnEscapedLineFeeds: register(new EditorBooleanOption(
6779
EditorOption.wrapOnEscapedLineFeeds, 'wrapOnEscapedLineFeeds', false,
6780
{ markdownDescription: nls.localize('wrapOnEscapedLineFeeds', "Controls whether literal `\\n` shall trigger a wordWrap when `#editor.wordWrap#` is enabled.\n\nFor example:\n```c\nchar* str=\"hello\\nworld\"\n```\nwill be displayed as\n```c\nchar* str=\"hello\\n\n world\"\n```") }
6781
)),
6782
6783
// Leave these at the end (because they have dependencies!)
6784
effectiveCursorStyle: register(new EffectiveCursorStyle()),
6785
editorClassName: register(new EditorClassName()),
6786
defaultColorDecorators: register(new EditorStringEnumOption(
6787
EditorOption.defaultColorDecorators, 'defaultColorDecorators', 'auto' as 'auto' | 'always' | 'never',
6788
['auto', 'always', 'never'] as const,
6789
{
6790
enumDescriptions: [
6791
nls.localize('editor.defaultColorDecorators.auto', "Show default color decorators only when no extension provides colors decorators."),
6792
nls.localize('editor.defaultColorDecorators.always', "Always show default color decorators."),
6793
nls.localize('editor.defaultColorDecorators.never', "Never show default color decorators."),
6794
],
6795
description: nls.localize('defaultColorDecorators', "Controls whether inline color decorations should be shown using the default document color provider.")
6796
}
6797
)),
6798
pixelRatio: register(new EditorPixelRatio()),
6799
tabFocusMode: register(new EditorBooleanOption(EditorOption.tabFocusMode, 'tabFocusMode', false,
6800
{ markdownDescription: nls.localize('tabFocusMode', "Controls whether the editor receives tabs or defers them to the workbench for navigation.") }
6801
)),
6802
layoutInfo: register(new EditorLayoutInfoComputer()),
6803
wrappingInfo: register(new EditorWrappingInfoComputer()),
6804
wrappingIndent: register(new WrappingIndentOption()),
6805
wrappingStrategy: register(new WrappingStrategy()),
6806
effectiveEditContextEnabled: register(new EffectiveEditContextEnabled()),
6807
effectiveAllowVariableFonts: register(new EffectiveAllowVariableFonts())
6808
};
6809
6810
type EditorOptionsType = typeof EditorOptions;
6811
type FindEditorOptionsKeyById<T extends EditorOption> = { [K in keyof EditorOptionsType]: EditorOptionsType[K]['id'] extends T ? K : never }[keyof EditorOptionsType];
6812
// eslint-disable-next-line @typescript-eslint/no-explicit-any
6813
type ComputedEditorOptionValue<T extends IEditorOption<any, any>> = T extends IEditorOption<any, infer R> ? R : never;
6814
export type FindComputedEditorOptionValueById<T extends EditorOption> = NonNullable<ComputedEditorOptionValue<EditorOptionsType[FindEditorOptionsKeyById<T>]>>;
6815
6816
export type MouseMiddleClickAction = 'default' | 'openLink' | 'ctrlLeftClick';
6817
6818