mirror of
https://github.com/microsoft/vscode.git
synced 2026-05-13 03:30:32 +01:00
don't leak proxies in editor land, also remove indentSize property which isn't API
This commit is contained in:
@@ -79,7 +79,6 @@ export class MainThreadTextEditorProperties {
|
||||
return {
|
||||
insertSpaces: modelOptions.insertSpaces,
|
||||
tabSize: modelOptions.tabSize,
|
||||
indentSize: modelOptions.indentSize,
|
||||
cursorStyle: cursorStyle,
|
||||
lineNumbers: lineNumbers
|
||||
};
|
||||
@@ -146,7 +145,6 @@ export class MainThreadTextEditorProperties {
|
||||
}
|
||||
return (
|
||||
a.tabSize === b.tabSize
|
||||
&& a.indentSize === b.indentSize
|
||||
&& a.insertSpaces === b.insertSpaces
|
||||
&& a.cursorStyle === b.cursorStyle
|
||||
&& a.lineNumbers === b.lineNumbers
|
||||
@@ -377,13 +375,6 @@ export class MainThreadTextEditor {
|
||||
if (typeof newConfiguration.tabSize !== 'undefined') {
|
||||
newOpts.tabSize = newConfiguration.tabSize;
|
||||
}
|
||||
if (typeof newConfiguration.indentSize !== 'undefined') {
|
||||
if (newConfiguration.indentSize === 'tabSize') {
|
||||
newOpts.indentSize = newOpts.tabSize || creationOpts.tabSize;
|
||||
} else {
|
||||
newOpts.indentSize = newConfiguration.indentSize;
|
||||
}
|
||||
}
|
||||
this._model.updateOptions(newOpts);
|
||||
}
|
||||
|
||||
|
||||
@@ -262,7 +262,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I
|
||||
registerDiffInformationCommand: (id: string, callback: (diff: vscode.LineChange[], ...args: any[]) => any, thisArg?: any): vscode.Disposable => {
|
||||
checkProposedApiEnabled(extension);
|
||||
return extHostCommands.registerCommand(true, id, async (...args: any[]): Promise<any> => {
|
||||
const activeTextEditor = extHostEditors.getActiveTextEditor();
|
||||
const activeTextEditor = extHostDocumentsAndEditors.activeEditor(true);
|
||||
if (!activeTextEditor) {
|
||||
extHostLogService.warn('Cannot execute ' + id + ' because there is no active text editor.');
|
||||
return undefined;
|
||||
|
||||
@@ -237,7 +237,6 @@ export interface MainThreadDocumentsShape extends IDisposable {
|
||||
|
||||
export interface ITextEditorConfigurationUpdate {
|
||||
tabSize?: number | 'auto';
|
||||
indentSize?: number | 'tabSize';
|
||||
insertSpaces?: boolean | 'auto';
|
||||
cursorStyle?: TextEditorCursorStyle;
|
||||
lineNumbers?: RenderLineNumbersType;
|
||||
@@ -245,7 +244,6 @@ export interface ITextEditorConfigurationUpdate {
|
||||
|
||||
export interface IResolvedTextEditorConfiguration {
|
||||
tabSize: number;
|
||||
indentSize: number;
|
||||
insertSpaces: boolean;
|
||||
cursorStyle: TextEditorCursorStyle;
|
||||
lineNumbers: RenderLineNumbersType;
|
||||
|
||||
@@ -44,8 +44,8 @@ export class ExtHostEditorInsets implements ExtHostEditorInsetsShape {
|
||||
createWebviewEditorInset(editor: vscode.TextEditor, line: number, height: number, options: vscode.WebviewOptions | undefined, extension: IExtensionDescription): vscode.WebviewEditorInset {
|
||||
|
||||
let apiEditor: ExtHostTextEditor | undefined;
|
||||
for (const candidate of this._editors.getVisibleTextEditors()) {
|
||||
if (candidate === editor) {
|
||||
for (const candidate of this._editors.getVisibleTextEditors(true)) {
|
||||
if (candidate.value === editor) {
|
||||
apiEditor = <ExtHostTextEditor>candidate;
|
||||
break;
|
||||
}
|
||||
@@ -121,7 +121,7 @@ export class ExtHostEditorInsets implements ExtHostEditorInsetsShape {
|
||||
}
|
||||
};
|
||||
|
||||
this._proxy.$createEditorInset(handle, apiEditor.id, apiEditor.document.uri, line + 1, height, options || {}, extension.identifier, extension.extensionLocation);
|
||||
this._proxy.$createEditorInset(handle, apiEditor.id, apiEditor.value.document.uri, line + 1, height, options || {}, extension.identifier, extension.extensionLocation);
|
||||
this._insets.set(handle, { editor, inset, onDidReceiveMessage });
|
||||
|
||||
return inset;
|
||||
|
||||
@@ -18,6 +18,7 @@ import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { ResourceMap } from 'vs/base/common/map';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { Iterable } from 'vs/base/common/iterator';
|
||||
import { Lazy } from 'vs/base/common/lazy';
|
||||
|
||||
class Reference<T> {
|
||||
private _count = 0;
|
||||
@@ -49,13 +50,13 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
|
||||
|
||||
private readonly _onDidAddDocuments = new Emitter<ExtHostDocumentData[]>();
|
||||
private readonly _onDidRemoveDocuments = new Emitter<ExtHostDocumentData[]>();
|
||||
private readonly _onDidChangeVisibleTextEditors = new Emitter<ExtHostTextEditor[]>();
|
||||
private readonly _onDidChangeActiveTextEditor = new Emitter<ExtHostTextEditor | undefined>();
|
||||
private readonly _onDidChangeVisibleTextEditors = new Emitter<vscode.TextEditor[]>();
|
||||
private readonly _onDidChangeActiveTextEditor = new Emitter<vscode.TextEditor | undefined>();
|
||||
|
||||
readonly onDidAddDocuments: Event<ExtHostDocumentData[]> = this._onDidAddDocuments.event;
|
||||
readonly onDidRemoveDocuments: Event<ExtHostDocumentData[]> = this._onDidRemoveDocuments.event;
|
||||
readonly onDidChangeVisibleTextEditors: Event<ExtHostTextEditor[]> = this._onDidChangeVisibleTextEditors.event;
|
||||
readonly onDidChangeActiveTextEditor: Event<ExtHostTextEditor | undefined> = this._onDidChangeActiveTextEditor.event;
|
||||
readonly onDidChangeVisibleTextEditors: Event<vscode.TextEditor[]> = this._onDidChangeVisibleTextEditors.event;
|
||||
readonly onDidChangeActiveTextEditor: Event<vscode.TextEditor | undefined> = this._onDidChangeActiveTextEditor.event;
|
||||
|
||||
constructor(
|
||||
@IExtHostRpcService private readonly _extHostRpc: IExtHostRpcService,
|
||||
@@ -135,7 +136,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
|
||||
data.id,
|
||||
this._extHostRpc.getProxy(MainContext.MainThreadTextEditors),
|
||||
this._logService,
|
||||
documentData,
|
||||
new Lazy(() => documentData.document),
|
||||
data.selections.map(typeConverters.Selection.to),
|
||||
data.options,
|
||||
data.visibleRanges.map(range => typeConverters.Range.to(range)),
|
||||
@@ -162,7 +163,7 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
|
||||
}
|
||||
|
||||
if (delta.removedEditors || delta.addedEditors) {
|
||||
this._onDidChangeVisibleTextEditors.fire(this.allEditors());
|
||||
this._onDidChangeVisibleTextEditors.fire(this.allEditors().map(editor => editor.value));
|
||||
}
|
||||
if (delta.newActiveEditor !== undefined) {
|
||||
this._onDidChangeActiveTextEditor.fire(this.activeEditor());
|
||||
@@ -181,11 +182,17 @@ export class ExtHostDocumentsAndEditors implements ExtHostDocumentsAndEditorsSha
|
||||
return this._editors.get(id);
|
||||
}
|
||||
|
||||
activeEditor(): ExtHostTextEditor | undefined {
|
||||
activeEditor(): vscode.TextEditor | undefined;
|
||||
activeEditor(internal: true): ExtHostTextEditor | undefined;
|
||||
activeEditor(internal?: true): vscode.TextEditor | ExtHostTextEditor | undefined {
|
||||
if (!this._activeEditorId) {
|
||||
return undefined;
|
||||
}
|
||||
const editor = this._editors.get(this._activeEditorId);
|
||||
if (internal) {
|
||||
return editor;
|
||||
} else {
|
||||
return this._editors.get(this._activeEditorId);
|
||||
return editor?.value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -10,11 +10,11 @@ import { TextEditorCursorStyle } from 'vs/editor/common/config/editorOptions';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { ISingleEditOperation } from 'vs/editor/common/model';
|
||||
import { IResolvedTextEditorConfiguration, ITextEditorConfigurationUpdate, MainThreadTextEditorsShape } from 'vs/workbench/api/common/extHost.protocol';
|
||||
import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData';
|
||||
import * as TypeConverters from 'vs/workbench/api/common/extHostTypeConverters';
|
||||
import { EndOfLine, Position, Range, Selection, SnippetString, TextEditorLineNumbersStyle, TextEditorRevealType } from 'vs/workbench/api/common/extHostTypes';
|
||||
import type * as vscode from 'vscode';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { Lazy } from 'vs/base/common/lazy';
|
||||
|
||||
export class TextEditorDecorationType implements vscode.TextEditorDecorationType {
|
||||
|
||||
@@ -134,36 +134,63 @@ export class TextEditorEdit {
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostTextEditorOptions implements vscode.TextEditorOptions {
|
||||
export class ExtHostTextEditorOptions {
|
||||
|
||||
private _proxy: MainThreadTextEditorsShape;
|
||||
private _id: string;
|
||||
private _logService: ILogService;
|
||||
|
||||
private _tabSize!: number;
|
||||
private _indentSize!: number;
|
||||
private _insertSpaces!: boolean;
|
||||
private _cursorStyle!: TextEditorCursorStyle;
|
||||
private _lineNumbers!: TextEditorLineNumbersStyle;
|
||||
|
||||
readonly value: vscode.TextEditorOptions;
|
||||
|
||||
constructor(proxy: MainThreadTextEditorsShape, id: string, source: IResolvedTextEditorConfiguration, logService: ILogService) {
|
||||
this._proxy = proxy;
|
||||
this._id = id;
|
||||
this._accept(source);
|
||||
this._logService = logService;
|
||||
|
||||
const that = this;
|
||||
|
||||
this.value = {
|
||||
get tabSize(): number | string {
|
||||
return that._tabSize;
|
||||
},
|
||||
set tabSize(value: number | string) {
|
||||
that._setTabSize(value);
|
||||
},
|
||||
get insertSpaces(): boolean | string {
|
||||
return that._insertSpaces;
|
||||
},
|
||||
set insertSpaces(value: boolean | string) {
|
||||
that._setInsertSpaces(value);
|
||||
},
|
||||
get cursorStyle(): TextEditorCursorStyle {
|
||||
return that._cursorStyle;
|
||||
},
|
||||
set cursorStyle(value: TextEditorCursorStyle) {
|
||||
that._setCursorStyle(value);
|
||||
},
|
||||
get lineNumbers(): TextEditorLineNumbersStyle {
|
||||
return that._lineNumbers;
|
||||
},
|
||||
set lineNumbers(value: TextEditorLineNumbersStyle) {
|
||||
that._setLineNumbers(value);
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
public _accept(source: IResolvedTextEditorConfiguration): void {
|
||||
this._tabSize = source.tabSize;
|
||||
this._indentSize = source.indentSize;
|
||||
this._insertSpaces = source.insertSpaces;
|
||||
this._cursorStyle = source.cursorStyle;
|
||||
this._lineNumbers = TypeConverters.TextEditorLineNumbersStyle.to(source.lineNumbers);
|
||||
}
|
||||
|
||||
public get tabSize(): number | string {
|
||||
return this._tabSize;
|
||||
}
|
||||
// --- internal: tabSize
|
||||
|
||||
private _validateTabSize(value: number | string): number | 'auto' | null {
|
||||
if (value === 'auto') {
|
||||
@@ -183,7 +210,7 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions {
|
||||
return null;
|
||||
}
|
||||
|
||||
public set tabSize(value: number | string) {
|
||||
private _setTabSize(value: number | string) {
|
||||
const tabSize = this._validateTabSize(value);
|
||||
if (tabSize === null) {
|
||||
// ignore invalid call
|
||||
@@ -202,50 +229,7 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions {
|
||||
}));
|
||||
}
|
||||
|
||||
public get indentSize(): number | string {
|
||||
return this._indentSize;
|
||||
}
|
||||
|
||||
private _validateIndentSize(value: number | string): number | 'tabSize' | null {
|
||||
if (value === 'tabSize') {
|
||||
return 'tabSize';
|
||||
}
|
||||
if (typeof value === 'number') {
|
||||
const r = Math.floor(value);
|
||||
return (r > 0 ? r : null);
|
||||
}
|
||||
if (typeof value === 'string') {
|
||||
const r = parseInt(value, 10);
|
||||
if (isNaN(r)) {
|
||||
return null;
|
||||
}
|
||||
return (r > 0 ? r : null);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
public set indentSize(value: number | string) {
|
||||
const indentSize = this._validateIndentSize(value);
|
||||
if (indentSize === null) {
|
||||
// ignore invalid call
|
||||
return;
|
||||
}
|
||||
if (typeof indentSize === 'number') {
|
||||
if (this._indentSize === indentSize) {
|
||||
// nothing to do
|
||||
return;
|
||||
}
|
||||
// reflect the new indentSize value immediately
|
||||
this._indentSize = indentSize;
|
||||
}
|
||||
this._warnOnError(this._proxy.$trySetOptions(this._id, {
|
||||
indentSize: indentSize
|
||||
}));
|
||||
}
|
||||
|
||||
public get insertSpaces(): boolean | string {
|
||||
return this._insertSpaces;
|
||||
}
|
||||
// --- internal: insert spaces
|
||||
|
||||
private _validateInsertSpaces(value: boolean | string): boolean | 'auto' {
|
||||
if (value === 'auto') {
|
||||
@@ -254,7 +238,7 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions {
|
||||
return (value === 'false' ? false : Boolean(value));
|
||||
}
|
||||
|
||||
public set insertSpaces(value: boolean | string) {
|
||||
private _setInsertSpaces(value: boolean | string) {
|
||||
const insertSpaces = this._validateInsertSpaces(value);
|
||||
if (typeof insertSpaces === 'boolean') {
|
||||
if (this._insertSpaces === insertSpaces) {
|
||||
@@ -269,11 +253,9 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions {
|
||||
}));
|
||||
}
|
||||
|
||||
public get cursorStyle(): TextEditorCursorStyle {
|
||||
return this._cursorStyle;
|
||||
}
|
||||
// --- internal: cursor style
|
||||
|
||||
public set cursorStyle(value: TextEditorCursorStyle) {
|
||||
private _setCursorStyle(value: TextEditorCursorStyle) {
|
||||
if (this._cursorStyle === value) {
|
||||
// nothing to do
|
||||
return;
|
||||
@@ -284,11 +266,9 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions {
|
||||
}));
|
||||
}
|
||||
|
||||
public get lineNumbers(): TextEditorLineNumbersStyle {
|
||||
return this._lineNumbers;
|
||||
}
|
||||
// --- internal: line number
|
||||
|
||||
public set lineNumbers(value: TextEditorLineNumbersStyle) {
|
||||
private _setLineNumbers(value: TextEditorLineNumbersStyle) {
|
||||
if (this._lineNumbers === value) {
|
||||
// nothing to do
|
||||
return;
|
||||
@@ -368,31 +348,170 @@ export class ExtHostTextEditorOptions implements vscode.TextEditorOptions {
|
||||
}
|
||||
}
|
||||
|
||||
export class ExtHostTextEditor implements vscode.TextEditor {
|
||||
|
||||
private readonly _documentData: ExtHostDocumentData;
|
||||
export class ExtHostTextEditor {
|
||||
|
||||
private _selections: Selection[];
|
||||
private _options: ExtHostTextEditorOptions;
|
||||
private _visibleRanges: Range[];
|
||||
private _viewColumn: vscode.ViewColumn | undefined;
|
||||
private _disposed: boolean = false;
|
||||
private _hasDecorationsForKey: { [key: string]: boolean; };
|
||||
private _hasDecorationsForKey = new Set<string>();
|
||||
|
||||
readonly value: vscode.TextEditor;
|
||||
|
||||
constructor(
|
||||
readonly id: string,
|
||||
private readonly _proxy: MainThreadTextEditorsShape,
|
||||
private readonly _logService: ILogService,
|
||||
document: ExtHostDocumentData,
|
||||
document: Lazy<vscode.TextDocument>,
|
||||
selections: Selection[], options: IResolvedTextEditorConfiguration,
|
||||
visibleRanges: Range[], viewColumn: vscode.ViewColumn | undefined
|
||||
) {
|
||||
this._documentData = document;
|
||||
this._selections = selections;
|
||||
this._options = new ExtHostTextEditorOptions(this._proxy, this.id, options, _logService);
|
||||
this._visibleRanges = visibleRanges;
|
||||
this._viewColumn = viewColumn;
|
||||
this._hasDecorationsForKey = Object.create(null);
|
||||
|
||||
const that = this;
|
||||
|
||||
this.value = Object.freeze({
|
||||
get document(): vscode.TextDocument {
|
||||
return document.getValue();
|
||||
},
|
||||
set document(_value) {
|
||||
throw readonly('document');
|
||||
},
|
||||
// --- selection
|
||||
get selection(): Selection {
|
||||
return that._selections && that._selections[0];
|
||||
},
|
||||
set selection(value: Selection) {
|
||||
if (!(value instanceof Selection)) {
|
||||
throw illegalArgument('selection');
|
||||
}
|
||||
that._selections = [value];
|
||||
that._trySetSelection();
|
||||
},
|
||||
get selections(): Selection[] {
|
||||
return that._selections;
|
||||
},
|
||||
set selections(value: Selection[]) {
|
||||
if (!Array.isArray(value) || value.some(a => !(a instanceof Selection))) {
|
||||
throw illegalArgument('selections');
|
||||
}
|
||||
that._selections = value;
|
||||
that._trySetSelection();
|
||||
},
|
||||
// --- visible ranges
|
||||
get visibleRanges(): Range[] {
|
||||
return that._visibleRanges;
|
||||
},
|
||||
set visibleRanges(_value: Range[]) {
|
||||
throw readonly('visibleRanges');
|
||||
},
|
||||
// --- options
|
||||
get options(): vscode.TextEditorOptions {
|
||||
return that._options.value;
|
||||
},
|
||||
set options(value: vscode.TextEditorOptions) {
|
||||
if (!that._disposed) {
|
||||
that._options.assign(value);
|
||||
}
|
||||
},
|
||||
// --- view column
|
||||
get viewColumn(): vscode.ViewColumn | undefined {
|
||||
return that._viewColumn;
|
||||
},
|
||||
set viewColumn(_value) {
|
||||
throw readonly('viewColumn');
|
||||
},
|
||||
// --- edit
|
||||
edit(callback: (edit: TextEditorEdit) => void, options: { undoStopBefore: boolean; undoStopAfter: boolean; } = { undoStopBefore: true, undoStopAfter: true }): Promise<boolean> {
|
||||
if (that._disposed) {
|
||||
return Promise.reject(new Error('TextEditor#edit not possible on closed editors'));
|
||||
}
|
||||
const edit = new TextEditorEdit(document.getValue(), options);
|
||||
callback(edit);
|
||||
return that._applyEdit(edit);
|
||||
},
|
||||
// --- snippet edit
|
||||
insertSnippet(snippet: SnippetString, where?: Position | readonly Position[] | Range | readonly Range[], options: { undoStopBefore: boolean; undoStopAfter: boolean; } = { undoStopBefore: true, undoStopAfter: true }): Promise<boolean> {
|
||||
if (that._disposed) {
|
||||
return Promise.reject(new Error('TextEditor#insertSnippet not possible on closed editors'));
|
||||
}
|
||||
let ranges: IRange[];
|
||||
|
||||
if (!where || (Array.isArray(where) && where.length === 0)) {
|
||||
ranges = that._selections.map(range => TypeConverters.Range.from(range));
|
||||
|
||||
} else if (where instanceof Position) {
|
||||
const { lineNumber, column } = TypeConverters.Position.from(where);
|
||||
ranges = [{ startLineNumber: lineNumber, startColumn: column, endLineNumber: lineNumber, endColumn: column }];
|
||||
|
||||
} else if (where instanceof Range) {
|
||||
ranges = [TypeConverters.Range.from(where)];
|
||||
} else {
|
||||
ranges = [];
|
||||
for (const posOrRange of where) {
|
||||
if (posOrRange instanceof Range) {
|
||||
ranges.push(TypeConverters.Range.from(posOrRange));
|
||||
} else {
|
||||
const { lineNumber, column } = TypeConverters.Position.from(posOrRange);
|
||||
ranges.push({ startLineNumber: lineNumber, startColumn: column, endLineNumber: lineNumber, endColumn: column });
|
||||
}
|
||||
}
|
||||
}
|
||||
return _proxy.$tryInsertSnippet(id, snippet.value, ranges, options);
|
||||
},
|
||||
setDecorations(decorationType: vscode.TextEditorDecorationType, ranges: Range[] | vscode.DecorationOptions[]): void {
|
||||
const willBeEmpty = (ranges.length === 0);
|
||||
if (willBeEmpty && !that._hasDecorationsForKey.has(decorationType.key)) {
|
||||
// avoid no-op call to the renderer
|
||||
return;
|
||||
}
|
||||
if (willBeEmpty) {
|
||||
that._hasDecorationsForKey.delete(decorationType.key);
|
||||
} else {
|
||||
that._hasDecorationsForKey.add(decorationType.key);
|
||||
}
|
||||
that._runOnProxy(() => {
|
||||
if (TypeConverters.isDecorationOptionsArr(ranges)) {
|
||||
return _proxy.$trySetDecorations(
|
||||
id,
|
||||
decorationType.key,
|
||||
TypeConverters.fromRangeOrRangeWithMessage(ranges)
|
||||
);
|
||||
} else {
|
||||
const _ranges: number[] = new Array<number>(4 * ranges.length);
|
||||
for (let i = 0, len = ranges.length; i < len; i++) {
|
||||
const range = ranges[i];
|
||||
_ranges[4 * i] = range.start.line + 1;
|
||||
_ranges[4 * i + 1] = range.start.character + 1;
|
||||
_ranges[4 * i + 2] = range.end.line + 1;
|
||||
_ranges[4 * i + 3] = range.end.character + 1;
|
||||
}
|
||||
return _proxy.$trySetDecorationsFast(
|
||||
id,
|
||||
decorationType.key,
|
||||
_ranges
|
||||
);
|
||||
}
|
||||
});
|
||||
},
|
||||
revealRange(range: Range, revealType: vscode.TextEditorRevealType): void {
|
||||
that._runOnProxy(() => _proxy.$tryRevealRange(
|
||||
id,
|
||||
TypeConverters.Range.from(range),
|
||||
(revealType || TextEditorRevealType.Default)
|
||||
));
|
||||
},
|
||||
show(column: vscode.ViewColumn) {
|
||||
_proxy.$tryShowEditor(id, TypeConverters.ViewColumn.from(column));
|
||||
},
|
||||
hide() {
|
||||
_proxy.$tryHideEditor(id);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
dispose() {
|
||||
@@ -400,164 +519,32 @@ export class ExtHostTextEditor implements vscode.TextEditor {
|
||||
this._disposed = true;
|
||||
}
|
||||
|
||||
show(column: vscode.ViewColumn) {
|
||||
this._proxy.$tryShowEditor(this.id, TypeConverters.ViewColumn.from(column));
|
||||
}
|
||||
|
||||
hide() {
|
||||
this._proxy.$tryHideEditor(this.id);
|
||||
}
|
||||
|
||||
// ---- the document
|
||||
|
||||
get document(): vscode.TextDocument {
|
||||
return this._documentData.document;
|
||||
}
|
||||
|
||||
set document(value) {
|
||||
throw readonly('document');
|
||||
}
|
||||
|
||||
// ---- options
|
||||
|
||||
get options(): vscode.TextEditorOptions {
|
||||
return this._options;
|
||||
}
|
||||
|
||||
set options(value: vscode.TextEditorOptions) {
|
||||
if (!this._disposed) {
|
||||
this._options.assign(value);
|
||||
}
|
||||
}
|
||||
// --- incoming: extension host MUST accept what the renderer says
|
||||
|
||||
_acceptOptions(options: IResolvedTextEditorConfiguration): void {
|
||||
ok(!this._disposed);
|
||||
this._options._accept(options);
|
||||
}
|
||||
|
||||
// ---- visible ranges
|
||||
|
||||
get visibleRanges(): Range[] {
|
||||
return this._visibleRanges;
|
||||
}
|
||||
|
||||
set visibleRanges(value: Range[]) {
|
||||
throw readonly('visibleRanges');
|
||||
}
|
||||
|
||||
_acceptVisibleRanges(value: Range[]): void {
|
||||
ok(!this._disposed);
|
||||
this._visibleRanges = value;
|
||||
}
|
||||
|
||||
// ---- view column
|
||||
|
||||
get viewColumn(): vscode.ViewColumn | undefined {
|
||||
return this._viewColumn;
|
||||
}
|
||||
|
||||
set viewColumn(value) {
|
||||
throw readonly('viewColumn');
|
||||
}
|
||||
|
||||
_acceptViewColumn(value: vscode.ViewColumn) {
|
||||
ok(!this._disposed);
|
||||
this._viewColumn = value;
|
||||
}
|
||||
|
||||
// ---- selections
|
||||
|
||||
get selection(): Selection {
|
||||
return this._selections && this._selections[0];
|
||||
}
|
||||
|
||||
set selection(value: Selection) {
|
||||
if (!(value instanceof Selection)) {
|
||||
throw illegalArgument('selection');
|
||||
}
|
||||
this._selections = [value];
|
||||
this._trySetSelection();
|
||||
}
|
||||
|
||||
get selections(): Selection[] {
|
||||
return this._selections;
|
||||
}
|
||||
|
||||
set selections(value: Selection[]) {
|
||||
if (!Array.isArray(value) || value.some(a => !(a instanceof Selection))) {
|
||||
throw illegalArgument('selections');
|
||||
}
|
||||
this._selections = value;
|
||||
this._trySetSelection();
|
||||
}
|
||||
|
||||
setDecorations(decorationType: vscode.TextEditorDecorationType, ranges: Range[] | vscode.DecorationOptions[]): void {
|
||||
const willBeEmpty = (ranges.length === 0);
|
||||
if (willBeEmpty && !this._hasDecorationsForKey[decorationType.key]) {
|
||||
// avoid no-op call to the renderer
|
||||
return;
|
||||
}
|
||||
if (willBeEmpty) {
|
||||
delete this._hasDecorationsForKey[decorationType.key];
|
||||
} else {
|
||||
this._hasDecorationsForKey[decorationType.key] = true;
|
||||
}
|
||||
this._runOnProxy(
|
||||
() => {
|
||||
if (TypeConverters.isDecorationOptionsArr(ranges)) {
|
||||
return this._proxy.$trySetDecorations(
|
||||
this.id,
|
||||
decorationType.key,
|
||||
TypeConverters.fromRangeOrRangeWithMessage(ranges)
|
||||
);
|
||||
} else {
|
||||
const _ranges: number[] = new Array<number>(4 * ranges.length);
|
||||
for (let i = 0, len = ranges.length; i < len; i++) {
|
||||
const range = ranges[i];
|
||||
_ranges[4 * i] = range.start.line + 1;
|
||||
_ranges[4 * i + 1] = range.start.character + 1;
|
||||
_ranges[4 * i + 2] = range.end.line + 1;
|
||||
_ranges[4 * i + 3] = range.end.character + 1;
|
||||
}
|
||||
return this._proxy.$trySetDecorationsFast(
|
||||
this.id,
|
||||
decorationType.key,
|
||||
_ranges
|
||||
);
|
||||
}
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
revealRange(range: Range, revealType: vscode.TextEditorRevealType): void {
|
||||
this._runOnProxy(
|
||||
() => this._proxy.$tryRevealRange(
|
||||
this.id,
|
||||
TypeConverters.Range.from(range),
|
||||
(revealType || TextEditorRevealType.Default)
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
private _trySetSelection(): Promise<vscode.TextEditor | null | undefined> {
|
||||
const selection = this._selections.map(TypeConverters.Selection.from);
|
||||
return this._runOnProxy(() => this._proxy.$trySetSelections(this.id, selection));
|
||||
}
|
||||
|
||||
_acceptSelections(selections: Selection[]): void {
|
||||
ok(!this._disposed);
|
||||
this._selections = selections;
|
||||
}
|
||||
|
||||
// ---- editing
|
||||
|
||||
edit(callback: (edit: TextEditorEdit) => void, options: { undoStopBefore: boolean; undoStopAfter: boolean; } = { undoStopBefore: true, undoStopAfter: true }): Promise<boolean> {
|
||||
if (this._disposed) {
|
||||
return Promise.reject(new Error('TextEditor#edit not possible on closed editors'));
|
||||
}
|
||||
const edit = new TextEditorEdit(this._documentData.document, options);
|
||||
callback(edit);
|
||||
return this._applyEdit(edit);
|
||||
private async _trySetSelection(): Promise<vscode.TextEditor | null | undefined> {
|
||||
const selection = this._selections.map(TypeConverters.Selection.from);
|
||||
await this._runOnProxy(() => this._proxy.$trySetSelections(this.id, selection));
|
||||
return this.value;
|
||||
}
|
||||
|
||||
private _applyEdit(editBuilder: TextEditorEdit): Promise<boolean> {
|
||||
@@ -613,44 +600,12 @@ export class ExtHostTextEditor implements vscode.TextEditor {
|
||||
undoStopAfter: editData.undoStopAfter
|
||||
});
|
||||
}
|
||||
|
||||
insertSnippet(snippet: SnippetString, where?: Position | readonly Position[] | Range | readonly Range[], options: { undoStopBefore: boolean; undoStopAfter: boolean; } = { undoStopBefore: true, undoStopAfter: true }): Promise<boolean> {
|
||||
if (this._disposed) {
|
||||
return Promise.reject(new Error('TextEditor#insertSnippet not possible on closed editors'));
|
||||
}
|
||||
let ranges: IRange[];
|
||||
|
||||
if (!where || (Array.isArray(where) && where.length === 0)) {
|
||||
ranges = this._selections.map(range => TypeConverters.Range.from(range));
|
||||
|
||||
} else if (where instanceof Position) {
|
||||
const { lineNumber, column } = TypeConverters.Position.from(where);
|
||||
ranges = [{ startLineNumber: lineNumber, startColumn: column, endLineNumber: lineNumber, endColumn: column }];
|
||||
|
||||
} else if (where instanceof Range) {
|
||||
ranges = [TypeConverters.Range.from(where)];
|
||||
} else {
|
||||
ranges = [];
|
||||
for (const posOrRange of where) {
|
||||
if (posOrRange instanceof Range) {
|
||||
ranges.push(TypeConverters.Range.from(posOrRange));
|
||||
} else {
|
||||
const { lineNumber, column } = TypeConverters.Position.from(posOrRange);
|
||||
ranges.push({ startLineNumber: lineNumber, startColumn: column, endLineNumber: lineNumber, endColumn: column });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return this._proxy.$tryInsertSnippet(this.id, snippet.value, ranges, options);
|
||||
}
|
||||
|
||||
// ---- util
|
||||
|
||||
private _runOnProxy(callback: () => Promise<any>): Promise<ExtHostTextEditor | undefined | null> {
|
||||
if (this._disposed) {
|
||||
this._logService.warn('TextEditor is closed/disposed');
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
|
||||
return callback().then(() => this, err => {
|
||||
if (!(err instanceof Error && err.name === 'DISPOSED')) {
|
||||
this._logService.warn(err);
|
||||
@@ -659,4 +614,3 @@ export class ExtHostTextEditor implements vscode.TextEditor {
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -41,12 +41,17 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
this._extHostDocumentsAndEditors.onDidChangeActiveTextEditor(e => this._onDidChangeActiveTextEditor.fire(e));
|
||||
}
|
||||
|
||||
getActiveTextEditor(): ExtHostTextEditor | undefined {
|
||||
getActiveTextEditor(): vscode.TextEditor | undefined {
|
||||
return this._extHostDocumentsAndEditors.activeEditor();
|
||||
}
|
||||
|
||||
getVisibleTextEditors(): vscode.TextEditor[] {
|
||||
return this._extHostDocumentsAndEditors.allEditors();
|
||||
getVisibleTextEditors(): vscode.TextEditor[];
|
||||
getVisibleTextEditors(internal: true): ExtHostTextEditor[];
|
||||
getVisibleTextEditors(internal?: true): ExtHostTextEditor[] | vscode.TextEditor[] {
|
||||
const editors = this._extHostDocumentsAndEditors.allEditors();
|
||||
return internal
|
||||
? editors
|
||||
: editors.map(editor => editor.value);
|
||||
}
|
||||
|
||||
showTextDocument(document: vscode.TextDocument, column: vscode.ViewColumn, preserveFocus: boolean): Promise<vscode.TextEditor>;
|
||||
@@ -75,7 +80,7 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
const editorId = await this._proxy.$tryShowTextDocument(document.uri, options);
|
||||
const editor = editorId && this._extHostDocumentsAndEditors.getEditor(editorId);
|
||||
if (editor) {
|
||||
return editor;
|
||||
return editor.value;
|
||||
}
|
||||
// we have no editor... having an id means that we had an editor
|
||||
// on the main side and that it isn't the current editor anymore...
|
||||
@@ -114,7 +119,7 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
// (2) fire change events
|
||||
if (data.options) {
|
||||
this._onDidChangeTextEditorOptions.fire({
|
||||
textEditor: textEditor,
|
||||
textEditor: textEditor.value,
|
||||
options: { ...data.options, lineNumbers: TypeConverters.TextEditorLineNumbersStyle.to(data.options.lineNumbers) }
|
||||
});
|
||||
}
|
||||
@@ -122,7 +127,7 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
const kind = TextEditorSelectionChangeKind.fromValue(data.selections.source);
|
||||
const selections = data.selections.selections.map(TypeConverters.Selection.to);
|
||||
this._onDidChangeTextEditorSelection.fire({
|
||||
textEditor,
|
||||
textEditor: textEditor.value,
|
||||
selections,
|
||||
kind
|
||||
});
|
||||
@@ -130,7 +135,7 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
if (data.visibleRanges) {
|
||||
const visibleRanges = arrays.coalesce(data.visibleRanges.map(TypeConverters.Range.to));
|
||||
this._onDidChangeTextEditorVisibleRanges.fire({
|
||||
textEditor,
|
||||
textEditor: textEditor.value,
|
||||
visibleRanges
|
||||
});
|
||||
}
|
||||
@@ -143,9 +148,9 @@ export class ExtHostEditors implements ExtHostEditorsShape {
|
||||
throw new Error('Unknown text editor');
|
||||
}
|
||||
const viewColumn = TypeConverters.ViewColumn.to(data[id]);
|
||||
if (textEditor.viewColumn !== viewColumn) {
|
||||
if (textEditor.value.viewColumn !== viewColumn) {
|
||||
textEditor._acceptViewColumn(viewColumn);
|
||||
this._onDidChangeTextEditorViewColumn.fire({ textEditor, viewColumn });
|
||||
this._onDidChangeTextEditorViewColumn.fire({ textEditor: textEditor.value, viewColumn });
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -11,6 +11,7 @@ import { ExtHostDocumentData } from 'vs/workbench/api/common/extHostDocumentData
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { mock } from 'vs/base/test/common/mock';
|
||||
import { NullLogService } from 'vs/platform/log/common/log';
|
||||
import { Lazy } from 'vs/base/common/lazy';
|
||||
|
||||
suite('ExtHostTextEditor', () => {
|
||||
|
||||
@@ -20,21 +21,21 @@ suite('ExtHostTextEditor', () => {
|
||||
], '\n', 1, 'text', false);
|
||||
|
||||
setup(() => {
|
||||
editor = new ExtHostTextEditor('fake', null!, new NullLogService(), doc, [], { cursorStyle: 0, insertSpaces: true, lineNumbers: 1, tabSize: 4, indentSize: 4 }, [], 1);
|
||||
editor = new ExtHostTextEditor('fake', null!, new NullLogService(), new Lazy(() => doc.document), [], { cursorStyle: 0, insertSpaces: true, lineNumbers: 1, tabSize: 4 }, [], 1);
|
||||
});
|
||||
|
||||
test('disposed editor', () => {
|
||||
|
||||
assert.ok(editor.document);
|
||||
assert.ok(editor.value.document);
|
||||
editor._acceptViewColumn(3);
|
||||
assert.strictEqual(3, editor.viewColumn);
|
||||
assert.strictEqual(3, editor.value.viewColumn);
|
||||
|
||||
editor.dispose();
|
||||
|
||||
assert.throws(() => editor._acceptViewColumn(2));
|
||||
assert.strictEqual(3, editor.viewColumn);
|
||||
assert.strictEqual(3, editor.value.viewColumn);
|
||||
|
||||
assert.ok(editor.document);
|
||||
assert.ok(editor.value.document);
|
||||
assert.throws(() => editor._acceptOptions(null!));
|
||||
assert.throws(() => editor._acceptSelections([]));
|
||||
});
|
||||
@@ -47,15 +48,15 @@ suite('ExtHostTextEditor', () => {
|
||||
applyCount += 1;
|
||||
return Promise.resolve(true);
|
||||
}
|
||||
}, new NullLogService(), doc, [], { cursorStyle: 0, insertSpaces: true, lineNumbers: 1, tabSize: 4, indentSize: 4 }, [], 1);
|
||||
}, new NullLogService(), new Lazy(() => doc.document), [], { cursorStyle: 0, insertSpaces: true, lineNumbers: 1, tabSize: 4 }, [], 1);
|
||||
|
||||
await editor.edit(edit => { });
|
||||
await editor.value.edit(edit => { });
|
||||
assert.strictEqual(applyCount, 0);
|
||||
|
||||
await editor.edit(edit => { edit.setEndOfLine(1); });
|
||||
await editor.value.edit(edit => { edit.setEndOfLine(1); });
|
||||
assert.strictEqual(applyCount, 1);
|
||||
|
||||
await editor.edit(edit => { edit.delete(new Range(0, 0, 1, 1)); });
|
||||
await editor.value.edit(edit => { edit.delete(new Range(0, 0, 1, 1)); });
|
||||
assert.strictEqual(applyCount, 2);
|
||||
});
|
||||
});
|
||||
@@ -89,7 +90,6 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
};
|
||||
opts = new ExtHostTextEditorOptions(mockProxy, '1', {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -103,20 +103,18 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
|
||||
function assertState(opts: ExtHostTextEditorOptions, expected: IResolvedTextEditorConfiguration): void {
|
||||
let actual = {
|
||||
tabSize: opts.tabSize,
|
||||
indentSize: opts.indentSize,
|
||||
insertSpaces: opts.insertSpaces,
|
||||
cursorStyle: opts.cursorStyle,
|
||||
lineNumbers: opts.lineNumbers
|
||||
tabSize: opts.value.tabSize,
|
||||
insertSpaces: opts.value.insertSpaces,
|
||||
cursorStyle: opts.value.cursorStyle,
|
||||
lineNumbers: opts.value.lineNumbers
|
||||
};
|
||||
assert.deepStrictEqual(actual, expected);
|
||||
}
|
||||
|
||||
test('can set tabSize to the same value', () => {
|
||||
opts.tabSize = 4;
|
||||
opts.value.tabSize = 4;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -125,10 +123,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('can change tabSize to positive integer', () => {
|
||||
opts.tabSize = 1;
|
||||
opts.value.tabSize = 1;
|
||||
assertState(opts, {
|
||||
tabSize: 1,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -137,10 +134,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('can change tabSize to positive float', () => {
|
||||
opts.tabSize = 2.3;
|
||||
opts.value.tabSize = 2.3;
|
||||
assertState(opts, {
|
||||
tabSize: 2,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -149,10 +145,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('can change tabSize to a string number', () => {
|
||||
opts.tabSize = '2';
|
||||
opts.value.tabSize = '2';
|
||||
assertState(opts, {
|
||||
tabSize: 2,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -161,10 +156,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('tabSize can request indentation detection', () => {
|
||||
opts.tabSize = 'auto';
|
||||
opts.value.tabSize = 'auto';
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -173,10 +167,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('ignores invalid tabSize 1', () => {
|
||||
opts.tabSize = null!;
|
||||
opts.value.tabSize = null!;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -185,10 +178,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('ignores invalid tabSize 2', () => {
|
||||
opts.tabSize = -5;
|
||||
opts.value.tabSize = -5;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -197,10 +189,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('ignores invalid tabSize 3', () => {
|
||||
opts.tabSize = 'hello';
|
||||
opts.value.tabSize = 'hello';
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -209,130 +200,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('ignores invalid tabSize 4', () => {
|
||||
opts.tabSize = '-17';
|
||||
opts.value.tabSize = '-17';
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
});
|
||||
assert.deepStrictEqual(calls, []);
|
||||
});
|
||||
|
||||
test('can set indentSize to the same value', () => {
|
||||
opts.indentSize = 4;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
});
|
||||
assert.deepStrictEqual(calls, []);
|
||||
});
|
||||
|
||||
test('can change indentSize to positive integer', () => {
|
||||
opts.indentSize = 1;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 1,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
});
|
||||
assert.deepStrictEqual(calls, [{ indentSize: 1 }]);
|
||||
});
|
||||
|
||||
test('can change indentSize to positive float', () => {
|
||||
opts.indentSize = 2.3;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 2,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
});
|
||||
assert.deepStrictEqual(calls, [{ indentSize: 2 }]);
|
||||
});
|
||||
|
||||
test('can change indentSize to a string number', () => {
|
||||
opts.indentSize = '2';
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 2,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
});
|
||||
assert.deepStrictEqual(calls, [{ indentSize: 2 }]);
|
||||
});
|
||||
|
||||
test('indentSize can request to use tabSize', () => {
|
||||
opts.indentSize = 'tabSize';
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
});
|
||||
assert.deepStrictEqual(calls, [{ indentSize: 'tabSize' }]);
|
||||
});
|
||||
|
||||
test('indentSize cannot request indentation detection', () => {
|
||||
opts.indentSize = 'auto';
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
});
|
||||
assert.deepStrictEqual(calls, []);
|
||||
});
|
||||
|
||||
test('ignores invalid indentSize 1', () => {
|
||||
opts.indentSize = null!;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
});
|
||||
assert.deepStrictEqual(calls, []);
|
||||
});
|
||||
|
||||
test('ignores invalid indentSize 2', () => {
|
||||
opts.indentSize = -5;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
});
|
||||
assert.deepStrictEqual(calls, []);
|
||||
});
|
||||
|
||||
test('ignores invalid indentSize 3', () => {
|
||||
opts.indentSize = 'hello';
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
});
|
||||
assert.deepStrictEqual(calls, []);
|
||||
});
|
||||
|
||||
test('ignores invalid indentSize 4', () => {
|
||||
opts.indentSize = '-17';
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -341,10 +211,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('can set insertSpaces to the same value', () => {
|
||||
opts.insertSpaces = false;
|
||||
opts.value.insertSpaces = false;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -353,10 +222,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('can set insertSpaces to boolean', () => {
|
||||
opts.insertSpaces = true;
|
||||
opts.value.insertSpaces = true;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: true,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -365,10 +233,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('can set insertSpaces to false string', () => {
|
||||
opts.insertSpaces = 'false';
|
||||
opts.value.insertSpaces = 'false';
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -377,10 +244,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('can set insertSpaces to truey', () => {
|
||||
opts.insertSpaces = 'hello';
|
||||
opts.value.insertSpaces = 'hello';
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: true,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -389,10 +255,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('insertSpaces can request indentation detection', () => {
|
||||
opts.insertSpaces = 'auto';
|
||||
opts.value.insertSpaces = 'auto';
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -401,10 +266,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('can set cursorStyle to same value', () => {
|
||||
opts.cursorStyle = TextEditorCursorStyle.Line;
|
||||
opts.value.cursorStyle = TextEditorCursorStyle.Line;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -413,10 +277,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('can change cursorStyle', () => {
|
||||
opts.cursorStyle = TextEditorCursorStyle.Block;
|
||||
opts.value.cursorStyle = TextEditorCursorStyle.Block;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Block,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -425,10 +288,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('can set lineNumbers to same value', () => {
|
||||
opts.lineNumbers = TextEditorLineNumbersStyle.On;
|
||||
opts.value.lineNumbers = TextEditorLineNumbersStyle.On;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -437,10 +299,9 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
|
||||
test('can change lineNumbers', () => {
|
||||
opts.lineNumbers = TextEditorLineNumbersStyle.Off;
|
||||
opts.value.lineNumbers = TextEditorLineNumbersStyle.Off;
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.Off
|
||||
@@ -457,7 +318,6 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -472,7 +332,6 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: true,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -487,7 +346,6 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
assertState(opts, {
|
||||
tabSize: 3,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Line,
|
||||
lineNumbers: RenderLineNumbersType.On
|
||||
@@ -502,7 +360,6 @@ suite('ExtHostTextEditorOptions', () => {
|
||||
});
|
||||
assertState(opts, {
|
||||
tabSize: 4,
|
||||
indentSize: 4,
|
||||
insertSpaces: false,
|
||||
cursorStyle: TextEditorCursorStyle.Block,
|
||||
lineNumbers: RenderLineNumbersType.Relative
|
||||
|
||||
Reference in New Issue
Block a user