chore(vscode): update to 1.54.2

This commit is contained in:
Joe Previte
2021-03-11 10:27:10 -07:00
1459 changed files with 53404 additions and 51004 deletions

View File

@@ -509,7 +509,7 @@ const editorConfiguration: IConfigurationNode = {
nls.localize('wordBasedSuggestionsMode.matchingDocuments', 'Suggest words from all open documents of the same language.'),
nls.localize('wordBasedSuggestionsMode.allDocuments', 'Suggest words from all open documents.')
],
description: nls.localize('wordBasedSuggestionsMode', "Controls form what documents word based completions are computed.")
description: nls.localize('wordBasedSuggestionsMode', "Controls from what documents word based completions are computed.")
},
'editor.semanticHighlighting.enabled': {
enum: [true, false, 'configuredByTheme'],

View File

@@ -690,6 +690,14 @@ export interface IDiffEditorOptions extends IEditorOptions {
* Control the wrapping of the diff editor.
*/
diffWordWrap?: 'off' | 'on' | 'inherit';
/**
* Aria label for original editor.
*/
originalAriaLabel?: string;
/**
* Aria label for modifed editor.
*/
modifiedAriaLabel?: string;
}
//#endregion

View File

@@ -659,9 +659,21 @@ export class Cursor extends Disposable {
}, eventsCollector, source);
}
public replacePreviousChar(eventsCollector: ViewModelEventsCollector, text: string, replaceCharCnt: number, source?: string | null | undefined): void {
public compositionType(eventsCollector: ViewModelEventsCollector, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number, source?: string | null | undefined): void {
if (text.length === 0 && replacePrevCharCnt === 0 && replaceNextCharCnt === 0) {
// this edit is a no-op
if (positionDelta !== 0) {
// but it still wants to move the cursor
const newSelections = this.getSelections().map(selection => {
const position = selection.getPosition();
return new Selection(position.lineNumber, position.column + positionDelta, position.lineNumber, position.column + positionDelta);
});
this.setSelections(eventsCollector, source, newSelections, CursorChangeReason.NotSet);
}
return;
}
this._executeEdit(() => {
this._executeEditOperation(TypeOperations.replacePreviousChar(this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), text, replaceCharCnt));
this._executeEditOperation(TypeOperations.compositionType(this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), text, replacePrevCharCnt, replaceNextCharCnt, positionDelta));
}, eventsCollector, source);
}

View File

