Merge from vscode 3c6f6af7347d38e87bc6406024e8dcf9e9bce229 (#8962)

* Merge from vscode 3c6f6af7347d38e87bc6406024e8dcf9e9bce229

* skip failing tests

* update mac build image
This commit is contained in:
Anthony Dresser
2020-01-27 15:28:17 -08:00
committed by Karl Burtram
parent 0eaee18dc4
commit fefe1454de
481 changed files with 12764 additions and 7836 deletions

View File

@@ -432,7 +432,7 @@ export const editorConfigurationBaseNode = Object.freeze<IConfigurationNode>({
order: 5,
type: 'object',
title: nls.localize('editorConfigurationTitle', "Editor"),
scope: ConfigurationScope.RESOURCE_LANGUAGE,
scope: ConfigurationScope.LANGUAGE_OVERRIDABLE,
});
const configurationRegistry = Registry.as<IConfigurationRegistry>(Extensions.Configuration);

View File

@@ -135,6 +135,11 @@ export interface IEditorOptions {
* Defaults to false.
*/
readOnly?: boolean;
/**
* Should the editor render validation decorations.
* Defaults to editable.
*/
renderValidationDecorations?: 'editable' | 'on' | 'off';
/**
* Control the behavior and rendering of the scrollbars.
*/
@@ -295,6 +300,10 @@ export interface IEditorOptions {
* Enable inline color decorators and color picker rendering.
*/
colorDecorators?: boolean;
/**
* Control the behaviour of comments in the editor.
*/
comments?: IEditorCommentsOptions;
/**
* Enable custom contextmenu.
* Defaults to true.
@@ -545,7 +554,7 @@ export interface IEditorOptions {
* Controls whether to focus the inline editor in the peek widget by default.
* Defaults to false.
*/
peekWidgetFocusInlineEditor?: boolean;
peekWidgetDefaultFocus?: 'tree' | 'editor';
}
export interface IEditorConstructionOptions extends IEditorOptions {
@@ -998,6 +1007,52 @@ class EditorAccessibilitySupport extends BaseEditorOption<EditorOption.accessibi
//#endregion
//#region comments
/**
* Configuration options for editor comments
*/
export interface IEditorCommentsOptions {
/**
* Insert a space after the line comment token and inside the block comments tokens.
* Defaults to true.
*/
insertSpace?: boolean;
}
export type EditorCommentsOptions = Readonly<Required<IEditorCommentsOptions>>;
class EditorComments extends BaseEditorOption<EditorOption.comments, EditorCommentsOptions> {
constructor() {
const defaults: EditorCommentsOptions = {
insertSpace: true,
};
super(
EditorOption.comments, 'comments', defaults,
{
'editor.comments.insertSpace': {
type: 'boolean',
default: defaults.insertSpace,
description: nls.localize('comments.insertSpace', "Controls whether a space character is inserted when commenting.")
},
}
);
}
public validate(_input: any): EditorCommentsOptions {
if (typeof _input !== 'object') {
return this.defaultValue;
}
const input = _input as IEditorCommentsOptions;
return {
insertSpace: EditorBooleanOption.boolean(input.insertSpace, this.defaultValue.insertSpace),
};
}
}
//#endregion
//#region cursorBlinking
/**
@@ -2290,6 +2345,21 @@ class EditorRenderLineNumbersOption extends BaseEditorOption<EditorOption.lineNu
//#endregion
//#region renderValidationDecorations
/**
* @internal
*/
export function filterValidationDecorations(options: IComputedEditorOptions): boolean {
const renderValidationDecorations = options.get(EditorOption.renderValidationDecorations);
if (renderValidationDecorations === 'editable') {
return options.get(EditorOption.readOnly);
}
return renderValidationDecorations === 'on' ? false : true;
}
//#endregion
//#region rulers
class EditorRulers extends SimpleEditorOption<EditorOption.rulers, number[]> {
@@ -3066,6 +3136,7 @@ export const enum EditorOption {
autoSurround,
codeLens,
colorDecorators,
comments,
contextmenu,
copyWithSyntaxHighlighting,
cursorBlinking,
@@ -3117,7 +3188,7 @@ export const enum EditorOption {
overviewRulerBorder,
overviewRulerLanes,
parameterHints,
peekWidgetFocusInlineEditor,
peekWidgetDefaultFocus,
quickSuggestions,
quickSuggestionsDelay,
readOnly,
@@ -3125,6 +3196,7 @@ export const enum EditorOption {
renderIndentGuides,
renderFinalNewline,
renderLineHighlight,
renderValidationDecorations,
renderWhitespace,
revealHorizontalRightPadding,
roundedSelection,
@@ -3169,6 +3241,7 @@ export const enum EditorOption {
* WORKAROUND: TS emits "any" for complex editor options values (anything except string, bool, enum, etc. ends up being "any")
* @monacodtsreplace
* /accessibilitySupport, any/accessibilitySupport, AccessibilitySupport/
* /comments, any/comments, EditorCommentsOptions/
* /find, any/find, EditorFindOptions/
* /fontInfo, any/fontInfo, FontInfo/
* /gotoLocation, any/gotoLocation, GoToLocationOptions/
@@ -3285,6 +3358,7 @@ export const EditorOptions = {
EditorOption.colorDecorators, 'colorDecorators', true,
{ description: nls.localize('colorDecorators', "Controls whether the editor should render the inline color decorators and color picker.") }
)),
comments: register(new EditorComments()),
contextmenu: register(new EditorBooleanOption(
EditorOption.contextmenu, 'contextmenu', true,
)),
@@ -3494,9 +3568,17 @@ export const EditorOptions = {
3, 0, 3
)),
parameterHints: register(new EditorParameterHints()),
peekWidgetFocusInlineEditor: register(new EditorBooleanOption(
EditorOption.peekWidgetFocusInlineEditor, 'peekWidgetFocusInlineEditor', false,
{ description: nls.localize('peekWidgetFocusInlineEditor', "Controls whether to focus the inline editor in the peek widget by default.") }
peekWidgetDefaultFocus: register(new EditorStringEnumOption(
EditorOption.peekWidgetDefaultFocus, 'peekWidgetDefaultFocus',
'tree' as 'tree' | 'editor',
['tree', 'editor'] as const,
{
enumDescriptions: [
nls.localize('peekWidgetDefaultFocus.tree', "Focus the tree when openeing peek"),
nls.localize('peekWidgetDefaultFocus.editor', "Focus the editor when opening peek")
],
description: nls.localize('peekWidgetDefaultFocus', "Controls whether to focus the inline editor or the tree in the peek widget.")
}
)),
quickSuggestions: register(new EditorQuickSuggestions()),
quickSuggestionsDelay: register(new EditorIntOption(
@@ -3533,6 +3615,11 @@ export const EditorOptions = {
description: nls.localize('renderLineHighlight', "Controls how the editor should render the current line highlight.")
}
)),
renderValidationDecorations: register(new EditorStringEnumOption(
EditorOption.renderValidationDecorations, 'renderValidationDecorations',
'editable' as 'editable' | 'on' | 'off',
['editable', 'on', 'off'] as const
)),
renderWhitespace: register(new EditorStringEnumOption(
EditorOption.renderWhitespace, 'renderWhitespace',
'none' as 'none' | 'boundary' | 'selection' | 'all',

View File

@@ -134,6 +134,7 @@ export class FontInfo extends BareFontInfo {
readonly typicalFullwidthCharacterWidth: number;
readonly canUseHalfwidthRightwardsArrow: boolean;
readonly spaceWidth: number;
readonly middotWidth: number;
readonly maxDigitWidth: number;
/**
@@ -152,6 +153,7 @@ export class FontInfo extends BareFontInfo {
typicalFullwidthCharacterWidth: number;
canUseHalfwidthRightwardsArrow: boolean;
spaceWidth: number;
middotWidth: number;
maxDigitWidth: number;
}, isTrusted: boolean) {
super(opts);
@@ -161,6 +163,7 @@ export class FontInfo extends BareFontInfo {
this.typicalFullwidthCharacterWidth = opts.typicalFullwidthCharacterWidth;
this.canUseHalfwidthRightwardsArrow = opts.canUseHalfwidthRightwardsArrow;
this.spaceWidth = opts.spaceWidth;
this.middotWidth = opts.middotWidth;
this.maxDigitWidth = opts.maxDigitWidth;
}
@@ -179,6 +182,7 @@ export class FontInfo extends BareFontInfo {
&& this.typicalFullwidthCharacterWidth === other.typicalFullwidthCharacterWidth
&& this.canUseHalfwidthRightwardsArrow === other.canUseHalfwidthRightwardsArrow
&& this.spaceWidth === other.spaceWidth
&& this.middotWidth === other.middotWidth
&& this.maxDigitWidth === other.maxDigitWidth
);
}

View File

@@ -545,7 +545,7 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors {
// Let the view get the event first.
try {
const eventsCollector = this._beginEmit();
eventsCollector.emit(new viewEvents.ViewCursorStateChangedEvent(viewSelections));
eventsCollector.emit(new viewEvents.ViewCursorStateChangedEvent(viewSelections, selections));
} finally {
this._endEmit();
}

View File

@@ -492,15 +492,20 @@ export class TypeOperations {
});
}
private static _autoClosingPairIsSymmetric(autoClosingPair: StandardAutoClosingPairConditional): boolean {
const { open, close } = autoClosingPair;
return (open.indexOf(close) >= 0 || close.indexOf(open) >= 0);
}
private static _isBeforeClosingBrace(config: CursorConfiguration, autoClosingPair: StandardAutoClosingPairConditional, characterAfter: string) {
const otherAutoClosingPairs = config.autoClosingPairsClose2.get(characterAfter);
if (!otherAutoClosingPairs) {
return false;
}
const thisBraceIsSymmetric = (autoClosingPair.open === autoClosingPair.close);
const thisBraceIsSymmetric = TypeOperations._autoClosingPairIsSymmetric(autoClosingPair);
for (const otherAutoClosingPair of otherAutoClosingPairs) {
const otherBraceIsSymmetric = (otherAutoClosingPair.open === otherAutoClosingPair.close);
const otherBraceIsSymmetric = TypeOperations._autoClosingPairIsSymmetric(otherAutoClosingPair);
if (!thisBraceIsSymmetric && otherBraceIsSymmetric) {
continue;
}

View File

@@ -72,11 +72,12 @@ function spacesDiff(a: string, aLength: number, b: string, bLength: number, resu
if (spacesDiff > 0 && 0 <= bSpacesCnt - 1 && bSpacesCnt - 1 < a.length && bSpacesCnt < b.length) {
if (b.charCodeAt(bSpacesCnt) !== CharCode.Space && a.charCodeAt(bSpacesCnt - 1) === CharCode.Space) {
// This looks like an alignment desire: e.g.
// const a = b + c,
// d = b - c;
result.looksLikeAlignment = true;
if (a.charCodeAt(a.length - 1) === CharCode.Comma) {
// This looks like an alignment desire: e.g.
// const a = b + c,
// d = b - c;
result.looksLikeAlignment = true;
}
}
}
return;

View File

@@ -1947,6 +1947,7 @@ export class TextModel extends Disposable implements model.ITextModel {
private _matchBracket(position: Position): [Range, Range] | null {
const lineNumber = position.lineNumber;
const lineTokens = this._getLineTokens(lineNumber);
const tokenCount = lineTokens.getCount();
const lineText = this._buffer.getLineContent(lineNumber);
const tokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1);
@@ -1959,6 +1960,15 @@ export class TextModel extends Disposable implements model.ITextModel {
if (currentModeBrackets && !ignoreBracketsInToken(lineTokens.getStandardTokenType(tokenIndex))) {
// limit search to not go before `maxBracketLength`
let searchStartOffset = Math.max(0, position.column - 1 - currentModeBrackets.maxBracketLength);
for (let i = tokenIndex - 1; i >= 0; i--) {
const tokenEndOffset = lineTokens.getEndOffset(i);
if (tokenEndOffset <= searchStartOffset) {
break;
}
if (ignoreBracketsInToken(lineTokens.getStandardTokenType(i))) {
searchStartOffset = tokenEndOffset;
}
}
// limit search to not go after `maxBracketLength`
const searchEndOffset = Math.min(lineText.length, position.column - 1 + currentModeBrackets.maxBracketLength);
@@ -1998,7 +2008,16 @@ export class TextModel extends Disposable implements model.ITextModel {
if (prevModeBrackets && !ignoreBracketsInToken(lineTokens.getStandardTokenType(prevTokenIndex))) {
// limit search in case previous token is very large, there's no need to go beyond `maxBracketLength`
const searchStartOffset = Math.max(0, position.column - 1 - prevModeBrackets.maxBracketLength);
const searchEndOffset = Math.min(lineText.length, position.column - 1 + prevModeBrackets.maxBracketLength);
let searchEndOffset = Math.min(lineText.length, position.column - 1 + prevModeBrackets.maxBracketLength);
for (let i = prevTokenIndex + 1; i < tokenCount; i++) {
const tokenStartOffset = lineTokens.getStartOffset(i);
if (tokenStartOffset >= searchEndOffset) {
break;
}
if (ignoreBracketsInToken(lineTokens.getStandardTokenType(i))) {
searchEndOffset = tokenStartOffset;
}
}
const foundBracket = BracketsUtils.findPrevBracketInRange(prevModeBrackets.reversedRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
// check that we didn't hit a bracket too far away from position

View File

@@ -804,7 +804,7 @@ export class TokensStore2 {
aIndex++;
}
const aMetadata = aTokens.getMetadata(aIndex - 1 > 0 ? aIndex - 1 : aIndex);
const aMetadata = aTokens.getMetadata(Math.min(Math.max(0, aIndex - 1), aLen - 1));
const languageId = TokenMetadata.getLanguageId(aMetadata);
const tokenType = TokenMetadata.getTokenType(aMetadata);

View File

@@ -369,6 +369,28 @@ export let completionKindFromString: {
};
})();
export interface CompletionItemLabel {
/**
* The function or variable. Rendered leftmost.
*/
name: string;
/**
* The signature without the return type. Render after `name`.
*/
signature?: string;
/**
* The fully qualified name, like package name or file path. Rendered after `signature`.
*/
qualifier?: string;
/**
* The return-type of a function or type of a property/variable. Rendered rightmost.
*/
type?: string;
}
export const enum CompletionItemTag {
Deprecated = 1
}
@@ -396,7 +418,7 @@ export interface CompletionItem {
* this is also the text that is inserted when selecting
* this completion.
*/
label: string;
label: string | CompletionItemLabel;
/**
* The kind of this completion item. Based on the kind
* an icon is chosen by the editor.
@@ -481,7 +503,6 @@ export interface CompletionItem {
export interface CompletionList {
suggestions: CompletionItem[];
incomplete?: boolean;
isDetailsResolved?: boolean;
dispose?(): void;
}
@@ -1257,20 +1278,36 @@ export namespace WorkspaceTextEdit {
* @internal
*/
export function is(thing: any): thing is WorkspaceTextEdit {
return isObject(thing) && (<WorkspaceTextEdit>thing).resource && Array.isArray((<WorkspaceTextEdit>thing).edits);
return isObject(thing) && URI.isUri((<WorkspaceTextEdit>thing).resource) && isObject((<WorkspaceTextEdit>thing).edit);
}
}
export interface WorkspaceEditMetadata {
needsConfirmation: boolean;
label: string;
description?: string;
iconPath?: { id: string } | { light: URI, dark: URI };
}
export interface WorkspaceFileEditOptions {
overwrite?: boolean;
ignoreIfNotExists?: boolean;
ignoreIfExists?: boolean;
recursive?: boolean;
}
export interface WorkspaceFileEdit {
oldUri?: URI;
newUri?: URI;
options?: { overwrite?: boolean, ignoreIfNotExists?: boolean, ignoreIfExists?: boolean, recursive?: boolean };
options?: WorkspaceFileEditOptions;
metadata?: WorkspaceEditMetadata;
}
export interface WorkspaceTextEdit {
resource: URI;
edit: TextEdit;
modelVersionId?: number;
edits: TextEdit[];
metadata?: WorkspaceEditMetadata;
}
export interface WorkspaceEdit {

View File

@@ -268,6 +268,10 @@ export class LinkComputer {
// `*` terminates a link if the link began with `*`
chClass = (linkBeginChCode === CharCode.Asterisk) ? CharacterClass.ForceTermination : CharacterClass.None;
break;
case CharCode.Pipe:
// `|` terminates a link if the link began with `|`
chClass = (linkBeginChCode === CharCode.Pipe) ? CharacterClass.ForceTermination : CharacterClass.None;
break;
default:
chClass = classifier.get(chCode);
}

View File

@@ -62,6 +62,11 @@ export class ScopedLineTokens {
return actualLineContent.substring(this.firstCharOffset, this._lastCharOffset);
}
public getActualLineContentBefore(offset: number): string {
const actualLineContent = this._actual.getLineContent();
return actualLineContent.substring(0, this.firstCharOffset + offset);
}
public getTokenCount(): number {
return this._lastTokenIndex - this._firstTokenIndex;
}

View File

@@ -49,28 +49,27 @@ export class BracketElectricCharacterSupport {
return null;
}
let tokenIndex = context.findTokenIndexAtOffset(column - 1);
const tokenIndex = context.findTokenIndexAtOffset(column - 1);
if (ignoreBracketsInToken(context.getStandardTokenType(tokenIndex))) {
return null;
}
let reversedBracketRegex = this._richEditBrackets.reversedRegex;
let text = context.getLineContent().substring(0, column - 1) + character;
const reversedBracketRegex = this._richEditBrackets.reversedRegex;
const text = context.getLineContent().substring(0, column - 1) + character;
let r = BracketsUtils.findPrevBracketInRange(reversedBracketRegex, 1, text, 0, text.length);
const r = BracketsUtils.findPrevBracketInRange(reversedBracketRegex, 1, text, 0, text.length);
if (!r) {
return null;
}
let bracketText = text.substring(r.startColumn - 1, r.endColumn - 1);
bracketText = bracketText.toLowerCase();
const bracketText = text.substring(r.startColumn - 1, r.endColumn - 1).toLowerCase();
let isOpen = this._richEditBrackets.textIsOpenBracket[bracketText];
const isOpen = this._richEditBrackets.textIsOpenBracket[bracketText];
if (isOpen) {
return null;
}
let textBeforeBracket = text.substring(0, r.startColumn - 1);
const textBeforeBracket = context.getActualLineContentBefore(r.startColumn - 1);
if (!/^\s*$/.test(textBeforeBracket)) {
// There is other text on the line before the bracket
return null;

View File

@@ -147,12 +147,10 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
let ret = Range.lift(rawMarker);
if (rawMarker.severity === MarkerSeverity.Hint) {
if (!rawMarker.tags || rawMarker.tags.indexOf(MarkerTag.Unnecessary) === -1) {
// * never render hints on multiple lines
// * make enough space for three dots
ret = ret.setEndPosition(ret.startLineNumber, ret.startColumn + 2);
}
if (rawMarker.severity === MarkerSeverity.Hint && !this._hasMarkerTag(rawMarker, MarkerTag.Unnecessary) && !this._hasMarkerTag(rawMarker, MarkerTag.Deprecated)) {
// * never render hints on multiple lines
// * make enough space for three dots
ret = ret.setEndPosition(ret.startLineNumber, ret.startColumn + 2);
}
ret = model.validateRange(ret);
@@ -188,7 +186,7 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
private _createDecorationOption(marker: IMarker): IModelDecorationOptions {
let className: string;
let className: string | undefined;
let color: ThemeColor | undefined = undefined;
let zIndex: number;
let inlineClassName: string | undefined = undefined;
@@ -196,7 +194,9 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
switch (marker.severity) {
case MarkerSeverity.Hint:
if (marker.tags && marker.tags.indexOf(MarkerTag.Unnecessary) >= 0) {
if (this._hasMarkerTag(marker, MarkerTag.Deprecated)) {
className = undefined;
} else if (this._hasMarkerTag(marker, MarkerTag.Unnecessary)) {
className = ClassName.EditorUnnecessaryDecoration;
} else {
className = ClassName.EditorHintDecoration;
@@ -251,4 +251,11 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
inlineClassName,
};
}
private _hasMarkerTag(marker: IMarker, tag: MarkerTag): boolean {
if (marker.tags) {
return marker.tags.indexOf(tag) >= 0;
}
return false;
}
}

View File

@@ -178,101 +178,103 @@ export enum EditorOption {
autoSurround = 10,
codeLens = 11,
colorDecorators = 12,
contextmenu = 13,
copyWithSyntaxHighlighting = 14,
cursorBlinking = 15,
cursorSmoothCaretAnimation = 16,
cursorStyle = 17,
cursorSurroundingLines = 18,
cursorSurroundingLinesStyle = 19,
cursorWidth = 20,
disableLayerHinting = 21,
disableMonospaceOptimizations = 22,
dragAndDrop = 23,
emptySelectionClipboard = 24,
extraEditorClassName = 25,
fastScrollSensitivity = 26,
find = 27,
fixedOverflowWidgets = 28,
folding = 29,
foldingStrategy = 30,
foldingHighlight = 31,
fontFamily = 32,
fontInfo = 33,
fontLigatures = 34,
fontSize = 35,
fontWeight = 36,
formatOnPaste = 37,
formatOnType = 38,
glyphMargin = 39,
gotoLocation = 40,
hideCursorInOverviewRuler = 41,
highlightActiveIndentGuide = 42,
hover = 43,
inDiffEditor = 44,
letterSpacing = 45,
lightbulb = 46,
lineDecorationsWidth = 47,
lineHeight = 48,
lineNumbers = 49,
lineNumbersMinChars = 50,
links = 51,
matchBrackets = 52,
minimap = 53,
mouseStyle = 54,
mouseWheelScrollSensitivity = 55,
mouseWheelZoom = 56,
multiCursorMergeOverlapping = 57,
multiCursorModifier = 58,
multiCursorPaste = 59,
occurrencesHighlight = 60,
overviewRulerBorder = 61,
overviewRulerLanes = 62,
parameterHints = 63,
peekWidgetFocusInlineEditor = 64,
quickSuggestions = 65,
quickSuggestionsDelay = 66,
readOnly = 67,
renderControlCharacters = 68,
renderIndentGuides = 69,
renderFinalNewline = 70,
renderLineHighlight = 71,
renderWhitespace = 72,
revealHorizontalRightPadding = 73,
roundedSelection = 74,
rulers = 75,
scrollbar = 76,
scrollBeyondLastColumn = 77,
scrollBeyondLastLine = 78,
selectionClipboard = 79,
selectionHighlight = 80,
selectOnLineNumbers = 81,
semanticHighlighting = 82,
showFoldingControls = 83,
showUnused = 84,
snippetSuggestions = 85,
smoothScrolling = 86,
stopRenderingLineAfter = 87,
suggest = 88,
suggestFontSize = 89,
suggestLineHeight = 90,
suggestOnTriggerCharacters = 91,
suggestSelection = 92,
tabCompletion = 93,
useTabStops = 94,
wordSeparators = 95,
wordWrap = 96,
wordWrapBreakAfterCharacters = 97,
wordWrapBreakBeforeCharacters = 98,
wordWrapColumn = 99,
wordWrapMinified = 100,
wrappingIndent = 101,
wrappingAlgorithm = 102,
editorClassName = 103,
pixelRatio = 104,
tabFocusMode = 105,
layoutInfo = 106,
wrappingInfo = 107
comments = 13,
contextmenu = 14,
copyWithSyntaxHighlighting = 15,
cursorBlinking = 16,
cursorSmoothCaretAnimation = 17,
cursorStyle = 18,
cursorSurroundingLines = 19,
cursorSurroundingLinesStyle = 20,
cursorWidth = 21,
disableLayerHinting = 22,
disableMonospaceOptimizations = 23,
dragAndDrop = 24,
emptySelectionClipboard = 25,
extraEditorClassName = 26,
fastScrollSensitivity = 27,
find = 28,
fixedOverflowWidgets = 29,
folding = 30,
foldingStrategy = 31,
foldingHighlight = 32,
fontFamily = 33,
fontInfo = 34,
fontLigatures = 35,
fontSize = 36,
fontWeight = 37,
formatOnPaste = 38,
formatOnType = 39,
glyphMargin = 40,
gotoLocation = 41,
hideCursorInOverviewRuler = 42,
highlightActiveIndentGuide = 43,
hover = 44,
inDiffEditor = 45,
letterSpacing = 46,
lightbulb = 47,
lineDecorationsWidth = 48,
lineHeight = 49,
lineNumbers = 50,
lineNumbersMinChars = 51,
links = 52,
matchBrackets = 53,
minimap = 54,
mouseStyle = 55,
mouseWheelScrollSensitivity = 56,
mouseWheelZoom = 57,
multiCursorMergeOverlapping = 58,
multiCursorModifier = 59,
multiCursorPaste = 60,
occurrencesHighlight = 61,
overviewRulerBorder = 62,
overviewRulerLanes = 63,
parameterHints = 64,
peekWidgetDefaultFocus = 65,
quickSuggestions = 66,
quickSuggestionsDelay = 67,
readOnly = 68,
renderControlCharacters = 69,
renderIndentGuides = 70,
renderFinalNewline = 71,
renderLineHighlight = 72,
renderValidationDecorations = 73,
renderWhitespace = 74,
revealHorizontalRightPadding = 75,
roundedSelection = 76,
rulers = 77,
scrollbar = 78,
scrollBeyondLastColumn = 79,
scrollBeyondLastLine = 80,
selectionClipboard = 81,
selectionHighlight = 82,
selectOnLineNumbers = 83,
semanticHighlighting = 84,
showFoldingControls = 85,
showUnused = 86,
snippetSuggestions = 87,
smoothScrolling = 88,
stopRenderingLineAfter = 89,
suggest = 90,
suggestFontSize = 91,
suggestLineHeight = 92,
suggestOnTriggerCharacters = 93,
suggestSelection = 94,
tabCompletion = 95,
useTabStops = 96,
wordSeparators = 97,
wordWrap = 98,
wordWrapBreakAfterCharacters = 99,
wordWrapBreakBeforeCharacters = 100,
wordWrapColumn = 101,
wordWrapMinified = 102,
wrappingIndent = 103,
wrappingAlgorithm = 104,
editorClassName = 105,
pixelRatio = 106,
tabFocusMode = 107,
layoutInfo = 108,
wrappingInfo = 109
}
/**

View File

@@ -69,13 +69,12 @@ export class ViewCursorStateChangedEvent {
public readonly type = ViewEventType.ViewCursorStateChanged;
/**
* The primary selection is always at index 0.
*/
public readonly selections: Selection[];
public readonly modelSelections: Selection[];
constructor(selections: Selection[]) {
constructor(selections: Selection[], modelSelections: Selection[]) {
this.selections = selections;
this.modelSelections = modelSelections;
}
}

View File

@@ -68,6 +68,7 @@ export class RenderLineInput {
public readonly tabSize: number;
public readonly startVisibleColumn: number;
public readonly spaceWidth: number;
public readonly middotWidth: number;
public readonly stopRenderingLineAfter: number;
public readonly renderWhitespace: RenderWhitespace;
public readonly renderControlCharacters: boolean;
@@ -92,6 +93,7 @@ export class RenderLineInput {
tabSize: number,
startVisibleColumn: number,
spaceWidth: number,
middotWidth: number,
stopRenderingLineAfter: number,
renderWhitespace: 'none' | 'boundary' | 'selection' | 'all',
renderControlCharacters: boolean,
@@ -110,6 +112,7 @@ export class RenderLineInput {
this.tabSize = tabSize;
this.startVisibleColumn = startVisibleColumn;
this.spaceWidth = spaceWidth;
this.middotWidth = middotWidth;
this.stopRenderingLineAfter = stopRenderingLineAfter;
this.renderWhitespace = (
renderWhitespace === 'all'
@@ -380,6 +383,7 @@ class ResolvedRenderLineInput {
public readonly startVisibleColumn: number,
public readonly containsRTL: boolean,
public readonly spaceWidth: number,
public readonly middotWidth: number,
public readonly renderWhitespace: RenderWhitespace,
public readonly renderControlCharacters: boolean,
) {
@@ -439,6 +443,7 @@ function resolveRenderLineInput(input: RenderLineInput): ResolvedRenderLineInput
input.startVisibleColumn,
input.containsRTL,
input.spaceWidth,
input.middotWidth,
input.renderWhitespace,
input.renderControlCharacters
);
@@ -734,9 +739,13 @@ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): Render
const startVisibleColumn = input.startVisibleColumn;
const containsRTL = input.containsRTL;
const spaceWidth = input.spaceWidth;
const middotWidth = input.middotWidth;
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;
@@ -808,7 +817,7 @@ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): Render
} else { // must be CharCode.Space
charWidth = 1;
sb.write1(0xB7); // &middot;
sb.write1(spaceRenderWhitespaceCharacter); // &middot; or word separator middle dot
}
charOffsetInPart += charWidth;

View File

@@ -138,8 +138,8 @@ export interface IViewModel {
deduceModelPositionRelativeToViewPosition(viewAnchorPosition: Position, deltaOffset: number, lineFeedCnt: number): Position;
getEOL(): string;
getPlainTextToCopy(ranges: Range[], emptySelectionClipboard: boolean, forceCRLF: boolean): string | string[];
getHTMLToCopy(ranges: Range[], emptySelectionClipboard: boolean): string | null;
getPlainTextToCopy(modelRanges: Range[], emptySelectionClipboard: boolean, forceCRLF: boolean): string | string[];
getRichTextToCopy(modelRanges: Range[], emptySelectionClipboard: boolean): { html: string, mode: string } | null;
}
export class MinimapLinesRenderingData {

View File

@@ -10,7 +10,7 @@ import * as editorCommon from 'vs/editor/common/editorCommon';
import { IModelDecoration, ITextModel } from 'vs/editor/common/model';
import { IViewModelLinesCollection } from 'vs/editor/common/viewModel/splitLinesCollection';
import { ICoordinatesConverter, InlineDecoration, InlineDecorationType, ViewModelDecoration } from 'vs/editor/common/viewModel/viewModel';
import { EditorOption } from 'vs/editor/common/config/editorOptions';
import { filterValidationDecorations } from 'vs/editor/common/config/editorOptions';
export interface IDecorationsViewportData {
/**
@@ -104,7 +104,7 @@ export class ViewModelDecorations implements IDisposable {
}
private _getDecorationsViewportData(viewportRange: Range): IDecorationsViewportData {
const modelDecorations = this._linesCollection.getDecorationsInRange(viewportRange, this.editorId, this.configuration.options.get(EditorOption.readOnly));
const modelDecorations = this._linesCollection.getDecorationsInRange(viewportRange, this.editorId, filterValidationDecorations(this.configuration.options));
const startLineNumber = viewportRange.startLineNumber;
const endLineNumber = viewportRange.endLineNumber;

View File

@@ -6,7 +6,7 @@
import { Color } from 'vs/base/common/color';
import { IDisposable } from 'vs/base/common/lifecycle';
import * as strings from 'vs/base/common/strings';
import { ConfigurationChangedEvent, EDITOR_FONT_DEFAULTS, EditorOption } from 'vs/editor/common/config/editorOptions';
import { ConfigurationChangedEvent, EDITOR_FONT_DEFAULTS, EditorOption, filterValidationDecorations } from 'vs/editor/common/config/editorOptions';
import { IPosition, Position } from 'vs/editor/common/core/position';
import { IRange, Range } from 'vs/editor/common/core/range';
import { IConfiguration, IViewState } from 'vs/editor/common/editorCommon';
@@ -596,7 +596,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
}
public getAllOverviewRulerDecorations(theme: ITheme): IOverviewRulerDecorations {
return this.lines.getAllOverviewRulerDecorations(this.editorId, this.configuration.options.get(EditorOption.readOnly), theme);
return this.lines.getAllOverviewRulerDecorations(this.editorId, filterValidationDecorations(this.configuration.options), theme);
}
public invalidateOverviewRulerColorCache(): void {
@@ -656,15 +656,15 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
return this.model.getEOL();
}
public getPlainTextToCopy(ranges: Range[], emptySelectionClipboard: boolean, forceCRLF: boolean): string | string[] {
public getPlainTextToCopy(modelRanges: Range[], emptySelectionClipboard: boolean, forceCRLF: boolean): string | string[] {
const newLineCharacter = forceCRLF ? '\r\n' : this.model.getEOL();
ranges = ranges.slice(0);
ranges.sort(Range.compareRangesUsingStarts);
modelRanges = modelRanges.slice(0);
modelRanges.sort(Range.compareRangesUsingStarts);
let hasEmptyRange = false;
let hasNonEmptyRange = false;
for (const range of ranges) {
for (const range of modelRanges) {
if (range.isEmpty()) {
hasEmptyRange = true;
} else {
@@ -678,10 +678,7 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
return '';
}
const modelLineNumbers = ranges.map((r) => {
const viewLineStart = new Position(r.startLineNumber, 1);
return this.coordinatesConverter.convertViewPositionToModelPosition(viewLineStart).lineNumber;
});
const modelLineNumbers = modelRanges.map((r) => r.startLineNumber);
let result = '';
for (let i = 0; i < modelLineNumbers.length; i++) {
@@ -697,14 +694,14 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
// mixed empty selections and non-empty selections
let result: string[] = [];
let prevModelLineNumber = 0;
for (const range of ranges) {
const modelLineNumber = this.coordinatesConverter.convertViewPositionToModelPosition(new Position(range.startLineNumber, 1)).lineNumber;
if (range.isEmpty()) {
for (const modelRange of modelRanges) {
const modelLineNumber = modelRange.startLineNumber;
if (modelRange.isEmpty()) {
if (modelLineNumber !== prevModelLineNumber) {
result.push(this.model.getLineContent(modelLineNumber));
}
} else {
result.push(this.getValueInRange(range, forceCRLF ? EndOfLinePreference.CRLF : EndOfLinePreference.TextDefined));
result.push(this.model.getValueInRange(modelRange, forceCRLF ? EndOfLinePreference.CRLF : EndOfLinePreference.TextDefined));
}
prevModelLineNumber = modelLineNumber;
}
@@ -712,31 +709,32 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
}
let result: string[] = [];
for (const range of ranges) {
if (!range.isEmpty()) {
result.push(this.getValueInRange(range, forceCRLF ? EndOfLinePreference.CRLF : EndOfLinePreference.TextDefined));
for (const modelRange of modelRanges) {
if (!modelRange.isEmpty()) {
result.push(this.model.getValueInRange(modelRange, forceCRLF ? EndOfLinePreference.CRLF : EndOfLinePreference.TextDefined));
}
}
return result.length === 1 ? result[0] : result;
}
public getHTMLToCopy(viewRanges: Range[], emptySelectionClipboard: boolean): string | null {
if (this.model.getLanguageIdentifier().id === LanguageId.PlainText) {
public getRichTextToCopy(modelRanges: Range[], emptySelectionClipboard: boolean): { html: string, mode: string } | null {
const languageId = this.model.getLanguageIdentifier();
if (languageId.id === LanguageId.PlainText) {
return null;
}
if (viewRanges.length !== 1) {
if (modelRanges.length !== 1) {
// no multiple selection support at this time
return null;
}
let range = this.coordinatesConverter.convertViewRangeToModelRange(viewRanges[0]);
let range = modelRanges[0];
if (range.isEmpty()) {
if (!emptySelectionClipboard) {
// nothing to copy
return null;
}
let lineNumber = range.startLineNumber;
const lineNumber = range.startLineNumber;
range = new Range(lineNumber, this.model.getLineMinColumn(lineNumber), lineNumber, this.model.getLineMaxColumn(lineNumber));
}
@@ -744,19 +742,22 @@ export class ViewModel extends viewEvents.ViewEventEmitter implements IViewModel
const colorMap = this._getColorMap();
const fontFamily = fontInfo.fontFamily === EDITOR_FONT_DEFAULTS.fontFamily ? fontInfo.fontFamily : `'${fontInfo.fontFamily}', ${EDITOR_FONT_DEFAULTS.fontFamily}`;
return (
`<div style="`
+ `color: ${colorMap[ColorId.DefaultForeground]};`
+ `background-color: ${colorMap[ColorId.DefaultBackground]};`
+ `font-family: ${fontFamily};`
+ `font-weight: ${fontInfo.fontWeight};`
+ `font-size: ${fontInfo.fontSize}px;`
+ `line-height: ${fontInfo.lineHeight}px;`
+ `white-space: pre;`
+ `">`
+ this._getHTMLToCopy(range, colorMap)
+ '</div>'
);
return {
mode: languageId.language,
html: (
`<div style="`
+ `color: ${colorMap[ColorId.DefaultForeground]};`
+ `background-color: ${colorMap[ColorId.DefaultBackground]};`
+ `font-family: ${fontFamily};`
+ `font-weight: ${fontInfo.fontWeight};`
+ `font-size: ${fontInfo.fontSize}px;`
+ `line-height: ${fontInfo.lineHeight}px;`
+ `white-space: pre;`
+ `">`
+ this._getHTMLToCopy(range, colorMap)
+ '</div>'
)
};
}
private _getHTMLToCopy(modelRange: Range, colorMap: string[]): string {