mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode e1d3dd53d17fb1529a002e4d6fb066db0a0bd385 (#6460)
* Merge from vscode e1d3dd53d17fb1529a002e4d6fb066db0a0bd385 * fix servers icon * fix tests
This commit is contained in:
@@ -13,7 +13,8 @@ import { InlineDecorationType } from 'vs/editor/common/viewModel/viewModel';
|
||||
export const enum RenderWhitespace {
|
||||
None = 0,
|
||||
Boundary = 1,
|
||||
All = 2
|
||||
Selection = 2,
|
||||
All = 3
|
||||
}
|
||||
|
||||
class LinePart {
|
||||
@@ -31,6 +32,28 @@ class LinePart {
|
||||
}
|
||||
}
|
||||
|
||||
export class LineRange {
|
||||
/**
|
||||
* Zero-based offset on which the range starts, inclusive.
|
||||
*/
|
||||
public readonly startOffset: number;
|
||||
|
||||
/**
|
||||
* Zero-based offset on which the range ends, inclusive.
|
||||
*/
|
||||
public readonly endOffset: number;
|
||||
|
||||
constructor(startIndex: number, endIndex: number) {
|
||||
this.startOffset = startIndex;
|
||||
this.endOffset = endIndex;
|
||||
}
|
||||
|
||||
public equals(otherLineRange: LineRange) {
|
||||
return this.startOffset === otherLineRange.startOffset
|
||||
&& this.endOffset === otherLineRange.endOffset;
|
||||
}
|
||||
}
|
||||
|
||||
export class RenderLineInput {
|
||||
|
||||
public readonly useMonospaceOptimizations: boolean;
|
||||
@@ -49,6 +72,12 @@ export class RenderLineInput {
|
||||
public readonly renderControlCharacters: boolean;
|
||||
public readonly fontLigatures: boolean;
|
||||
|
||||
/**
|
||||
* Defined only when renderWhitespace is 'selection'. Selections are non-overlapping,
|
||||
* and ordered by position within the line.
|
||||
*/
|
||||
public readonly selectionsOnLine: LineRange[] | null;
|
||||
|
||||
constructor(
|
||||
useMonospaceOptimizations: boolean,
|
||||
canUseHalfwidthRightwardsArrow: boolean,
|
||||
@@ -62,9 +91,10 @@ export class RenderLineInput {
|
||||
tabSize: number,
|
||||
spaceWidth: number,
|
||||
stopRenderingLineAfter: number,
|
||||
renderWhitespace: 'none' | 'boundary' | 'all',
|
||||
renderWhitespace: 'none' | 'boundary' | 'selection' | 'all',
|
||||
renderControlCharacters: boolean,
|
||||
fontLigatures: boolean
|
||||
fontLigatures: boolean,
|
||||
selectionsOnLine: LineRange[] | null
|
||||
) {
|
||||
this.useMonospaceOptimizations = useMonospaceOptimizations;
|
||||
this.canUseHalfwidthRightwardsArrow = canUseHalfwidthRightwardsArrow;
|
||||
@@ -83,10 +113,35 @@ export class RenderLineInput {
|
||||
? RenderWhitespace.All
|
||||
: renderWhitespace === 'boundary'
|
||||
? RenderWhitespace.Boundary
|
||||
: RenderWhitespace.None
|
||||
: renderWhitespace === 'selection'
|
||||
? RenderWhitespace.Selection
|
||||
: RenderWhitespace.None
|
||||
);
|
||||
this.renderControlCharacters = renderControlCharacters;
|
||||
this.fontLigatures = fontLigatures;
|
||||
this.selectionsOnLine = selectionsOnLine && selectionsOnLine.sort((a, b) => a.startOffset < b.startOffset ? -1 : 1);
|
||||
}
|
||||
|
||||
private sameSelection(otherSelections: LineRange[] | null): boolean {
|
||||
if (this.selectionsOnLine === null) {
|
||||
return otherSelections === null;
|
||||
}
|
||||
|
||||
if (otherSelections === null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (otherSelections.length !== this.selectionsOnLine.length) {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0; i < this.selectionsOnLine.length; i++) {
|
||||
if (!this.selectionsOnLine[i].equals(otherSelections[i])) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
public equals(other: RenderLineInput): boolean {
|
||||
@@ -106,6 +161,7 @@ export class RenderLineInput {
|
||||
&& this.fontLigatures === other.fontLigatures
|
||||
&& LineDecoration.equalsArr(this.lineDecorations, other.lineDecorations)
|
||||
&& this.lineTokens.equals(other.lineTokens)
|
||||
&& this.sameSelection(other.selectionsOnLine)
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -338,8 +394,8 @@ function resolveRenderLineInput(input: RenderLineInput): ResolvedRenderLineInput
|
||||
}
|
||||
|
||||
let tokens = transformAndRemoveOverflowing(input.lineTokens, input.fauxIndentLength, len);
|
||||
if (input.renderWhitespace === RenderWhitespace.All || input.renderWhitespace === RenderWhitespace.Boundary) {
|
||||
tokens = _applyRenderWhitespace(lineContent, len, input.continuesWithWrappedLine, tokens, input.fauxIndentLength, input.tabSize, useMonospaceOptimizations, input.renderWhitespace === RenderWhitespace.Boundary);
|
||||
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, useMonospaceOptimizations, input.selectionsOnLine, input.renderWhitespace === RenderWhitespace.Boundary);
|
||||
}
|
||||
let containsForeignElements = ForeignElementType.None;
|
||||
if (input.lineDecorations.length > 0) {
|
||||
@@ -481,7 +537,7 @@ 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 (→ or ·) do not have the same width as .
|
||||
* The rendering phase will generate `style="width:..."` for these tokens.
|
||||
*/
|
||||
function _applyRenderWhitespace(lineContent: string, len: number, continuesWithWrappedLine: boolean, tokens: LinePart[], fauxIndentLength: number, tabSize: number, useMonospaceOptimizations: boolean, onlyBoundary: boolean): LinePart[] {
|
||||
function _applyRenderWhitespace(lineContent: string, len: number, continuesWithWrappedLine: boolean, tokens: LinePart[], fauxIndentLength: number, tabSize: number, useMonospaceOptimizations: boolean, selections: LineRange[] | null, onlyBoundary: boolean): LinePart[] {
|
||||
|
||||
let result: LinePart[] = [], resultLen = 0;
|
||||
let tokenIndex = 0;
|
||||
@@ -511,11 +567,17 @@ function _applyRenderWhitespace(lineContent: string, len: number, continuesWithW
|
||||
}
|
||||
}
|
||||
tmpIndent = tmpIndent % tabSize;
|
||||
|
||||
let wasInWhitespace = false;
|
||||
let currentSelectionIndex = 0;
|
||||
let currentSelection = selections && selections[currentSelectionIndex];
|
||||
for (let charIndex = fauxIndentLength; charIndex < len; charIndex++) {
|
||||
const chCode = lineContent.charCodeAt(charIndex);
|
||||
|
||||
if (currentSelection && charIndex >= currentSelection.endOffset) {
|
||||
currentSelectionIndex++;
|
||||
currentSelection = selections && selections[currentSelectionIndex];
|
||||
}
|
||||
|
||||
let isInWhitespace: boolean;
|
||||
if (charIndex < firstNonWhitespaceIndex || charIndex > lastNonWhitespaceIndex) {
|
||||
// in leading or trailing whitespace
|
||||
@@ -540,6 +602,11 @@ function _applyRenderWhitespace(lineContent: string, len: number, continuesWithW
|
||||
isInWhitespace = false;
|
||||
}
|
||||
|
||||
// If rendering whitespace on selection, check that the charIndex falls within a selection
|
||||
if (isInWhitespace && selections) {
|
||||
isInWhitespace = !!currentSelection && currentSelection.startOffset <= charIndex && currentSelection.endOffset > charIndex;
|
||||
}
|
||||
|
||||
if (wasInWhitespace) {
|
||||
// was in whitespace token
|
||||
if (!isInWhitespace || (!useMonospaceOptimizations && tmpIndent >= tabSize)) {
|
||||
|
||||
Reference in New Issue
Block a user