@@ -297,6 +297,20 @@ export class CursorMoveCommands {
return this._moveDownByModelLines(viewModel, cursors, inSelectionMode, value);
}
}
case CursorMove.Direction.PrevBlankLine: {
if (unit === CursorMove.Unit.WrappedLine) {
return cursors.map(cursor => CursorState.fromViewState(MoveOperations.moveToPrevBlankLine(viewModel.cursorConfig, viewModel, cursor.viewState, inSelectionMode)));
} else {
return cursors.map(cursor => CursorState.fromModelState(MoveOperations.moveToPrevBlankLine(viewModel.cursorConfig, viewModel.model, cursor.modelState, inSelectionMode)));
}
}
case CursorMove.Direction.NextBlankLine: {
if (unit === CursorMove.Unit.WrappedLine) {
return cursors.map(cursor => CursorState.fromViewState(MoveOperations.moveToNextBlankLine(viewModel.cursorConfig, viewModel, cursor.viewState, inSelectionMode)));
} else {
return cursors.map(cursor => CursorState.fromModelState(MoveOperations.moveToNextBlankLine(viewModel.cursorConfig, viewModel.model, cursor.modelState, inSelectionMode)));
}
}
case CursorMove.Direction.WrappedLineStart: {
// Move to the beginning of the current view line
return this._moveToViewMinColumn(viewModel, cursors, inSelectionMode);
@@ -614,7 +628,7 @@ export namespace CursorMove {
description: `Property-value pairs that can be passed through this argument:
* 'to': A mandatory logical position value providing where to move the cursor.
\`\`\`
'left', 'right', 'up', 'down'
'left', 'right', 'up', 'down', 'prevBlankLine', 'nextBlankLine',
'wrappedLineStart', 'wrappedLineEnd', 'wrappedLineColumnCenter'
'wrappedLineFirstNonWhitespaceCharacter', 'wrappedLineLastNonWhitespaceCharacter'
'viewPortTop', 'viewPortCenter', 'viewPortBottom', 'viewPortIfOutside'
@@ -633,7 +647,7 @@ export namespace CursorMove {
'properties': {
'to': {
'type': 'string',
'enum': ['left', 'right', 'up', 'down', 'wrappedLineStart', 'wrappedLineEnd', 'wrappedLineColumnCenter', 'wrappedLineFirstNonWhitespaceCharacter', 'wrappedLineLastNonWhitespaceCharacter', 'viewPortTop', 'viewPortCenter', 'viewPortBottom', 'viewPortIfOutside']
'enum': ['left', 'right', 'up', 'down', 'prevBlankLine', 'nextBlankLine', 'wrappedLineStart', 'wrappedLineEnd', 'wrappedLineColumnCenter', 'wrappedLineFirstNonWhitespaceCharacter', 'wrappedLineLastNonWhitespaceCharacter', 'viewPortTop', 'viewPortCenter', 'viewPortBottom', 'viewPortIfOutside']
},
'by': {
'type': 'string',
@@ -662,6 +676,9 @@ export namespace CursorMove {
Up: 'up',
Down: 'down',
PrevBlankLine: 'prevBlankLine',
NextBlankLine: 'nextBlankLine',
WrappedLineStart: 'wrappedLineStart',
WrappedLineFirstNonWhitespaceCharacter: 'wrappedLineFirstNonWhitespaceCharacter',
WrappedLineColumnCenter: 'wrappedLineColumnCenter',
@@ -715,6 +732,12 @@ export namespace CursorMove {
case RawDirection.Down:
direction = Direction.Down;
break;
case RawDirection.PrevBlankLine:
direction = Direction.PrevBlankLine;
break;
case RawDirection.NextBlankLine:
direction = Direction.NextBlankLine;
break;
case RawDirection.WrappedLineStart:
direction = Direction.WrappedLineStart;
break;
@@ -790,6 +813,8 @@ export namespace CursorMove {
Right,
Up,
Down,
PrevBlankLine,
NextBlankLine,
WrappedLineStart,
WrappedLineFirstNonWhitespaceCharacter,
@@ -809,6 +834,8 @@ export namespace CursorMove {
| Direction.Right
| Direction.Up
| Direction.Down
| Direction.PrevBlankLine
| Direction.NextBlankLine
| Direction.WrappedLineStart
| Direction.WrappedLineFirstNonWhitespaceCharacter
| Direction.WrappedLineColumnCenter

View File

@@ -229,6 +229,47 @@ export class MoveOperations {
);
}
private static _isBlankLine(model: ICursorSimpleModel, lineNumber: number): boolean {
if (model.getLineFirstNonWhitespaceColumn(lineNumber) === 0) {
// empty or contains only whitespace
return true;
}
return false;
}
public static moveToPrevBlankLine(config: CursorConfiguration, model: ICursorSimpleModel, cursor: SingleCursorState, inSelectionMode: boolean): SingleCursorState {
let lineNumber = cursor.position.lineNumber;
// If our current line is blank, move to the previous non-blank line
while (lineNumber > 1 && this._isBlankLine(model, lineNumber)) {
lineNumber--;
}
// Find the previous blank line
while (lineNumber > 1 && !this._isBlankLine(model, lineNumber)) {
lineNumber--;
}
return cursor.move(inSelectionMode, lineNumber, model.getLineMinColumn(lineNumber), 0);
}
public static moveToNextBlankLine(config: CursorConfiguration, model: ICursorSimpleModel, cursor: SingleCursorState, inSelectionMode: boolean): SingleCursorState {
const lineCount = model.getLineCount();
let lineNumber = cursor.position.lineNumber;
// If our current line is blank, move to the next non-blank line
while (lineNumber < lineCount && this._isBlankLine(model, lineNumber)) {
lineNumber++;
}
// Find the next blank line
while (lineNumber < lineCount && !this._isBlankLine(model, lineNumber)) {
lineNumber++;
}
return cursor.move(inSelectionMode, lineNumber, model.getLineMinColumn(lineNumber), 0);
}
public static moveToBeginningOfLine(config: CursorConfiguration, model: ICursorSimpleModel, cursor: SingleCursorState, inSelectionMode: boolean): SingleCursorState {
let lineNumber = cursor.position.lineNumber;
let minColumn = model.getLineMinColumn(lineNumber);

View File

@@ -258,34 +258,33 @@ export class TypeOperations {
return commands;
}
public static replacePreviousChar(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], txt: string, replaceCharCnt: number): EditOperationResult {
let commands: Array<ICommand | null> = [];
for (let i = 0, len = selections.length; i < len; i++) {
const selection = selections[i];
if (!selection.isEmpty()) {
// looks like https://github.com/microsoft/vscode/issues/2773
// where a cursor operation occurred before a canceled composition
// => ignore composition
commands[i] = null;
continue;
}
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);
}
public static compositionType(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ITextModel, selections: Selection[], text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number): EditOperationResult {
const commands = selections.map(selection => this._compositionType(model, selection, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta));
return new EditOperationResult(EditOperationType.Typing, commands, {
shouldPushStackElementBefore: (prevEditOperationType !== EditOperationType.Typing),
shouldPushStackElementAfter: false
});
}
private static _compositionType(model: ITextModel, selection: Selection, text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number): ICommand | null {
if (!selection.isEmpty()) {
// looks like https://github.com/microsoft/vscode/issues/2773
// where a cursor operation occurred before a canceled composition
// => ignore composition
return null;
}
const pos = selection.getPosition();
const startColumn = Math.max(1, pos.column - replacePrevCharCnt);
const endColumn = Math.min(model.getLineMaxColumn(pos.lineNumber), pos.column + replaceNextCharCnt);
const range = new Range(pos.lineNumber, startColumn, pos.lineNumber, endColumn);
const oldText = model.getValueInRange(range);
if (oldText === text && positionDelta === 0) {
// => ignore composition that doesn't do anything
return null;
}
return new ReplaceCommandWithOffsetCursorState(range, text, 0, positionDelta);
}
private static _typeCommand(range: Range, text: string, keepPosition: boolean): ICommand {
if (keepPosition) {
return new ReplaceCommandWithoutChangingPosition(range, text, true);

View File

@@ -700,6 +700,7 @@ export const enum Handler {
CompositionEnd = 'compositionEnd',
Type = 'type',
ReplacePreviousChar = 'replacePreviousChar',
CompositionType = 'compositionType',
Paste = 'paste',
Cut = 'cut',
}
@@ -719,6 +720,16 @@ export interface ReplacePreviousCharPayload {
replaceCharCnt: number;
}
/**
* @internal
*/
export interface CompositionTypePayload {
text: string;
replacePrevCharCnt: number;
replaceNextCharCnt: number;
positionDelta: number;
}
/**
* @internal
*/

View File

@@ -3,70 +3,71 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vs/nls';
import { RawContextKey } from 'vs/platform/contextkey/common/contextkey';
export namespace EditorContextKeys {
export const editorSimpleInput = new RawContextKey<boolean>('editorSimpleInput', false);
export const editorSimpleInput = new RawContextKey<boolean>('editorSimpleInput', false, true);
/**
* A context key that is set when the editor's text has focus (cursor is blinking).
* Is false when focus is in simple editor widgets (repl input, scm commit input).
*/
export const editorTextFocus = new RawContextKey<boolean>('editorTextFocus', false);
export const editorTextFocus = new RawContextKey<boolean>('editorTextFocus', false, nls.localize('editorTextFocus', "Whether the editor text has focus (cursor is blinking)"));
/**
* A context key that is set when the editor's text or an editor's widget has focus.
*/
export const focus = new RawContextKey<boolean>('editorFocus', false);
export const focus = new RawContextKey<boolean>('editorFocus', false, nls.localize('editorFocus', "Whether the editor or an editor widget has focus (e.g. focus is in the find widget)"));
/**
* A context key that is set when any editor input has focus (regular editor, repl input...).
*/
export const textInputFocus = new RawContextKey<boolean>('textInputFocus', false);
export const textInputFocus = new RawContextKey<boolean>('textInputFocus', false, nls.localize('textInputFocus', "Whether an editor or a rich text input has focus (cursor is blinking)"));
export const readOnly = new RawContextKey<boolean>('editorReadonly', false);
export const inDiffEditor = new RawContextKey<boolean>('inDiffEditor', false);
export const columnSelection = new RawContextKey<boolean>('editorColumnSelection', false);
export const readOnly = new RawContextKey<boolean>('editorReadonly', false, nls.localize('editorReadonly', "Whether the editor is read only"));
export const inDiffEditor = new RawContextKey<boolean>('inDiffEditor', false, nls.localize('inDiffEditor', "Whether the context is a diff editor"));
export const columnSelection = new RawContextKey<boolean>('editorColumnSelection', false, nls.localize('editorColumnSelection', "Whether `editor.columnSelection` is enabled"));
export const writable = readOnly.toNegated();
export const hasNonEmptySelection = new RawContextKey<boolean>('editorHasSelection', false);
export const hasNonEmptySelection = new RawContextKey<boolean>('editorHasSelection', false, nls.localize('editorHasSelection', "Whether the editor has text selected"));
export const hasOnlyEmptySelection = hasNonEmptySelection.toNegated();
export const hasMultipleSelections = new RawContextKey<boolean>('editorHasMultipleSelections', false);
export const hasMultipleSelections = new RawContextKey<boolean>('editorHasMultipleSelections', false, nls.localize('editorHasMultipleSelections', "Whether the editor has multiple selections"));
export const hasSingleSelection = hasMultipleSelections.toNegated();
export const tabMovesFocus = new RawContextKey<boolean>('editorTabMovesFocus', false);
export const tabMovesFocus = new RawContextKey<boolean>('editorTabMovesFocus', false, nls.localize('editorTabMovesFocus', "Whether `Tab` will move focus out of the editor"));
export const tabDoesNotMoveFocus = tabMovesFocus.toNegated();
export const isInWalkThroughSnippet = new RawContextKey<boolean>('isInEmbeddedEditor', false);
export const canUndo = new RawContextKey<boolean>('canUndo', false);
export const canRedo = new RawContextKey<boolean>('canRedo', false);
export const isInWalkThroughSnippet = new RawContextKey<boolean>('isInEmbeddedEditor', false, true);
export const canUndo = new RawContextKey<boolean>('canUndo', false, true);
export const canRedo = new RawContextKey<boolean>('canRedo', false, true);
export const hoverVisible = new RawContextKey<boolean>('editorHoverVisible', false);
export const hoverVisible = new RawContextKey<boolean>('editorHoverVisible', false, nls.localize('editorHoverVisible', "Whether the editor hover is visible"));
/**
* A context key that is set when an editor is part of a larger editor, like notebooks or
* (future) a diff editor
*/
export const inCompositeEditor = new RawContextKey<boolean>('inCompositeEditor', undefined);
export const inCompositeEditor = new RawContextKey<boolean>('inCompositeEditor', undefined, nls.localize('inCompositeEditor', "Whether the editor is part of a larger editor (e.g. notebooks)"));
export const notInCompositeEditor = inCompositeEditor.toNegated();
// -- mode context keys
export const languageId = new RawContextKey<string>('editorLangId', '');
export const hasCompletionItemProvider = new RawContextKey<boolean>('editorHasCompletionItemProvider', false);
export const hasCodeActionsProvider = new RawContextKey<boolean>('editorHasCodeActionsProvider', false);
export const hasCodeLensProvider = new RawContextKey<boolean>('editorHasCodeLensProvider', false);
export const hasDefinitionProvider = new RawContextKey<boolean>('editorHasDefinitionProvider', false);
export const hasDeclarationProvider = new RawContextKey<boolean>('editorHasDeclarationProvider', false);
export const hasImplementationProvider = new RawContextKey<boolean>('editorHasImplementationProvider', false);
export const hasTypeDefinitionProvider = new RawContextKey<boolean>('editorHasTypeDefinitionProvider', false);
export const hasHoverProvider = new RawContextKey<boolean>('editorHasHoverProvider', false);
export const hasDocumentHighlightProvider = new RawContextKey<boolean>('editorHasDocumentHighlightProvider', false);
export const hasDocumentSymbolProvider = new RawContextKey<boolean>('editorHasDocumentSymbolProvider', false);
export const hasReferenceProvider = new RawContextKey<boolean>('editorHasReferenceProvider', false);
export const hasRenameProvider = new RawContextKey<boolean>('editorHasRenameProvider', false);
export const hasSignatureHelpProvider = new RawContextKey<boolean>('editorHasSignatureHelpProvider', false);
export const hasInlineHintsProvider = new RawContextKey<boolean>('editorHasInlineHintsProvider', false);
export const languageId = new RawContextKey<string>('editorLangId', '', nls.localize('editorLangId', "The language identifier of the editor"));
export const hasCompletionItemProvider = new RawContextKey<boolean>('editorHasCompletionItemProvider', false, nls.localize('editorHasCompletionItemProvider', "Whether the editor has a completion item provider"));
export const hasCodeActionsProvider = new RawContextKey<boolean>('editorHasCodeActionsProvider', false, nls.localize('editorHasCodeActionsProvider', "Whether the editor has a code actions provider"));
export const hasCodeLensProvider = new RawContextKey<boolean>('editorHasCodeLensProvider', false, nls.localize('editorHasCodeLensProvider', "Whether the editor has a code lens provider"));
export const hasDefinitionProvider = new RawContextKey<boolean>('editorHasDefinitionProvider', false, nls.localize('editorHasDefinitionProvider', "Whether the editor has a definition provider"));
export const hasDeclarationProvider = new RawContextKey<boolean>('editorHasDeclarationProvider', false, nls.localize('editorHasDeclarationProvider', "Whether the editor has a declaration provider"));
export const hasImplementationProvider = new RawContextKey<boolean>('editorHasImplementationProvider', false, nls.localize('editorHasImplementationProvider', "Whether the editor has an implementation provider"));
export const hasTypeDefinitionProvider = new RawContextKey<boolean>('editorHasTypeDefinitionProvider', false, nls.localize('editorHasTypeDefinitionProvider', "Whether the editor has a type definition provider"));
export const hasHoverProvider = new RawContextKey<boolean>('editorHasHoverProvider', false, nls.localize('editorHasHoverProvider', "Whether the editor has a hover provider"));
export const hasDocumentHighlightProvider = new RawContextKey<boolean>('editorHasDocumentHighlightProvider', false, nls.localize('editorHasDocumentHighlightProvider', "Whether the editor has a document highlight provider"));
export const hasDocumentSymbolProvider = new RawContextKey<boolean>('editorHasDocumentSymbolProvider', false, nls.localize('editorHasDocumentSymbolProvider', "Whether the editor has a document symbol provider"));
export const hasReferenceProvider = new RawContextKey<boolean>('editorHasReferenceProvider', false, nls.localize('editorHasReferenceProvider', "Whether the editor has a reference provider"));
export const hasRenameProvider = new RawContextKey<boolean>('editorHasRenameProvider', false, nls.localize('editorHasRenameProvider', "Whether the editor has a rename provider"));
export const hasSignatureHelpProvider = new RawContextKey<boolean>('editorHasSignatureHelpProvider', false, nls.localize('editorHasSignatureHelpProvider', "Whether the editor has a signature help provider"));
export const hasInlineHintsProvider = new RawContextKey<boolean>('editorHasInlineHintsProvider', false, nls.localize('editorHasInlineHintsProvider', "Whether the editor has an inline hints provider"));
// -- mode context keys: formatting
export const hasDocumentFormattingProvider = new RawContextKey<boolean>('editorHasDocumentFormattingProvider', false);
export const hasDocumentSelectionFormattingProvider = new RawContextKey<boolean>('editorHasDocumentSelectionFormattingProvider', false);
export const hasMultipleDocumentFormattingProvider = new RawContextKey<boolean>('editorHasMultipleDocumentFormattingProvider', false);
export const hasMultipleDocumentSelectionFormattingProvider = new RawContextKey<boolean>('editorHasMultipleDocumentSelectionFormattingProvider', false);
export const hasDocumentFormattingProvider = new RawContextKey<boolean>('editorHasDocumentFormattingProvider', false, nls.localize('editorHasDocumentFormattingProvider', "Whether the editor has a document formatting provider"));
export const hasDocumentSelectionFormattingProvider = new RawContextKey<boolean>('editorHasDocumentSelectionFormattingProvider', false, nls.localize('editorHasDocumentSelectionFormattingProvider', "Whether the editor has a document selection formatting provider"));
export const hasMultipleDocumentFormattingProvider = new RawContextKey<boolean>('editorHasMultipleDocumentFormattingProvider', false, nls.localize('editorHasMultipleDocumentFormattingProvider', "Whether the editor has multiple document formatting providers"));
export const hasMultipleDocumentSelectionFormattingProvider = new RawContextKey<boolean>('editorHasMultipleDocumentSelectionFormattingProvider', false, nls.localize('editorHasMultipleDocumentSelectionFormattingProvider', "Whether the editor has multiple document selection formatting providers"));
}

View File

@@ -38,6 +38,7 @@ import { IUndoRedoService, ResourceEditStackSnapshot } from 'vs/platform/undoRed
import { TextChange } from 'vs/editor/common/model/textChange';
import { Constants } from 'vs/base/common/uint';
import { PieceTreeTextBuffer } from 'vs/editor/common/model/pieceTreeTextBuffer/pieceTreeTextBuffer';
import { listenStream } from 'vs/base/common/stream';
function createTextBufferBuilder() {
return new PieceTreeTextBufferBuilder();
@@ -64,33 +65,33 @@ export function createTextBufferFactoryFromStream(stream: ITextStream | VSBuffer
let done = false;
stream.on('data', (chunk: string | VSBuffer) => {
if (validator) {
const error = validator(chunk);
if (error) {
listenStream<string | VSBuffer>(stream, {
onData: chunk => {
if (validator) {
const error = validator(chunk);
if (error) {
done = true;
reject(error);
}
}
if (filter) {
chunk = filter(chunk);
}
builder.acceptChunk((typeof chunk === 'string') ? chunk : chunk.toString());
},
onError: error => {
if (!done) {
done = true;
reject(error);
}
}
if (filter) {
chunk = filter(chunk);
}
builder.acceptChunk((typeof chunk === 'string') ? chunk : chunk.toString());
});
stream.on('error', (error) => {
if (!done) {
done = true;
reject(error);
}
});
stream.on('end', () => {
if (!done) {
done = true;
resolve(builder.finish());
},
onEnd: () => {
if (!done) {
done = true;
resolve(builder.finish());
}
}
});
});

View File

@@ -266,7 +266,7 @@ export interface HoverProvider {
}
/**
* An evaluatable expression represents additional information for an expression in a document. Evaluatable expression are
* An evaluatable expression represents additional information for an expression in a document. Evaluatable expressions are
* evaluated by a debugger or runtime and their result is rendered in a tooltip-like widget.
* @internal
*/
@@ -275,15 +275,16 @@ export interface EvaluatableExpression {
* The range to which this expression applies.
*/
range: IRange;
/*
/**
* This expression overrides the expression extracted from the range.
*/
expression?: string;
}
/**
* The hover provider interface defines the contract between extensions and
* the [hover](https://code.visualstudio.com/docs/editor/intellisense)-feature.
* The evaluatable expression provider interface defines the contract between extensions and
* the debug hover.
* @internal
*/
export interface EvaluatableExpressionProvider {
@@ -295,6 +296,73 @@ export interface EvaluatableExpressionProvider {
provideEvaluatableExpression(model: model.ITextModel, position: Position, token: CancellationToken): ProviderResult<EvaluatableExpression>;
}
/**
* An open ended information bag passed to the inline value provider.
* A minimal context containes just the document location where the debugger has stopped.
* @internal
*/
export interface InlineValueContext {
stoppedLocation: Range;
}
/**
* Provide inline value as text.
* @internal
*/
export interface InlineValueText {
type: 'text';
range: IRange;
text: string;
}
/**
* Provide inline value through a variable lookup.
* @internal
*/
export interface InlineValueVariableLookup {
type: 'variable';
range: IRange;
variableName?: string;
caseSensitiveLookup: boolean;
}
/**
* Provide inline value through an expression evaluation.
* @internal
*/
export interface InlineValueExpression {
type: 'expression';
range: IRange;
expression?: string;
}
/**
* Inline value information can be provided by different means:
* - directly as a text value (class InlineValueText).
* - as a name to use for a variable lookup (class InlineValueVariableLookup)
* - as an evaluatable expression (class InlineValueEvaluatableExpression)
* The InlineValue types combines all inline value types into one type.
* @internal
*/
export type InlineValue = InlineValueText | InlineValueVariableLookup | InlineValueExpression;
/**
* The inline values provider interface defines the contract between extensions and
* the debugger's inline values feature.
* @internal
*/
export interface InlineValuesProvider {
/**
*/
onDidChangeInlineValues?: Event<void> | undefined;
/**
* Provide the "inline values" for the given range and document. Multiple hovers at the same
* position will be merged by the editor. A hover can have a range which defaults
* to the word range at the position when omitted.
*/
provideInlineValues(model: model.ITextModel, viewPort: Range, context: InlineValueContext, token: CancellationToken): ProviderResult<InlineValue[]>;
}
export const enum CompletionItemKind {
Method,
Function,
@@ -1439,9 +1507,9 @@ export interface AuthenticationSession {
* @internal
*/
export interface AuthenticationSessionsChangeEvent {
added: ReadonlyArray<string>;
removed: ReadonlyArray<string>;
changed: ReadonlyArray<string>;
added: ReadonlyArray<AuthenticationSession>;
removed: ReadonlyArray<AuthenticationSession>;
changed: ReadonlyArray<AuthenticationSession>;
}
/**
@@ -1659,9 +1727,17 @@ export interface CodeLensProvider {
resolveCodeLens?(model: model.ITextModel, codeLens: CodeLens, token: CancellationToken): ProviderResult<CodeLens>;
}
export enum InlineHintKind {
Other = 0,
Type = 1,
Parameter = 2,
}
export interface InlineHint {
text: string;
range: IRange;
kind: InlineHintKind;
description?: string | IMarkdownString;
whitespaceBefore?: boolean;
whitespaceAfter?: boolean;
@@ -1737,6 +1813,11 @@ export const HoverProviderRegistry = new LanguageFeatureRegistry<HoverProvider>(
*/
export const EvaluatableExpressionProviderRegistry = new LanguageFeatureRegistry<EvaluatableExpressionProvider>();
/**
* @internal
*/
export const InlineValuesProviderRegistry = new LanguageFeatureRegistry<InlineValuesProvider>();
/**
* @internal
*/

View File

@@ -57,33 +57,21 @@ export class RichEditSupport {
public readonly indentationRules: IndentationRule | undefined;
public readonly foldingRules: FoldingRules;
constructor(languageIdentifier: LanguageIdentifier, previous: RichEditSupport | undefined, rawConf: LanguageConfiguration) {
constructor(languageIdentifier: LanguageIdentifier, rawConf: LanguageConfiguration) {
this._languageIdentifier = languageIdentifier;
this._brackets = null;
this._electricCharacter = null;
let prev: LanguageConfiguration | null = null;
if (previous) {
prev = previous._conf;
}
this._conf = RichEditSupport._mergeConf(prev, rawConf);
this._conf = rawConf;
this._onEnterSupport = (this._conf.brackets || this._conf.indentationRules || this._conf.onEnterRules ? new OnEnterSupport(this._conf) : null);
this.comments = RichEditSupport._handleComments(this._conf);
this.characterPair = new CharacterPairSupport(this._conf);
this.wordDefinition = this._conf.wordPattern || DEFAULT_WORD_REGEXP;
this.indentationRules = this._conf.indentationRules;
if (this._conf.indentationRules) {
this.indentRulesSupport = new IndentRulesSupport(this._conf.indentationRules);
} else {
this.indentRulesSupport = null;
}
this.foldingRules = this._conf.folding || {};
}
@@ -108,21 +96,6 @@ export class RichEditSupport {
return this._onEnterSupport.onEnter(autoIndent, previousLineText, beforeEnterText, afterEnterText);
}
private static _mergeConf(prev: LanguageConfiguration | null, current: LanguageConfiguration): LanguageConfiguration {
return {
comments: (prev ? current.comments || prev.comments : current.comments),
brackets: (prev ? current.brackets || prev.brackets : current.brackets),
wordPattern: (prev ? current.wordPattern || prev.wordPattern : current.wordPattern),
indentationRules: (prev ? current.indentationRules || prev.indentationRules : current.indentationRules),
onEnterRules: (prev ? current.onEnterRules || prev.onEnterRules : current.onEnterRules),
autoClosingPairs: (prev ? current.autoClosingPairs || prev.autoClosingPairs : current.autoClosingPairs),
surroundingPairs: (prev ? current.surroundingPairs || prev.surroundingPairs : current.surroundingPairs),
autoCloseBefore: (prev ? current.autoCloseBefore || prev.autoCloseBefore : current.autoCloseBefore),
folding: (prev ? current.folding || prev.folding : current.folding),
__electricCharacterSupport: (prev ? current.__electricCharacterSupport || prev.__electricCharacterSupport : current.__electricCharacterSupport),
};
}
private static _handleComments(conf: LanguageConfiguration): ICommentsConfiguration | null {
let commentRule = conf.comments;
if (!commentRule) {
@@ -151,38 +124,120 @@ export class LanguageConfigurationChangeEvent {
) { }
}
export class LanguageConfigurationRegistryImpl {
class LanguageConfigurationEntry {
private readonly _entries = new Map<LanguageId, RichEditSupport | undefined>();
constructor(
public readonly configuration: LanguageConfiguration,
public readonly priority: number,
public readonly order: number
) { }
private readonly _onDidChange = new Emitter<LanguageConfigurationChangeEvent>();
public readonly onDidChange: Event<LanguageConfigurationChangeEvent> = this._onDidChange.event;
public static cmp(a: LanguageConfigurationEntry, b: LanguageConfigurationEntry) {
if (a.priority === b.priority) {
// higher order last
return a.order - b.order;
}
// higher priority last
return a.priority - b.priority;
}
}
public register(languageIdentifier: LanguageIdentifier, configuration: LanguageConfiguration): IDisposable {
let previous = this._getRichEditSupport(languageIdentifier.id);
let current = new RichEditSupport(languageIdentifier, previous, configuration);
this._entries.set(languageIdentifier.id, current);
this._onDidChange.fire(new LanguageConfigurationChangeEvent(languageIdentifier));
class LanguageConfigurationEntries {
private readonly _entries: LanguageConfigurationEntry[];
private _order: number;
private _resolved: RichEditSupport | null = null;
constructor(
public readonly languageIdentifier: LanguageIdentifier
) {
this._entries = [];
this._order = 0;
this._resolved = null;
}
public register(configuration: LanguageConfiguration, priority: number): IDisposable {
const entry = new LanguageConfigurationEntry(configuration, priority, ++this._order);
this._entries.push(entry);
this._resolved = null;
return toDisposable(() => {
if (this._entries.get(languageIdentifier.id) === current) {
this._entries.set(languageIdentifier.id, previous);
this._onDidChange.fire(new LanguageConfigurationChangeEvent(languageIdentifier));
for (let i = 0; i < this._entries.length; i++) {
if (this._entries[i] === entry) {
this._entries.splice(i, 1);
this._resolved = null;
break;
}
}
});
}
private _getRichEditSupport(languageId: LanguageId): RichEditSupport | undefined {
return this._entries.get(languageId);
public getRichEditSupport(): RichEditSupport | null {
if (!this._resolved) {
const config = this._resolve();
if (config) {
this._resolved = new RichEditSupport(this.languageIdentifier, config);
}
}
return this._resolved;
}
public getIndentationRules(languageId: LanguageId) {
const value = this._entries.get(languageId);
if (!value) {
private _resolve(): LanguageConfiguration | null {
if (this._entries.length === 0) {
return null;
}
this._entries.sort(LanguageConfigurationEntry.cmp);
const result: LanguageConfiguration = {};
for (const entry of this._entries) {
const conf = entry.configuration;
result.comments = conf.comments || result.comments;
result.brackets = conf.brackets || result.brackets;
result.wordPattern = conf.wordPattern || result.wordPattern;
result.indentationRules = conf.indentationRules || result.indentationRules;
result.onEnterRules = conf.onEnterRules || result.onEnterRules;
result.autoClosingPairs = conf.autoClosingPairs || result.autoClosingPairs;
result.surroundingPairs = conf.surroundingPairs || result.surroundingPairs;
result.autoCloseBefore = conf.autoCloseBefore || result.autoCloseBefore;
result.folding = conf.folding || result.folding;
result.__electricCharacterSupport = conf.__electricCharacterSupport || result.__electricCharacterSupport;
}
return result;
}
}
return value.indentationRules || null;
export class LanguageConfigurationRegistryImpl {
private readonly _entries2 = new Map<LanguageId, LanguageConfigurationEntries>();
private readonly _onDidChange = new Emitter<LanguageConfigurationChangeEvent>();
public readonly onDidChange: Event<LanguageConfigurationChangeEvent> = this._onDidChange.event;
/**
* @param priority Use a higher number for higher priority
*/
public register(languageIdentifier: LanguageIdentifier, configuration: LanguageConfiguration, priority: number = 0): IDisposable {
let entries = this._entries2.get(languageIdentifier.id);
if (!entries) {
entries = new LanguageConfigurationEntries(languageIdentifier);
this._entries2.set(languageIdentifier.id, entries);
}
const disposable = entries.register(configuration, priority);
this._onDidChange.fire(new LanguageConfigurationChangeEvent(languageIdentifier));
return toDisposable(() => {
disposable.dispose();
this._onDidChange.fire(new LanguageConfigurationChangeEvent(languageIdentifier));
});
}
private _getRichEditSupport(languageId: LanguageId): RichEditSupport | null {
const entries = this._entries2.get(languageId);
return entries ? entries.getRichEditSupport() : null;
}
public getIndentationRules(languageId: LanguageId): IndentationRule | null {
const value = this._getRichEditSupport(languageId);
return value ? value.indentationRules || null : null;
}
// begin electricCharacter
@@ -273,11 +328,12 @@ export class LanguageConfigurationRegistryImpl {
public getWordDefinitions(): [LanguageId, RegExp][] {
let result: [LanguageId, RegExp][] = [];
this._entries.forEach((value, language) => {
for (const [language, entries] of this._entries2) {
const value = entries.getRichEditSupport();
if (value) {
result.push([language, value.wordDefinition]);
}
});
}
return result;
}

View File

@@ -9,7 +9,7 @@ import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { LRUCache } from 'vs/base/common/map';
import { MovingAverage } from 'vs/base/common/numbers';
import { ITextModel } from 'vs/editor/common/model';
import { LanguageSelector, score } from 'vs/editor/common/modes/languageSelector';
import { LanguageFilter, LanguageSelector, score } from 'vs/editor/common/modes/languageSelector';
import { shouldSynchronizeModel } from 'vs/editor/common/services/modelService';
interface Entry<T> {
@@ -25,7 +25,7 @@ function isExclusive(selector: LanguageSelector): boolean {
} else if (Array.isArray(selector)) {
return selector.every(isExclusive);
} else {
return !!selector.exclusive;
return !!(selector as LanguageFilter).exclusive; // TODO: microsoft/TypeScript#42768
}
}

View File

@@ -55,7 +55,7 @@ export function score(selector: LanguageSelector | undefined, candidateUri: URI,
} else if (selector) {
// filter -> select accordingly, use defaults for scheme
const { language, pattern, scheme, hasAccessToAllModels } = selector;
const { language, pattern, scheme, hasAccessToAllModels } = selector as LanguageFilter; // TODO: microsoft/TypeScript#42768
if (!candidateIsSynchronized && !hasAccessToAllModels) {
return 0;

View File

@@ -85,4 +85,4 @@ LanguageConfigurationRegistry.register(PLAINTEXT_LANGUAGE_IDENTIFIER, {
folding: {
offSide: true
}
});
}, 0);

View File

@@ -37,9 +37,14 @@ export function getIconClasses(modelService: IModelService, modeService: IModeSe
// Name & Extension(s)
if (name) {
classes.push(`${name}-name-file-icon`);
const dotSegments = name.split('.');
for (let i = 1; i < dotSegments.length; i++) {
classes.push(`${dotSegments.slice(i).join('.')}-ext-file-icon`); // add each combination of all found extensions if more than one
// Avoid doing an explosive combination of extensions for very long filenames
// (most file systems do not allow files > 255 length) with lots of `.` characters
// https://github.com/microsoft/vscode/issues/116199
if (name.length <= 255) {
const dotSegments = name.split('.');
for (let i = 1; i < dotSegments.length; i++) {
classes.push(`${dotSegments.slice(i).join('.')}-ext-file-icon`); // add each combination of all found extensions if more than one
}
}
classes.push(`ext-file-icon`); // extra segment to increase file-ext score
}

View File

@@ -15,6 +15,7 @@ export const enum SemanticTokensProviderStylingConstants {
export class SemanticTokensProviderStyling {
private readonly _hashTable: HashTable;
private _hasWarnedOverlappingTokens: boolean;
constructor(
private readonly _legend: SemanticTokensLegend,
@@ -22,6 +23,7 @@ export class SemanticTokensProviderStyling {
private readonly _logService: ILogService
) {
this._hashTable = new HashTable();
this._hasWarnedOverlappingTokens = false;
}
public getMetadata(tokenTypeIndex: number, tokenModifierSet: number, languageId: LanguageIdentifier): number {
@@ -90,6 +92,14 @@ export class SemanticTokensProviderStyling {
return metadata;
}
public warnOverlappingSemanticTokens(lineNumber: number, startColumn: number): void {
if (!this._hasWarnedOverlappingTokens) {
this._hasWarnedOverlappingTokens = true;
console.warn(`Overlapping semantic tokens detected at lineNumber ${lineNumber}, column ${startColumn}`);
}
}
}
const enum SemanticColoringConstants {
@@ -142,6 +152,9 @@ export function toMultilineTokens2(tokens: SemanticTokens, styling: SemanticToke
let destData = new Uint32Array((tokenEndIndex - tokenStartIndex) * 4);
let destOffset = 0;
let areaLine = 0;
let prevLineNumber = 0;
let prevStartCharacter = 0;
let prevEndCharacter = 0;
while (tokenIndex < tokenEndIndex) {
const srcOffset = 5 * tokenIndex;
const deltaLine = srcData[srcOffset];
@@ -157,11 +170,25 @@ export function toMultilineTokens2(tokens: SemanticTokens, styling: SemanticToke
if (areaLine === 0) {
areaLine = lineNumber;
}
if (prevLineNumber === lineNumber && prevEndCharacter > startCharacter) {
styling.warnOverlappingSemanticTokens(lineNumber, startCharacter + 1);
if (prevStartCharacter < startCharacter) {
// the previous token survives after the overlapping one
destData[destOffset - 4 + 2] = startCharacter;
} else {
// the previous token is entirely covered by the overlapping one
destOffset -= 4;
}
}
destData[destOffset] = lineNumber - areaLine;
destData[destOffset + 1] = startCharacter;
destData[destOffset + 2] = startCharacter + length;
destData[destOffset + 3] = metadata;
destOffset += 4;
prevLineNumber = lineNumber;
prevStartCharacter = startCharacter;
prevEndCharacter = startCharacter + length;
}
lastLineNumber = lineNumber;

View File

@@ -351,6 +351,12 @@ export enum IndentAction {
Outdent = 3
}
export enum InlineHintKind {
Other = 0,
Type = 1,
Parameter = 2
}
/**
* Virtual Key Codes, the value does not hold any inherent meaning.
* Inspired somewhat from https://msdn.microsoft.com/en-us/library/windows/desktop/dd375731(v=vs.85).aspx

View File

@@ -948,8 +948,8 @@ export class ViewModel extends Disposable implements IViewModel {
public type(text: string, source?: string | null | undefined): void {
this._executeCursorEdit(eventsCollector => this._cursor.type(eventsCollector, text, source));
}
public replacePreviousChar(text: string, replaceCharCnt: number, source?: string | null | undefined): void {
this._executeCursorEdit(eventsCollector => this._cursor.replacePreviousChar(eventsCollector, text, replaceCharCnt, source));
public compositionType(text: string, replacePrevCharCnt: number, replaceNextCharCnt: number, positionDelta: number, source?: string | null | undefined): void {
this._executeCursorEdit(eventsCollector => this._cursor.compositionType(eventsCollector, text, replacePrevCharCnt, replaceNextCharCnt, positionDelta, source));
}
public paste(text: string, pasteOnNewLine: boolean, multicursorText?: string[] | null | undefined, source?: string | null | undefined): void {
this._executeCursorEdit(eventsCollector => this._cursor.paste(eventsCollector, text, pasteOnNewLine, multicursorText, source));