mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 10:58:30 -05:00
Merge from vscode 1ec43773e37997841c5af42b33ddb180e9735bf2
This commit is contained in:
@@ -457,6 +457,9 @@ export class TextAreaHandler extends ViewPart {
|
||||
this.textArea.setAttribute('aria-autocomplete', 'both');
|
||||
this.textArea.removeAttribute('aria-activedescendant');
|
||||
}
|
||||
if (options.role) {
|
||||
this.textArea.setAttribute('role', options.role);
|
||||
}
|
||||
}
|
||||
|
||||
// --- end view API
|
||||
|
||||
@@ -333,6 +333,7 @@ export interface IOverviewRuler {
|
||||
*/
|
||||
export interface IEditorAriaOptions {
|
||||
activeDescendant: string | undefined;
|
||||
role?: string;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -14,17 +14,17 @@ import { IModelDecorationOptions, IModelDecorationOverviewRulerOptions, Overview
|
||||
import { IResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { IColorTheme, IThemeService, ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
class RefCountedStyleSheet {
|
||||
export class RefCountedStyleSheet {
|
||||
|
||||
private readonly _parent: CodeEditorServiceImpl;
|
||||
private readonly _editorId: string;
|
||||
public readonly styleSheet: HTMLStyleElement;
|
||||
private readonly _styleSheet: HTMLStyleElement;
|
||||
private _refCount: number;
|
||||
|
||||
constructor(parent: CodeEditorServiceImpl, editorId: string, styleSheet: HTMLStyleElement) {
|
||||
this._parent = parent;
|
||||
this._editorId = editorId;
|
||||
this.styleSheet = styleSheet;
|
||||
this._styleSheet = styleSheet;
|
||||
this._refCount = 0;
|
||||
}
|
||||
|
||||
@@ -35,17 +35,26 @@ class RefCountedStyleSheet {
|
||||
public unref(): void {
|
||||
this._refCount--;
|
||||
if (this._refCount === 0) {
|
||||
this.styleSheet.parentNode?.removeChild(this.styleSheet);
|
||||
this._styleSheet.parentNode?.removeChild(this._styleSheet);
|
||||
this._parent._removeEditorStyleSheets(this._editorId);
|
||||
}
|
||||
}
|
||||
|
||||
public insertRule(rule: string, index?: number): void {
|
||||
const sheet = <CSSStyleSheet>this._styleSheet.sheet;
|
||||
sheet.insertRule(rule, index);
|
||||
}
|
||||
|
||||
public removeRulesContainingSelector(ruleName: string): void {
|
||||
dom.removeCSSRulesContainingSelector(ruleName, this._styleSheet);
|
||||
}
|
||||
}
|
||||
|
||||
class GlobalStyleSheet {
|
||||
public readonly styleSheet: HTMLStyleElement;
|
||||
export class GlobalStyleSheet {
|
||||
private readonly _styleSheet: HTMLStyleElement;
|
||||
|
||||
constructor(styleSheet: HTMLStyleElement) {
|
||||
this.styleSheet = styleSheet;
|
||||
this._styleSheet = styleSheet;
|
||||
}
|
||||
|
||||
public ref(): void {
|
||||
@@ -53,6 +62,15 @@ class GlobalStyleSheet {
|
||||
|
||||
public unref(): void {
|
||||
}
|
||||
|
||||
public insertRule(rule: string, index?: number): void {
|
||||
const sheet = <CSSStyleSheet>this._styleSheet.sheet;
|
||||
sheet.insertRule(rule, index);
|
||||
}
|
||||
|
||||
public removeRulesContainingSelector(ruleName: string): void {
|
||||
dom.removeCSSRulesContainingSelector(ruleName, this._styleSheet);
|
||||
}
|
||||
}
|
||||
|
||||
export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
|
||||
@@ -62,9 +80,9 @@ export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
|
||||
private readonly _editorStyleSheets = new Map<string, RefCountedStyleSheet>();
|
||||
private readonly _themeService: IThemeService;
|
||||
|
||||
constructor(@IThemeService themeService: IThemeService, styleSheet: HTMLStyleElement | null = null) {
|
||||
constructor(@IThemeService themeService: IThemeService, styleSheet: GlobalStyleSheet | null = null) {
|
||||
super();
|
||||
this._globalStyleSheet = styleSheet ? new GlobalStyleSheet(styleSheet) : null;
|
||||
this._globalStyleSheet = styleSheet ? styleSheet : null;
|
||||
this._themeService = themeService;
|
||||
}
|
||||
|
||||
@@ -100,7 +118,7 @@ export abstract class CodeEditorServiceImpl extends AbstractCodeEditorService {
|
||||
if (!provider) {
|
||||
const styleSheet = this._getOrCreateStyleSheet(editor);
|
||||
const providerArgs: ProviderArguments = {
|
||||
styleSheet: styleSheet.styleSheet,
|
||||
styleSheet: styleSheet,
|
||||
key: key,
|
||||
parentTypeKey: parentTypeKey,
|
||||
options: options || Object.create(null)
|
||||
@@ -188,7 +206,7 @@ class DecorationSubTypeOptionsProvider implements IModelDecorationOptionsProvide
|
||||
}
|
||||
|
||||
interface ProviderArguments {
|
||||
styleSheet: HTMLStyleElement;
|
||||
styleSheet: GlobalStyleSheet | RefCountedStyleSheet;
|
||||
key: string;
|
||||
parentTypeKey?: string;
|
||||
options: IDecorationRenderOptions;
|
||||
@@ -330,7 +348,7 @@ class DecorationCSSRules {
|
||||
private readonly _providerArgs: ProviderArguments;
|
||||
private _usesThemeColors: boolean;
|
||||
|
||||
public constructor(ruleType: ModelDecorationCSSRuleType, providerArgs: ProviderArguments, themeService: IThemeService) {
|
||||
constructor(ruleType: ModelDecorationCSSRuleType, providerArgs: ProviderArguments, themeService: IThemeService) {
|
||||
this._theme = themeService.getColorTheme();
|
||||
this._ruleType = ruleType;
|
||||
this._providerArgs = providerArgs;
|
||||
@@ -414,7 +432,7 @@ class DecorationCSSRules {
|
||||
default:
|
||||
throw new Error('Unknown rule type: ' + this._ruleType);
|
||||
}
|
||||
const sheet = <CSSStyleSheet>this._providerArgs.styleSheet.sheet;
|
||||
const sheet = this._providerArgs.styleSheet;
|
||||
|
||||
let hasContent = false;
|
||||
if (unthemedCSS.length > 0) {
|
||||
@@ -433,7 +451,7 @@ class DecorationCSSRules {
|
||||
}
|
||||
|
||||
private _removeCSS(): void {
|
||||
dom.removeCSSRulesContainingSelector(this._unThemedSelector, this._providerArgs.styleSheet);
|
||||
this._providerArgs.styleSheet.removeRulesContainingSelector(this._unThemedSelector);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -40,9 +40,9 @@ class SingleModelEditStackData {
|
||||
public changes: TextChange[]
|
||||
) { }
|
||||
|
||||
public append(model: ITextModel, operations: IValidEditOperation[], afterEOL: EndOfLineSequence, afterVersionId: number, afterCursorState: Selection[] | null): void {
|
||||
if (operations.length > 0) {
|
||||
this.changes = compressConsecutiveTextChanges(this.changes, operations.map(op => op.textChange));
|
||||
public append(model: ITextModel, textChanges: TextChange[], afterEOL: EndOfLineSequence, afterVersionId: number, afterCursorState: Selection[] | null): void {
|
||||
if (textChanges.length > 0) {
|
||||
this.changes = compressConsecutiveTextChanges(this.changes, textChanges);
|
||||
}
|
||||
this.afterEOL = afterEOL;
|
||||
this.afterVersionId = afterVersionId;
|
||||
@@ -168,9 +168,9 @@ export class SingleModelEditStackElement implements IResourceUndoRedoElement {
|
||||
return (this.model === model && this._data instanceof SingleModelEditStackData);
|
||||
}
|
||||
|
||||
public append(model: ITextModel, operations: IValidEditOperation[], afterEOL: EndOfLineSequence, afterVersionId: number, afterCursorState: Selection[] | null): void {
|
||||
public append(model: ITextModel, textChanges: TextChange[], afterEOL: EndOfLineSequence, afterVersionId: number, afterCursorState: Selection[] | null): void {
|
||||
if (this._data instanceof SingleModelEditStackData) {
|
||||
this._data.append(model, operations, afterEOL, afterVersionId, afterCursorState);
|
||||
this._data.append(model, textChanges, afterEOL, afterVersionId, afterCursorState);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -258,10 +258,10 @@ export class MultiModelEditStackElement implements IWorkspaceUndoRedoElement {
|
||||
return false;
|
||||
}
|
||||
|
||||
public append(model: ITextModel, operations: IValidEditOperation[], afterEOL: EndOfLineSequence, afterVersionId: number, afterCursorState: Selection[] | null): void {
|
||||
public append(model: ITextModel, textChanges: TextChange[], afterEOL: EndOfLineSequence, afterVersionId: number, afterCursorState: Selection[] | null): void {
|
||||
const key = uriGetComparisonKey(model.uri);
|
||||
const editStackElement = this._editStackElementsMap.get(key)!;
|
||||
editStackElement.append(model, operations, afterEOL, afterVersionId, afterCursorState);
|
||||
editStackElement.append(model, textChanges, afterEOL, afterVersionId, afterCursorState);
|
||||
}
|
||||
|
||||
public close(): void {
|
||||
@@ -355,7 +355,14 @@ export class EditStack {
|
||||
const editStackElement = this._getOrCreateEditStackElement(beforeCursorState);
|
||||
const inverseEditOperations = this._model.applyEdits(editOperations, true);
|
||||
const afterCursorState = EditStack._computeCursorState(cursorStateComputer, inverseEditOperations);
|
||||
editStackElement.append(this._model, inverseEditOperations, getModelEOL(this._model), this._model.getAlternativeVersionId(), afterCursorState);
|
||||
const textChanges = inverseEditOperations.map((op, index) => ({ index: index, textChange: op.textChange }));
|
||||
textChanges.sort((a, b) => {
|
||||
if (a.textChange.oldPosition === b.textChange.oldPosition) {
|
||||
return a.index - b.index;
|
||||
}
|
||||
return a.textChange.oldPosition - b.textChange.oldPosition;
|
||||
});
|
||||
editStackElement.append(this._model, textChanges.map(op => op.textChange), getModelEOL(this._model), this._model.getAlternativeVersionId(), afterCursorState);
|
||||
return afterCursorState;
|
||||
}
|
||||
|
||||
|
||||
@@ -661,12 +661,14 @@ const enum Constants {
|
||||
class HashTableEntry {
|
||||
public readonly tokenTypeIndex: number;
|
||||
public readonly tokenModifierSet: number;
|
||||
public readonly languageId: number;
|
||||
public readonly metadata: number;
|
||||
public next: HashTableEntry | null;
|
||||
|
||||
constructor(tokenTypeIndex: number, tokenModifierSet: number, metadata: number) {
|
||||
constructor(tokenTypeIndex: number, tokenModifierSet: number, languageId: number, metadata: number) {
|
||||
this.tokenTypeIndex = tokenTypeIndex;
|
||||
this.tokenModifierSet = tokenModifierSet;
|
||||
this.languageId = languageId;
|
||||
this.metadata = metadata;
|
||||
this.next = null;
|
||||
}
|
||||
@@ -697,16 +699,17 @@ class HashTable {
|
||||
}
|
||||
}
|
||||
|
||||
private _hashFunc(tokenTypeIndex: number, tokenModifierSet: number): number {
|
||||
return ((((tokenTypeIndex << 5) - tokenTypeIndex) + tokenModifierSet) | 0) % this._currentLength; // tokenTypeIndex * 31 + tokenModifierSet, keep as int32
|
||||
private _hashFunc(tokenTypeIndex: number, tokenModifierSet: number, languageId: number): number {
|
||||
const hash = (n1: number, n2: number) => (((n1 << 5) - n1) + n2) | 0; // n1 * 31 + n2, keep as int32
|
||||
return hash(hash(tokenTypeIndex, tokenModifierSet), languageId) % this._currentLength;
|
||||
}
|
||||
|
||||
public get(tokenTypeIndex: number, tokenModifierSet: number): HashTableEntry | null {
|
||||
const hash = this._hashFunc(tokenTypeIndex, tokenModifierSet);
|
||||
public get(tokenTypeIndex: number, tokenModifierSet: number, languageId: number): HashTableEntry | null {
|
||||
const hash = this._hashFunc(tokenTypeIndex, tokenModifierSet, languageId);
|
||||
|
||||
let p = this._elements[hash];
|
||||
while (p) {
|
||||
if (p.tokenTypeIndex === tokenTypeIndex && p.tokenModifierSet === tokenModifierSet) {
|
||||
if (p.tokenTypeIndex === tokenTypeIndex && p.tokenModifierSet === tokenModifierSet && p.languageId === languageId) {
|
||||
return p;
|
||||
}
|
||||
p = p.next;
|
||||
@@ -715,7 +718,7 @@ class HashTable {
|
||||
return null;
|
||||
}
|
||||
|
||||
public add(tokenTypeIndex: number, tokenModifierSet: number, metadata: number): void {
|
||||
public add(tokenTypeIndex: number, tokenModifierSet: number, languageId: number, metadata: number): void {
|
||||
this._elementsCount++;
|
||||
if (this._growCount !== 0 && this._elementsCount >= this._growCount) {
|
||||
// expand!
|
||||
@@ -737,11 +740,11 @@ class HashTable {
|
||||
}
|
||||
}
|
||||
}
|
||||
this._add(new HashTableEntry(tokenTypeIndex, tokenModifierSet, metadata));
|
||||
this._add(new HashTableEntry(tokenTypeIndex, tokenModifierSet, languageId, metadata));
|
||||
}
|
||||
|
||||
private _add(element: HashTableEntry): void {
|
||||
const hash = this._hashFunc(element.tokenTypeIndex, element.tokenModifierSet);
|
||||
const hash = this._hashFunc(element.tokenTypeIndex, element.tokenModifierSet, element.languageId);
|
||||
element.next = this._elements[hash];
|
||||
this._elements[hash] = element;
|
||||
}
|
||||
@@ -759,8 +762,8 @@ class SemanticColoringProviderStyling {
|
||||
this._hashTable = new HashTable();
|
||||
}
|
||||
|
||||
public getMetadata(tokenTypeIndex: number, tokenModifierSet: number): number {
|
||||
const entry = this._hashTable.get(tokenTypeIndex, tokenModifierSet);
|
||||
public getMetadata(tokenTypeIndex: number, tokenModifierSet: number, languageId: LanguageIdentifier): number {
|
||||
const entry = this._hashTable.get(tokenTypeIndex, tokenModifierSet, languageId.id);
|
||||
let metadata: number;
|
||||
if (entry) {
|
||||
metadata = entry.metadata;
|
||||
@@ -775,7 +778,7 @@ class SemanticColoringProviderStyling {
|
||||
modifierSet = modifierSet >> 1;
|
||||
}
|
||||
|
||||
const tokenStyle = this._themeService.getColorTheme().getTokenStyleMetadata(tokenType, tokenModifiers);
|
||||
const tokenStyle = this._themeService.getColorTheme().getTokenStyleMetadata(tokenType, tokenModifiers, languageId.language);
|
||||
if (typeof tokenStyle === 'undefined') {
|
||||
metadata = Constants.NO_STYLING;
|
||||
} else {
|
||||
@@ -801,7 +804,7 @@ class SemanticColoringProviderStyling {
|
||||
metadata = Constants.NO_STYLING;
|
||||
}
|
||||
}
|
||||
this._hashTable.add(tokenTypeIndex, tokenModifierSet, metadata);
|
||||
this._hashTable.add(tokenTypeIndex, tokenModifierSet, languageId.id, metadata);
|
||||
}
|
||||
if (this._logService.getLevel() === LogLevel.Trace) {
|
||||
const type = this._legend.tokenTypes[tokenTypeIndex];
|
||||
@@ -1042,6 +1045,8 @@ class ModelSemanticColoring extends Disposable {
|
||||
|
||||
const result: MultilineTokens2[] = [];
|
||||
|
||||
const languageId = this._model.getLanguageIdentifier();
|
||||
|
||||
let tokenIndex = 0;
|
||||
let lastLineNumber = 1;
|
||||
let lastStartCharacter = 0;
|
||||
@@ -1081,7 +1086,7 @@ class ModelSemanticColoring extends Disposable {
|
||||
const length = srcData[srcOffset + 2];
|
||||
const tokenTypeIndex = srcData[srcOffset + 3];
|
||||
const tokenModifierSet = srcData[srcOffset + 4];
|
||||
const metadata = styling.getMetadata(tokenTypeIndex, tokenModifierSet);
|
||||
const metadata = styling.getMetadata(tokenTypeIndex, tokenModifierSet, languageId);
|
||||
|
||||
if (metadata !== Constants.NO_STYLING) {
|
||||
if (areaLine === 0) {
|
||||
|
||||
@@ -20,10 +20,6 @@
|
||||
color: var(--outline-element-color);
|
||||
}
|
||||
|
||||
.monaco-tree .monaco-tree-row.focused .outline-element .outline-element-detail {
|
||||
visibility: inherit;
|
||||
}
|
||||
|
||||
.monaco-list .outline-element .outline-element-decoration {
|
||||
opacity: 0.75;
|
||||
font-size: 90%;
|
||||
|
||||
@@ -62,7 +62,6 @@ function flatten(bucket: DocumentSymbol[], entries: DocumentSymbol[], overrideCo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
CommandsRegistry.registerCommand('_executeDocumentSymbolProvider', async function (accessor, ...args) {
|
||||
const [resource] = args;
|
||||
assertType(URI.isUri(resource));
|
||||
@@ -241,7 +241,7 @@ export class ChangeIndentationSizeAction extends EditorAction {
|
||||
}
|
||||
}
|
||||
});
|
||||
}, 50/* quick open is sensitive to being opened so soon after another */);
|
||||
}, 50/* quick input is sensitive to being opened so soon after another */);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -72,7 +72,7 @@ export abstract class AbstractEditorNavigationQuickAccessProvider implements IQu
|
||||
|
||||
// Remember view state and update it when the cursor position
|
||||
// changes even later because it could be that the user has
|
||||
// configured quick open to remain open when focus is lost and
|
||||
// configured quick access to remain open when focus is lost and
|
||||
// we always want to restore the current location.
|
||||
let lastKnownEditorViewState = withNullAsUndefined(editor.saveViewState());
|
||||
disposables.add(codeEditor.onDidChangeCursorPosition(() => {
|
||||
|
||||
@@ -17,6 +17,7 @@ import { values } from 'vs/base/common/collections';
|
||||
import { trim, format } from 'vs/base/common/strings';
|
||||
import { fuzzyScore, FuzzyScore, createMatches } from 'vs/base/common/filters';
|
||||
import { assign } from 'vs/base/common/objects';
|
||||
import { prepareQuery, IPreparedQuery } from 'vs/base/common/fuzzyScorer';
|
||||
|
||||
export interface IGotoSymbolQuickPickItem extends IQuickPickItem {
|
||||
kind: SymbolKind,
|
||||
@@ -155,7 +156,7 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
|
||||
// Collect symbol picks
|
||||
picker.busy = true;
|
||||
try {
|
||||
const items = await this.doGetSymbolPicks(symbolsPromise, picker.value.substr(AbstractGotoSymbolQuickAccessProvider.PREFIX.length).trim(), picksCts.token);
|
||||
const items = await this.doGetSymbolPicks(symbolsPromise, prepareQuery(picker.value.substr(AbstractGotoSymbolQuickAccessProvider.PREFIX.length).trim()), undefined, picksCts.token);
|
||||
if (token.isCancellationRequested) {
|
||||
return;
|
||||
}
|
||||
@@ -194,18 +195,24 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
|
||||
return disposables;
|
||||
}
|
||||
|
||||
protected async doGetSymbolPicks(symbolsPromise: Promise<DocumentSymbol[]>, filter: string, token: CancellationToken): Promise<Array<IGotoSymbolQuickPickItem | IQuickPickSeparator>> {
|
||||
protected async doGetSymbolPicks(symbolsPromise: Promise<DocumentSymbol[]>, query: IPreparedQuery, options: { extraContainerLabel?: string } | undefined, token: CancellationToken): Promise<Array<IGotoSymbolQuickPickItem | IQuickPickSeparator>> {
|
||||
const symbols = await symbolsPromise;
|
||||
if (token.isCancellationRequested) {
|
||||
return [];
|
||||
}
|
||||
|
||||
// Normalize filter
|
||||
const filterBySymbolKind = filter.indexOf(AbstractGotoSymbolQuickAccessProvider.SCOPE_PREFIX) === 0;
|
||||
const filterBySymbolKind = query.original.indexOf(AbstractGotoSymbolQuickAccessProvider.SCOPE_PREFIX) === 0;
|
||||
const filterPos = filterBySymbolKind ? 1 : 0;
|
||||
const [symbolFilter, containerFilter] = filter.split(' ') as [string, string | undefined];
|
||||
const symbolFilterLow = symbolFilter.toLowerCase();
|
||||
const containerFilterLow = containerFilter?.toLowerCase();
|
||||
|
||||
// Split between symbol and container query if separated by space
|
||||
let symbolQuery: IPreparedQuery;
|
||||
let containerQuery: IPreparedQuery | undefined;
|
||||
if (query.values && query.values.length > 1) {
|
||||
symbolQuery = prepareQuery(query.values[0].original);
|
||||
containerQuery = prepareQuery(query.values[1].original);
|
||||
} else {
|
||||
symbolQuery = query;
|
||||
}
|
||||
|
||||
// Convert to symbol picks and apply filtering
|
||||
const filteredSymbolPicks: IGotoSymbolQuickPickItem[] = [];
|
||||
@@ -213,22 +220,28 @@ export abstract class AbstractGotoSymbolQuickAccessProvider extends AbstractEdit
|
||||
const symbol = symbols[index];
|
||||
|
||||
const symbolLabel = trim(symbol.name);
|
||||
const containerLabel = symbol.containerName;
|
||||
|
||||
let containerLabel = symbol.containerName;
|
||||
if (containerLabel && options?.extraContainerLabel) {
|
||||
containerLabel = `${options.extraContainerLabel} • ${containerLabel}`;
|
||||
} else {
|
||||
containerLabel = options?.extraContainerLabel;
|
||||
}
|
||||
|
||||
let symbolScore: FuzzyScore | undefined = undefined;
|
||||
let containerScore: FuzzyScore | undefined = undefined;
|
||||
|
||||
let includeSymbol = true;
|
||||
if (filter.length > filterPos) {
|
||||
if (query.original.length > filterPos) {
|
||||
|
||||
// Score by symbol
|
||||
symbolScore = fuzzyScore(symbolFilter, symbolFilterLow, filterPos, symbolLabel, symbolLabel.toLowerCase(), 0, true);
|
||||
symbolScore = fuzzyScore(symbolQuery.original, symbolQuery.originalLowercase, filterPos, symbolLabel, symbolLabel.toLowerCase(), 0, true);
|
||||
includeSymbol = !!symbolScore;
|
||||
|
||||
// Score by container if specified
|
||||
if (includeSymbol && containerFilter && containerFilterLow) {
|
||||
if (includeSymbol && containerQuery) {
|
||||
if (containerLabel) {
|
||||
containerScore = fuzzyScore(containerFilter, containerFilterLow, filterPos, containerLabel, containerLabel.toLowerCase(), 0, true);
|
||||
containerScore = fuzzyScore(containerQuery.original, containerQuery.originalLowercase, filterPos, containerLabel, containerLabel.toLowerCase(), 0, true);
|
||||
}
|
||||
|
||||
includeSymbol = !!containerScore;
|
||||
|
||||
@@ -401,12 +401,13 @@ class WordHighlighter {
|
||||
private renderDecorations(): void {
|
||||
this.renderDecorationsTimer = -1;
|
||||
let decorations: IModelDeltaDecoration[] = [];
|
||||
for (let i = 0, len = this.workerRequestValue.length; i < len; i++) {
|
||||
let info = this.workerRequestValue[i];
|
||||
decorations.push({
|
||||
range: info.range,
|
||||
options: WordHighlighter._getDecorationOptions(info.kind)
|
||||
});
|
||||
for (const info of this.workerRequestValue) {
|
||||
if (info.range) {
|
||||
decorations.push({
|
||||
range: info.range,
|
||||
options: WordHighlighter._getDecorationOptions(info.kind)
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
this._decorationIds = this.editor.deltaDecorations(this._decorationIds, decorations);
|
||||
|
||||
@@ -129,10 +129,6 @@ export class StandaloneQuickInputServiceImpl implements IQuickInputService {
|
||||
cancel(): Promise<void> {
|
||||
return this.activeService.cancel();
|
||||
}
|
||||
|
||||
hide(focusLost?: boolean | undefined): void {
|
||||
return this.activeService.hide(focusLost);
|
||||
}
|
||||
}
|
||||
|
||||
export class QuickInputEditorContribution implements IEditorContribution {
|
||||
|
||||
@@ -134,26 +134,6 @@
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* tree */
|
||||
.monaco-editor.vs .monaco-tree .monaco-tree-row,
|
||||
.monaco-editor.vs-dark .monaco-tree .monaco-tree-row {
|
||||
-ms-high-contrast-adjust: none;
|
||||
color: windowtext !important;
|
||||
}
|
||||
.monaco-editor.vs .monaco-tree .monaco-tree-row.selected,
|
||||
.monaco-editor.vs-dark .monaco-tree .monaco-tree-row.selected,
|
||||
.monaco-editor.vs .monaco-tree .monaco-tree-row.focused,
|
||||
.monaco-editor.vs-dark .monaco-tree .monaco-tree-row.focused {
|
||||
color: highlighttext !important;
|
||||
background-color: highlight !important;
|
||||
}
|
||||
.monaco-editor.vs .monaco-tree .monaco-tree-row:hover,
|
||||
.monaco-editor.vs-dark .monaco-tree .monaco-tree-row:hover {
|
||||
background: transparent !important;
|
||||
border: 1px solid highlight;
|
||||
box-sizing: border-box;
|
||||
}
|
||||
|
||||
/* scrollbars */
|
||||
.monaco-editor.vs .monaco-scrollable-element > .scrollbar,
|
||||
.monaco-editor.vs-dark .monaco-scrollable-element > .scrollbar {
|
||||
|
||||
@@ -131,7 +131,7 @@ class StandaloneTheme implements IStandaloneTheme {
|
||||
return this._tokenTheme;
|
||||
}
|
||||
|
||||
public getTokenStyleMetadata(type: string, modifiers: string[]): ITokenStyle | undefined {
|
||||
public getTokenStyleMetadata(type: string, modifiers: string[], modelLanguage: string): ITokenStyle | undefined {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
|
||||
@@ -56,7 +56,7 @@ suite('TokenizationSupport2Adapter', () => {
|
||||
throw new Error('Not implemented');
|
||||
},
|
||||
|
||||
getTokenStyleMetadata: (type: string, modifiers: string[]): ITokenStyle | undefined => {
|
||||
getTokenStyleMetadata: (type: string, modifiers: string[], modelLanguage: string): ITokenStyle | undefined => {
|
||||
return undefined;
|
||||
},
|
||||
|
||||
|
||||
@@ -5616,4 +5616,24 @@ suite('Undo stops', () => {
|
||||
});
|
||||
});
|
||||
|
||||
test('issue #93585: Undo multi cursor edit corrupts document', () => {
|
||||
let model = createTextModel(
|
||||
[
|
||||
'hello world',
|
||||
'hello world',
|
||||
].join('\n')
|
||||
);
|
||||
|
||||
withTestCodeEditor(null, { model: model }, (editor, cursor) => {
|
||||
cursor.setSelections('test', [
|
||||
new Selection(2, 7, 2, 12),
|
||||
new Selection(1, 7, 1, 12),
|
||||
]);
|
||||
cursorCommand(cursor, H.Type, { text: 'no' }, 'keyboard');
|
||||
assert.equal(model.getValue(), 'hello no\nhello no');
|
||||
|
||||
CoreEditingCommands.Undo.runEditorCommand(null, editor, null);
|
||||
assert.equal(model.getValue(), 'hello world\nhello world');
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
@@ -4,18 +4,17 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as assert from 'assert';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { CodeEditorServiceImpl } from 'vs/editor/browser/services/codeEditorServiceImpl';
|
||||
import { CodeEditorServiceImpl, GlobalStyleSheet } from 'vs/editor/browser/services/codeEditorServiceImpl';
|
||||
import { IDecorationRenderOptions } from 'vs/editor/common/editorCommon';
|
||||
import { IResourceEditorInput } from 'vs/platform/editor/common/editor';
|
||||
import { TestColorTheme, TestThemeService } from 'vs/platform/theme/test/common/testThemeService';
|
||||
|
||||
const themeServiceMock = new TestThemeService();
|
||||
|
||||
export class TestCodeEditorServiceImpl extends CodeEditorServiceImpl {
|
||||
class TestCodeEditorServiceImpl extends CodeEditorServiceImpl {
|
||||
getActiveCodeEditor(): ICodeEditor | null {
|
||||
return null;
|
||||
}
|
||||
@@ -25,6 +24,32 @@ export class TestCodeEditorServiceImpl extends CodeEditorServiceImpl {
|
||||
}
|
||||
}
|
||||
|
||||
class TestGlobalStyleSheet extends GlobalStyleSheet {
|
||||
|
||||
public rules: string[] = [];
|
||||
|
||||
constructor() {
|
||||
super(null!);
|
||||
}
|
||||
|
||||
public insertRule(rule: string, index?: number): void {
|
||||
this.rules.unshift(rule);
|
||||
}
|
||||
|
||||
public removeRulesContainingSelector(ruleName: string): void {
|
||||
for (let i = 0; i < this.rules.length; i++) {
|
||||
if (this.rules[i].indexOf(ruleName) >= 0) {
|
||||
this.rules.splice(i, 1);
|
||||
i--;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public read(): string {
|
||||
return this.rules.join('\n');
|
||||
}
|
||||
}
|
||||
|
||||
suite.skip('Decoration Render Options', () => { // {{SQL CARBON EDIT}} skip suite
|
||||
let options: IDecorationRenderOptions = {
|
||||
gutterIconPath: URI.parse('https://github.com/Microsoft/vscode/blob/master/resources/linux/code.png'),
|
||||
@@ -45,59 +70,45 @@ suite.skip('Decoration Render Options', () => { // {{SQL CARBON EDIT}} skip suit
|
||||
assert.throws(() => s.resolveDecorationOptions('example', false));
|
||||
});
|
||||
|
||||
function readStyleSheet(styleSheet: HTMLStyleElement): string {
|
||||
if ((<any>styleSheet.sheet).rules) {
|
||||
return Array.prototype.map.call((<any>styleSheet.sheet).rules, (r: { cssText: string }) => r.cssText).join('\n');
|
||||
}
|
||||
return styleSheet.sheet!.toString();
|
||||
function readStyleSheet(styleSheet: TestGlobalStyleSheet): string {
|
||||
return styleSheet.read();
|
||||
}
|
||||
|
||||
test('css properties', () => {
|
||||
let styleSheet = dom.createStyleSheet();
|
||||
let s = new TestCodeEditorServiceImpl(themeServiceMock, styleSheet);
|
||||
const styleSheet = new TestGlobalStyleSheet();
|
||||
const s = new TestCodeEditorServiceImpl(themeServiceMock, styleSheet);
|
||||
s.registerDecorationType('example', options);
|
||||
let sheet = readStyleSheet(styleSheet);
|
||||
assert(
|
||||
sheet.indexOf('background: url(\'https://github.com/Microsoft/vscode/blob/master/resources/linux/code.png\') center center no-repeat;') > 0
|
||||
|| sheet.indexOf('background: url("https://github.com/Microsoft/vscode/blob/master/resources/linux/code.png") center center / contain no-repeat;') > 0
|
||||
|| sheet.indexOf('background-image: url("https://github.com/Microsoft/vscode/blob/master/resources/linux/code.png"); background-size: contain; background-position: center center; background-repeat: no-repeat no-repeat;') > 0
|
||||
);
|
||||
assert(sheet.indexOf('border-color: yellow;') > 0);
|
||||
assert(sheet.indexOf('background-color: red;') > 0);
|
||||
const sheet = readStyleSheet(styleSheet);
|
||||
assert(sheet.indexOf(`{background:url('https://github.com/Microsoft/vscode/blob/master/resources/linux/code.png') center center no-repeat;background-size:contain;}`) >= 0);
|
||||
assert(sheet.indexOf(`{background-color:red;border-color:yellow;box-sizing: border-box;}`) >= 0);
|
||||
});
|
||||
|
||||
test('theme color', () => {
|
||||
let options: IDecorationRenderOptions = {
|
||||
const options: IDecorationRenderOptions = {
|
||||
backgroundColor: { id: 'editorBackground' },
|
||||
borderColor: { id: 'editorBorder' },
|
||||
};
|
||||
let colors: { [key: string]: string } = {
|
||||
|
||||
const styleSheet = new TestGlobalStyleSheet();
|
||||
const themeService = new TestThemeService(new TestColorTheme({
|
||||
editorBackground: '#FF0000'
|
||||
};
|
||||
|
||||
let styleSheet = dom.createStyleSheet();
|
||||
let themeService = new TestThemeService(new TestColorTheme(colors));
|
||||
let s = new TestCodeEditorServiceImpl(themeService, styleSheet);
|
||||
}));
|
||||
const s = new TestCodeEditorServiceImpl(themeService, styleSheet);
|
||||
s.registerDecorationType('example', options);
|
||||
let sheet = readStyleSheet(styleSheet);
|
||||
assert.equal(sheet, '.monaco-editor .ced-example-0 { background-color: rgb(255, 0, 0); border-color: transparent; box-sizing: border-box; }');
|
||||
assert.equal(readStyleSheet(styleSheet), '.monaco-editor .ced-example-0 {background-color:#ff0000;border-color:transparent;box-sizing: border-box;}');
|
||||
|
||||
colors = {
|
||||
themeService.setTheme(new TestColorTheme({
|
||||
editorBackground: '#EE0000',
|
||||
editorBorder: '#00FFFF'
|
||||
};
|
||||
themeService.setTheme(new TestColorTheme(colors));
|
||||
sheet = readStyleSheet(styleSheet);
|
||||
assert.equal(sheet, '.monaco-editor .ced-example-0 { background-color: rgb(238, 0, 0); border-color: rgb(0, 255, 255); box-sizing: border-box; }');
|
||||
}));
|
||||
assert.equal(readStyleSheet(styleSheet), '.monaco-editor .ced-example-0 {background-color:#ee0000;border-color:#00ffff;box-sizing: border-box;}');
|
||||
|
||||
s.removeDecorationType('example');
|
||||
sheet = readStyleSheet(styleSheet);
|
||||
assert.equal(sheet, '');
|
||||
|
||||
assert.equal(readStyleSheet(styleSheet), '');
|
||||
});
|
||||
|
||||
test('theme overrides', () => {
|
||||
let options: IDecorationRenderOptions = {
|
||||
const options: IDecorationRenderOptions = {
|
||||
color: { id: 'editorBackground' },
|
||||
light: {
|
||||
color: '#FF00FF'
|
||||
@@ -109,86 +120,59 @@ suite.skip('Decoration Render Options', () => { // {{SQL CARBON EDIT}} skip suit
|
||||
}
|
||||
}
|
||||
};
|
||||
let colors: { [key: string]: string } = {
|
||||
|
||||
const styleSheet = new TestGlobalStyleSheet();
|
||||
const themeService = new TestThemeService(new TestColorTheme({
|
||||
editorBackground: '#FF0000',
|
||||
infoForeground: '#444444'
|
||||
};
|
||||
|
||||
let styleSheet = dom.createStyleSheet();
|
||||
let themeService = new TestThemeService(new TestColorTheme(colors));
|
||||
let s = new TestCodeEditorServiceImpl(themeService, styleSheet);
|
||||
}));
|
||||
const s = new TestCodeEditorServiceImpl(themeService, styleSheet);
|
||||
s.registerDecorationType('example', options);
|
||||
let sheet = readStyleSheet(styleSheet);
|
||||
let expected =
|
||||
'.vs-dark.monaco-editor .ced-example-4::after, .hc-black.monaco-editor .ced-example-4::after { color: rgb(68, 68, 68) !important; }\n' +
|
||||
'.vs-dark.monaco-editor .ced-example-1, .hc-black.monaco-editor .ced-example-1 { color: rgb(0, 0, 0) !important; }\n' +
|
||||
'.vs.monaco-editor .ced-example-1 { color: rgb(255, 0, 255) !important; }\n' +
|
||||
'.monaco-editor .ced-example-1 { color: rgb(255, 0, 0) !important; }';
|
||||
assert.equal(sheet, expected);
|
||||
const expected = [
|
||||
'.vs-dark.monaco-editor .ced-example-4::after, .hc-black.monaco-editor .ced-example-4::after {color:#444444 !important;}',
|
||||
'.vs-dark.monaco-editor .ced-example-1, .hc-black.monaco-editor .ced-example-1 {color:#000000 !important;}',
|
||||
'.vs.monaco-editor .ced-example-1 {color:#FF00FF !important;}',
|
||||
'.monaco-editor .ced-example-1 {color:#ff0000 !important;}'
|
||||
].join('\n');
|
||||
assert.equal(readStyleSheet(styleSheet), expected);
|
||||
|
||||
s.removeDecorationType('example');
|
||||
sheet = readStyleSheet(styleSheet);
|
||||
assert.equal(sheet, '');
|
||||
assert.equal(readStyleSheet(styleSheet), '');
|
||||
});
|
||||
|
||||
test('css properties, gutterIconPaths', () => {
|
||||
let styleSheet = dom.createStyleSheet();
|
||||
const styleSheet = new TestGlobalStyleSheet();
|
||||
const s = new TestCodeEditorServiceImpl(themeServiceMock, styleSheet);
|
||||
|
||||
// unix file path (used as string)
|
||||
let s = new TestCodeEditorServiceImpl(themeServiceMock, styleSheet);
|
||||
s.registerDecorationType('example', { gutterIconPath: URI.file('/Users/foo/bar.png') });
|
||||
let sheet = readStyleSheet(styleSheet);//.innerHTML || styleSheet.sheet.toString();
|
||||
assert(
|
||||
sheet.indexOf('background: url(\'file:///Users/foo/bar.png\') center center no-repeat;') > 0
|
||||
|| sheet.indexOf('background: url("file:///Users/foo/bar.png") center center no-repeat;') > 0
|
||||
|| sheet.indexOf('background-image: url("file:///Users/foo/bar.png"); background-position: center center; background-repeat: no-repeat no-repeat;') > 0
|
||||
);
|
||||
// URI, only minimal encoding
|
||||
s.registerDecorationType('example', { gutterIconPath: URI.parse('data:image/svg+xml;base64,PHN2ZyB4b+') });
|
||||
assert(readStyleSheet(styleSheet).indexOf(`{background:url('data:image/svg+xml;base64,PHN2ZyB4b+') center center no-repeat;}`) > 0);
|
||||
s.removeDecorationType('example');
|
||||
|
||||
// windows file path (used as string)
|
||||
if (platform.isWindows) {
|
||||
s = new TestCodeEditorServiceImpl(themeServiceMock, styleSheet);
|
||||
// windows file path (used as string)
|
||||
s.registerDecorationType('example', { gutterIconPath: URI.file('c:\\files\\miles\\more.png') });
|
||||
sheet = readStyleSheet(styleSheet);
|
||||
assert(
|
||||
sheet.indexOf('background: url(\'file:///c%3A/files/miles/more.png\') center center no-repeat;') > 0
|
||||
|| sheet.indexOf('background: url("file:///c%3A/files/miles/more.png") center center no-repeat;') > 0
|
||||
|| sheet.indexOf('background: url("file:///c:/files/miles/more.png") center center no-repeat;') > 0
|
||||
|| sheet.indexOf('background-image: url("file:///c:/files/miles/more.png"); background-position: center center; background-repeat: no-repeat no-repeat;') > 0
|
||||
);
|
||||
assert(readStyleSheet(styleSheet).indexOf(`{background:url('file:///c:/files/miles/more.png') center center no-repeat;}`) > 0);
|
||||
s.removeDecorationType('example');
|
||||
|
||||
// single quote must always be escaped/encoded
|
||||
s.registerDecorationType('example', { gutterIconPath: URI.file('c:\\files\\foo\\b\'ar.png') });
|
||||
assert(readStyleSheet(styleSheet).indexOf(`{background:url('file:///c:/files/foo/b%27ar.png') center center no-repeat;}`) > 0);
|
||||
s.removeDecorationType('example');
|
||||
} else {
|
||||
// unix file path (used as string)
|
||||
s.registerDecorationType('example', { gutterIconPath: URI.file('/Users/foo/bar.png') });
|
||||
assert(readStyleSheet(styleSheet).indexOf(`{background:url('file:///Users/foo/bar.png') center center no-repeat;}`) > 0);
|
||||
s.removeDecorationType('example');
|
||||
|
||||
// single quote must always be escaped/encoded
|
||||
s.registerDecorationType('example', { gutterIconPath: URI.file('/Users/foo/b\'ar.png') });
|
||||
assert(readStyleSheet(styleSheet).indexOf(`{background:url('file:///Users/foo/b%27ar.png') center center no-repeat;}`) > 0);
|
||||
s.removeDecorationType('example');
|
||||
}
|
||||
|
||||
// URI, only minimal encoding
|
||||
s = new TestCodeEditorServiceImpl(themeServiceMock, styleSheet);
|
||||
s.registerDecorationType('example', { gutterIconPath: URI.parse('data:image/svg+xml;base64,PHN2ZyB4b+') });
|
||||
sheet = readStyleSheet(styleSheet);
|
||||
assert(
|
||||
sheet.indexOf('background: url(\'data:image/svg+xml;base64,PHN2ZyB4b+\') center center no-repeat;') > 0
|
||||
|| sheet.indexOf('background: url("data:image/svg+xml;base64,PHN2ZyB4b+") center center no-repeat;') > 0
|
||||
|| sheet.indexOf('background-image: url("data:image/svg+xml;base64,PHN2ZyB4b+"); background-position: center center; background-repeat: no-repeat no-repeat;') > 0
|
||||
);
|
||||
s.removeDecorationType('example');
|
||||
|
||||
// single quote must always be escaped/encoded
|
||||
s = new TestCodeEditorServiceImpl(themeServiceMock, styleSheet);
|
||||
s.registerDecorationType('example', { gutterIconPath: URI.file('/Users/foo/b\'ar.png') });
|
||||
sheet = readStyleSheet(styleSheet);
|
||||
assert(
|
||||
sheet.indexOf('background: url(\'file:///Users/foo/b%27ar.png\') center center no-repeat;') > 0
|
||||
|| sheet.indexOf('background: url("file:///Users/foo/b%27ar.png") center center no-repeat;') > 0
|
||||
|| sheet.indexOf('background-image: url("file:///Users/foo/b%27ar.png"); background-position: center center; background-repeat: no-repeat no-repeat;') > 0
|
||||
);
|
||||
s.removeDecorationType('example');
|
||||
|
||||
s = new TestCodeEditorServiceImpl(themeServiceMock, styleSheet);
|
||||
s.registerDecorationType('example', { gutterIconPath: URI.parse('http://test/pa\'th') });
|
||||
sheet = readStyleSheet(styleSheet);
|
||||
assert(
|
||||
sheet.indexOf('background: url(\'http://test/pa%27th\') center center no-repeat;') > 0
|
||||
|| sheet.indexOf('background: url("http://test/pa%27th") center center no-repeat;') > 0
|
||||
|| sheet.indexOf('background-image: url("http://test/pa%27th"); background-position: center center; background-repeat: no-repeat no-repeat;') > 0
|
||||
);
|
||||
assert(readStyleSheet(styleSheet).indexOf(`{background:url('http://test/pa%27th') center center no-repeat;}`) > 0);
|
||||
s.removeDecorationType('example');
|
||||
});
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user