Merge from vscode 8a997f7321ae6612fc0e6eb3eac4f358a6233bfb

This commit is contained in:
ADS Merger
2020-02-11 07:08:19 +00:00
parent 0f934081e1
commit 085752f111
217 changed files with 2561 additions and 2063 deletions

View File

@@ -366,6 +366,10 @@ export interface IEditorOptions {
* Defaults to 10 (ms)
*/
quickSuggestionsDelay?: number;
/**
* Controls the spacing around the editor.
*/
padding?: IEditorPaddingOptions;
/**
* Parameter hint options.
*/
@@ -2082,6 +2086,65 @@ function _multiCursorModifierFromString(multiCursorModifier: 'ctrlCmd' | 'alt'):
//#endregion
//#region padding
/**
* Configuration options for editor padding
*/
export interface IEditorPaddingOptions {
/**
* Spacing between top edge of editor and first line.
*/
top?: number;
/**
* Spacing between bottom edge of editor and last line.
*/
bottom?: number;
}
export interface InternalEditorPaddingOptions {
readonly top: number;
readonly bottom: number;
}
class EditorPadding extends BaseEditorOption<EditorOption.padding, InternalEditorPaddingOptions> {
constructor() {
super(
EditorOption.padding, 'padding', { top: 0, bottom: 0 },
{
'editor.padding.top': {
type: 'number',
default: 0,
minimum: 0,
maximum: 1000,
description: nls.localize('padding.top', "Controls the amount of space between the top edge of the editor and the first line.")
},
'editor.padding.bottom': {
type: 'number',
default: 0,
minimum: 0,
maximum: 1000,
description: nls.localize('padding.bottom', "Controls the amount of space between the bottom edge of the editor and the last line.")
}
}
);
}
public validate(_input: any): InternalEditorPaddingOptions {
if (typeof _input !== 'object') {
return this.defaultValue;
}
const input = _input as IEditorPaddingOptions;
return {
top: EditorIntOption.clampedInt(input.top, 0, 0, 1000),
bottom: EditorIntOption.clampedInt(input.bottom, 0, 0, 1000)
};
}
}
//#endregion
//#region parameterHints
/**
@@ -3188,6 +3251,7 @@ export const enum EditorOption {
occurrencesHighlight,
overviewRulerBorder,
overviewRulerLanes,
padding,
parameterHints,
peekWidgetDefaultFocus,
definitionLinkOpensInPeek,
@@ -3575,6 +3639,7 @@ export const EditorOptions = {
EditorOption.overviewRulerLanes, 'overviewRulerLanes',
3, 0, 3
)),
padding: register(new EditorPadding()),
parameterHints: register(new EditorParameterHints()),
peekWidgetDefaultFocus: register(new EditorStringEnumOption(
EditorOption.peekWidgetDefaultFocus, 'peekWidgetDefaultFocus',
@@ -3634,7 +3699,7 @@ export const EditorOptions = {
)),
renderWhitespace: register(new EditorStringEnumOption(
EditorOption.renderWhitespace, 'renderWhitespace',
'none' as 'none' | 'boundary' | 'selection' | 'all',
'selection' as 'selection' | 'none' | 'boundary' | 'all',
['none', 'boundary', 'selection', 'all'] as const,
{
enumDescriptions: [

View File

@@ -135,6 +135,7 @@ export class FontInfo extends BareFontInfo {
readonly canUseHalfwidthRightwardsArrow: boolean;
readonly spaceWidth: number;
readonly middotWidth: number;
readonly wsmiddotWidth: number;
readonly maxDigitWidth: number;
/**
@@ -154,6 +155,7 @@ export class FontInfo extends BareFontInfo {
canUseHalfwidthRightwardsArrow: boolean;
spaceWidth: number;
middotWidth: number;
wsmiddotWidth: number;
maxDigitWidth: number;
}, isTrusted: boolean) {
super(opts);
@@ -164,6 +166,7 @@ export class FontInfo extends BareFontInfo {
this.canUseHalfwidthRightwardsArrow = opts.canUseHalfwidthRightwardsArrow;
this.spaceWidth = opts.spaceWidth;
this.middotWidth = opts.middotWidth;
this.wsmiddotWidth = opts.wsmiddotWidth;
this.maxDigitWidth = opts.maxDigitWidth;
}
@@ -183,6 +186,7 @@ export class FontInfo extends BareFontInfo {
&& this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow
&& this.spaceWidth === other.spaceWidth
&& this.middotWidth === other.middotWidth
&& this.wsmiddotWidth === other.wsmiddotWidth
&& this.maxDigitWidth === other.maxDigitWidth
);
}

View File

@@ -61,6 +61,11 @@ export interface ITextEditorModel extends IEditorModel {
* Figure out if this model is resolved or not.
*/
isResolved(): this is IResolvedTextEditorModel;
/**
* The mode id of the text model if known.
*/
getMode(): string | undefined;
}
export interface IResolvedTextEditorModel extends ITextEditorModel {

View File

@@ -229,53 +229,54 @@ export enum EditorOption {
occurrencesHighlight = 61,
overviewRulerBorder = 62,
overviewRulerLanes = 63,
parameterHints = 64,
peekWidgetDefaultFocus = 65,
definitionLinkOpensInPeek = 66,
quickSuggestions = 67,
quickSuggestionsDelay = 68,
readOnly = 69,
renderControlCharacters = 70,
renderIndentGuides = 71,
renderFinalNewline = 72,
renderLineHighlight = 73,
renderValidationDecorations = 74,
renderWhitespace = 75,
revealHorizontalRightPadding = 76,
roundedSelection = 77,
rulers = 78,
scrollbar = 79,
scrollBeyondLastColumn = 80,
scrollBeyondLastLine = 81,
scrollPredominantAxis = 82,
selectionClipboard = 83,
selectionHighlight = 84,
selectOnLineNumbers = 85,
showFoldingControls = 86,
showUnused = 87,
snippetSuggestions = 88,
smoothScrolling = 89,
stopRenderingLineAfter = 90,
suggest = 91,
suggestFontSize = 92,
suggestLineHeight = 93,
suggestOnTriggerCharacters = 94,
suggestSelection = 95,
tabCompletion = 96,
useTabStops = 97,
wordSeparators = 98,
wordWrap = 99,
wordWrapBreakAfterCharacters = 100,
wordWrapBreakBeforeCharacters = 101,
wordWrapColumn = 102,
wordWrapMinified = 103,
wrappingIndent = 104,
wrappingStrategy = 105,
editorClassName = 106,
pixelRatio = 107,
tabFocusMode = 108,
layoutInfo = 109,
wrappingInfo = 110
padding = 64,
parameterHints = 65,
peekWidgetDefaultFocus = 66,
definitionLinkOpensInPeek = 67,
quickSuggestions = 68,
quickSuggestionsDelay = 69,
readOnly = 70,
renderControlCharacters = 71,
renderIndentGuides = 72,
renderFinalNewline = 73,
renderLineHighlight = 74,
renderValidationDecorations = 75,
renderWhitespace = 76,
revealHorizontalRightPadding = 77,
roundedSelection = 78,
rulers = 79,
scrollbar = 80,
scrollBeyondLastColumn = 81,
scrollBeyondLastLine = 82,
scrollPredominantAxis = 83,
selectionClipboard = 84,
selectionHighlight = 85,
selectOnLineNumbers = 86,
showFoldingControls = 87,
showUnused = 88,
snippetSuggestions = 89,
smoothScrolling = 90,
stopRenderingLineAfter = 91,
suggest = 92,
suggestFontSize = 93,
suggestLineHeight = 94,
suggestOnTriggerCharacters = 95,
suggestSelection = 96,
tabCompletion = 97,
useTabStops = 98,
wordSeparators = 99,
wordWrap = 100,
wordWrapBreakAfterCharacters = 101,
wordWrapBreakBeforeCharacters = 102,
wordWrapColumn = 103,
wordWrapMinified = 104,
wrappingIndent = 105,
wrappingStrategy = 106,
editorClassName = 107,
pixelRatio = 108,
tabFocusMode = 109,
layoutInfo = 110,
wrappingInfo = 111
}
/**

View File

@@ -111,8 +111,10 @@ export class LinesLayout {
private _minWidth: number;
private _lineCount: number;
private _lineHeight: number;
private _paddingTop: number;
private _paddingBottom: number;
constructor(lineCount: number, lineHeight: number) {
constructor(lineCount: number, lineHeight: number, paddingTop: number, paddingBottom: number) {
this._instanceId = strings.singleLetterHash(++LinesLayout.INSTANCE_COUNT);
this._pendingChanges = new PendingChanges();
this._lastWhitespaceId = 0;
@@ -121,6 +123,8 @@ export class LinesLayout {
this._minWidth = -1; /* marker for not being computed */
this._lineCount = lineCount;
this._lineHeight = lineHeight;
this._paddingTop = paddingTop;
this._paddingBottom = paddingBottom;
}
/**
@@ -158,6 +162,14 @@ export class LinesLayout {
this._lineHeight = lineHeight;
}
/**
* Changes the padding used to calculate vertical offsets.
*/
public setPadding(paddingTop: number, paddingBottom: number): void {
this._paddingTop = paddingTop;
this._paddingBottom = paddingBottom;
}
/**
* Set the number of lines.
*
@@ -404,7 +416,8 @@ export class LinesLayout {
this._checkPendingChanges();
const linesHeight = this._lineHeight * this._lineCount;
const whitespacesHeight = this.getWhitespacesTotalHeight();
return linesHeight + whitespacesHeight;
return linesHeight + whitespacesHeight + this._paddingTop + this._paddingBottom;
}
/**
@@ -495,7 +508,7 @@ export class LinesLayout {
const previousWhitespacesHeight = this.getWhitespaceAccumulatedHeightBeforeLineNumber(lineNumber);
return previousLinesHeight + previousWhitespacesHeight;
return previousLinesHeight + previousWhitespacesHeight + this._paddingTop;
}
/**
@@ -719,7 +732,7 @@ export class LinesLayout {
} else {
previousWhitespacesHeight = 0;
}
return previousLinesHeight + previousWhitespacesHeight;
return previousLinesHeight + previousWhitespacesHeight + this._paddingTop;
}
public getWhitespaceIndexAtOrAfterVerticallOffset(verticalOffset: number): number {

View File

@@ -161,8 +161,9 @@ export class ViewLayout extends Disposable implements IViewLayout {
this._configuration = configuration;
const options = this._configuration.options;
const layoutInfo = options.get(EditorOption.layoutInfo);
const padding = options.get(EditorOption.padding);
this._linesLayout = new LinesLayout(lineCount, options.get(EditorOption.lineHeight));
this._linesLayout = new LinesLayout(lineCount, options.get(EditorOption.lineHeight), padding.top, padding.bottom);
this._scrollable = this._register(new EditorScrollable(0, scheduleAtNextAnimationFrame));
this._configureSmoothScrollDuration();
@@ -202,6 +203,10 @@ export class ViewLayout extends Disposable implements IViewLayout {
if (e.hasChanged(EditorOption.lineHeight)) {
this._linesLayout.setLineHeight(options.get(EditorOption.lineHeight));
}
if (e.hasChanged(EditorOption.padding)) {
const padding = options.get(EditorOption.padding);
this._linesLayout.setPadding(padding.top, padding.bottom);
}
if (e.hasChanged(EditorOption.layoutInfo)) {
const layoutInfo = options.get(EditorOption.layoutInfo);
const width = layoutInfo.contentWidth;

View File

@@ -68,7 +68,8 @@ export class RenderLineInput {
public readonly tabSize: number;
public readonly startVisibleColumn: number;
public readonly spaceWidth: number;
public readonly middotWidth: number;
public readonly renderSpaceWidth: number;
public readonly renderSpaceCharCode: number;
public readonly stopRenderingLineAfter: number;
public readonly renderWhitespace: RenderWhitespace;
public readonly renderControlCharacters: boolean;
@@ -94,6 +95,7 @@ export class RenderLineInput {
startVisibleColumn: number,
spaceWidth: number,
middotWidth: number,
wsmiddotWidth: number,
stopRenderingLineAfter: number,
renderWhitespace: 'none' | 'boundary' | 'selection' | 'all',
renderControlCharacters: boolean,
@@ -112,7 +114,6 @@ export class RenderLineInput {
this.tabSize = tabSize;
this.startVisibleColumn = startVisibleColumn;
this.spaceWidth = spaceWidth;
this.middotWidth = middotWidth;
this.stopRenderingLineAfter = stopRenderingLineAfter;
this.renderWhitespace = (
renderWhitespace === 'all'
@@ -126,6 +127,16 @@ export class RenderLineInput {
this.renderControlCharacters = renderControlCharacters;
this.fontLigatures = fontLigatures;
this.selectionsOnLine = selectionsOnLine && selectionsOnLine.sort((a, b) => a.startOffset < b.startOffset ? -1 : 1);
const wsmiddotDiff = Math.abs(wsmiddotWidth - spaceWidth);
const middotDiff = Math.abs(middotWidth - spaceWidth);
if (wsmiddotDiff < middotDiff) {
this.renderSpaceWidth = wsmiddotWidth;
this.renderSpaceCharCode = 0x2E31; // U+2E31 - WORD SEPARATOR MIDDLE DOT
} else {
this.renderSpaceWidth = middotWidth;
this.renderSpaceCharCode = 0xB7; // U+00B7 - MIDDLE DOT
}
}
private sameSelection(otherSelections: LineRange[] | null): boolean {
@@ -162,6 +173,8 @@ export class RenderLineInput {
&& this.tabSize === other.tabSize
&& this.startVisibleColumn === other.startVisibleColumn
&& this.spaceWidth === other.spaceWidth
&& this.renderSpaceWidth === other.renderSpaceWidth
&& this.renderSpaceCharCode === other.renderSpaceCharCode
&& this.stopRenderingLineAfter === other.stopRenderingLineAfter
&& this.renderWhitespace === other.renderWhitespace
&& this.renderControlCharacters === other.renderControlCharacters
@@ -383,7 +396,7 @@ class ResolvedRenderLineInput {
public readonly startVisibleColumn: number,
public readonly containsRTL: boolean,
public readonly spaceWidth: number,
public readonly middotWidth: number,
public readonly renderSpaceCharCode: number,
public readonly renderWhitespace: RenderWhitespace,
public readonly renderControlCharacters: boolean,
) {
@@ -392,7 +405,6 @@ class ResolvedRenderLineInput {
}
function resolveRenderLineInput(input: RenderLineInput): ResolvedRenderLineInput {
const useMonospaceOptimizations = input.useMonospaceOptimizations;
const lineContent = input.lineContent;
let isOverflowing: boolean;
@@ -408,7 +420,7 @@ function resolveRenderLineInput(input: RenderLineInput): ResolvedRenderLineInput
let tokens = transformAndRemoveOverflowing(input.lineTokens, input.fauxIndentLength, len);
if (input.renderWhitespace === RenderWhitespace.All || input.renderWhitespace === RenderWhitespace.Boundary || (input.renderWhitespace === RenderWhitespace.Selection && !!input.selectionsOnLine)) {
tokens = _applyRenderWhitespace(lineContent, len, input.continuesWithWrappedLine, tokens, input.fauxIndentLength, input.tabSize, input.startVisibleColumn, useMonospaceOptimizations, input.selectionsOnLine, input.renderWhitespace === RenderWhitespace.Boundary);
tokens = _applyRenderWhitespace(input, lineContent, len, tokens);
}
let containsForeignElements = ForeignElementType.None;
if (input.lineDecorations.length > 0) {
@@ -431,7 +443,7 @@ function resolveRenderLineInput(input: RenderLineInput): ResolvedRenderLineInput
}
return new ResolvedRenderLineInput(
useMonospaceOptimizations,
input.useMonospaceOptimizations,
input.canUseHalfwidthRightwardsArrow,
lineContent,
len,
@@ -443,7 +455,7 @@ function resolveRenderLineInput(input: RenderLineInput): ResolvedRenderLineInput
input.startVisibleColumn,
input.containsRTL,
input.spaceWidth,
input.middotWidth,
input.renderSpaceCharCode,
input.renderWhitespace,
input.renderControlCharacters
);
@@ -553,7 +565,16 @@ function splitLargeTokens(lineContent: string, tokens: LinePart[], onlyAtSpaces:
* Moreover, a token is created for every visual indent because on some fonts the glyphs used for rendering whitespace (&rarr; or &middot;) do not have the same width as &nbsp;.
* The rendering phase will generate `style="width:..."` for these tokens.
*/
function _applyRenderWhitespace(lineContent: string, len: number, continuesWithWrappedLine: boolean, tokens: LinePart[], fauxIndentLength: number, tabSize: number, startVisibleColumn: number, useMonospaceOptimizations: boolean, selections: LineRange[] | null, onlyBoundary: boolean): LinePart[] {
function _applyRenderWhitespace(input: RenderLineInput, lineContent: string, len: number, tokens: LinePart[]): LinePart[] {
const continuesWithWrappedLine = input.continuesWithWrappedLine;
const fauxIndentLength = input.fauxIndentLength;
const tabSize = input.tabSize;
const startVisibleColumn = input.startVisibleColumn;
const useMonospaceOptimizations = input.useMonospaceOptimizations;
const selections = input.selectionsOnLine;
const onlyBoundary = (input.renderWhitespace === RenderWhitespace.Boundary);
const generateLinePartForEachWhitespace = (input.renderSpaceWidth !== input.spaceWidth);
let result: LinePart[] = [], resultLen = 0;
let tokenIndex = 0;
@@ -616,7 +637,14 @@ function _applyRenderWhitespace(lineContent: string, len: number, continuesWithW
// was in whitespace token
if (!isInWhitespace || (!useMonospaceOptimizations && tmpIndent >= tabSize)) {
// leaving whitespace token or entering a new indent
result[resultLen++] = new LinePart(charIndex, 'mtkw');
if (generateLinePartForEachWhitespace) {
const lastEndIndex = (resultLen > 0 ? result[resultLen - 1].endIndex : fauxIndentLength);
for (let i = lastEndIndex + 1; i <= charIndex; i++) {
result[resultLen++] = new LinePart(i, 'mtkw');
}
} else {
result[resultLen++] = new LinePart(charIndex, 'mtkw');
}
tmpIndent = tmpIndent % tabSize;
}
} else {
@@ -661,7 +689,18 @@ function _applyRenderWhitespace(lineContent: string, len: number, continuesWithW
}
}
result[resultLen++] = new LinePart(len, generateWhitespace ? 'mtkw' : tokenType);
if (generateWhitespace) {
if (generateLinePartForEachWhitespace) {
const lastEndIndex = (resultLen > 0 ? result[resultLen - 1].endIndex : fauxIndentLength);
for (let i = lastEndIndex + 1; i <= len; i++) {
result[resultLen++] = new LinePart(i, 'mtkw');
}
} else {
result[resultLen++] = new LinePart(len, 'mtkw');
}
} else {
result[resultLen++] = new LinePart(len, tokenType);
}
return result;
}
@@ -739,13 +778,10 @@ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): Render
const startVisibleColumn = input.startVisibleColumn;
const containsRTL = input.containsRTL;
const spaceWidth = input.spaceWidth;
const middotWidth = input.middotWidth;
const renderSpaceCharCode = input.renderSpaceCharCode;
const renderWhitespace = input.renderWhitespace;
const renderControlCharacters = input.renderControlCharacters;
// use U+2E31 - WORD SEPARATOR MIDDLE DOT or U+00B7 - MIDDLE DOT
const spaceRenderWhitespaceCharacter = (middotWidth > spaceWidth ? 0x2E31 : 0xB7);
const characterMapping = new CharacterMapping(len + 1, parts.length);
let charIndex = 0;
@@ -815,7 +851,7 @@ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): Render
} else { // must be CharCode.Space
charWidth = 1;
sb.write1(spaceRenderWhitespaceCharacter); // &middot; or word separator middle dot
sb.write1(renderSpaceCharCode); // &middot; or word separator middle dot
}
charOffsetInPart += charWidth;