Merge from vscode cfc1ab4c5f816765b91fb7ead3c3427a7c8581a3

This commit is contained in:
ADS Merger
2020-03-11 04:19:23 +00:00
parent 16fab722d5
commit 4c3e48773d
880 changed files with 20441 additions and 11232 deletions

View File

@@ -1338,7 +1338,7 @@ export class EditorFontLigatures extends BaseEditorOption<EditorOption.fontLigat
description: nls.localize('fontFeatureSettings', "Explicit font-feature-settings.")
}
],
description: nls.localize('fontLigaturesGeneral', "Configures font ligatures."),
description: nls.localize('fontLigaturesGeneral', "Configures font ligatures or font features."),
default: false
}
);

View File

@@ -323,7 +323,7 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors {
}
public revealRange(source: string, revealHorizontal: boolean, viewRange: Range, verticalType: viewEvents.VerticalRevealType, scrollType: editorCommon.ScrollType) {
this.emitCursorRevealRange(source, viewRange, verticalType, revealHorizontal, scrollType);
this.emitCursorRevealRange(source, viewRange, null, verticalType, revealHorizontal, scrollType);
}
public scrollTo(desiredScrollTop: number): void {
@@ -594,19 +594,19 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors {
}
} else {
if (viewPositions.length > 1) {
// no revealing!
this.emitCursorRevealRange(source, null, this._cursors.getViewSelections(), verticalType, revealHorizontal, scrollType);
return;
}
}
const viewRange = new Range(viewPosition.lineNumber, viewPosition.column, viewPosition.lineNumber, viewPosition.column);
this.emitCursorRevealRange(source, viewRange, verticalType, revealHorizontal, scrollType);
this.emitCursorRevealRange(source, viewRange, null, verticalType, revealHorizontal, scrollType);
}
public emitCursorRevealRange(source: string, viewRange: Range, verticalType: viewEvents.VerticalRevealType, revealHorizontal: boolean, scrollType: editorCommon.ScrollType) {
public emitCursorRevealRange(source: string, viewRange: Range | null, viewSelections: Selection[] | null, verticalType: viewEvents.VerticalRevealType, revealHorizontal: boolean, scrollType: editorCommon.ScrollType) {
try {
const eventsCollector = this._beginEmit();
eventsCollector.emit(new viewEvents.ViewRevealRangeRequestEvent(source, viewRange, verticalType, revealHorizontal, scrollType));
eventsCollector.emit(new viewEvents.ViewRevealRangeRequestEvent(source, viewRange, viewSelections, verticalType, revealHorizontal, scrollType));
} finally {
this._endEmit();
}
@@ -779,7 +779,7 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors {
}
private _type(source: string, text: string): void {
if (!this._isDoingComposition && source === 'keyboard') {
if (source === 'keyboard') {
// If this event is coming straight from the keyboard, look for electric characters and enter
const len = text.length;
@@ -790,7 +790,7 @@ export class Cursor extends viewEvents.ViewEventEmitter implements ICursors {
// Here we must interpret each typed character individually
const autoClosedCharacters = AutoClosedAction.getAllAutoClosedCharacters(this._autoClosedActions);
this._executeEditOperation(TypeOperations.typeWithInterceptors(this._prevEditOperationType, this.context.config, this.context.model, this.getSelections(), autoClosedCharacters, chr));
this._executeEditOperation(TypeOperations.typeWithInterceptors(this._isDoingComposition, this._prevEditOperationType, this.context.config, this.context.model, this.getSelections(), autoClosedCharacters, chr));
offset += charLength;
}

View File

@@ -411,7 +411,7 @@ export class CursorMoveCommands {
let newViewState = MoveOperations.moveLeft(context.config, context.viewModel, cursor.viewState, inSelectionMode, noOfColumns);
if (noOfColumns === 1 && newViewState.position.lineNumber !== cursor.viewState.position.lineNumber) {
if (!cursor.viewState.hasSelection() && noOfColumns === 1 && newViewState.position.lineNumber !== cursor.viewState.position.lineNumber) {
// moved over to the previous view line
const newViewModelPosition = context.viewModel.coordinatesConverter.convertViewPositionToModelPosition(newViewState.position);
if (newViewModelPosition.lineNumber === cursor.modelState.position.lineNumber) {
@@ -442,7 +442,7 @@ export class CursorMoveCommands {
const cursor = cursors[i];
let newViewState = MoveOperations.moveRight(context.config, context.viewModel, cursor.viewState, inSelectionMode, noOfColumns);
if (noOfColumns === 1 && newViewState.position.lineNumber !== cursor.viewState.position.lineNumber) {
if (!cursor.viewState.hasSelection() && noOfColumns === 1 && newViewState.position.lineNumber !== cursor.viewState.position.lineNumber) {
// moved over to the next view line
const newViewModelPosition = context.viewModel.coordinatesConverter.convertViewPositionToModelPosition(newViewState.position);
if (newViewModelPosition.lineNumber === cursor.modelState.position.lineNumber) {

View File

@@ -91,9 +91,10 @@ export class MoveOperations {
public static down(config: CursorConfiguration, model: ICursorSimpleModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnLastLine: boolean): CursorPosition {
const currentVisibleColumn = CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize) + leftoverVisibleColumns;
const lineCount = model.getLineCount();
const wasOnLastPosition = (lineNumber === lineCount && column === model.getLineMaxColumn(lineNumber));
lineNumber = lineNumber + count;
let lineCount = model.getLineCount();
if (lineNumber > lineCount) {
lineNumber = lineCount;
if (allowMoveOnLastLine) {
@@ -105,7 +106,11 @@ export class MoveOperations {
column = CursorColumns.columnFromVisibleColumn2(config, model, lineNumber, currentVisibleColumn);
}
leftoverVisibleColumns = currentVisibleColumn - CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize);
if (wasOnLastPosition) {
leftoverVisibleColumns = 0;
} else {
leftoverVisibleColumns = currentVisibleColumn - CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize);
}
return new CursorPosition(lineNumber, column, leftoverVisibleColumns);
}
@@ -144,6 +149,7 @@ export class MoveOperations {
public static up(config: CursorConfiguration, model: ICursorSimpleModel, lineNumber: number, column: number, leftoverVisibleColumns: number, count: number, allowMoveOnFirstLine: boolean): CursorPosition {
const currentVisibleColumn = CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize) + leftoverVisibleColumns;
const wasOnFirstPosition = (lineNumber === 1 && column === 1);
lineNumber = lineNumber - count;
if (lineNumber < 1) {
@@ -157,7 +163,11 @@ export class MoveOperations {
column = CursorColumns.columnFromVisibleColumn2(config, model, lineNumber, currentVisibleColumn);
}
leftoverVisibleColumns = currentVisibleColumn - CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize);
if (wasOnFirstPosition) {
leftoverVisibleColumns = 0;
} else {
leftoverVisibleColumns = currentVisibleColumn - CursorColumns.visibleColumnFromColumn(model.getLineContent(lineNumber), column, config.tabSize);
}
return new CursorPosition(lineNumber, column, leftoverVisibleColumns);
}

View File

@@ -269,9 +269,15 @@ export class TypeOperations {
commands[i] = null;
continue;
}
let pos = selection.getPosition();
let startColumn = Math.max(1, pos.column - replaceCharCnt);
let range = new Range(pos.lineNumber, startColumn, pos.lineNumber, pos.column);
const pos = selection.getPosition();
const startColumn = Math.max(1, pos.column - replaceCharCnt);
const range = new Range(pos.lineNumber, startColumn, pos.lineNumber, pos.column);
const oldText = model.getValueInRange(range);
if (oldText === txt) {
// => ignore composition that doesn't do anything
commands[i] = null;
continue;
}
commands[i] = new ReplaceCommand(range, txt);
}
return new EditOperationResult(EditOperationType.Typing, commands, {
@@ -796,9 +802,9 @@ export class TypeOperations {
return null;
}
public static typeWithInterceptors(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult {
public static typeWithInterceptors(isDoingComposition: boolean, prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], autoClosedCharacters: Range[], ch: string): EditOperationResult {
if (ch === '\n') {
if (!isDoingComposition && ch === '\n') {
let commands: ICommand[] = [];
for (let i = 0, len = selections.length; i < len; i++) {
commands[i] = TypeOperations._enter(config, model, false, selections[i]);
@@ -809,7 +815,7 @@ export class TypeOperations {
});
}
if (this._isAutoIndentType(config, model, selections)) {
if (!isDoingComposition && this._isAutoIndentType(config, model, selections)) {
let commands: Array<ICommand | null> = [];
let autoIndentFails = false;
for (let i = 0, len = selections.length; i < len; i++) {
@@ -827,13 +833,15 @@ export class TypeOperations {
}
}
if (this._isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) {
if (!isDoingComposition && this._isAutoClosingOvertype(config, model, selections, autoClosedCharacters, ch)) {
return this._runAutoClosingOvertype(prevEditOperationType, config, model, selections, ch);
}
const autoClosingPairOpenCharType = this._isAutoClosingOpenCharType(config, model, selections, ch, true);
if (autoClosingPairOpenCharType) {
return this._runAutoClosingOpenCharType(prevEditOperationType, config, model, selections, ch, true, autoClosingPairOpenCharType);
if (!isDoingComposition) {
const autoClosingPairOpenCharType = this._isAutoClosingOpenCharType(config, model, selections, ch, true);
if (autoClosingPairOpenCharType) {
return this._runAutoClosingOpenCharType(prevEditOperationType, config, model, selections, ch, true, autoClosingPairOpenCharType);
}
}
if (this._isSurroundSelectionType(config, model, selections, ch)) {
@@ -842,7 +850,7 @@ export class TypeOperations {
// Electric characters make sense only when dealing with a single cursor,
// as multiple cursors typing brackets for example would interfer with bracket matching
if (this._isTypeInterceptorElectricChar(config, model, selections)) {
if (!isDoingComposition && this._isTypeInterceptorElectricChar(config, model, selections)) {
const r = this._typeInterceptorElectricChar(prevEditOperationType, config, model, selections[0], ch);
if (r) {
return r;

View File

@@ -10,6 +10,7 @@ import { WordCharacterClass, WordCharacterClassifier, getMapForWordSeparators }
import { Position } from 'vs/editor/common/core/position';
import { Range } from 'vs/editor/common/core/range';
import { Selection } from 'vs/editor/common/core/selection';
import { ITextModel, IWordAtPosition } from 'vs/editor/common/model';
interface IFindWordResult {
/**
@@ -535,6 +536,28 @@ export class WordOperations {
return new Range(pos.lineNumber, pos.column, toPosition.lineNumber, toPosition.column);
}
private static _createWordAtPosition(model: ITextModel, lineNumber: number, word: IFindWordResult): IWordAtPosition {
const range = new Range(lineNumber, word.start + 1, lineNumber, word.end + 1);
return {
word: model.getValueInRange(range),
startColumn: range.startColumn,
endColumn: range.endColumn
};
}
public static getWordAtPosition(model: ITextModel, _wordSeparators: string, position: Position): IWordAtPosition | null {
const wordSeparators = getMapForWordSeparators(_wordSeparators);
const prevWord = WordOperations._findPreviousWordOnLine(wordSeparators, model, position);
if (prevWord && prevWord.wordType === WordType.Regular && prevWord.start <= position.column - 1 && position.column - 1 <= prevWord.end) {
return WordOperations._createWordAtPosition(model, position.lineNumber, prevWord);
}
const nextWord = WordOperations._findNextWordOnLine(wordSeparators, model, position);
if (nextWord && nextWord.wordType === WordType.Regular && nextWord.start <= position.column - 1 && position.column - 1 <= nextWord.end) {
return WordOperations._createWordAtPosition(model, position.lineNumber, nextWord);
}
return null;
}
public static word(config: CursorConfiguration, model: ICursorSimpleModel, cursor: SingleCursorState, inSelectionMode: boolean, position: Position): SingleCursorState {
const wordSeparators = getMapForWordSeparators(config.wordSeparators);
let prevWord = WordOperations._findPreviousWordOnLine(wordSeparators, model, position);

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { IEditorAction } from 'vs/editor/common/editorCommon';
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
import { IContextKeyService, ContextKeyExpression } from 'vs/platform/contextkey/common/contextkey';
export class InternalEditorAction implements IEditorAction {
@@ -12,7 +12,7 @@ export class InternalEditorAction implements IEditorAction {
public readonly label: string;
public readonly alias: string;
private readonly _precondition: ContextKeyExpr | undefined;
private readonly _precondition: ContextKeyExpression | undefined;
private readonly _run: () => Promise<void>;
private readonly _contextKeyService: IContextKeyService;
@@ -20,7 +20,7 @@ export class InternalEditorAction implements IEditorAction {
id: string,
label: string,
alias: string,
precondition: ContextKeyExpr | undefined,
precondition: ContextKeyExpression | undefined,
run: () => Promise<void>,
contextKeyService: IContextKeyService
) {

View File

@@ -3,7 +3,7 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { ContextKeyExpr, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
export namespace EditorContextKeys {
@@ -24,13 +24,13 @@ export namespace EditorContextKeys {
export const readOnly = new RawContextKey<boolean>('editorReadonly', false);
export const columnSelection = new RawContextKey<boolean>('editorColumnSelection', false);
export const writable: ContextKeyExpr = readOnly.toNegated();
export const writable = readOnly.toNegated();
export const hasNonEmptySelection = new RawContextKey<boolean>('editorHasSelection', false);
export const hasOnlyEmptySelection: ContextKeyExpr = hasNonEmptySelection.toNegated();
export const hasOnlyEmptySelection = hasNonEmptySelection.toNegated();
export const hasMultipleSelections = new RawContextKey<boolean>('editorHasMultipleSelections', false);
export const hasSingleSelection: ContextKeyExpr = hasMultipleSelections.toNegated();
export const hasSingleSelection = hasMultipleSelections.toNegated();
export const tabMovesFocus = new RawContextKey<boolean>('editorTabMovesFocus', false);
export const tabDoesNotMoveFocus: ContextKeyExpr = tabMovesFocus.toNegated();
export const tabDoesNotMoveFocus = tabMovesFocus.toNegated();
export const isInEmbeddedEditor = new RawContextKey<boolean>('isInEmbeddedEditor', false);
export const canUndo = new RawContextKey<boolean>('canUndo', false);
export const canRedo = new RawContextKey<boolean>('canRedo', false);

View File

@@ -123,6 +123,10 @@ export interface IModelDecorationOptions {
* If set, the decoration will be rendered in the lines decorations with this CSS class name.
*/
linesDecorationsClassName?: string | null;
/**
* If set, the decoration will be rendered in the lines decorations with this CSS class name, but only for the first line in case of line wrapping.
*/
firstLineDecorationClassName?: string | null;
/**
* If set, the decoration will be rendered in the margin (covering its full width) with this CSS class name.
*/

View File

@@ -3053,6 +3053,7 @@ export class ModelDecorationOptions implements model.IModelDecorationOptions {
readonly minimap: ModelDecorationMinimapOptions | null;
readonly glyphMarginClassName: string | null;
readonly linesDecorationsClassName: string | null;
readonly firstLineDecorationClassName: string | null;
readonly marginClassName: string | null;
readonly inlineClassName: string | null;
readonly inlineClassNameAffectsLetterSpacing: boolean;
@@ -3072,6 +3073,7 @@ export class ModelDecorationOptions implements model.IModelDecorationOptions {
this.minimap = options.minimap ? new ModelDecorationMinimapOptions(options.minimap) : null;
this.glyphMarginClassName = options.glyphMarginClassName ? cleanClassName(options.glyphMarginClassName) : null;
this.linesDecorationsClassName = options.linesDecorationsClassName ? cleanClassName(options.linesDecorationsClassName) : null;
this.firstLineDecorationClassName = options.firstLineDecorationClassName ? cleanClassName(options.firstLineDecorationClassName) : null;
this.marginClassName = options.marginClassName ? cleanClassName(options.marginClassName) : null;
this.inlineClassName = options.inlineClassName ? cleanClassName(options.inlineClassName) : null;
this.inlineClassNameAffectsLetterSpacing = options.inlineClassNameAffectsLetterSpacing || false;

View File

@@ -515,7 +515,7 @@ export class Searcher {
private _prevMatchStartIndex: number;
private _prevMatchLength: number;
constructor(wordSeparators: WordCharacterClassifier | null, searchRegex: RegExp, ) {
constructor(wordSeparators: WordCharacterClassifier | null, searchRegex: RegExp,) {
this._wordSeparators = wordSeparators;
this._searchRegex = searchRegex;
this._prevMatchStartIndex = -1;

View File

@@ -781,6 +781,17 @@ export class TokensStore2 {
let aIndex = 0;
let result: number[] = [], resultLen = 0;
let lastEndOffset = 0;
const emitToken = (endOffset: number, metadata: number) => {
if (endOffset === lastEndOffset) {
return;
}
lastEndOffset = endOffset;
result[resultLen++] = endOffset;
result[resultLen++] = metadata;
};
for (let bIndex = 0; bIndex < bLen; bIndex++) {
const bStartCharacter = bTokens.getStartCharacter(bIndex);
const bEndCharacter = bTokens.getEndCharacter(bIndex);
@@ -797,42 +808,36 @@ export class TokensStore2 {
// push any token from `a` that is before `b`
while (aIndex < aLen && aTokens.getEndOffset(aIndex) <= bStartCharacter) {
result[resultLen++] = aTokens.getEndOffset(aIndex);
result[resultLen++] = aTokens.getMetadata(aIndex);
emitToken(aTokens.getEndOffset(aIndex), aTokens.getMetadata(aIndex));
aIndex++;
}
// push the token from `a` if it intersects the token from `b`
if (aIndex < aLen && aTokens.getStartOffset(aIndex) < bStartCharacter) {
result[resultLen++] = bStartCharacter;
result[resultLen++] = aTokens.getMetadata(aIndex);
emitToken(bStartCharacter, aTokens.getMetadata(aIndex));
}
// skip any tokens from `a` that are contained inside `b`
while (aIndex < aLen && aTokens.getEndOffset(aIndex) < bEndCharacter) {
result[resultLen++] = aTokens.getEndOffset(aIndex);
result[resultLen++] = (aTokens.getMetadata(aIndex) & aMask) | (bMetadata & bMask);
emitToken(aTokens.getEndOffset(aIndex), (aTokens.getMetadata(aIndex) & aMask) | (bMetadata & bMask));
aIndex++;
}
if (aIndex < aLen && aTokens.getEndOffset(aIndex) === bEndCharacter) {
// `a` ends exactly at the same spot as `b`!
result[resultLen++] = aTokens.getEndOffset(aIndex);
result[resultLen++] = (aTokens.getMetadata(aIndex) & aMask) | (bMetadata & bMask);
emitToken(aTokens.getEndOffset(aIndex), (aTokens.getMetadata(aIndex) & aMask) | (bMetadata & bMask));
aIndex++;
} else {
const aMergeIndex = Math.min(Math.max(0, aIndex - 1), aLen - 1);
// push the token from `b`
result[resultLen++] = bEndCharacter;
result[resultLen++] = (aTokens.getMetadata(aMergeIndex) & aMask) | (bMetadata & bMask);
emitToken(bEndCharacter, (aTokens.getMetadata(aMergeIndex) & aMask) | (bMetadata & bMask));
}
}
// push the remaining tokens from `a`
while (aIndex < aLen) {
result[resultLen++] = aTokens.getEndOffset(aIndex);
result[resultLen++] = aTokens.getMetadata(aIndex);
emitToken(aTokens.getEndOffset(aIndex), aTokens.getMetadata(aIndex));
aIndex++;
}

View File

@@ -1246,11 +1246,11 @@ export interface SelectionRangeProvider {
export interface FoldingContext {
}
/**
* A provider of colors for editor models.
* A provider of folding ranges for editor models.
*/
export interface FoldingRangeProvider {
/**
* Provides the color ranges for a specific model.
* Provides the folding ranges for a specific model.
*/
provideFoldingRanges(model: model.ITextModel, context: FoldingContext, token: CancellationToken): ProviderResult<FoldingRange[]>;
}
@@ -1589,6 +1589,7 @@ export interface SemanticTokensEdits {
}
export interface DocumentSemanticTokensProvider {
onDidChange?: Event<void>;
getLegend(): SemanticTokensLegend;
provideDocumentSemanticTokens(model: model.ITextModel, lastResultId: string | null, token: CancellationToken): ProviderResult<SemanticTokens | SemanticTokensEdits>;
releaseDocumentSemanticTokens(resultId: string | undefined): void;

View File

@@ -5,7 +5,6 @@
import { mergeSort } from 'vs/base/common/arrays';
import { stringDiff } from 'vs/base/common/diff/diff';
import { FIN, Iterator, IteratorResult } from 'vs/base/common/iterator';
import { IDisposable } from 'vs/base/common/lifecycle';
import { globals } from 'vs/base/common/platform';
import { URI } from 'vs/base/common/uri';
@@ -65,7 +64,7 @@ export interface ICommonModel extends ILinkComputerTarget, IMirrorModel {
getLineCount(): number;
getLineContent(lineNumber: number): string;
getLineWords(lineNumber: number, wordDefinition: RegExp): IWordAtPosition[];
createWordIterator(wordDefinition: RegExp): Iterator<string>;
words(wordDefinition: RegExp): Iterable<string>;
getWordUntilPosition(position: IPosition, wordDefinition: RegExp): IWordAtPosition;
getValueInRange(range: IRange): string;
getWordAtPosition(position: IPosition, wordDefinition: RegExp): Range | null;
@@ -153,36 +152,37 @@ class MirrorModel extends BaseMirrorModel implements ICommonModel {
};
}
public createWordIterator(wordDefinition: RegExp): Iterator<string> {
let obj: { done: false; value: string; };
public words(wordDefinition: RegExp): Iterable<string> {
const lines = this._lines;
const wordenize = this._wordenize.bind(this);
let lineNumber = 0;
let lineText: string;
let lineText = '';
let wordRangesIdx = 0;
let wordRanges: IWordRange[] = [];
let next = (): IteratorResult<string> => {
if (wordRangesIdx < wordRanges.length) {
const value = lineText.substring(wordRanges[wordRangesIdx].start, wordRanges[wordRangesIdx].end);
wordRangesIdx += 1;
if (!obj) {
obj = { done: false, value: value };
} else {
obj.value = value;
return {
*[Symbol.iterator]() {
while (true) {
if (wordRangesIdx < wordRanges.length) {
const value = lineText.substring(wordRanges[wordRangesIdx].start, wordRanges[wordRangesIdx].end);
wordRangesIdx += 1;
yield value;
} else {
if (lineNumber < lines.length) {
lineText = lines[lineNumber];
wordRanges = wordenize(lineText, wordDefinition);
wordRangesIdx = 0;
lineNumber += 1;
} else {
break;
}
}
}
return obj;
} else if (lineNumber >= this._lines.length) {
return FIN;
} else {
lineText = this._lines[lineNumber];
wordRanges = this._wordenize(lineText, wordDefinition);
wordRangesIdx = 0;
lineNumber += 1;
return next();
}
};
return { next };
}
public getLineWords(lineNumber: number, wordDefinition: RegExp): IWordAtPosition[] {
@@ -545,12 +545,7 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable {
seen.add(model.getValueInRange(wordAt));
}
for (
let iter = model.createWordIterator(wordDefRegExp), e = iter.next();
!e.done && seen.size <= EditorSimpleWorker._suggestionsLimit;
e = iter.next()
) {
const word = e.value;
for (let word of model.words(wordDefRegExp)) {
if (seen.has(word)) {
continue;
}
@@ -559,6 +554,9 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable {
continue;
}
words.push(word);
if (seen.size > EditorSimpleWorker._suggestionsLimit) {
break;
}
}
return words;
}

View File

@@ -31,6 +31,7 @@ export interface IModeService {
_serviceBrand: undefined;
onDidCreateMode: Event<IMode>;
onLanguagesMaybeChanged: Event<void>;
// --- reading
isRegisteredMode(mimetypeOrModeId: string): boolean;

View File

@@ -50,7 +50,7 @@ export class ModeServiceImpl implements IModeService {
public readonly onDidCreateMode: Event<IMode> = this._onDidCreateMode.event;
protected readonly _onLanguagesMaybeChanged = new Emitter<void>();
private readonly onLanguagesMaybeChanged: Event<void> = this._onLanguagesMaybeChanged.event;
public readonly onLanguagesMaybeChanged: Event<void> = this._onLanguagesMaybeChanged.event;
constructor(warnOnOverwrite = false) {
this._instantiatedModes = {};

View File

@@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import { Emitter, Event } from 'vs/base/common/event';
import { Disposable, IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
import { Disposable, IDisposable, DisposableStore, dispose } from 'vs/base/common/lifecycle';
import * as platform from 'vs/base/common/platform';
import * as errors from 'vs/base/common/errors';
import { URI } from 'vs/base/common/uri';
@@ -207,11 +207,22 @@ export class ModelServiceImpl extends Disposable implements IModelService {
};
}
private _getEOL(resource: URI | undefined, language: string): string {
if (resource) {
return this._resourcePropertiesService.getEOL(resource, language);
}
const eol = this._configurationService.getValue<string>('files.eol', { overrideIdentifier: language });
if (eol && eol !== 'auto') {
return eol;
}
return platform.OS === platform.OperatingSystem.Linux || platform.OS === platform.OperatingSystem.Macintosh ? '\n' : '\r\n';
}
public getCreationOptions(language: string, resource: URI | undefined, isForSimpleWidget: boolean): ITextModelCreationOptions {
let creationOptions = this._modelCreationOptionsByLanguageAndResource[language + resource];
if (!creationOptions) {
const editor = this._configurationService.getValue<IRawEditorConfig>('editor', { overrideIdentifier: language, resource });
const eol = this._resourcePropertiesService.getEOL(resource, language);
const eol = this._getEOL(resource, language);
creationOptions = ModelServiceImpl._readModelOptions({ editor, eol }, isForSimpleWidget);
this._modelCreationOptionsByLanguageAndResource[language + resource] = creationOptions;
}
@@ -516,7 +527,7 @@ class SemanticStyling extends Disposable {
this._caches = new WeakMap<DocumentSemanticTokensProvider, SemanticColoringProviderStyling>();
if (this._themeService) {
// workaround for tests which use undefined... :/
this._register(this._themeService.onThemeChange(() => {
this._register(this._themeService.onDidColorThemeChange(() => {
this._caches = new WeakMap<DocumentSemanticTokensProvider, SemanticColoringProviderStyling>();
}));
}
@@ -651,7 +662,7 @@ class SemanticColoringProviderStyling {
modifierSet = modifierSet >> 1;
}
const tokenStyle = this._themeService.getTheme().getTokenStyleMetadata(tokenType, tokenModifiers);
const tokenStyle = this._themeService.getColorTheme().getTokenStyleMetadata(tokenType, tokenModifiers);
if (typeof tokenStyle === 'undefined') {
metadata = Constants.NO_STYLING;
} else {
@@ -724,6 +735,7 @@ class ModelSemanticColoring extends Disposable {
private readonly _fetchSemanticTokens: RunOnceScheduler;
private _currentResponse: SemanticTokensResponse | null;
private _currentRequestCancellationTokenSource: CancellationTokenSource | null;
private _providersChangeListeners: IDisposable[];
constructor(model: ITextModel, themeService: IThemeService, stylingProvider: SemanticStyling) {
super();
@@ -734,16 +746,31 @@ class ModelSemanticColoring extends Disposable {
this._fetchSemanticTokens = this._register(new RunOnceScheduler(() => this._fetchSemanticTokensNow(), 300));
this._currentResponse = null;
this._currentRequestCancellationTokenSource = null;
this._providersChangeListeners = [];
this._register(this._model.onDidChangeContent(e => {
if (!this._fetchSemanticTokens.isScheduled()) {
this._fetchSemanticTokens.schedule();
}
}));
this._register(DocumentSemanticTokensProviderRegistry.onDidChange(e => this._fetchSemanticTokens.schedule()));
const bindChangeListeners = () => {
dispose(this._providersChangeListeners);
this._providersChangeListeners = [];
for (const provider of DocumentSemanticTokensProviderRegistry.all(model)) {
if (typeof provider.onDidChange === 'function') {
this._providersChangeListeners.push(provider.onDidChange(() => this._fetchSemanticTokens.schedule(0)));
}
}
};
bindChangeListeners();
this._register(DocumentSemanticTokensProviderRegistry.onDidChange(e => {
bindChangeListeners();
this._fetchSemanticTokens.schedule();
}));
if (themeService) {
// workaround for tests which use undefined... :/
this._register(themeService.onThemeChange(_ => {
this._register(themeService.onDidColorThemeChange(_ => {
// clear out existing tokens
this._setSemanticTokens(null, null, null, []);
this._fetchSemanticTokens.schedule();

View File

@@ -75,5 +75,5 @@ export interface ITextResourcePropertiesService {
/**
* Returns the End of Line characters for the given resource
*/
getEOL(resource: URI | undefined, language?: string): string;
getEOL(resource: URI, language?: string): string;
}

View File

@@ -1,17 +0,0 @@
{
"registrations": [
{
"component": {
"type": "git",
"git": {
"name": "promise-polyfill",
"repositoryUrl": "https://github.com/taylorhakes/promise-polyfill",
"commitHash": "efe662be6ea569c439ec92a4f8662c0a7faf0b96"
}
},
"license": "MIT",
"version": "8.0.0"
}
],
"version": 1
}

View File

@@ -1,291 +0,0 @@
/*!
Copyright (c) 2014 Taylor Hakes
Copyright (c) 2014 Forbes Lindesay
*/
(function (global, factory) {
typeof exports === 'object' && typeof module !== 'undefined' ? factory() :
typeof define === 'function' && define.amd ? define(factory) :
(factory());
}(this, (function () {
'use strict';
/**
* @this {Promise}
*/
function finallyConstructor(callback) {
var constructor = this.constructor;
return this.then(
function (value) {
return constructor.resolve(callback()).then(function () {
return value;
});
},
function (reason) {
return constructor.resolve(callback()).then(function () {
return constructor.reject(reason);
});
}
);
}
// Store setTimeout reference so promise-polyfill will be unaffected by
// other code modifying setTimeout (like sinon.useFakeTimers())
var setTimeoutFunc = setTimeout;
function noop() { }
// Polyfill for Function.prototype.bind
function bind(fn, thisArg) {
return function () {
fn.apply(thisArg, arguments);
};
}
/**
* @constructor
* @param {Function} fn
*/
function Promise(fn) {
if (!(this instanceof Promise))
throw new TypeError('Promises must be constructed via new');
if (typeof fn !== 'function') throw new TypeError('not a function');
/** @type {!number} */
this._state = 0;
/** @type {!boolean} */
this._handled = false;
/** @type {Promise|undefined} */
this._value = undefined;
/** @type {!Array<!Function>} */
this._deferreds = [];
doResolve(fn, this);
}
function handle(self, deferred) {
while (self._state === 3) {
self = self._value;
}
if (self._state === 0) {
self._deferreds.push(deferred);
return;
}
self._handled = true;
Promise._immediateFn(function () {
var cb = self._state === 1 ? deferred.onFulfilled : deferred.onRejected;
if (cb === null) {
(self._state === 1 ? resolve : reject)(deferred.promise, self._value);
return;
}
var ret;
try {
ret = cb(self._value);
} catch (e) {
reject(deferred.promise, e);
return;
}
resolve(deferred.promise, ret);
});
}
function resolve(self, newValue) {
try {
// Promise Resolution Procedure: https://github.com/promises-aplus/promises-spec#the-promise-resolution-procedure
if (newValue === self)
throw new TypeError('A promise cannot be resolved with itself.');
if (
newValue &&
(typeof newValue === 'object' || typeof newValue === 'function')
) {
var then = newValue.then;
if (newValue instanceof Promise) {
self._state = 3;
self._value = newValue;
finale(self);
return;
} else if (typeof then === 'function') {
doResolve(bind(then, newValue), self);
return;
}
}
self._state = 1;
self._value = newValue;
finale(self);
} catch (e) {
reject(self, e);
}
}
function reject(self, newValue) {
self._state = 2;
self._value = newValue;
finale(self);
}
function finale(self) {
if (self._state === 2 && self._deferreds.length === 0) {
Promise._immediateFn(function () {
if (!self._handled) {
Promise._unhandledRejectionFn(self._value);
}
});
}
for (var i = 0, len = self._deferreds.length; i < len; i++) {
handle(self, self._deferreds[i]);
}
self._deferreds = null;
}
/**
* @constructor
*/
function Handler(onFulfilled, onRejected, promise) {
this.onFulfilled = typeof onFulfilled === 'function' ? onFulfilled : null;
this.onRejected = typeof onRejected === 'function' ? onRejected : null;
this.promise = promise;
}
/**
* Take a potentially misbehaving resolver function and make sure
* onFulfilled and onRejected are only called once.
*
* Makes no guarantees about asynchrony.
*/
function doResolve(fn, self) {
var done = false;
try {
fn(
function (value) {
if (done) return;
done = true;
resolve(self, value);
},
function (reason) {
if (done) return;
done = true;
reject(self, reason);
}
);
} catch (ex) {
if (done) return;
done = true;
reject(self, ex);
}
}
Promise.prototype['catch'] = function (onRejected) {
return this.then(null, onRejected);
};
Promise.prototype.then = function (onFulfilled, onRejected) {
// @ts-ignore
var prom = new this.constructor(noop);
handle(this, new Handler(onFulfilled, onRejected, prom));
return prom;
};
Promise.prototype['finally'] = finallyConstructor;
Promise.all = function (arr) {
return new Promise(function (resolve, reject) {
if (!arr || typeof arr.length === 'undefined')
throw new TypeError('Promise.all accepts an array');
var args = Array.prototype.slice.call(arr);
if (args.length === 0) return resolve([]);
var remaining = args.length;
function res(i, val) {
try {
if (val && (typeof val === 'object' || typeof val === 'function')) {
var then = val.then;
if (typeof then === 'function') {
then.call(
val,
function (val) {
res(i, val);
},
reject
);
return;
}
}
args[i] = val;
if (--remaining === 0) {
resolve(args);
}
} catch (ex) {
reject(ex);
}
}
for (var i = 0; i < args.length; i++) {
res(i, args[i]);
}
});
};
Promise.resolve = function (value) {
if (value && typeof value === 'object' && value.constructor === Promise) {
return value;
}
return new Promise(function (resolve) {
resolve(value);
});
};
Promise.reject = function (value) {
return new Promise(function (resolve, reject) {
reject(value);
});
};
Promise.race = function (values) {
return new Promise(function (resolve, reject) {
for (var i = 0, len = values.length; i < len; i++) {
values[i].then(resolve, reject);
}
});
};
// Use polyfill for setImmediate for performance gains
Promise._immediateFn =
(typeof setImmediate === 'function' &&
function (fn) {
setImmediate(fn);
}) ||
function (fn) {
setTimeoutFunc(fn, 0);
};
Promise._unhandledRejectionFn = function _unhandledRejectionFn(err) {
if (typeof console !== 'undefined' && console) {
console.warn('Possible Unhandled Promise Rejection:', err); // eslint-disable-line no-console
}
};
/** @suppress {undefinedVars} */
var globalNS = (function () {
// the only reliable means to get the global object is
// `Function('return this')()`
// However, this causes CSP violations in Chrome apps.
if (typeof self !== 'undefined') {
return self;
}
if (typeof window !== 'undefined') {
return window;
}
if (typeof global !== 'undefined') {
return global;
}
throw new Error('unable to locate global object');
})();
if (!('Promise' in globalNS)) {
globalNS['Promise'] = Promise;
} else if (!globalNS.Promise.prototype['finally']) {
globalNS.Promise.prototype['finally'] = finallyConstructor;
}
})));

View File

@@ -1,20 +0,0 @@
Copyright (c) 2014 Taylor Hakes
Copyright (c) 2014 Forbes Lindesay
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:
The above copyright notice and this permission notice shall be included in
all copies or substantial portions of the Software.
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
THE SOFTWARE.

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'vs/editor/common/standalone/promise-polyfill/polyfill';
import { CancellationTokenSource } from 'vs/base/common/cancellation';
import { Emitter } from 'vs/base/common/event';
import { KeyChord, KeyMod as ConstKeyMod } from 'vs/base/common/keyCodes';

View File

@@ -45,6 +45,10 @@ export namespace GoToLineNLS {
export const gotoLineActionLabel = nls.localize('gotoLineActionLabel', "Go to Line...");
}
export namespace QuickHelpNLS {
export const helpQuickAccessActionLabel = nls.localize('helpQuickAccess', "Show all Quick Access Providers");
}
export namespace QuickCommandNLS {
export const ariaLabelEntryWithKey = nls.localize('ariaLabelEntryWithKey', "{0}, {1}, commands");
export const ariaLabelEntry = nls.localize('ariaLabelEntry', "{0}, commands");
@@ -71,7 +75,6 @@ export namespace QuickOutlineNLS {
export namespace StandaloneCodeEditorNLS {
export const editorViewAccessibleLabel = nls.localize('editorViewAccessibleLabel', "Editor content");
export const accessibilityHelpMessageIE = nls.localize('accessibilityHelpMessageIE', "Press Ctrl+F1 for Accessibility Options.");
export const accessibilityHelpMessage = nls.localize('accessibilityHelpMessage', "Press Alt+F1 for Accessibility Options.");
}

View File

@@ -7,23 +7,23 @@ import { IConfiguration } from 'vs/editor/common/editorCommon';
import { ViewEventDispatcher } from 'vs/editor/common/view/viewEventDispatcher';
import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
import { IViewLayout, IViewModel } from 'vs/editor/common/viewModel/viewModel';
import { ITheme, ThemeType } from 'vs/platform/theme/common/themeService';
import { IColorTheme, ThemeType } from 'vs/platform/theme/common/themeService';
import { ColorIdentifier } from 'vs/platform/theme/common/colorRegistry';
import { Color } from 'vs/base/common/color';
export class EditorTheme {
private _theme: ITheme;
private _theme: IColorTheme;
public get type(): ThemeType {
return this._theme.type;
}
constructor(theme: ITheme) {
constructor(theme: IColorTheme) {
this._theme = theme;
}
public update(theme: ITheme): void {
public update(theme: IColorTheme): void {
this._theme = theme;
}
@@ -42,7 +42,7 @@ export class ViewContext {
constructor(
configuration: IConfiguration,
theme: ITheme,
theme: IColorTheme,
model: IViewModel,
privateViewEventBus: ViewEventDispatcher
) {

View File

@@ -205,7 +205,12 @@ export class ViewRevealRangeRequestEvent {
/**
* Range to be reavealed.
*/
public readonly range: Range;
public readonly range: Range | null;
/**
* Selections to be revealed.
*/
public readonly selections: Selection[] | null;
public readonly verticalType: VerticalRevealType;
/**
@@ -221,9 +226,10 @@ export class ViewRevealRangeRequestEvent {
*/
readonly source: string;
constructor(source: string, range: Range, verticalType: VerticalRevealType, revealHorizontal: boolean, scrollType: ScrollType) {
constructor(source: string, range: Range | null, selections: Selection[] | null, verticalType: VerticalRevealType, revealHorizontal: boolean, scrollType: ScrollType) {
this.source = source;
this.range = range;
this.selections = selections;
this.verticalType = verticalType;
this.revealHorizontal = revealHorizontal;
this.scrollType = scrollType;

View File

@@ -683,7 +683,7 @@ function _applyRenderWhitespace(input: RenderLineInput, lineContent: string, len
wasInWhitespace = isInWhitespace;
if (charIndex === tokenEndIndex) {
while (charIndex === tokenEndIndex) {
tokenIndex++;
if (tokenIndex < tokensLength) {
tokenType = tokens[tokenIndex].type;