mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-15 10:58:31 -05:00
Merge from vscode a348d103d1256a06a2c9b3f9b406298a9fef6898 (#15681)
* Merge from vscode a348d103d1256a06a2c9b3f9b406298a9fef6898 * Fixes and cleanup * Distro * Fix hygiene yarn * delete no yarn lock changes file * Fix hygiene * Fix layer check * Fix CI * Skip lib checks * Remove tests deleted in vs code * Fix tests * Distro * Fix tests and add removed extension point * Skip failing notebook tests for now * Disable broken tests and cleanup build folder * Update yarn.lock and fix smoke tests * Bump sqlite * fix contributed actions and file spacing * Fix user data path * Update yarn.locks Co-authored-by: ADS Merger <karlb@microsoft.com>
This commit is contained in:
@@ -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 which documents word based completions are computed.")
|
||||
},
|
||||
'editor.semanticHighlighting.enabled': {
|
||||
enum: [true, false, 'configuredByTheme'],
|
||||
|
||||
@@ -28,7 +28,7 @@ export type EditorAutoSurroundStrategy = 'languageDefined' | 'quotes' | 'bracket
|
||||
/**
|
||||
* Configuration options for typing over closing quotes or brackets
|
||||
*/
|
||||
export type EditorAutoClosingOvertypeStrategy = 'always' | 'auto' | 'never';
|
||||
export type EditorAutoClosingEditStrategy = 'always' | 'auto' | 'never';
|
||||
|
||||
/**
|
||||
* Configuration options for auto indentation in the editor
|
||||
@@ -139,10 +139,15 @@ export interface IEditorOptions {
|
||||
*/
|
||||
extraEditorClassName?: string;
|
||||
/**
|
||||
* Should the editor be read only.
|
||||
* Should the editor be read only. See also `domReadOnly`.
|
||||
* Defaults to false.
|
||||
*/
|
||||
readOnly?: boolean;
|
||||
/**
|
||||
* Should the textarea used for input use the DOM `readonly` attribute.
|
||||
* Defaults to false.
|
||||
*/
|
||||
domReadOnly?: boolean;
|
||||
/**
|
||||
* Enable linked editing.
|
||||
* Defaults to false.
|
||||
@@ -413,10 +418,14 @@ export interface IEditorOptions {
|
||||
* Defaults to language defined behavior.
|
||||
*/
|
||||
autoClosingQuotes?: EditorAutoClosingStrategy;
|
||||
/**
|
||||
* Options for pressing backspace near quotes or bracket pairs.
|
||||
*/
|
||||
autoClosingDelete?: EditorAutoClosingEditStrategy;
|
||||
/**
|
||||
* Options for typing over closing quotes or brackets.
|
||||
*/
|
||||
autoClosingOvertype?: EditorAutoClosingOvertypeStrategy;
|
||||
autoClosingOvertype?: EditorAutoClosingEditStrategy;
|
||||
/**
|
||||
* Options for auto surrounding.
|
||||
* Defaults to always allowing auto surrounding.
|
||||
@@ -695,6 +704,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
|
||||
@@ -894,7 +911,7 @@ class EditorBooleanOption<K1 extends EditorOption> extends SimpleEditorOption<K1
|
||||
super(id, name, defaultValue, schema);
|
||||
}
|
||||
|
||||
public validate(input: any): boolean {
|
||||
public override validate(input: any): boolean {
|
||||
return boolean(input, this.defaultValue);
|
||||
}
|
||||
}
|
||||
@@ -929,7 +946,7 @@ class EditorIntOption<K1 extends EditorOption> extends SimpleEditorOption<K1, nu
|
||||
this.maximum = maximum;
|
||||
}
|
||||
|
||||
public validate(input: any): number {
|
||||
public override validate(input: any): number {
|
||||
return EditorIntOption.clampedInt(input, this.defaultValue, this.minimum, this.maximum);
|
||||
}
|
||||
}
|
||||
@@ -968,7 +985,7 @@ class EditorFloatOption<K1 extends EditorOption> extends SimpleEditorOption<K1,
|
||||
this.validationFn = validationFn;
|
||||
}
|
||||
|
||||
public validate(input: any): number {
|
||||
public override validate(input: any): number {
|
||||
return this.validationFn(EditorFloatOption.float(input, this.defaultValue));
|
||||
}
|
||||
}
|
||||
@@ -990,7 +1007,7 @@ class EditorStringOption<K1 extends EditorOption> extends SimpleEditorOption<K1,
|
||||
super(id, name, defaultValue, schema);
|
||||
}
|
||||
|
||||
public validate(input: any): string {
|
||||
public override validate(input: any): string {
|
||||
return EditorStringOption.string(input, this.defaultValue);
|
||||
}
|
||||
}
|
||||
@@ -1022,7 +1039,7 @@ class EditorStringEnumOption<K1 extends EditorOption, V extends string> extends
|
||||
this._allowedValues = allowedValues;
|
||||
}
|
||||
|
||||
public validate(input: any): V {
|
||||
public override validate(input: any): V {
|
||||
return stringSet<V>(input, this.defaultValue, this._allowedValues);
|
||||
}
|
||||
}
|
||||
@@ -1100,7 +1117,7 @@ class EditorAccessibilitySupport extends BaseEditorOption<EditorOption.accessibi
|
||||
return this.defaultValue;
|
||||
}
|
||||
|
||||
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: AccessibilitySupport): AccessibilitySupport {
|
||||
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: AccessibilitySupport): AccessibilitySupport {
|
||||
if (value === AccessibilitySupport.Unknown) {
|
||||
// The editor reads the `accessibilitySupport` from the environment
|
||||
return env.accessibilitySupport;
|
||||
@@ -1319,7 +1336,7 @@ class EditorEmptySelectionClipboard extends EditorBooleanOption<EditorOption.emp
|
||||
);
|
||||
}
|
||||
|
||||
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: boolean): boolean {
|
||||
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: boolean): boolean {
|
||||
return value && env.emptySelectionClipboard;
|
||||
}
|
||||
}
|
||||
@@ -1390,8 +1407,8 @@ class EditorFind extends BaseEditorOption<EditorOption.find, EditorFindOptions>
|
||||
enum: ['never', 'always', 'multiline'],
|
||||
default: defaults.autoFindInSelection,
|
||||
enumDescriptions: [
|
||||
nls.localize('editor.find.autoFindInSelection.never', 'Never turn on Find in selection automatically (default)'),
|
||||
nls.localize('editor.find.autoFindInSelection.always', 'Always turn on Find in selection automatically'),
|
||||
nls.localize('editor.find.autoFindInSelection.never', 'Never turn on Find in selection automatically (default).'),
|
||||
nls.localize('editor.find.autoFindInSelection.always', 'Always turn on Find in selection automatically.'),
|
||||
nls.localize('editor.find.autoFindInSelection.multiline', 'Turn on Find in selection automatically when multiple lines of content are selected.')
|
||||
],
|
||||
description: nls.localize('find.autoFindInSelection', "Controls the condition for turning on find in selection automatically.")
|
||||
@@ -1521,14 +1538,14 @@ class EditorFontSize extends SimpleEditorOption<EditorOption.fontSize, number> {
|
||||
);
|
||||
}
|
||||
|
||||
public validate(input: any): number {
|
||||
public override validate(input: any): number {
|
||||
let r = EditorFloatOption.float(input, this.defaultValue);
|
||||
if (r === 0) {
|
||||
return EDITOR_FONT_DEFAULTS.fontSize;
|
||||
}
|
||||
return EditorFloatOption.clamp(r, 6, 100);
|
||||
}
|
||||
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: number): number {
|
||||
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: number): number {
|
||||
// The final fontSize respects the editor zoom level.
|
||||
// So take the result from env.fontInfo
|
||||
return env.fontInfo.fontSize;
|
||||
@@ -1631,6 +1648,7 @@ class EditorGoToLocation extends BaseEditorOption<EditorOption.gotoLocation, GoT
|
||||
nls.localize('editor.gotoLocation.multiple.goto', 'Go to the primary result and enable peek-less navigation to others')
|
||||
]
|
||||
};
|
||||
const alternativeCommandOptions = ['', 'editor.action.referenceSearch.trigger', 'editor.action.goToReferences', 'editor.action.peekImplementation', 'editor.action.goToImplementation', 'editor.action.peekTypeDefinition', 'editor.action.goToTypeDefinition', 'editor.action.peekDeclaration', 'editor.action.revealDeclaration', 'editor.action.peekDefinition', 'editor.action.revealDefinitionAside', 'editor.action.revealDefinition'];
|
||||
super(
|
||||
EditorOption.gotoLocation, 'gotoLocation', defaults,
|
||||
{
|
||||
@@ -1660,26 +1678,31 @@ class EditorGoToLocation extends BaseEditorOption<EditorOption.gotoLocation, GoT
|
||||
'editor.gotoLocation.alternativeDefinitionCommand': {
|
||||
type: 'string',
|
||||
default: defaults.alternativeDefinitionCommand,
|
||||
enum: alternativeCommandOptions,
|
||||
description: nls.localize('alternativeDefinitionCommand', "Alternative command id that is being executed when the result of 'Go to Definition' is the current location.")
|
||||
},
|
||||
'editor.gotoLocation.alternativeTypeDefinitionCommand': {
|
||||
type: 'string',
|
||||
default: defaults.alternativeTypeDefinitionCommand,
|
||||
enum: alternativeCommandOptions,
|
||||
description: nls.localize('alternativeTypeDefinitionCommand', "Alternative command id that is being executed when the result of 'Go to Type Definition' is the current location.")
|
||||
},
|
||||
'editor.gotoLocation.alternativeDeclarationCommand': {
|
||||
type: 'string',
|
||||
default: defaults.alternativeDeclarationCommand,
|
||||
enum: alternativeCommandOptions,
|
||||
description: nls.localize('alternativeDeclarationCommand', "Alternative command id that is being executed when the result of 'Go to Declaration' is the current location.")
|
||||
},
|
||||
'editor.gotoLocation.alternativeImplementationCommand': {
|
||||
type: 'string',
|
||||
default: defaults.alternativeImplementationCommand,
|
||||
enum: alternativeCommandOptions,
|
||||
description: nls.localize('alternativeImplementationCommand', "Alternative command id that is being executed when the result of 'Go to Implementation' is the current location.")
|
||||
},
|
||||
'editor.gotoLocation.alternativeReferenceCommand': {
|
||||
type: 'string',
|
||||
default: defaults.alternativeReferenceCommand,
|
||||
enum: alternativeCommandOptions,
|
||||
description: nls.localize('alternativeReferenceCommand', "Alternative command id that is being executed when the result of 'Go to Reference' is the current location.")
|
||||
},
|
||||
}
|
||||
@@ -2458,7 +2481,7 @@ class EditorLineHeight extends EditorIntOption<EditorOption.lineHeight> {
|
||||
);
|
||||
}
|
||||
|
||||
public compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: number): number {
|
||||
public override compute(env: IEnvironmentalOptions, options: IComputedEditorOptions, value: number): number {
|
||||
// The lineHeight is computed from the fontSize if it is 0.
|
||||
// Moreover, the final lineHeight respects the editor zoom level.
|
||||
// So take the result from env.fontInfo
|
||||
@@ -2754,7 +2777,7 @@ export type ValidQuickSuggestionsOptions = boolean | Readonly<Required<IQuickSug
|
||||
|
||||
class EditorQuickSuggestions extends BaseEditorOption<EditorOption.quickSuggestions, ValidQuickSuggestionsOptions> {
|
||||
|
||||
public readonly defaultValue: Readonly<Required<IQuickSuggestionsOptions>>;
|
||||
public override readonly defaultValue: Readonly<Required<IQuickSuggestionsOptions>>;
|
||||
|
||||
constructor() {
|
||||
const defaults: ValidQuickSuggestionsOptions = {
|
||||
@@ -3137,7 +3160,7 @@ export interface ISuggestOptions {
|
||||
*/
|
||||
snippetsPreventQuickSuggestions?: boolean;
|
||||
/**
|
||||
* Favours words that appear close to the cursor.
|
||||
* Favors words that appear close to the cursor.
|
||||
*/
|
||||
localityBonus?: boolean;
|
||||
/**
|
||||
@@ -3329,7 +3352,7 @@ class EditorSuggest extends BaseEditorOption<EditorOption.suggest, InternalSugge
|
||||
'editor.suggest.localityBonus': {
|
||||
type: 'boolean',
|
||||
default: defaults.localityBonus,
|
||||
description: nls.localize('suggest.localityBonus', "Controls whether sorting favours words that appear close to the cursor.")
|
||||
description: nls.localize('suggest.localityBonus', "Controls whether sorting favors words that appear close to the cursor.")
|
||||
},
|
||||
'editor.suggest.shareSuggestSelections': {
|
||||
type: 'boolean',
|
||||
@@ -3724,6 +3747,7 @@ export const enum EditorOption {
|
||||
accessibilityPageSize,
|
||||
ariaLabel,
|
||||
autoClosingBrackets,
|
||||
autoClosingDelete,
|
||||
autoClosingOvertype,
|
||||
autoClosingQuotes,
|
||||
autoIndent,
|
||||
@@ -3745,6 +3769,7 @@ export const enum EditorOption {
|
||||
cursorWidth,
|
||||
disableLayerHinting,
|
||||
disableMonospaceOptimizations,
|
||||
domReadOnly,
|
||||
dragAndDrop,
|
||||
emptySelectionClipboard,
|
||||
extraEditorClassName,
|
||||
@@ -3882,7 +3907,9 @@ export const EditorOptions = {
|
||||
)),
|
||||
accessibilitySupport: register(new EditorAccessibilitySupport()),
|
||||
accessibilityPageSize: register(new EditorIntOption(EditorOption.accessibilityPageSize, 'accessibilityPageSize', 10, 1, Constants.MAX_SAFE_SMALL_INTEGER,
|
||||
{ description: nls.localize('accessibilityPageSize', "Controls the number of lines in the editor that can be read out by a screen reader. Warning: this has a performance implication for numbers larger than the default.") })),
|
||||
{
|
||||
description: nls.localize('accessibilityPageSize', "Controls the number of lines in the editor that can be read out by a screen reader at once. When we detect a screen reader we automatically set the default to be 500. Warning: this has a performance implication for numbers larger than the default.")
|
||||
})),
|
||||
ariaLabel: register(new EditorStringOption(
|
||||
EditorOption.ariaLabel, 'ariaLabel', nls.localize('editorViewAccessibleLabel', "Editor content")
|
||||
)),
|
||||
@@ -3900,6 +3927,19 @@ export const EditorOptions = {
|
||||
description: nls.localize('autoClosingBrackets', "Controls whether the editor should automatically close brackets after the user adds an opening bracket.")
|
||||
}
|
||||
)),
|
||||
autoClosingDelete: register(new EditorStringEnumOption(
|
||||
EditorOption.autoClosingDelete, 'autoClosingDelete',
|
||||
'auto' as 'always' | 'auto' | 'never',
|
||||
['always', 'auto', 'never'] as const,
|
||||
{
|
||||
enumDescriptions: [
|
||||
'',
|
||||
nls.localize('editor.autoClosingDelete.auto', "Remove adjacent closing quotes or brackets only if they were automatically inserted."),
|
||||
'',
|
||||
],
|
||||
description: nls.localize('autoClosingDelete', "Controls whether the editor should remove adjacent closing quotes or brackets when deleting.")
|
||||
}
|
||||
)),
|
||||
autoClosingOvertype: register(new EditorStringEnumOption(
|
||||
EditorOption.autoClosingOvertype, 'autoClosingOvertype',
|
||||
'auto' as 'always' | 'auto' | 'never',
|
||||
@@ -3962,7 +4002,7 @@ export const EditorOptions = {
|
||||
)),
|
||||
stickyTabStops: register(new EditorBooleanOption(
|
||||
EditorOption.stickyTabStops, 'stickyTabStops', false,
|
||||
{ description: nls.localize('stickyTabStops', "Emulate selection behaviour of tab characters when using spaces for indentation. Selection will stick to tab stops.") }
|
||||
{ description: nls.localize('stickyTabStops', "Emulate selection behavior of tab characters when using spaces for indentation. Selection will stick to tab stops.") }
|
||||
)),
|
||||
codeLens: register(new EditorBooleanOption(
|
||||
EditorOption.codeLens, 'codeLens', true,
|
||||
@@ -4041,6 +4081,9 @@ export const EditorOptions = {
|
||||
disableMonospaceOptimizations: register(new EditorBooleanOption(
|
||||
EditorOption.disableMonospaceOptimizations, 'disableMonospaceOptimizations', false
|
||||
)),
|
||||
domReadOnly: register(new EditorBooleanOption(
|
||||
EditorOption.domReadOnly, 'domReadOnly', false,
|
||||
)),
|
||||
dragAndDrop: register(new EditorBooleanOption(
|
||||
EditorOption.dragAndDrop, 'dragAndDrop', true,
|
||||
{ description: nls.localize('dragAndDrop', "Controls whether the editor should allow moving selections via drag and drop.") }
|
||||
@@ -4263,7 +4306,7 @@ export const EditorOptions = {
|
||||
)),
|
||||
renderLineHighlightOnlyWhenFocus: register(new EditorBooleanOption(
|
||||
EditorOption.renderLineHighlightOnlyWhenFocus, 'renderLineHighlightOnlyWhenFocus', false,
|
||||
{ description: nls.localize('renderLineHighlightOnlyWhenFocus', "Controls if the editor should render the current line highlight only when the editor is focused") }
|
||||
{ description: nls.localize('renderLineHighlightOnlyWhenFocus', "Controls if the editor should render the current line highlight only when the editor is focused.") }
|
||||
)),
|
||||
renderValidationDecorations: register(new EditorStringEnumOption(
|
||||
EditorOption.renderValidationDecorations, 'renderValidationDecorations',
|
||||
@@ -4279,7 +4322,7 @@ export const EditorOptions = {
|
||||
'',
|
||||
nls.localize('renderWhitespace.boundary', "Render whitespace characters except for single spaces between words."),
|
||||
nls.localize('renderWhitespace.selection', "Render whitespace characters only on selected text."),
|
||||
nls.localize('renderWhitespace.trailing', "Render only trailing whitespace characters"),
|
||||
nls.localize('renderWhitespace.trailing', "Render only trailing whitespace characters."),
|
||||
''
|
||||
],
|
||||
description: nls.localize('renderWhitespace', "Controls how the editor should render whitespace characters.")
|
||||
|
||||
@@ -156,7 +156,7 @@ export class Cursor extends Disposable {
|
||||
this._prevEditOperationType = EditOperationType.Other;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
this._cursors.dispose();
|
||||
this._autoClosedActions = dispose(this._autoClosedActions);
|
||||
super.dispose();
|
||||
@@ -620,6 +620,10 @@ export class Cursor extends Disposable {
|
||||
this._isDoingComposition = isDoingComposition;
|
||||
}
|
||||
|
||||
public getAutoClosedCharacters(): Range[] {
|
||||
return AutoClosedAction.getAllAutoClosedCharacters(this._autoClosedActions);
|
||||
}
|
||||
|
||||
public startComposition(eventsCollector: ViewModelEventsCollector): void {
|
||||
this._selectionsWhenCompositionStarted = this.getSelections().slice(0);
|
||||
}
|
||||
@@ -628,8 +632,7 @@ export class Cursor extends Disposable {
|
||||
this._executeEdit(() => {
|
||||
if (source === 'keyboard') {
|
||||
// composition finishes, let's check if we need to auto complete if necessary.
|
||||
const autoClosedCharacters = AutoClosedAction.getAllAutoClosedCharacters(this._autoClosedActions);
|
||||
this._executeEditOperation(TypeOperations.compositionEndWithInterceptors(this._prevEditOperationType, this.context.cursorConfig, this._model, this._selectionsWhenCompositionStarted, this.getSelections(), autoClosedCharacters));
|
||||
this._executeEditOperation(TypeOperations.compositionEndWithInterceptors(this._prevEditOperationType, this.context.cursorConfig, this._model, this._selectionsWhenCompositionStarted, this.getSelections(), this.getAutoClosedCharacters()));
|
||||
this._selectionsWhenCompositionStarted = null;
|
||||
}
|
||||
}, eventsCollector, source);
|
||||
@@ -647,8 +650,7 @@ export class Cursor extends Disposable {
|
||||
const chr = text.substr(offset, charLength);
|
||||
|
||||
// Here we must interpret each typed character individually
|
||||
const autoClosedCharacters = AutoClosedAction.getAllAutoClosedCharacters(this._autoClosedActions);
|
||||
this._executeEditOperation(TypeOperations.typeWithInterceptors(this._isDoingComposition, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), autoClosedCharacters, chr));
|
||||
this._executeEditOperation(TypeOperations.typeWithInterceptors(this._isDoingComposition, this._prevEditOperationType, this.context.cursorConfig, this._model, this.getSelections(), this.getAutoClosedCharacters(), chr));
|
||||
|
||||
offset += charLength;
|
||||
}
|
||||
@@ -659,9 +661,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);
|
||||
}
|
||||
|
||||
|
||||
@@ -87,7 +87,7 @@ export class ColumnSelection {
|
||||
|
||||
public static columnSelectLeft(config: CursorConfiguration, model: ICursorSimpleModel, prevColumnSelectData: IColumnSelectData): IColumnSelectResult {
|
||||
let toViewVisualColumn = prevColumnSelectData.toViewVisualColumn;
|
||||
if (toViewVisualColumn > 1) {
|
||||
if (toViewVisualColumn > 0) {
|
||||
toViewVisualColumn--;
|
||||
}
|
||||
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { EditorAutoClosingStrategy, EditorAutoSurroundStrategy, ConfigurationChangedEvent, EditorAutoClosingOvertypeStrategy, EditorOption, EditorAutoIndentStrategy } from 'vs/editor/common/config/editorOptions';
|
||||
import { EditorAutoClosingStrategy, EditorAutoSurroundStrategy, ConfigurationChangedEvent, EditorAutoClosingEditStrategy, EditorOption, EditorAutoIndentStrategy } from 'vs/editor/common/config/editorOptions';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ISelection, Selection } from 'vs/editor/common/core/selection';
|
||||
@@ -73,7 +73,8 @@ export class CursorConfiguration {
|
||||
public readonly multiCursorPaste: 'spread' | 'full';
|
||||
public readonly autoClosingBrackets: EditorAutoClosingStrategy;
|
||||
public readonly autoClosingQuotes: EditorAutoClosingStrategy;
|
||||
public readonly autoClosingOvertype: EditorAutoClosingOvertypeStrategy;
|
||||
public readonly autoClosingDelete: EditorAutoClosingEditStrategy;
|
||||
public readonly autoClosingOvertype: EditorAutoClosingEditStrategy;
|
||||
public readonly autoSurround: EditorAutoSurroundStrategy;
|
||||
public readonly autoIndent: EditorAutoIndentStrategy;
|
||||
public readonly autoClosingPairs: AutoClosingPairs;
|
||||
@@ -92,6 +93,7 @@ export class CursorConfiguration {
|
||||
|| e.hasChanged(EditorOption.multiCursorPaste)
|
||||
|| e.hasChanged(EditorOption.autoClosingBrackets)
|
||||
|| e.hasChanged(EditorOption.autoClosingQuotes)
|
||||
|| e.hasChanged(EditorOption.autoClosingDelete)
|
||||
|| e.hasChanged(EditorOption.autoClosingOvertype)
|
||||
|| e.hasChanged(EditorOption.autoSurround)
|
||||
|| e.hasChanged(EditorOption.useTabStops)
|
||||
@@ -125,6 +127,7 @@ export class CursorConfiguration {
|
||||
this.multiCursorPaste = options.get(EditorOption.multiCursorPaste);
|
||||
this.autoClosingBrackets = options.get(EditorOption.autoClosingBrackets);
|
||||
this.autoClosingQuotes = options.get(EditorOption.autoClosingQuotes);
|
||||
this.autoClosingDelete = options.get(EditorOption.autoClosingDelete);
|
||||
this.autoClosingOvertype = options.get(EditorOption.autoClosingOvertype);
|
||||
this.autoSurround = options.get(EditorOption.autoSurround);
|
||||
this.autoIndent = options.get(EditorOption.autoIndent);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { ReplaceCommand } from 'vs/editor/common/commands/replaceCommand';
|
||||
import { EditorAutoClosingStrategy } from 'vs/editor/common/config/editorOptions';
|
||||
import { EditorAutoClosingEditStrategy, EditorAutoClosingStrategy } from 'vs/editor/common/config/editorOptions';
|
||||
import { CursorColumns, CursorConfiguration, EditOperationResult, EditOperationType, ICursorSimpleModel, isQuote } from 'vs/editor/common/controller/cursorCommon';
|
||||
import { MoveOperations } from 'vs/editor/common/controller/cursorMoveOperations';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
@@ -50,15 +50,20 @@ export class DeleteOperations {
|
||||
}
|
||||
|
||||
public static isAutoClosingPairDelete(
|
||||
autoClosingDelete: EditorAutoClosingEditStrategy,
|
||||
autoClosingBrackets: EditorAutoClosingStrategy,
|
||||
autoClosingQuotes: EditorAutoClosingStrategy,
|
||||
autoClosingPairsOpen: Map<string, StandardAutoClosingPairConditional[]>,
|
||||
model: ICursorSimpleModel,
|
||||
selections: Selection[]
|
||||
selections: Selection[],
|
||||
autoClosedCharacters: Range[]
|
||||
): boolean {
|
||||
if (autoClosingBrackets === 'never' && autoClosingQuotes === 'never') {
|
||||
return false;
|
||||
}
|
||||
if (autoClosingDelete === 'never') {
|
||||
return false;
|
||||
}
|
||||
|
||||
for (let i = 0, len = selections.length; i < len; i++) {
|
||||
const selection = selections[i];
|
||||
@@ -100,6 +105,21 @@ export class DeleteOperations {
|
||||
if (!foundAutoClosingPair) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Must delete the pair only if it was automatically inserted by the editor
|
||||
if (autoClosingDelete === 'auto') {
|
||||
let found = false;
|
||||
for (let j = 0, lenJ = autoClosedCharacters.length; j < lenJ; j++) {
|
||||
const autoClosedCharacter = autoClosedCharacters[j];
|
||||
if (position.lineNumber === autoClosedCharacter.startLineNumber && position.column === autoClosedCharacter.startColumn) {
|
||||
found = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
@@ -120,9 +140,9 @@ export class DeleteOperations {
|
||||
return [true, commands];
|
||||
}
|
||||
|
||||
public static deleteLeft(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[]): [boolean, Array<ICommand | null>] {
|
||||
public static deleteLeft(prevEditOperationType: EditOperationType, config: CursorConfiguration, model: ICursorSimpleModel, selections: Selection[], autoClosedCharacters: Range[]): [boolean, Array<ICommand | null>] {
|
||||
|
||||
if (this.isAutoClosingPairDelete(config.autoClosingBrackets, config.autoClosingQuotes, config.autoClosingPairs.autoClosingPairsOpenByEnd, model, selections)) {
|
||||
if (this.isAutoClosingPairDelete(config.autoClosingDelete, config.autoClosingBrackets, config.autoClosingQuotes, config.autoClosingPairs.autoClosingPairsOpenByEnd, model, selections, autoClosedCharacters)) {
|
||||
return this._runAutoClosingPairDelete(config, model, selections);
|
||||
}
|
||||
|
||||
|
||||
@@ -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);
|
||||
@@ -958,7 +957,7 @@ export class TypeWithAutoClosingCommand extends ReplaceCommandWithOffsetCursorSt
|
||||
this.enclosingRange = null;
|
||||
}
|
||||
|
||||
public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {
|
||||
public override computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {
|
||||
let inverseEditOperations = helper.getInverseEditOperations();
|
||||
let range = inverseEditOperations[0].range;
|
||||
this.closeCharacterRange = new Range(range.startLineNumber, range.endColumn - this._closeCharacter.length, range.endLineNumber, range.endColumn);
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import { CharCode } from 'vs/base/common/charCode';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { EditorAutoClosingStrategy } from 'vs/editor/common/config/editorOptions';
|
||||
import { EditorAutoClosingEditStrategy, EditorAutoClosingStrategy } from 'vs/editor/common/config/editorOptions';
|
||||
import { CursorConfiguration, ICursorSimpleModel, SingleCursorState } from 'vs/editor/common/controller/cursorCommon';
|
||||
import { DeleteOperations } from 'vs/editor/common/controller/cursorDeleteOperations';
|
||||
import { WordCharacterClass, WordCharacterClassifier, getMapForWordSeparators } from 'vs/editor/common/controller/wordCharacterClassifier';
|
||||
@@ -52,9 +52,11 @@ export interface DeleteWordContext {
|
||||
model: ITextModel;
|
||||
selection: Selection;
|
||||
whitespaceHeuristics: boolean;
|
||||
autoClosingDelete: EditorAutoClosingEditStrategy;
|
||||
autoClosingBrackets: EditorAutoClosingStrategy;
|
||||
autoClosingQuotes: EditorAutoClosingStrategy;
|
||||
autoClosingPairs: AutoClosingPairs;
|
||||
autoClosedCharacters: Range[];
|
||||
}
|
||||
|
||||
export class WordOperations {
|
||||
@@ -384,7 +386,7 @@ export class WordOperations {
|
||||
return selection;
|
||||
}
|
||||
|
||||
if (DeleteOperations.isAutoClosingPairDelete(ctx.autoClosingBrackets, ctx.autoClosingQuotes, ctx.autoClosingPairs.autoClosingPairsOpenByEnd, ctx.model, [ctx.selection])) {
|
||||
if (DeleteOperations.isAutoClosingPairDelete(ctx.autoClosingDelete, ctx.autoClosingBrackets, ctx.autoClosingQuotes, ctx.autoClosingPairs.autoClosingPairsOpenByEnd, ctx.model, [ctx.selection], ctx.autoClosedCharacters)) {
|
||||
const position = ctx.selection.getPosition();
|
||||
return new Range(position.lineNumber, position.column - 1, position.lineNumber, position.column + 1);
|
||||
}
|
||||
|
||||
@@ -76,7 +76,7 @@ export class Selection extends Range {
|
||||
/**
|
||||
* Transform to a human-readable representation.
|
||||
*/
|
||||
public toString(): string {
|
||||
public override toString(): string {
|
||||
return '[' + this.selectionStartLineNumber + ',' + this.selectionStartColumn + ' -> ' + this.positionLineNumber + ',' + this.positionColumn + ']';
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ export class Selection extends Range {
|
||||
/**
|
||||
* Create a new selection with a different `positionLineNumber` and `positionColumn`.
|
||||
*/
|
||||
public setEndPosition(endLineNumber: number, endColumn: number): Selection {
|
||||
public override setEndPosition(endLineNumber: number, endColumn: number): Selection {
|
||||
if (this.getDirection() === SelectionDirection.LTR) {
|
||||
return new Selection(this.startLineNumber, this.startColumn, endLineNumber, endColumn);
|
||||
}
|
||||
@@ -131,7 +131,7 @@ export class Selection extends Range {
|
||||
/**
|
||||
* Create a new selection with a different `selectionStartLineNumber` and `selectionStartColumn`.
|
||||
*/
|
||||
public setStartPosition(startLineNumber: number, startColumn: number): Selection {
|
||||
public override setStartPosition(startLineNumber: number, startColumn: number): Selection {
|
||||
if (this.getDirection() === SelectionDirection.LTR) {
|
||||
return new Selection(startLineNumber, startColumn, this.endLineNumber, this.endColumn);
|
||||
}
|
||||
@@ -143,7 +143,7 @@ export class Selection extends Range {
|
||||
/**
|
||||
* Create a `Selection` from one or two positions
|
||||
*/
|
||||
public static fromPositions(start: IPosition, end: IPosition = start): Selection {
|
||||
public static override fromPositions(start: IPosition, end: IPosition = start): Selection {
|
||||
return new Selection(start.lineNumber, start.column, end.lineNumber, end.column);
|
||||
}
|
||||
|
||||
|
||||
@@ -23,10 +23,26 @@ export interface IStringBuilder {
|
||||
appendASCIIString(str: string): void;
|
||||
}
|
||||
|
||||
let _utf16LE_TextDecoder: TextDecoder | null;
|
||||
function getUTF16LE_TextDecoder(): TextDecoder {
|
||||
if (!_utf16LE_TextDecoder) {
|
||||
_utf16LE_TextDecoder = new TextDecoder('UTF-16LE');
|
||||
}
|
||||
return _utf16LE_TextDecoder;
|
||||
}
|
||||
|
||||
let _utf16BE_TextDecoder: TextDecoder | null;
|
||||
function getUTF16BE_TextDecoder(): TextDecoder {
|
||||
if (!_utf16BE_TextDecoder) {
|
||||
_utf16BE_TextDecoder = new TextDecoder('UTF-16BE');
|
||||
}
|
||||
return _utf16BE_TextDecoder;
|
||||
}
|
||||
|
||||
let _platformTextDecoder: TextDecoder | null;
|
||||
export function getPlatformTextDecoder(): TextDecoder {
|
||||
if (!_platformTextDecoder) {
|
||||
_platformTextDecoder = new TextDecoder(platform.isLittleEndian() ? 'UTF-16LE' : 'UTF-16BE');
|
||||
_platformTextDecoder = platform.isLittleEndian() ? getUTF16LE_TextDecoder() : getUTF16BE_TextDecoder();
|
||||
}
|
||||
return _platformTextDecoder;
|
||||
}
|
||||
@@ -45,7 +61,14 @@ if (hasTextDecoder) {
|
||||
|
||||
function standardDecodeUTF16LE(source: Uint8Array, offset: number, len: number): string {
|
||||
const view = new Uint16Array(source.buffer, offset, len);
|
||||
return getPlatformTextDecoder().decode(view);
|
||||
if (len > 0 && (view[0] === 0xFEFF || view[0] === 0xFFFE)) {
|
||||
// UTF16 sometimes starts with a BOM https://de.wikipedia.org/wiki/Byte_Order_Mark
|
||||
// It looks like TextDecoder.decode will eat up a leading BOM (0xFEFF or 0xFFFE)
|
||||
// We don't want that behavior because we know the string is UTF16LE and the BOM should be maintained
|
||||
// So we use the manual decoder
|
||||
return compatDecodeUTF16LE(source, offset, len);
|
||||
}
|
||||
return getUTF16LE_TextDecoder().decode(view);
|
||||
}
|
||||
|
||||
function compatDecodeUTF16LE(source: Uint8Array, offset: number, len: number): string {
|
||||
|
||||
@@ -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
|
||||
*/
|
||||
|
||||
@@ -3,70 +3,71 @@
|
||||
* Licensed under the Source EULA. 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"));
|
||||
|
||||
}
|
||||
|
||||
@@ -19,7 +19,7 @@ function uriGetComparisonKey(resource: URI): string {
|
||||
return resource.toString();
|
||||
}
|
||||
|
||||
class SingleModelEditStackData {
|
||||
export class SingleModelEditStackData {
|
||||
|
||||
public static create(model: ITextModel, beforeCursorState: Selection[] | null): SingleModelEditStackData {
|
||||
const alternativeVersionId = model.getAlternativeVersionId();
|
||||
|
||||
@@ -25,7 +25,11 @@ export interface IModelChangedEvent {
|
||||
readonly versionId: number;
|
||||
}
|
||||
|
||||
export class MirrorTextModel {
|
||||
export interface IMirrorTextModel {
|
||||
readonly version: number;
|
||||
}
|
||||
|
||||
export class MirrorTextModel implements IMirrorTextModel {
|
||||
|
||||
protected _uri: URI;
|
||||
protected _lines: string[];
|
||||
|
||||
@@ -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();
|
||||
@@ -56,41 +57,29 @@ interface ITextStream {
|
||||
on(event: string, callback: any): void;
|
||||
}
|
||||
|
||||
export function createTextBufferFactoryFromStream(stream: ITextStream, filter?: (chunk: string) => string, validator?: (chunk: string) => Error | undefined): Promise<model.ITextBufferFactory>;
|
||||
export function createTextBufferFactoryFromStream(stream: VSBufferReadableStream, filter?: (chunk: VSBuffer) => VSBuffer, validator?: (chunk: VSBuffer) => Error | undefined): Promise<model.ITextBufferFactory>;
|
||||
export function createTextBufferFactoryFromStream(stream: ITextStream | VSBufferReadableStream, filter?: (chunk: any) => string | VSBuffer, validator?: (chunk: any) => Error | undefined): Promise<model.ITextBufferFactory> {
|
||||
export function createTextBufferFactoryFromStream(stream: ITextStream): Promise<model.ITextBufferFactory>;
|
||||
export function createTextBufferFactoryFromStream(stream: VSBufferReadableStream): Promise<model.ITextBufferFactory>;
|
||||
export function createTextBufferFactoryFromStream(stream: ITextStream | VSBufferReadableStream): Promise<model.ITextBufferFactory> {
|
||||
return new Promise<model.ITextBufferFactory>((resolve, reject) => {
|
||||
const builder = createTextBufferBuilder();
|
||||
|
||||
let done = false;
|
||||
|
||||
stream.on('data', (chunk: string | VSBuffer) => {
|
||||
if (validator) {
|
||||
const error = validator(chunk);
|
||||
if (error) {
|
||||
listenStream<string | VSBuffer>(stream, {
|
||||
onData: 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());
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
@@ -383,7 +372,7 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
this._tokenization = new TextModelTokenization(this);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
this._isDisposing = true;
|
||||
this._onWillDispose.fire();
|
||||
this._languageRegistryListener.dispose();
|
||||
@@ -880,55 +869,49 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
* Validates `range` is within buffer bounds, but allows it to sit in between surrogate pairs, etc.
|
||||
* Will try to not allocate if possible.
|
||||
*/
|
||||
private _validateRangeRelaxedNoAllocations(range: IRange): Range {
|
||||
public _validateRangeRelaxedNoAllocations(range: IRange): Range {
|
||||
const linesCount = this._buffer.getLineCount();
|
||||
|
||||
const initialStartLineNumber = range.startLineNumber;
|
||||
const initialStartColumn = range.startColumn;
|
||||
let startLineNumber: number;
|
||||
let startColumn: number;
|
||||
let startLineNumber = Math.floor((typeof initialStartLineNumber === 'number' && !isNaN(initialStartLineNumber)) ? initialStartLineNumber : 1);
|
||||
let startColumn = Math.floor((typeof initialStartColumn === 'number' && !isNaN(initialStartColumn)) ? initialStartColumn : 1);
|
||||
|
||||
if (initialStartLineNumber < 1) {
|
||||
if (startLineNumber < 1) {
|
||||
startLineNumber = 1;
|
||||
startColumn = 1;
|
||||
} else if (initialStartLineNumber > linesCount) {
|
||||
} else if (startLineNumber > linesCount) {
|
||||
startLineNumber = linesCount;
|
||||
startColumn = this.getLineMaxColumn(startLineNumber);
|
||||
} else {
|
||||
startLineNumber = initialStartLineNumber | 0;
|
||||
if (initialStartColumn <= 1) {
|
||||
if (startColumn <= 1) {
|
||||
startColumn = 1;
|
||||
} else {
|
||||
const maxColumn = this.getLineMaxColumn(startLineNumber);
|
||||
if (initialStartColumn >= maxColumn) {
|
||||
if (startColumn >= maxColumn) {
|
||||
startColumn = maxColumn;
|
||||
} else {
|
||||
startColumn = initialStartColumn | 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const initialEndLineNumber = range.endLineNumber;
|
||||
const initialEndColumn = range.endColumn;
|
||||
let endLineNumber: number;
|
||||
let endColumn: number;
|
||||
let endLineNumber = Math.floor((typeof initialEndLineNumber === 'number' && !isNaN(initialEndLineNumber)) ? initialEndLineNumber : 1);
|
||||
let endColumn = Math.floor((typeof initialEndColumn === 'number' && !isNaN(initialEndColumn)) ? initialEndColumn : 1);
|
||||
|
||||
if (initialEndLineNumber < 1) {
|
||||
if (endLineNumber < 1) {
|
||||
endLineNumber = 1;
|
||||
endColumn = 1;
|
||||
} else if (initialEndLineNumber > linesCount) {
|
||||
} else if (endLineNumber > linesCount) {
|
||||
endLineNumber = linesCount;
|
||||
endColumn = this.getLineMaxColumn(endLineNumber);
|
||||
} else {
|
||||
endLineNumber = initialEndLineNumber | 0;
|
||||
if (initialEndColumn <= 1) {
|
||||
if (endColumn <= 1) {
|
||||
endColumn = 1;
|
||||
} else {
|
||||
const maxColumn = this.getLineMaxColumn(endLineNumber);
|
||||
if (initialEndColumn >= maxColumn) {
|
||||
if (endColumn >= maxColumn) {
|
||||
endColumn = maxColumn;
|
||||
} else {
|
||||
endColumn = initialEndColumn | 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -2111,10 +2094,42 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
return this._matchBracket(this.validatePosition(position));
|
||||
}
|
||||
|
||||
private _establishBracketSearchOffsets(position: Position, lineTokens: LineTokens, modeBrackets: RichEditBrackets, tokenIndex: number) {
|
||||
const tokenCount = lineTokens.getCount();
|
||||
const currentLanguageId = lineTokens.getLanguageId(tokenIndex);
|
||||
|
||||
// limit search to not go before `maxBracketLength`
|
||||
let searchStartOffset = Math.max(0, position.column - 1 - modeBrackets.maxBracketLength);
|
||||
for (let i = tokenIndex - 1; i >= 0; i--) {
|
||||
const tokenEndOffset = lineTokens.getEndOffset(i);
|
||||
if (tokenEndOffset <= searchStartOffset) {
|
||||
break;
|
||||
}
|
||||
if (ignoreBracketsInToken(lineTokens.getStandardTokenType(i)) || lineTokens.getLanguageId(i) !== currentLanguageId) {
|
||||
searchStartOffset = tokenEndOffset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// limit search to not go after `maxBracketLength`
|
||||
let searchEndOffset = Math.min(lineTokens.getLineContent().length, position.column - 1 + modeBrackets.maxBracketLength);
|
||||
for (let i = tokenIndex + 1; i < tokenCount; i++) {
|
||||
const tokenStartOffset = lineTokens.getStartOffset(i);
|
||||
if (tokenStartOffset >= searchEndOffset) {
|
||||
break;
|
||||
}
|
||||
if (ignoreBracketsInToken(lineTokens.getStandardTokenType(i)) || lineTokens.getLanguageId(i) !== currentLanguageId) {
|
||||
searchEndOffset = tokenStartOffset;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return { searchStartOffset, searchEndOffset };
|
||||
}
|
||||
|
||||
private _matchBracket(position: Position): [Range, Range] | null {
|
||||
const lineNumber = position.lineNumber;
|
||||
const lineTokens = this._getLineTokens(lineNumber);
|
||||
const tokenCount = lineTokens.getCount();
|
||||
const lineText = this._buffer.getLineContent(lineNumber);
|
||||
|
||||
const tokenIndex = lineTokens.findTokenIndexAtOffset(position.column - 1);
|
||||
@@ -2125,19 +2140,8 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
|
||||
// check that the token is not to be ignored
|
||||
if (currentModeBrackets && !ignoreBracketsInToken(lineTokens.getStandardTokenType(tokenIndex))) {
|
||||
// limit search to not go before `maxBracketLength`
|
||||
let searchStartOffset = Math.max(0, position.column - 1 - currentModeBrackets.maxBracketLength);
|
||||
for (let i = tokenIndex - 1; i >= 0; i--) {
|
||||
const tokenEndOffset = lineTokens.getEndOffset(i);
|
||||
if (tokenEndOffset <= searchStartOffset) {
|
||||
break;
|
||||
}
|
||||
if (ignoreBracketsInToken(lineTokens.getStandardTokenType(i))) {
|
||||
searchStartOffset = tokenEndOffset;
|
||||
}
|
||||
}
|
||||
// limit search to not go after `maxBracketLength`
|
||||
const searchEndOffset = Math.min(lineText.length, position.column - 1 + currentModeBrackets.maxBracketLength);
|
||||
|
||||
let { searchStartOffset, searchEndOffset } = this._establishBracketSearchOffsets(position, lineTokens, currentModeBrackets, tokenIndex);
|
||||
|
||||
// it might be the case that [currentTokenStart -> currentTokenEnd] contains multiple brackets
|
||||
// `bestResult` will contain the most right-side result
|
||||
@@ -2176,18 +2180,9 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
|
||||
// check that previous token is not to be ignored
|
||||
if (prevModeBrackets && !ignoreBracketsInToken(lineTokens.getStandardTokenType(prevTokenIndex))) {
|
||||
// limit search in case previous token is very large, there's no need to go beyond `maxBracketLength`
|
||||
const searchStartOffset = Math.max(0, position.column - 1 - prevModeBrackets.maxBracketLength);
|
||||
let searchEndOffset = Math.min(lineText.length, position.column - 1 + prevModeBrackets.maxBracketLength);
|
||||
for (let i = prevTokenIndex + 1; i < tokenCount; i++) {
|
||||
const tokenStartOffset = lineTokens.getStartOffset(i);
|
||||
if (tokenStartOffset >= searchEndOffset) {
|
||||
break;
|
||||
}
|
||||
if (ignoreBracketsInToken(lineTokens.getStandardTokenType(i))) {
|
||||
searchEndOffset = tokenStartOffset;
|
||||
}
|
||||
}
|
||||
|
||||
let { searchStartOffset, searchEndOffset } = this._establishBracketSearchOffsets(position, lineTokens, prevModeBrackets, prevTokenIndex);
|
||||
|
||||
const foundBracket = BracketsUtils.findPrevBracketInRange(prevModeBrackets.reversedRegex, lineNumber, lineText, searchStartOffset, searchEndOffset);
|
||||
|
||||
// check that we didn't hit a bracket too far away from position
|
||||
|
||||
@@ -246,7 +246,7 @@ export class TextModelTokenization extends Disposable {
|
||||
this._resetTokenizationState();
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
this._isDisposed = true;
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -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>;
|
||||
}
|
||||
|
||||
/**
|
||||
* A value-object that contains contextual information when requesting inline values from a InlineValuesProvider.
|
||||
* @internal
|
||||
*/
|
||||
export interface InlineValueContext {
|
||||
frameId: number;
|
||||
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,
|
||||
@@ -631,8 +699,8 @@ export interface CodeAction {
|
||||
* @internal
|
||||
*/
|
||||
export const enum CodeActionTriggerType {
|
||||
Auto = 1,
|
||||
Manual = 2,
|
||||
Invoke = 1,
|
||||
Auto = 2,
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -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>;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1615,33 +1683,6 @@ export interface CommentThreadChangedEvent {
|
||||
readonly changed: CommentThread[];
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IWebviewPortMapping {
|
||||
webviewPort: number;
|
||||
extensionHostPort: number;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IWebviewOptions {
|
||||
readonly enableScripts?: boolean;
|
||||
readonly enableCommandUris?: boolean;
|
||||
readonly localResourceRoots?: ReadonlyArray<UriComponents>;
|
||||
readonly portMapping?: ReadonlyArray<IWebviewPortMapping>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IWebviewPanelOptions {
|
||||
readonly enableFindWidget?: boolean;
|
||||
readonly retainContextWhenHidden?: boolean;
|
||||
}
|
||||
|
||||
|
||||
export interface CodeLens {
|
||||
range: IRange;
|
||||
id?: string;
|
||||
@@ -1659,9 +1700,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 +1786,11 @@ export const HoverProviderRegistry = new LanguageFeatureRegistry<HoverProvider>(
|
||||
*/
|
||||
export const EvaluatableExpressionProviderRegistry = new LanguageFeatureRegistry<EvaluatableExpressionProvider>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const InlineValuesProviderRegistry = new LanguageFeatureRegistry<InlineValuesProvider>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
|
||||
@@ -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
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -58,11 +58,12 @@ export const ModesRegistry = new EditorModesRegistry();
|
||||
Registry.add(Extensions.ModesRegistry, ModesRegistry);
|
||||
|
||||
export const PLAINTEXT_MODE_ID = 'plaintext';
|
||||
export const PLAINTEXT_EXTENSION = '.txt';
|
||||
export const PLAINTEXT_LANGUAGE_IDENTIFIER = new LanguageIdentifier(PLAINTEXT_MODE_ID, LanguageId.PlainText);
|
||||
|
||||
ModesRegistry.registerLanguage({
|
||||
id: PLAINTEXT_MODE_ID,
|
||||
extensions: ['.txt'],
|
||||
extensions: [PLAINTEXT_EXTENSION],
|
||||
aliases: [nls.localize('plainText.alias', "Plain Text"), 'text'],
|
||||
mimetypes: ['text/plain']
|
||||
});
|
||||
|
||||
@@ -313,11 +313,21 @@ export class ThemeTrieElementRule {
|
||||
export class ExternalThemeTrieElement {
|
||||
|
||||
public readonly mainRule: ThemeTrieElementRule;
|
||||
public readonly children: { [segment: string]: ExternalThemeTrieElement };
|
||||
public readonly children: Map<string, ExternalThemeTrieElement>;
|
||||
|
||||
constructor(mainRule: ThemeTrieElementRule, children?: { [segment: string]: ExternalThemeTrieElement }) {
|
||||
constructor(
|
||||
mainRule: ThemeTrieElementRule,
|
||||
children: Map<string, ExternalThemeTrieElement> | { [key: string]: ExternalThemeTrieElement } = new Map<string, ExternalThemeTrieElement>()
|
||||
) {
|
||||
this.mainRule = mainRule;
|
||||
this.children = children || Object.create(null);
|
||||
if (children instanceof Map) {
|
||||
this.children = children;
|
||||
} else {
|
||||
this.children = new Map<string, ExternalThemeTrieElement>();
|
||||
for (const key in children) {
|
||||
this.children.set(key, children[key]);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -336,9 +346,9 @@ export class ThemeTrieElement {
|
||||
* used for testing purposes
|
||||
*/
|
||||
public toExternalThemeTrieElement(): ExternalThemeTrieElement {
|
||||
let children: { [segment: string]: ExternalThemeTrieElement } = Object.create(null);
|
||||
const children = new Map<string, ExternalThemeTrieElement>();
|
||||
this._children.forEach((element, index) => {
|
||||
children[index] = element.toExternalThemeTrieElement();
|
||||
children.set(index, element.toExternalThemeTrieElement());
|
||||
});
|
||||
return new ExternalThemeTrieElement(this._mainRule, children);
|
||||
}
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { mergeSort } from 'vs/base/common/arrays';
|
||||
import { stringDiff } from 'vs/base/common/diff/diff';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { globals } from 'vs/base/common/platform';
|
||||
@@ -14,7 +13,7 @@ import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { DiffComputer } from 'vs/editor/common/diff/diffComputer';
|
||||
import { IChange } from 'vs/editor/common/editorCommon';
|
||||
import { EndOfLineSequence, IWordAtPosition } from 'vs/editor/common/model';
|
||||
import { IModelChangedEvent, MirrorTextModel as BaseMirrorModel } from 'vs/editor/common/model/mirrorTextModel';
|
||||
import { IMirrorTextModel, IModelChangedEvent, MirrorTextModel as BaseMirrorModel } from 'vs/editor/common/model/mirrorTextModel';
|
||||
import { ensureValidWordDefinition, getWordAtText } from 'vs/editor/common/model/wordHelper';
|
||||
import { IInplaceReplaceSupportResult, ILink, TextEdit } from 'vs/editor/common/modes';
|
||||
import { ILinkComputerTarget, computeLinks } from 'vs/editor/common/modes/linkComputer';
|
||||
@@ -25,7 +24,7 @@ import * as types from 'vs/base/common/types';
|
||||
import { EditorWorkerHost } from 'vs/editor/common/services/editorWorkerServiceImpl';
|
||||
import { StopWatch } from 'vs/base/common/stopwatch';
|
||||
|
||||
export interface IMirrorModel {
|
||||
export interface IMirrorModel extends IMirrorTextModel {
|
||||
readonly uri: URI;
|
||||
readonly version: number;
|
||||
getValue(): string;
|
||||
@@ -97,10 +96,6 @@ class MirrorModel extends BaseMirrorModel implements ICommonModel {
|
||||
return this._uri;
|
||||
}
|
||||
|
||||
public get version(): number {
|
||||
return this._versionId;
|
||||
}
|
||||
|
||||
public get eol(): string {
|
||||
return this._eol;
|
||||
}
|
||||
@@ -455,7 +450,7 @@ export class EditorSimpleWorker implements IRequestHandler, IDisposable {
|
||||
const result: TextEdit[] = [];
|
||||
let lastEol: EndOfLineSequence | undefined = undefined;
|
||||
|
||||
edits = mergeSort(edits, (a, b) => {
|
||||
edits = edits.slice(0).sort((a, b) => {
|
||||
if (a.range && b.range) {
|
||||
return Range.compareRangesUsingStarts(a.range, b.range);
|
||||
}
|
||||
|
||||
@@ -77,7 +77,7 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
|
||||
this._register(modes.CompletionProviderRegistry.register('*', new WordBasedCompletionItemProvider(this._workerManager, configurationService, this._modelService)));
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
@@ -225,7 +225,7 @@ class WorkerManager extends Disposable {
|
||||
this._register(this._modelService.onModelRemoved(_ => this._checkStopEmptyWorker()));
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
if (this._editorWorkerClient) {
|
||||
this._editorWorkerClient.dispose();
|
||||
this._editorWorkerClient = null;
|
||||
@@ -292,7 +292,7 @@ class EditorModelManager extends Disposable {
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
for (let modelUrl in this._syncedModels) {
|
||||
dispose(this._syncedModels[modelUrl]);
|
||||
}
|
||||
@@ -523,7 +523,7 @@ export class EditorWorkerClient extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
override dispose(): void {
|
||||
super.dispose();
|
||||
this._disposed = true;
|
||||
}
|
||||
|
||||
@@ -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
|
||||
}
|
||||
|
||||
@@ -81,7 +81,7 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
|
||||
this._register(this._markerService.onMarkerChanged(this._handleMarkerChange, this));
|
||||
}
|
||||
|
||||
dispose() {
|
||||
override dispose() {
|
||||
super.dispose();
|
||||
this._markerDecorations.forEach(value => value.dispose());
|
||||
this._markerDecorations.clear();
|
||||
|
||||
@@ -4,7 +4,6 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Event } from 'vs/base/common/event';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IMode, LanguageId, LanguageIdentifier } from 'vs/editor/common/modes';
|
||||
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
|
||||
@@ -22,7 +21,7 @@ export interface ILanguageExtensionPoint {
|
||||
configuration?: URI;
|
||||
}
|
||||
|
||||
export interface ILanguageSelection extends IDisposable {
|
||||
export interface ILanguageSelection {
|
||||
readonly languageIdentifier: LanguageIdentifier;
|
||||
readonly onDidChange: Event<LanguageIdentifier>;
|
||||
}
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Disposable, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { IMode, LanguageId, LanguageIdentifier } from 'vs/editor/common/modes';
|
||||
import { FrankensteinMode } from 'vs/editor/common/modes/abstractMode';
|
||||
@@ -13,20 +13,28 @@ import { LanguagesRegistry } from 'vs/editor/common/services/languagesRegistry';
|
||||
import { ILanguageSelection, IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { firstOrDefault } from 'vs/base/common/arrays';
|
||||
|
||||
class LanguageSelection extends Disposable implements ILanguageSelection {
|
||||
class LanguageSelection implements ILanguageSelection {
|
||||
|
||||
public languageIdentifier: LanguageIdentifier;
|
||||
|
||||
private readonly _selector: () => LanguageIdentifier;
|
||||
|
||||
private readonly _onDidChange: Emitter<LanguageIdentifier> = this._register(new Emitter<LanguageIdentifier>());
|
||||
public readonly onDidChange: Event<LanguageIdentifier> = this._onDidChange.event;
|
||||
private readonly _onDidChange: Emitter<LanguageIdentifier>;
|
||||
public readonly onDidChange: Event<LanguageIdentifier>;
|
||||
|
||||
constructor(onLanguagesMaybeChanged: Event<void>, selector: () => LanguageIdentifier) {
|
||||
super();
|
||||
this._selector = selector;
|
||||
this.languageIdentifier = this._selector();
|
||||
this._register(onLanguagesMaybeChanged(() => this._evaluate()));
|
||||
|
||||
let listener: IDisposable;
|
||||
this._onDidChange = new Emitter<LanguageIdentifier>({
|
||||
onFirstListenerAdd: () => {
|
||||
listener = onLanguagesMaybeChanged(() => this._evaluate());
|
||||
},
|
||||
onLastListenerRemove: () => {
|
||||
listener.dispose();
|
||||
}
|
||||
});
|
||||
this.onDidChange = this._onDidChange.event;
|
||||
}
|
||||
|
||||
private _evaluate(): void {
|
||||
@@ -49,7 +57,7 @@ export class ModeServiceImpl extends Disposable implements IModeService {
|
||||
private readonly _onDidCreateMode = this._register(new Emitter<IMode>());
|
||||
public readonly onDidCreateMode: Event<IMode> = this._onDidCreateMode.event;
|
||||
|
||||
protected readonly _onLanguagesMaybeChanged = this._register(new Emitter<void>());
|
||||
protected readonly _onLanguagesMaybeChanged = this._register(new Emitter<void>({ leakWarningThreshold: 200 /* https://github.com/microsoft/vscode/issues/119968 */ }));
|
||||
public readonly onLanguagesMaybeChanged: Event<void> = this._onLanguagesMaybeChanged.event;
|
||||
|
||||
constructor(warnOnOverwrite = false) {
|
||||
|
||||
@@ -78,10 +78,6 @@ class ModelData implements IDisposable {
|
||||
this._languageSelectionListener.dispose();
|
||||
this._languageSelectionListener = null;
|
||||
}
|
||||
if (this._languageSelection) {
|
||||
this._languageSelection.dispose();
|
||||
this._languageSelection = null;
|
||||
}
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
@@ -741,6 +737,19 @@ export class ModelSemanticColoring extends Disposable {
|
||||
this._fetchDocumentSemanticTokens.schedule();
|
||||
}
|
||||
}));
|
||||
this._register(this._model.onDidChangeLanguage(() => {
|
||||
// clear any outstanding state
|
||||
if (this._currentDocumentResponse) {
|
||||
this._currentDocumentResponse.dispose();
|
||||
this._currentDocumentResponse = null;
|
||||
}
|
||||
if (this._currentDocumentRequestCancellationTokenSource) {
|
||||
this._currentDocumentRequestCancellationTokenSource.cancel();
|
||||
this._currentDocumentRequestCancellationTokenSource = null;
|
||||
}
|
||||
this._setDocumentSemanticTokens(null, null, null, []);
|
||||
this._fetchDocumentSemanticTokens.schedule(0);
|
||||
}));
|
||||
const bindDocumentChangeListeners = () => {
|
||||
dispose(this._documentProvidersChangeListeners);
|
||||
this._documentProvidersChangeListeners = [];
|
||||
@@ -765,7 +774,7 @@ export class ModelSemanticColoring extends Disposable {
|
||||
this._fetchDocumentSemanticTokens.schedule(0);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
if (this._currentDocumentResponse) {
|
||||
this._currentDocumentResponse.dispose();
|
||||
this._currentDocumentResponse = null;
|
||||
|
||||
@@ -57,11 +57,6 @@ export interface ITextEditorModel extends IEditorModel {
|
||||
*/
|
||||
isReadonly(): boolean;
|
||||
|
||||
/**
|
||||
* Figure out if this model is resolved or not.
|
||||
*/
|
||||
isResolved(): this is IResolvedTextEditorModel;
|
||||
|
||||
/**
|
||||
* The mode id of the text model if known.
|
||||
*/
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -76,7 +76,7 @@ class MonacoWebWorkerImpl<T> extends EditorWorkerClient implements MonacoWebWork
|
||||
}
|
||||
|
||||
// foreign host request
|
||||
public fhr(method: string, args: any[]): Promise<any> {
|
||||
public override fhr(method: string, args: any[]): Promise<any> {
|
||||
if (!this._foreignModuleHost || typeof this._foreignModuleHost[method] !== 'function') {
|
||||
return Promise.reject(new Error('Missing method ' + method + ' or missing main thread foreign host.'));
|
||||
}
|
||||
|
||||
@@ -173,126 +173,128 @@ export enum EditorOption {
|
||||
accessibilityPageSize = 3,
|
||||
ariaLabel = 4,
|
||||
autoClosingBrackets = 5,
|
||||
autoClosingOvertype = 6,
|
||||
autoClosingQuotes = 7,
|
||||
autoIndent = 8,
|
||||
automaticLayout = 9,
|
||||
autoSurround = 10,
|
||||
codeLens = 11,
|
||||
codeLensFontFamily = 12,
|
||||
codeLensFontSize = 13,
|
||||
colorDecorators = 14,
|
||||
columnSelection = 15,
|
||||
comments = 16,
|
||||
contextmenu = 17,
|
||||
copyWithSyntaxHighlighting = 18,
|
||||
cursorBlinking = 19,
|
||||
cursorSmoothCaretAnimation = 20,
|
||||
cursorStyle = 21,
|
||||
cursorSurroundingLines = 22,
|
||||
cursorSurroundingLinesStyle = 23,
|
||||
cursorWidth = 24,
|
||||
disableLayerHinting = 25,
|
||||
disableMonospaceOptimizations = 26,
|
||||
dragAndDrop = 27,
|
||||
emptySelectionClipboard = 28,
|
||||
extraEditorClassName = 29,
|
||||
fastScrollSensitivity = 30,
|
||||
find = 31,
|
||||
fixedOverflowWidgets = 32,
|
||||
folding = 33,
|
||||
foldingStrategy = 34,
|
||||
foldingHighlight = 35,
|
||||
unfoldOnClickAfterEndOfLine = 36,
|
||||
fontFamily = 37,
|
||||
fontInfo = 38,
|
||||
fontLigatures = 39,
|
||||
fontSize = 40,
|
||||
fontWeight = 41,
|
||||
formatOnPaste = 42,
|
||||
formatOnType = 43,
|
||||
glyphMargin = 44,
|
||||
gotoLocation = 45,
|
||||
hideCursorInOverviewRuler = 46,
|
||||
highlightActiveIndentGuide = 47,
|
||||
hover = 48,
|
||||
inDiffEditor = 49,
|
||||
letterSpacing = 50,
|
||||
lightbulb = 51,
|
||||
lineDecorationsWidth = 52,
|
||||
lineHeight = 53,
|
||||
lineNumbers = 54,
|
||||
lineNumbersMinChars = 55,
|
||||
linkedEditing = 56,
|
||||
links = 57,
|
||||
matchBrackets = 58,
|
||||
minimap = 59,
|
||||
mouseStyle = 60,
|
||||
mouseWheelScrollSensitivity = 61,
|
||||
mouseWheelZoom = 62,
|
||||
multiCursorMergeOverlapping = 63,
|
||||
multiCursorModifier = 64,
|
||||
multiCursorPaste = 65,
|
||||
occurrencesHighlight = 66,
|
||||
overviewRulerBorder = 67,
|
||||
overviewRulerLanes = 68,
|
||||
padding = 69,
|
||||
parameterHints = 70,
|
||||
peekWidgetDefaultFocus = 71,
|
||||
definitionLinkOpensInPeek = 72,
|
||||
quickSuggestions = 73,
|
||||
quickSuggestionsDelay = 74,
|
||||
readOnly = 75,
|
||||
renameOnType = 76,
|
||||
renderControlCharacters = 77,
|
||||
renderIndentGuides = 78,
|
||||
renderFinalNewline = 79,
|
||||
renderLineHighlight = 80,
|
||||
renderLineHighlightOnlyWhenFocus = 81,
|
||||
renderValidationDecorations = 82,
|
||||
renderWhitespace = 83,
|
||||
revealHorizontalRightPadding = 84,
|
||||
roundedSelection = 85,
|
||||
rulers = 86,
|
||||
scrollbar = 87,
|
||||
scrollBeyondLastColumn = 88,
|
||||
scrollBeyondLastLine = 89,
|
||||
scrollPredominantAxis = 90,
|
||||
selectionClipboard = 91,
|
||||
selectionHighlight = 92,
|
||||
selectOnLineNumbers = 93,
|
||||
showFoldingControls = 94,
|
||||
showUnused = 95,
|
||||
snippetSuggestions = 96,
|
||||
smartSelect = 97,
|
||||
smoothScrolling = 98,
|
||||
stickyTabStops = 99,
|
||||
stopRenderingLineAfter = 100,
|
||||
suggest = 101,
|
||||
suggestFontSize = 102,
|
||||
suggestLineHeight = 103,
|
||||
suggestOnTriggerCharacters = 104,
|
||||
suggestSelection = 105,
|
||||
tabCompletion = 106,
|
||||
tabIndex = 107,
|
||||
unusualLineTerminators = 108,
|
||||
useTabStops = 109,
|
||||
wordSeparators = 110,
|
||||
wordWrap = 111,
|
||||
wordWrapBreakAfterCharacters = 112,
|
||||
wordWrapBreakBeforeCharacters = 113,
|
||||
wordWrapColumn = 114,
|
||||
wordWrapOverride1 = 115,
|
||||
wordWrapOverride2 = 116,
|
||||
wrappingIndent = 117,
|
||||
wrappingStrategy = 118,
|
||||
showDeprecated = 119,
|
||||
inlineHints = 120,
|
||||
editorClassName = 121,
|
||||
pixelRatio = 122,
|
||||
tabFocusMode = 123,
|
||||
layoutInfo = 124,
|
||||
wrappingInfo = 125
|
||||
autoClosingDelete = 6,
|
||||
autoClosingOvertype = 7,
|
||||
autoClosingQuotes = 8,
|
||||
autoIndent = 9,
|
||||
automaticLayout = 10,
|
||||
autoSurround = 11,
|
||||
codeLens = 12,
|
||||
codeLensFontFamily = 13,
|
||||
codeLensFontSize = 14,
|
||||
colorDecorators = 15,
|
||||
columnSelection = 16,
|
||||
comments = 17,
|
||||
contextmenu = 18,
|
||||
copyWithSyntaxHighlighting = 19,
|
||||
cursorBlinking = 20,
|
||||
cursorSmoothCaretAnimation = 21,
|
||||
cursorStyle = 22,
|
||||
cursorSurroundingLines = 23,
|
||||
cursorSurroundingLinesStyle = 24,
|
||||
cursorWidth = 25,
|
||||
disableLayerHinting = 26,
|
||||
disableMonospaceOptimizations = 27,
|
||||
domReadOnly = 28,
|
||||
dragAndDrop = 29,
|
||||
emptySelectionClipboard = 30,
|
||||
extraEditorClassName = 31,
|
||||
fastScrollSensitivity = 32,
|
||||
find = 33,
|
||||
fixedOverflowWidgets = 34,
|
||||
folding = 35,
|
||||
foldingStrategy = 36,
|
||||
foldingHighlight = 37,
|
||||
unfoldOnClickAfterEndOfLine = 38,
|
||||
fontFamily = 39,
|
||||
fontInfo = 40,
|
||||
fontLigatures = 41,
|
||||
fontSize = 42,
|
||||
fontWeight = 43,
|
||||
formatOnPaste = 44,
|
||||
formatOnType = 45,
|
||||
glyphMargin = 46,
|
||||
gotoLocation = 47,
|
||||
hideCursorInOverviewRuler = 48,
|
||||
highlightActiveIndentGuide = 49,
|
||||
hover = 50,
|
||||
inDiffEditor = 51,
|
||||
letterSpacing = 52,
|
||||
lightbulb = 53,
|
||||
lineDecorationsWidth = 54,
|
||||
lineHeight = 55,
|
||||
lineNumbers = 56,
|
||||
lineNumbersMinChars = 57,
|
||||
linkedEditing = 58,
|
||||
links = 59,
|
||||
matchBrackets = 60,
|
||||
minimap = 61,
|
||||
mouseStyle = 62,
|
||||
mouseWheelScrollSensitivity = 63,
|
||||
mouseWheelZoom = 64,
|
||||
multiCursorMergeOverlapping = 65,
|
||||
multiCursorModifier = 66,
|
||||
multiCursorPaste = 67,
|
||||
occurrencesHighlight = 68,
|
||||
overviewRulerBorder = 69,
|
||||
overviewRulerLanes = 70,
|
||||
padding = 71,
|
||||
parameterHints = 72,
|
||||
peekWidgetDefaultFocus = 73,
|
||||
definitionLinkOpensInPeek = 74,
|
||||
quickSuggestions = 75,
|
||||
quickSuggestionsDelay = 76,
|
||||
readOnly = 77,
|
||||
renameOnType = 78,
|
||||
renderControlCharacters = 79,
|
||||
renderIndentGuides = 80,
|
||||
renderFinalNewline = 81,
|
||||
renderLineHighlight = 82,
|
||||
renderLineHighlightOnlyWhenFocus = 83,
|
||||
renderValidationDecorations = 84,
|
||||
renderWhitespace = 85,
|
||||
revealHorizontalRightPadding = 86,
|
||||
roundedSelection = 87,
|
||||
rulers = 88,
|
||||
scrollbar = 89,
|
||||
scrollBeyondLastColumn = 90,
|
||||
scrollBeyondLastLine = 91,
|
||||
scrollPredominantAxis = 92,
|
||||
selectionClipboard = 93,
|
||||
selectionHighlight = 94,
|
||||
selectOnLineNumbers = 95,
|
||||
showFoldingControls = 96,
|
||||
showUnused = 97,
|
||||
snippetSuggestions = 98,
|
||||
smartSelect = 99,
|
||||
smoothScrolling = 100,
|
||||
stickyTabStops = 101,
|
||||
stopRenderingLineAfter = 102,
|
||||
suggest = 103,
|
||||
suggestFontSize = 104,
|
||||
suggestLineHeight = 105,
|
||||
suggestOnTriggerCharacters = 106,
|
||||
suggestSelection = 107,
|
||||
tabCompletion = 108,
|
||||
tabIndex = 109,
|
||||
unusualLineTerminators = 110,
|
||||
useTabStops = 111,
|
||||
wordSeparators = 112,
|
||||
wordWrap = 113,
|
||||
wordWrapBreakAfterCharacters = 114,
|
||||
wordWrapBreakBeforeCharacters = 115,
|
||||
wordWrapColumn = 116,
|
||||
wordWrapOverride1 = 117,
|
||||
wordWrapOverride2 = 118,
|
||||
wrappingIndent = 119,
|
||||
wrappingStrategy = 120,
|
||||
showDeprecated = 121,
|
||||
inlineHints = 122,
|
||||
editorClassName = 123,
|
||||
pixelRatio = 124,
|
||||
tabFocusMode = 125,
|
||||
layoutInfo = 126,
|
||||
wrappingInfo = 127
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -351,12 +353,19 @@ 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
|
||||
* But these are "more general", as they should work across browsers & OS`s.
|
||||
*/
|
||||
export enum KeyCode {
|
||||
DependsOnKbLayout = -1,
|
||||
/**
|
||||
* Placed first to cover the 0 value of the enum.
|
||||
*/
|
||||
|
||||
@@ -178,7 +178,7 @@ export class ViewLayout extends Disposable implements IViewLayout {
|
||||
this._updateHeight();
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
super.dispose();
|
||||
}
|
||||
|
||||
|
||||
@@ -346,38 +346,48 @@ export class RenderLineOutput {
|
||||
export function renderViewLine(input: RenderLineInput, sb: IStringBuilder): RenderLineOutput {
|
||||
if (input.lineContent.length === 0) {
|
||||
|
||||
let containsForeignElements = ForeignElementType.None;
|
||||
|
||||
let content: string = '<span><span></span></span>';
|
||||
|
||||
if (input.lineDecorations.length > 0) {
|
||||
// This line is empty, but it contains inline decorations
|
||||
const beforeClassNames: string[] = [];
|
||||
const afterClassNames: string[] = [];
|
||||
for (let i = 0, len = input.lineDecorations.length; i < len; i++) {
|
||||
const lineDecoration = input.lineDecorations[i];
|
||||
if (lineDecoration.type === InlineDecorationType.Before) {
|
||||
beforeClassNames.push(input.lineDecorations[i].className);
|
||||
containsForeignElements |= ForeignElementType.Before;
|
||||
}
|
||||
if (lineDecoration.type === InlineDecorationType.After) {
|
||||
afterClassNames.push(input.lineDecorations[i].className);
|
||||
containsForeignElements |= ForeignElementType.After;
|
||||
sb.appendASCIIString(`<span>`);
|
||||
|
||||
let beforeCount = 0;
|
||||
let afterCount = 0;
|
||||
let containsForeignElements = ForeignElementType.None;
|
||||
for (const lineDecoration of input.lineDecorations) {
|
||||
if (lineDecoration.type === InlineDecorationType.Before || lineDecoration.type === InlineDecorationType.After) {
|
||||
sb.appendASCIIString(`<span class="`);
|
||||
sb.appendASCIIString(lineDecoration.className);
|
||||
sb.appendASCIIString(`"></span>`);
|
||||
|
||||
if (lineDecoration.type === InlineDecorationType.Before) {
|
||||
containsForeignElements |= ForeignElementType.Before;
|
||||
beforeCount++;
|
||||
}
|
||||
if (lineDecoration.type === InlineDecorationType.After) {
|
||||
containsForeignElements |= ForeignElementType.After;
|
||||
afterCount++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (containsForeignElements !== ForeignElementType.None) {
|
||||
const beforeSpan = (beforeClassNames.length > 0 ? `<span class="${beforeClassNames.join(' ')}"></span>` : ``);
|
||||
const afterSpan = (afterClassNames.length > 0 ? `<span class="${afterClassNames.join(' ')}"></span>` : ``);
|
||||
content = `<span>${beforeSpan}${afterSpan}</span>`;
|
||||
}
|
||||
sb.appendASCIIString(`</span>`);
|
||||
|
||||
const characterMapping = new CharacterMapping(1, beforeCount + afterCount);
|
||||
characterMapping.setPartData(0, beforeCount, 0, 0);
|
||||
|
||||
return new RenderLineOutput(
|
||||
characterMapping,
|
||||
false,
|
||||
containsForeignElements
|
||||
);
|
||||
}
|
||||
|
||||
sb.appendASCIIString(content);
|
||||
// completely empty line
|
||||
sb.appendASCIIString('<span><span></span></span>');
|
||||
return new RenderLineOutput(
|
||||
new CharacterMapping(0, 0),
|
||||
false,
|
||||
containsForeignElements
|
||||
ForeignElementType.None
|
||||
);
|
||||
}
|
||||
|
||||
@@ -943,7 +953,12 @@ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): Render
|
||||
break;
|
||||
|
||||
case CharCode.Null:
|
||||
sb.appendASCIIString('�');
|
||||
if (renderControlCharacters) {
|
||||
// See https://unicode-table.com/en/blocks/control-pictures/
|
||||
sb.write1(9216);
|
||||
} else {
|
||||
sb.appendASCIIString('�');
|
||||
}
|
||||
break;
|
||||
|
||||
case CharCode.UTF8_BOM:
|
||||
@@ -957,8 +972,12 @@ function _renderLine(input: ResolvedRenderLineInput, sb: IStringBuilder): Render
|
||||
if (strings.isFullWidthCharacter(charCode)) {
|
||||
charWidth++;
|
||||
}
|
||||
// See https://unicode-table.com/en/blocks/control-pictures/
|
||||
if (renderControlCharacters && charCode < 32) {
|
||||
sb.write1(9216 + charCode);
|
||||
} else if (renderControlCharacters && charCode === 127) {
|
||||
// DEL
|
||||
sb.write1(9249);
|
||||
} else {
|
||||
sb.write1(charCode);
|
||||
}
|
||||
|
||||
@@ -32,7 +32,7 @@ class WrappingCharacterClassifier extends CharacterClassifier<CharacterClass> {
|
||||
}
|
||||
}
|
||||
|
||||
public get(charCode: number): CharacterClass {
|
||||
public override get(charCode: number): CharacterClass {
|
||||
if (charCode >= 0 && charCode < 256) {
|
||||
return <CharacterClass>this._asciiMap[charCode];
|
||||
} else {
|
||||
|
||||
@@ -213,6 +213,7 @@ export interface IViewModel extends ICursorSimpleModel {
|
||||
getCursorStates(): CursorState[];
|
||||
setCursorStates(source: string | null | undefined, reason: CursorChangeReason, states: PartialCursorState[] | null): void;
|
||||
getCursorColumnSelectData(): IColumnSelectData;
|
||||
getCursorAutoClosedCharacters(): Range[];
|
||||
setCursorColumnSelectData(columnSelectData: IColumnSelectData): void;
|
||||
getPrevEditOperationType(): EditOperationType;
|
||||
setPrevEditOperationType(type: EditOperationType): void;
|
||||
|
||||
@@ -142,7 +142,7 @@ export class ViewModel extends Disposable implements IViewModel {
|
||||
this._updateConfigurationViewLineCountNow();
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
public override dispose(): void {
|
||||
// First remove listeners, as disposing the lines might end up sending
|
||||
// model decoration changed events ... and we no longer care about them ...
|
||||
super.dispose();
|
||||
@@ -914,6 +914,9 @@ export class ViewModel extends Disposable implements IViewModel {
|
||||
public getCursorColumnSelectData(): IColumnSelectData {
|
||||
return this._cursor.getCursorColumnSelectData();
|
||||
}
|
||||
public getCursorAutoClosedCharacters(): Range[] {
|
||||
return this._cursor.getAutoClosedCharacters();
|
||||
}
|
||||
public setCursorColumnSelectData(columnSelectData: IColumnSelectData): void {
|
||||
this._cursor.setCursorColumnSelectData(columnSelectData);
|
||||
}
|
||||
@@ -964,8 +967,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));
|
||||
|
||||
Reference in New Issue
Block a user