mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-02-16 18:46:40 -05:00
Merge from vscode 011858832762aaff245b2336fb1c38166e7a10fb (#4663)
This commit is contained in:
@@ -20,6 +20,7 @@ import { IConstructorSignature1, ServicesAccessor } from 'vs/platform/instantiat
|
||||
import { IKeybindings, KeybindingsRegistry } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
|
||||
export type ServicesAccessor = ServicesAccessor;
|
||||
export type IEditorContributionCtor = IConstructorSignature1<ICodeEditor, IEditorContribution>;
|
||||
@@ -88,7 +89,7 @@ export abstract class Command {
|
||||
id: this.id,
|
||||
handler: (accessor, args) => this.runCommand(accessor, args),
|
||||
weight: this._kbOpts.weight,
|
||||
when: kbWhen || null,
|
||||
when: kbWhen,
|
||||
primary: this._kbOpts.primary,
|
||||
secondary: this._kbOpts.secondary,
|
||||
win: this._kbOpts.win,
|
||||
@@ -156,7 +157,7 @@ export abstract class EditorCommand extends Command {
|
||||
|
||||
return editor.invokeWithinContext((editorAccessor) => {
|
||||
const kbService = editorAccessor.get(IContextKeyService);
|
||||
if (!kbService.contextMatchesRules(this.precondition)) {
|
||||
if (!kbService.contextMatchesRules(withNullAsUndefined(this.precondition))) {
|
||||
// precondition does not hold
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -272,7 +272,7 @@ class Widget {
|
||||
|
||||
public setPosition(position: IPosition | null | undefined, range: IRange | null | undefined, preference: ContentWidgetPositionPreference[] | null | undefined): void {
|
||||
this._setPosition(position, range);
|
||||
this._preference = preference || null;
|
||||
this._preference = withUndefinedAsNull(preference);
|
||||
this._cachedDomNodeClientWidth = -1;
|
||||
this._cachedDomNodeClientHeight = -1;
|
||||
}
|
||||
|
||||
@@ -49,6 +49,7 @@ import { ServiceCollection } from 'vs/platform/instantiation/common/serviceColle
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IThemeService, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
|
||||
let EDITOR_ID = 0;
|
||||
|
||||
@@ -308,7 +309,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
|
||||
action.id,
|
||||
action.label,
|
||||
action.alias,
|
||||
action.precondition,
|
||||
withNullAsUndefined(action.precondition),
|
||||
(): Promise<void> => {
|
||||
return this._instantiationService.invokeFunction((accessor) => {
|
||||
return Promise.resolve(action.runEditorCommand(accessor, this, null));
|
||||
@@ -1644,6 +1645,8 @@ export class EditorModeContext extends Disposable {
|
||||
private readonly _hasRenameProvider: IContextKey<boolean>;
|
||||
private readonly _hasDocumentFormattingProvider: IContextKey<boolean>;
|
||||
private readonly _hasDocumentSelectionFormattingProvider: IContextKey<boolean>;
|
||||
private readonly _hasMultipleDocumentFormattingProvider: IContextKey<boolean>;
|
||||
private readonly _hasMultipleDocumentSelectionFormattingProvider: IContextKey<boolean>;
|
||||
private readonly _hasSignatureHelpProvider: IContextKey<boolean>;
|
||||
private readonly _isInWalkThrough: IContextKey<boolean>;
|
||||
|
||||
@@ -1667,9 +1670,11 @@ export class EditorModeContext extends Disposable {
|
||||
this._hasDocumentSymbolProvider = EditorContextKeys.hasDocumentSymbolProvider.bindTo(contextKeyService);
|
||||
this._hasReferenceProvider = EditorContextKeys.hasReferenceProvider.bindTo(contextKeyService);
|
||||
this._hasRenameProvider = EditorContextKeys.hasRenameProvider.bindTo(contextKeyService);
|
||||
this._hasSignatureHelpProvider = EditorContextKeys.hasSignatureHelpProvider.bindTo(contextKeyService);
|
||||
this._hasDocumentFormattingProvider = EditorContextKeys.hasDocumentFormattingProvider.bindTo(contextKeyService);
|
||||
this._hasDocumentSelectionFormattingProvider = EditorContextKeys.hasDocumentSelectionFormattingProvider.bindTo(contextKeyService);
|
||||
this._hasSignatureHelpProvider = EditorContextKeys.hasSignatureHelpProvider.bindTo(contextKeyService);
|
||||
this._hasMultipleDocumentFormattingProvider = EditorContextKeys.hasMultipleDocumentFormattingProvider.bindTo(contextKeyService);
|
||||
this._hasMultipleDocumentSelectionFormattingProvider = EditorContextKeys.hasMultipleDocumentSelectionFormattingProvider.bindTo(contextKeyService);
|
||||
this._isInWalkThrough = EditorContextKeys.isInEmbeddedEditor.bindTo(contextKeyService);
|
||||
|
||||
const update = () => this._update();
|
||||
@@ -1744,6 +1749,8 @@ export class EditorModeContext extends Disposable {
|
||||
this._hasSignatureHelpProvider.set(modes.SignatureHelpProviderRegistry.has(model));
|
||||
this._hasDocumentFormattingProvider.set(modes.DocumentFormattingEditProviderRegistry.has(model) || modes.DocumentRangeFormattingEditProviderRegistry.has(model));
|
||||
this._hasDocumentSelectionFormattingProvider.set(modes.DocumentRangeFormattingEditProviderRegistry.has(model));
|
||||
this._hasMultipleDocumentFormattingProvider.set(modes.DocumentFormattingEditProviderRegistry.all(model).length > 1 || modes.DocumentRangeFormattingEditProviderRegistry.all(model).length > 1);
|
||||
this._hasMultipleDocumentSelectionFormattingProvider.set(modes.DocumentRangeFormattingEditProviderRegistry.all(model).length > 1);
|
||||
this._isInWalkThrough.set(model.uri.scheme === Schemas.walkThroughSnippet);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ export class InternalEditorAction implements IEditorAction {
|
||||
public readonly label: string;
|
||||
public readonly alias: string;
|
||||
|
||||
private readonly _precondition: ContextKeyExpr | null;
|
||||
private readonly _precondition: ContextKeyExpr | undefined;
|
||||
private readonly _run: () => Promise<void>;
|
||||
private readonly _contextKeyService: IContextKeyService;
|
||||
|
||||
@@ -20,7 +20,7 @@ export class InternalEditorAction implements IEditorAction {
|
||||
id: string,
|
||||
label: string,
|
||||
alias: string,
|
||||
precondition: ContextKeyExpr | null,
|
||||
precondition: ContextKeyExpr | undefined,
|
||||
run: () => Promise<void>,
|
||||
contextKeyService: IContextKeyService
|
||||
) {
|
||||
|
||||
@@ -46,7 +46,12 @@ export namespace EditorContextKeys {
|
||||
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);
|
||||
|
||||
// -- mode context keys: formatting
|
||||
export const hasDocumentFormattingProvider = new RawContextKey<boolean>('editorHasDocumentFormattingProvider', false);
|
||||
export const hasDocumentSelectionFormattingProvider = new RawContextKey<boolean>('editorHasDocumentSelectionFormattingProvider', false);
|
||||
export const hasSignatureHelpProvider = new RawContextKey<boolean>('editorHasSignatureHelpProvider', false);
|
||||
export const hasMultipleDocumentFormattingProvider = new RawContextKey<boolean>('editorHasMultipleDocumentFormattingProvider', false);
|
||||
export const hasMultipleDocumentSelectionFormattingProvider = new RawContextKey<boolean>('editorHasMultipleDocumentSelectionFormattingProvider', false);
|
||||
|
||||
}
|
||||
|
||||
@@ -32,6 +32,7 @@ import { ignoreBracketsInToken } from 'vs/editor/common/modes/supports';
|
||||
import { BracketsUtils, RichEditBracket, RichEditBrackets } from 'vs/editor/common/modes/supports/richEditBrackets';
|
||||
import { IStringStream, ITextSnapshot } from 'vs/platform/files/common/files';
|
||||
import { ITheme, ThemeColor } from 'vs/platform/theme/common/themeService';
|
||||
import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||
|
||||
const CHEAP_TOKENIZATION_LENGTH_LIMIT = 2048;
|
||||
|
||||
@@ -2877,8 +2878,8 @@ export class ModelDecorationOptions implements model.IModelDecorationOptions {
|
||||
this.stickiness = options.stickiness || model.TrackedRangeStickiness.AlwaysGrowsWhenTypingAtEdges;
|
||||
this.zIndex = options.zIndex || 0;
|
||||
this.className = options.className ? cleanClassName(options.className) : null;
|
||||
this.hoverMessage = options.hoverMessage || null;
|
||||
this.glyphMarginHoverMessage = options.glyphMarginHoverMessage || null;
|
||||
this.hoverMessage = withUndefinedAsNull(options.hoverMessage);
|
||||
this.glyphMarginHoverMessage = withUndefinedAsNull(options.glyphMarginHoverMessage);
|
||||
this.isWholeLine = options.isWholeLine || false;
|
||||
this.showIfCollapsed = options.showIfCollapsed || false;
|
||||
this.collapseOnReplaceEdit = options.collapseOnReplaceEdit || false;
|
||||
|
||||
@@ -929,6 +929,8 @@ export interface DocumentFormattingEditProvider {
|
||||
*/
|
||||
readonly extensionId?: ExtensionIdentifier;
|
||||
|
||||
readonly displayName?: string;
|
||||
|
||||
/**
|
||||
* Provide formatting edits for a whole document.
|
||||
*/
|
||||
@@ -939,13 +941,13 @@ export interface DocumentFormattingEditProvider {
|
||||
* the formatting-feature.
|
||||
*/
|
||||
export interface DocumentRangeFormattingEditProvider {
|
||||
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
readonly extensionId?: ExtensionIdentifier;
|
||||
|
||||
readonly displayName?: string;
|
||||
|
||||
/**
|
||||
* Provide formatting edits for a range in a document.
|
||||
*
|
||||
@@ -1396,6 +1398,24 @@ export interface WorkspaceCommentProvider {
|
||||
onDidChangeCommentThreads(): Event<CommentThreadChangedEvent>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IWebviewOptions {
|
||||
readonly enableScripts?: boolean;
|
||||
readonly enableCommandUris?: boolean;
|
||||
readonly localResourceRoots?: ReadonlyArray<URI>;
|
||||
readonly portMapping?: ReadonlyArray<{ port: number, resolvedPort: number }>;
|
||||
}
|
||||
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export interface IWebviewPanelOptions {
|
||||
readonly enableFindWidget?: boolean;
|
||||
readonly retainContextWhenHidden?: boolean;
|
||||
}
|
||||
|
||||
export interface ICodeLensSymbol {
|
||||
range: IRange;
|
||||
id?: string;
|
||||
|
||||
@@ -26,7 +26,7 @@ export interface IEditorWorkerService {
|
||||
canComputeDirtyDiff(original: URI, modified: URI): boolean;
|
||||
computeDirtyDiff(original: URI, modified: URI, ignoreTrimWhitespace: boolean): Promise<IChange[] | null>;
|
||||
|
||||
computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined): Promise<TextEdit[] | null | undefined>;
|
||||
computeMoreMinimalEdits(resource: URI, edits: TextEdit[] | null | undefined): Promise<TextEdit[] | undefined>;
|
||||
|
||||
canComputeWordRanges(resource: URI): boolean;
|
||||
computeWordRanges(resource: URI, range: IRange): Promise<{ [word: string]: IRange[] } | null>;
|
||||
|
||||
@@ -20,6 +20,7 @@ import { IDiffComputationResult, IEditorWorkerService } from 'vs/editor/common/s
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
|
||||
import { regExpFlags } from 'vs/base/common/strings';
|
||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
|
||||
/**
|
||||
* Stop syncing a model to the worker if it was not needed for 1 min.
|
||||
@@ -88,14 +89,15 @@ export class EditorWorkerServiceImpl extends Disposable implements IEditorWorker
|
||||
return this._workerManager.withWorker().then(client => client.computeDirtyDiff(original, modified, ignoreTrimWhitespace));
|
||||
}
|
||||
|
||||
public computeMoreMinimalEdits(resource: URI, edits: modes.TextEdit[] | null | undefined): Promise<modes.TextEdit[] | null | undefined> {
|
||||
if (!Array.isArray(edits) || edits.length === 0) {
|
||||
return Promise.resolve(edits);
|
||||
} else {
|
||||
public computeMoreMinimalEdits(resource: URI, edits: modes.TextEdit[] | null | undefined): Promise<modes.TextEdit[] | undefined> {
|
||||
if (isNonEmptyArray(edits)) {
|
||||
if (!canSyncModel(this._modelService, resource)) {
|
||||
return Promise.resolve(edits); // File too large
|
||||
}
|
||||
return this._workerManager.withWorker().then(client => client.computeMoreMinimalEdits(resource, edits));
|
||||
|
||||
} else {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import { NULL_LANGUAGE_IDENTIFIER, NULL_MODE_ID } from 'vs/editor/common/modes/n
|
||||
import { ILanguageExtensionPoint } from 'vs/editor/common/services/modeService';
|
||||
import { Extensions, IConfigurationRegistry } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||
|
||||
const hasOwnProperty = Object.prototype.hasOwnProperty;
|
||||
|
||||
@@ -267,7 +268,7 @@ export class LanguagesRegistry extends Disposable {
|
||||
return null;
|
||||
}
|
||||
const language = this._languages[modeId];
|
||||
return (language.mimetypes[0] || null);
|
||||
return withUndefinedAsNull(language.mimetypes[0]);
|
||||
}
|
||||
|
||||
public extractModeIds(commaSeparatedMimetypesOrCommaSeparatedIds: string | undefined): string[] {
|
||||
|
||||
@@ -16,6 +16,7 @@ import { keys } from 'vs/base/common/map';
|
||||
import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDecorationService';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||
|
||||
function MODEL_ID(resource: URI): string {
|
||||
return resource.toString();
|
||||
@@ -80,7 +81,7 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
|
||||
|
||||
getMarker(model: ITextModel, decoration: IModelDecoration): IMarker | null {
|
||||
const markerDecorations = this._markerDecorations.get(MODEL_ID(model.uri));
|
||||
return markerDecorations ? markerDecorations.getMarker(decoration) || null : null;
|
||||
return markerDecorations ? withUndefinedAsNull(markerDecorations.getMarker(decoration)) : null;
|
||||
}
|
||||
|
||||
getLiveMarkers(model: ITextModel): [Range, IMarker][] {
|
||||
|
||||
@@ -163,7 +163,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
|
||||
const lineContent = model.getLineContent(lineNumber);
|
||||
const indent = TextModel.computeIndentLevel(lineContent, tabSize);
|
||||
const lineHasSpace = config.fontInfo.spaceWidth * indent > 22;
|
||||
const isFolded = (lineNumber) => {
|
||||
const isFolded = (lineNumber: number) => {
|
||||
return lineNumber > 2 && this._editor.getTopForLineNumber(lineNumber) === this._editor.getTopForLineNumber(lineNumber - 1);
|
||||
};
|
||||
|
||||
|
||||
@@ -25,7 +25,7 @@ class CodeLensViewZone implements editorBrowser.IViewZone {
|
||||
|
||||
afterLineNumber: number;
|
||||
|
||||
private _lastHeight: number;
|
||||
private _lastHeight?: number;
|
||||
private readonly _onHeight: Function;
|
||||
|
||||
constructor(afterLineNumber: number, onHeight: Function) {
|
||||
|
||||
@@ -67,7 +67,7 @@ suite('FindController', () => {
|
||||
getBoolean: (key: string) => !!queryState[key],
|
||||
getNumber: (key: string) => undefined,
|
||||
store: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); },
|
||||
remove: (key) => undefined
|
||||
remove: () => undefined
|
||||
} as any);
|
||||
|
||||
if (platform.isMacintosh) {
|
||||
@@ -442,7 +442,7 @@ suite('FindController query options persistence', () => {
|
||||
getBoolean: (key: string) => !!queryState[key],
|
||||
getNumber: (key: string) => undefined,
|
||||
store: (key: string, value: any) => { queryState[key] = value; return Promise.resolve(); },
|
||||
remove: (key) => undefined
|
||||
remove: () => undefined
|
||||
} as any);
|
||||
|
||||
test('matchCase', () => {
|
||||
|
||||
@@ -66,7 +66,7 @@ export class FoldingModel {
|
||||
public update(newRegions: FoldingRegions, blockedLineNumers: number[] = []): void {
|
||||
let newEditorDecorations: IModelDeltaDecoration[] = [];
|
||||
|
||||
let isBlocked = (startLineNumber, endLineNumber) => {
|
||||
let isBlocked = (startLineNumber: number, endLineNumber: number) => {
|
||||
for (let blockedLineNumber of blockedLineNumers) {
|
||||
if (startLineNumber < blockedLineNumber && blockedLineNumber <= endLineNumber) { // first line is visible
|
||||
return true;
|
||||
|
||||
@@ -3,138 +3,258 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { alert } from 'vs/base/browser/ui/aria/aria';
|
||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { illegalArgument, onUnexpectedExternalError } from 'vs/base/common/errors';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { registerLanguageCommand } from 'vs/editor/browser/editorExtensions';
|
||||
import { DocumentFormattingEditProviderRegistry, DocumentRangeFormattingEditProviderRegistry, OnTypeFormattingEditProviderRegistry, FormattingOptions, TextEdit } from 'vs/editor/common/modes';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { first } from 'vs/base/common/async';
|
||||
import { CodeEditorStateFlag, EditorState } from 'vs/editor/browser/core/editorState';
|
||||
import { IActiveCodeEditor, isCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { registerLanguageCommand, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ISingleEditOperation, ITextModel } from 'vs/editor/common/model';
|
||||
import { DocumentFormattingEditProvider, DocumentFormattingEditProviderRegistry, DocumentRangeFormattingEditProvider, DocumentRangeFormattingEditProviderRegistry, FormattingOptions, OnTypeFormattingEditProviderRegistry, TextEdit } from 'vs/editor/common/modes';
|
||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { FormattingEdit } from 'vs/editor/contrib/format/formattingEdit';
|
||||
import * as nls from 'vs/nls';
|
||||
import { ExtensionIdentifier } from 'vs/platform/extensions/common/extensions';
|
||||
import { IDisposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export const enum FormatMode {
|
||||
Auto = 1,
|
||||
Manual = 2,
|
||||
}
|
||||
export function alertFormattingEdits(edits: ISingleEditOperation[]): void {
|
||||
|
||||
export const enum FormatKind {
|
||||
Document = 8,
|
||||
Range = 16,
|
||||
OnType = 32,
|
||||
}
|
||||
edits = edits.filter(edit => edit.range);
|
||||
if (!edits.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
export interface IFormatterConflictCallback {
|
||||
(extensionIds: (ExtensionIdentifier | undefined)[], model: ITextModel, mode: number): void;
|
||||
}
|
||||
|
||||
let _conflictResolver: IFormatterConflictCallback | undefined;
|
||||
|
||||
export function setFormatterConflictCallback(callback: IFormatterConflictCallback): IDisposable {
|
||||
let oldCallback = _conflictResolver;
|
||||
_conflictResolver = callback;
|
||||
return {
|
||||
dispose() {
|
||||
if (oldCallback) {
|
||||
_conflictResolver = oldCallback;
|
||||
oldCallback = undefined;
|
||||
}
|
||||
let { range } = edits[0];
|
||||
for (let i = 1; i < edits.length; i++) {
|
||||
range = Range.plusRange(range, edits[i].range);
|
||||
}
|
||||
const { startLineNumber, endLineNumber } = range;
|
||||
if (startLineNumber === endLineNumber) {
|
||||
if (edits.length === 1) {
|
||||
alert(nls.localize('hint11', "Made 1 formatting edit on line {0}", startLineNumber));
|
||||
} else {
|
||||
alert(nls.localize('hintn1', "Made {0} formatting edits on line {1}", edits.length, startLineNumber));
|
||||
}
|
||||
} else {
|
||||
if (edits.length === 1) {
|
||||
alert(nls.localize('hint1n', "Made 1 formatting edit between lines {0} and {1}", startLineNumber, endLineNumber));
|
||||
} else {
|
||||
alert(nls.localize('hintnn', "Made {0} formatting edits between lines {1} and {2}", edits.length, startLineNumber, endLineNumber));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
function invokeFormatterCallback<T extends { extensionId?: ExtensionIdentifier }>(formatter: T[], model: ITextModel, mode: number): void {
|
||||
if (_conflictResolver) {
|
||||
const ids = formatter.map(formatter => formatter.extensionId);
|
||||
_conflictResolver(ids, model, mode);
|
||||
}
|
||||
}
|
||||
|
||||
export async function getDocumentRangeFormattingEdits(
|
||||
telemetryService: ITelemetryService,
|
||||
export function getRealAndSyntheticDocumentFormattersOrdered(model: ITextModel): DocumentFormattingEditProvider[] {
|
||||
const result: DocumentFormattingEditProvider[] = [];
|
||||
const seen = new Set<string>();
|
||||
|
||||
// (1) add all document formatter
|
||||
const docFormatter = DocumentFormattingEditProviderRegistry.ordered(model);
|
||||
for (const formatter of docFormatter) {
|
||||
result.push(formatter);
|
||||
if (formatter.extensionId) {
|
||||
seen.add(ExtensionIdentifier.toKey(formatter.extensionId));
|
||||
}
|
||||
}
|
||||
|
||||
// (2) add all range formatter as document formatter (unless the same extension already did that)
|
||||
const rangeFormatter = DocumentRangeFormattingEditProviderRegistry.ordered(model);
|
||||
for (const formatter of rangeFormatter) {
|
||||
if (formatter.extensionId) {
|
||||
if (seen.has(ExtensionIdentifier.toKey(formatter.extensionId))) {
|
||||
continue;
|
||||
}
|
||||
seen.add(ExtensionIdentifier.toKey(formatter.extensionId));
|
||||
}
|
||||
result.push({
|
||||
displayName: formatter.displayName,
|
||||
extensionId: formatter.extensionId,
|
||||
provideDocumentFormattingEdits(model, options, token) {
|
||||
return formatter.provideDocumentRangeFormattingEdits(model, model.getFullModelRange(), options, token);
|
||||
}
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
export async function formatDocumentRangeWithProvider(
|
||||
accessor: ServicesAccessor,
|
||||
provider: DocumentRangeFormattingEditProvider,
|
||||
editorOrModel: ITextModel | IActiveCodeEditor,
|
||||
range: Range,
|
||||
token: CancellationToken
|
||||
): Promise<boolean> {
|
||||
const workerService = accessor.get(IEditorWorkerService);
|
||||
|
||||
let model: ITextModel;
|
||||
let validate: () => boolean;
|
||||
if (isCodeEditor(editorOrModel)) {
|
||||
model = editorOrModel.getModel();
|
||||
const state = new EditorState(editorOrModel, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position);
|
||||
validate = () => state.validate(editorOrModel);
|
||||
} else {
|
||||
model = editorOrModel;
|
||||
const versionNow = editorOrModel.getVersionId();
|
||||
validate = () => versionNow === editorOrModel.getVersionId();
|
||||
}
|
||||
|
||||
const rawEdits = await provider.provideDocumentRangeFormattingEdits(
|
||||
model,
|
||||
range,
|
||||
model.getFormattingOptions(),
|
||||
token
|
||||
);
|
||||
|
||||
const edits = await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
|
||||
|
||||
if (!validate()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!edits || edits.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isCodeEditor(editorOrModel)) {
|
||||
// use editor to apply edits
|
||||
FormattingEdit.execute(editorOrModel, edits);
|
||||
alertFormattingEdits(edits);
|
||||
editorOrModel.pushUndoStop();
|
||||
editorOrModel.focus();
|
||||
editorOrModel.revealPositionInCenterIfOutsideViewport(editorOrModel.getPosition(), editorCommon.ScrollType.Immediate);
|
||||
|
||||
} else {
|
||||
// use model to apply edits
|
||||
const [{ range }] = edits;
|
||||
const initialSelection = new Selection(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn);
|
||||
model.pushEditOperations([initialSelection], edits.map(edit => {
|
||||
return {
|
||||
text: edit.text,
|
||||
range: Range.lift(edit.range),
|
||||
forceMoveMarkers: true
|
||||
};
|
||||
}), undoEdits => {
|
||||
for (const { range } of undoEdits) {
|
||||
if (Range.areIntersectingOrTouching(range, initialSelection)) {
|
||||
return [new Selection(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn)];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function formatDocumentWithProvider(
|
||||
accessor: ServicesAccessor,
|
||||
provider: DocumentFormattingEditProvider,
|
||||
editorOrModel: ITextModel | IActiveCodeEditor,
|
||||
token: CancellationToken
|
||||
): Promise<boolean> {
|
||||
const workerService = accessor.get(IEditorWorkerService);
|
||||
|
||||
let model: ITextModel;
|
||||
let validate: () => boolean;
|
||||
if (isCodeEditor(editorOrModel)) {
|
||||
model = editorOrModel.getModel();
|
||||
const state = new EditorState(editorOrModel, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position);
|
||||
validate = () => state.validate(editorOrModel);
|
||||
} else {
|
||||
model = editorOrModel;
|
||||
const versionNow = editorOrModel.getVersionId();
|
||||
validate = () => versionNow === editorOrModel.getVersionId();
|
||||
}
|
||||
|
||||
const rawEdits = await provider.provideDocumentFormattingEdits(
|
||||
model,
|
||||
model.getFormattingOptions(),
|
||||
token
|
||||
);
|
||||
|
||||
const edits = await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
|
||||
|
||||
if (!validate()) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (!edits || edits.length === 0) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (isCodeEditor(editorOrModel)) {
|
||||
// use editor to apply edits
|
||||
FormattingEdit.execute(editorOrModel, edits);
|
||||
alertFormattingEdits(edits);
|
||||
editorOrModel.pushUndoStop();
|
||||
editorOrModel.focus();
|
||||
editorOrModel.revealPositionInCenterIfOutsideViewport(editorOrModel.getPosition(), editorCommon.ScrollType.Immediate);
|
||||
|
||||
} else {
|
||||
// use model to apply edits
|
||||
const [{ range }] = edits;
|
||||
const initialSelection = new Selection(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn);
|
||||
model.pushEditOperations([initialSelection], edits.map(edit => {
|
||||
return {
|
||||
text: edit.text,
|
||||
range: Range.lift(edit.range),
|
||||
forceMoveMarkers: true
|
||||
};
|
||||
}), undoEdits => {
|
||||
for (const { range } of undoEdits) {
|
||||
if (Range.areIntersectingOrTouching(range, initialSelection)) {
|
||||
return [new Selection(range.startLineNumber, range.startColumn, range.endLineNumber, range.endColumn)];
|
||||
}
|
||||
}
|
||||
return null;
|
||||
});
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
export async function getDocumentRangeFormattingEditsUntilResult(
|
||||
workerService: IEditorWorkerService,
|
||||
model: ITextModel,
|
||||
range: Range,
|
||||
options: FormattingOptions,
|
||||
mode: FormatMode,
|
||||
token: CancellationToken
|
||||
): Promise<TextEdit[] | undefined | null> {
|
||||
): Promise<TextEdit[] | undefined> {
|
||||
|
||||
const providers = DocumentRangeFormattingEditProviderRegistry.ordered(model);
|
||||
|
||||
/* __GDPR__
|
||||
"formatterInfo" : {
|
||||
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"language" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"extensions" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
for (const provider of providers) {
|
||||
let rawEdits = await Promise.resolve(provider.provideDocumentRangeFormattingEdits(model, range, options, token)).catch(onUnexpectedExternalError);
|
||||
if (isNonEmptyArray(rawEdits)) {
|
||||
return await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
|
||||
}
|
||||
*/
|
||||
telemetryService.publicLog('formatterInfo', {
|
||||
type: 'range',
|
||||
language: model.getLanguageIdentifier().language,
|
||||
count: providers.length,
|
||||
extensions: providers.map(p => p.extensionId ? ExtensionIdentifier.toKey(p.extensionId) : 'unknown')
|
||||
});
|
||||
|
||||
invokeFormatterCallback(providers, model, mode | FormatKind.Range);
|
||||
|
||||
return first(providers.map(provider => () => {
|
||||
return Promise.resolve(provider.provideDocumentRangeFormattingEdits(model, range, options, token)).catch(onUnexpectedExternalError);
|
||||
}), isNonEmptyArray).then(edits => {
|
||||
// break edits into smaller edits
|
||||
return workerService.computeMoreMinimalEdits(model.uri, edits);
|
||||
});
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getDocumentFormattingEdits(
|
||||
telemetryService: ITelemetryService,
|
||||
export async function getDocumentFormattingEditsUntilResult(
|
||||
workerService: IEditorWorkerService,
|
||||
model: ITextModel,
|
||||
options: FormattingOptions,
|
||||
mode: FormatMode,
|
||||
token: CancellationToken
|
||||
): Promise<TextEdit[] | null | undefined> {
|
||||
): Promise<TextEdit[] | undefined> {
|
||||
|
||||
const docFormattingProviders = DocumentFormattingEditProviderRegistry.ordered(model);
|
||||
|
||||
/* __GDPR__
|
||||
"formatterInfo" : {
|
||||
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"language" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"extensions" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
const providers = getRealAndSyntheticDocumentFormattersOrdered(model);
|
||||
for (const provider of providers) {
|
||||
let rawEdits = await Promise.resolve(provider.provideDocumentFormattingEdits(model, options, token)).catch(onUnexpectedExternalError);
|
||||
if (isNonEmptyArray(rawEdits)) {
|
||||
return await workerService.computeMoreMinimalEdits(model.uri, rawEdits);
|
||||
}
|
||||
*/
|
||||
telemetryService.publicLog('formatterInfo', {
|
||||
type: 'document',
|
||||
language: model.getLanguageIdentifier().language,
|
||||
count: docFormattingProviders.length,
|
||||
extensions: docFormattingProviders.map(p => p.extensionId ? ExtensionIdentifier.toKey(p.extensionId) : 'unknown')
|
||||
});
|
||||
|
||||
if (docFormattingProviders.length > 0) {
|
||||
return first(docFormattingProviders.map(provider => () => {
|
||||
// first with result wins...
|
||||
return Promise.resolve(provider.provideDocumentFormattingEdits(model, options, token)).catch(onUnexpectedExternalError);
|
||||
}), isNonEmptyArray).then(edits => {
|
||||
// break edits into smaller edits
|
||||
return workerService.computeMoreMinimalEdits(model.uri, edits);
|
||||
});
|
||||
} else {
|
||||
// try range formatters when no document formatter is registered
|
||||
return getDocumentRangeFormattingEdits(telemetryService, workerService, model, model.getFullModelRange(), options, mode | FormatKind.Document, token);
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export function getOnTypeFormattingEdits(
|
||||
telemetryService: ITelemetryService,
|
||||
workerService: IEditorWorkerService,
|
||||
model: ITextModel,
|
||||
position: Position,
|
||||
@@ -144,21 +264,6 @@ export function getOnTypeFormattingEdits(
|
||||
|
||||
const providers = OnTypeFormattingEditProviderRegistry.ordered(model);
|
||||
|
||||
/* __GDPR__
|
||||
"formatterInfo" : {
|
||||
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"language" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"count" : { "classification": "SystemMetaData", "purpose": "FeatureInsight", "isMeasurement": true },
|
||||
"extensions" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
}
|
||||
*/
|
||||
telemetryService.publicLog('formatterInfo', {
|
||||
type: 'ontype',
|
||||
language: model.getLanguageIdentifier().language,
|
||||
count: providers.length,
|
||||
extensions: providers.map(p => p.extensionId ? ExtensionIdentifier.toKey(p.extensionId) : 'unknown')
|
||||
});
|
||||
|
||||
if (providers.length === 0) {
|
||||
return Promise.resolve(undefined);
|
||||
}
|
||||
@@ -181,7 +286,7 @@ registerLanguageCommand('_executeFormatRangeProvider', function (accessor, args)
|
||||
if (!model) {
|
||||
throw illegalArgument('resource');
|
||||
}
|
||||
return getDocumentRangeFormattingEdits(accessor.get(ITelemetryService), accessor.get(IEditorWorkerService), model, Range.lift(range), options, FormatMode.Auto, CancellationToken.None);
|
||||
return getDocumentRangeFormattingEditsUntilResult(accessor.get(IEditorWorkerService), model, Range.lift(range), options, CancellationToken.None);
|
||||
});
|
||||
|
||||
registerLanguageCommand('_executeFormatDocumentProvider', function (accessor, args) {
|
||||
@@ -194,7 +299,7 @@ registerLanguageCommand('_executeFormatDocumentProvider', function (accessor, ar
|
||||
throw illegalArgument('resource');
|
||||
}
|
||||
|
||||
return getDocumentFormattingEdits(accessor.get(ITelemetryService), accessor.get(IEditorWorkerService), model, options, FormatMode.Auto, CancellationToken.None);
|
||||
return getDocumentFormattingEditsUntilResult(accessor.get(IEditorWorkerService), model, options, CancellationToken.None);
|
||||
});
|
||||
|
||||
registerLanguageCommand('_executeFormatOnTypeProvider', function (accessor, args) {
|
||||
@@ -207,5 +312,5 @@ registerLanguageCommand('_executeFormatOnTypeProvider', function (accessor, args
|
||||
throw illegalArgument('resource');
|
||||
}
|
||||
|
||||
return getOnTypeFormattingEdits(accessor.get(ITelemetryService), accessor.get(IEditorWorkerService), model, Position.lift(position), ch, options);
|
||||
return getOnTypeFormattingEdits(accessor.get(IEditorWorkerService), model, Position.lift(position), ch, options);
|
||||
});
|
||||
|
||||
@@ -3,122 +3,27 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { alert } from 'vs/base/browser/ui/aria/aria';
|
||||
import { isNonEmptyArray } from 'vs/base/common/arrays';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { KeyChord, KeyCode, KeyMod } from 'vs/base/common/keyCodes';
|
||||
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { CodeEditorStateFlag, EditorState } from 'vs/editor/browser/core/editorState';
|
||||
import { IActiveCodeEditor, ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { EditorAction, registerEditorAction, registerEditorContribution, ServicesAccessor } from 'vs/editor/browser/editorExtensions';
|
||||
import { ICodeEditorService } from 'vs/editor/browser/services/codeEditorService';
|
||||
import { CharacterSet } from 'vs/editor/common/core/characterClassifier';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { ISingleEditOperation } from 'vs/editor/common/model';
|
||||
import { DocumentRangeFormattingEditProviderRegistry, FormattingOptions, OnTypeFormattingEditProviderRegistry } from 'vs/editor/common/modes';
|
||||
import { DocumentRangeFormattingEditProviderRegistry, OnTypeFormattingEditProviderRegistry } from 'vs/editor/common/modes';
|
||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
import { getOnTypeFormattingEdits, getDocumentFormattingEdits, getDocumentRangeFormattingEdits, FormatMode } from 'vs/editor/contrib/format/format';
|
||||
import { getOnTypeFormattingEdits, formatDocumentWithProvider, formatDocumentRangeWithProvider, alertFormattingEdits, getRealAndSyntheticDocumentFormattersOrdered } from 'vs/editor/contrib/format/format';
|
||||
import { FormattingEdit } from 'vs/editor/contrib/format/formattingEdit';
|
||||
import * as nls from 'vs/nls';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
function alertFormattingEdits(edits: ISingleEditOperation[]): void {
|
||||
|
||||
edits = edits.filter(edit => edit.range);
|
||||
if (!edits.length) {
|
||||
return;
|
||||
}
|
||||
|
||||
let { range } = edits[0];
|
||||
for (let i = 1; i < edits.length; i++) {
|
||||
range = Range.plusRange(range, edits[i].range);
|
||||
}
|
||||
const { startLineNumber, endLineNumber } = range;
|
||||
if (startLineNumber === endLineNumber) {
|
||||
if (edits.length === 1) {
|
||||
alert(nls.localize('hint11', "Made 1 formatting edit on line {0}", startLineNumber));
|
||||
} else {
|
||||
alert(nls.localize('hintn1', "Made {0} formatting edits on line {1}", edits.length, startLineNumber));
|
||||
}
|
||||
} else {
|
||||
if (edits.length === 1) {
|
||||
alert(nls.localize('hint1n', "Made 1 formatting edit between lines {0} and {1}", startLineNumber, endLineNumber));
|
||||
} else {
|
||||
alert(nls.localize('hintnn', "Made {0} formatting edits between lines {1} and {2}", edits.length, startLineNumber, endLineNumber));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const enum FormatRangeType {
|
||||
Full,
|
||||
Selection,
|
||||
}
|
||||
|
||||
function formatDocumentRange(
|
||||
telemetryService: ITelemetryService,
|
||||
workerService: IEditorWorkerService,
|
||||
editor: IActiveCodeEditor,
|
||||
rangeOrRangeType: Range | FormatRangeType,
|
||||
options: FormattingOptions,
|
||||
token: CancellationToken
|
||||
): Promise<void> {
|
||||
|
||||
|
||||
const state = new EditorState(editor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position);
|
||||
const model = editor.getModel();
|
||||
|
||||
let range: Range;
|
||||
if (rangeOrRangeType === FormatRangeType.Full) {
|
||||
// full
|
||||
range = model.getFullModelRange();
|
||||
|
||||
} else if (rangeOrRangeType === FormatRangeType.Selection) {
|
||||
// selection or line (when empty)
|
||||
range = editor.getSelection();
|
||||
if (range.isEmpty()) {
|
||||
range = new Range(range.startLineNumber, 1, range.endLineNumber, model.getLineMaxColumn(range.endLineNumber));
|
||||
}
|
||||
} else {
|
||||
// as is
|
||||
range = rangeOrRangeType;
|
||||
}
|
||||
|
||||
return getDocumentRangeFormattingEdits(telemetryService, workerService, model, range, options, FormatMode.Manual, token).then(edits => {
|
||||
// make edit only when the editor didn't change while
|
||||
// computing and only when there are edits
|
||||
if (state.validate(editor) && isNonEmptyArray(edits)) {
|
||||
FormattingEdit.execute(editor, edits);
|
||||
alertFormattingEdits(edits);
|
||||
editor.focus();
|
||||
editor.revealPositionInCenterIfOutsideViewport(editor.getPosition(), editorCommon.ScrollType.Immediate);
|
||||
}
|
||||
});
|
||||
|
||||
}
|
||||
|
||||
function formatDocument(telemetryService: ITelemetryService, workerService: IEditorWorkerService, editor: IActiveCodeEditor, options: FormattingOptions, token: CancellationToken): Promise<void> {
|
||||
|
||||
const allEdits: ISingleEditOperation[] = [];
|
||||
const state = new EditorState(editor, CodeEditorStateFlag.Value | CodeEditorStateFlag.Position);
|
||||
|
||||
return getDocumentFormattingEdits(telemetryService, workerService, editor.getModel(), options, FormatMode.Manual, token).then(edits => {
|
||||
// make edit only when the editor didn't change while
|
||||
// computing and only when there are edits
|
||||
if (state.validate(editor) && isNonEmptyArray(edits)) {
|
||||
FormattingEdit.execute(editor, edits);
|
||||
|
||||
alertFormattingEdits(allEdits);
|
||||
editor.pushUndoStop();
|
||||
editor.focus();
|
||||
editor.revealPositionInCenterIfOutsideViewport(editor.getPosition(), editorCommon.ScrollType.Immediate);
|
||||
}
|
||||
});
|
||||
}
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
|
||||
class FormatOnType implements editorCommon.IEditorContribution {
|
||||
|
||||
@@ -130,17 +35,25 @@ class FormatOnType implements editorCommon.IEditorContribution {
|
||||
|
||||
constructor(
|
||||
editor: ICodeEditor,
|
||||
@ITelemetryService private readonly _telemetryService: ITelemetryService,
|
||||
@IEditorWorkerService private readonly _workerService: IEditorWorkerService
|
||||
) {
|
||||
this._editor = editor;
|
||||
this._callOnDispose.push(editor.onDidChangeConfiguration(() => this.update()));
|
||||
this._callOnDispose.push(editor.onDidChangeModel(() => this.update()));
|
||||
this._callOnDispose.push(editor.onDidChangeModelLanguage(() => this.update()));
|
||||
this._callOnDispose.push(OnTypeFormattingEditProviderRegistry.onDidChange(this.update, this));
|
||||
this._callOnDispose.push(editor.onDidChangeConfiguration(() => this._update()));
|
||||
this._callOnDispose.push(editor.onDidChangeModel(() => this._update()));
|
||||
this._callOnDispose.push(editor.onDidChangeModelLanguage(() => this._update()));
|
||||
this._callOnDispose.push(OnTypeFormattingEditProviderRegistry.onDidChange(this._update, this));
|
||||
}
|
||||
|
||||
private update(): void {
|
||||
getId(): string {
|
||||
return FormatOnType.ID;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._callOnDispose = dispose(this._callOnDispose);
|
||||
this._callOnModel = dispose(this._callOnModel);
|
||||
}
|
||||
|
||||
private _update(): void {
|
||||
|
||||
// clean up
|
||||
this._callOnModel = dispose(this._callOnModel);
|
||||
@@ -171,12 +84,12 @@ class FormatOnType implements editorCommon.IEditorContribution {
|
||||
this._callOnModel.push(this._editor.onDidType((text: string) => {
|
||||
let lastCharCode = text.charCodeAt(text.length - 1);
|
||||
if (triggerChars.has(lastCharCode)) {
|
||||
this.trigger(String.fromCharCode(lastCharCode));
|
||||
this._trigger(String.fromCharCode(lastCharCode));
|
||||
}
|
||||
}));
|
||||
}
|
||||
|
||||
private trigger(ch: string): void {
|
||||
private _trigger(ch: string): void {
|
||||
if (!this._editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
@@ -214,7 +127,6 @@ class FormatOnType implements editorCommon.IEditorContribution {
|
||||
});
|
||||
|
||||
getOnTypeFormattingEdits(
|
||||
this._telemetryService,
|
||||
this._workerService,
|
||||
model,
|
||||
position,
|
||||
@@ -238,42 +150,41 @@ class FormatOnType implements editorCommon.IEditorContribution {
|
||||
throw err;
|
||||
});
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
return FormatOnType.ID;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this._callOnDispose = dispose(this._callOnDispose);
|
||||
this._callOnModel = dispose(this._callOnModel);
|
||||
}
|
||||
}
|
||||
|
||||
class FormatOnPaste implements editorCommon.IEditorContribution {
|
||||
|
||||
private static readonly ID = 'editor.contrib.formatOnPaste';
|
||||
|
||||
private callOnDispose: IDisposable[];
|
||||
private callOnModel: IDisposable[];
|
||||
private _callOnDispose: IDisposable[];
|
||||
private _callOnModel: IDisposable[];
|
||||
|
||||
constructor(
|
||||
private readonly editor: ICodeEditor,
|
||||
@IEditorWorkerService private readonly workerService: IEditorWorkerService,
|
||||
@ITelemetryService private readonly telemetryService: ITelemetryService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
) {
|
||||
this.callOnDispose = [];
|
||||
this.callOnModel = [];
|
||||
this._callOnDispose = [];
|
||||
this._callOnModel = [];
|
||||
|
||||
this.callOnDispose.push(editor.onDidChangeConfiguration(() => this.update()));
|
||||
this.callOnDispose.push(editor.onDidChangeModel(() => this.update()));
|
||||
this.callOnDispose.push(editor.onDidChangeModelLanguage(() => this.update()));
|
||||
this.callOnDispose.push(DocumentRangeFormattingEditProviderRegistry.onDidChange(this.update, this));
|
||||
this._callOnDispose.push(editor.onDidChangeConfiguration(() => this._update()));
|
||||
this._callOnDispose.push(editor.onDidChangeModel(() => this._update()));
|
||||
this._callOnDispose.push(editor.onDidChangeModelLanguage(() => this._update()));
|
||||
this._callOnDispose.push(DocumentRangeFormattingEditProviderRegistry.onDidChange(this._update, this));
|
||||
}
|
||||
|
||||
private update(): void {
|
||||
getId(): string {
|
||||
return FormatOnPaste.ID;
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
this._callOnDispose = dispose(this._callOnDispose);
|
||||
this._callOnModel = dispose(this._callOnModel);
|
||||
}
|
||||
|
||||
private _update(): void {
|
||||
|
||||
// clean up
|
||||
this.callOnModel = dispose(this.callOnModel);
|
||||
this._callOnModel = dispose(this._callOnModel);
|
||||
|
||||
// we are disabled
|
||||
if (!this.editor.getConfiguration().contribInfo.formatOnPaste) {
|
||||
@@ -285,53 +196,41 @@ class FormatOnPaste implements editorCommon.IEditorContribution {
|
||||
return;
|
||||
}
|
||||
|
||||
let model = this.editor.getModel();
|
||||
|
||||
// no support
|
||||
if (!DocumentRangeFormattingEditProviderRegistry.has(model)) {
|
||||
// no formatter
|
||||
if (!DocumentRangeFormattingEditProviderRegistry.has(this.editor.getModel())) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.callOnModel.push(this.editor.onDidPaste((range: Range) => {
|
||||
this.trigger(range);
|
||||
}));
|
||||
this._callOnModel.push(this.editor.onDidPaste(range => this._trigger(range)));
|
||||
}
|
||||
|
||||
private trigger(range: Range): void {
|
||||
private _trigger(range: Range): void {
|
||||
if (!this.editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.editor.getSelections().length > 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
const model = this.editor.getModel();
|
||||
formatDocumentRange(this.telemetryService, this.workerService, this.editor, range, model.getFormattingOptions(), CancellationToken.None);
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
return FormatOnPaste.ID;
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
this.callOnDispose = dispose(this.callOnDispose);
|
||||
this.callOnModel = dispose(this.callOnModel);
|
||||
const provider = DocumentRangeFormattingEditProviderRegistry.ordered(this.editor.getModel());
|
||||
if (provider.length !== 1) {
|
||||
// print status in n>1 case?
|
||||
return;
|
||||
}
|
||||
this._instantiationService.invokeFunction(formatDocumentRangeWithProvider, provider[0], this.editor, range, CancellationToken.None).catch(onUnexpectedError);
|
||||
}
|
||||
}
|
||||
|
||||
export class FormatDocumentAction extends EditorAction {
|
||||
class FormatDocumentAction extends EditorAction {
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: 'editor.action.formatDocument',
|
||||
label: nls.localize('formatDocument.label', "Format Document"),
|
||||
alias: 'Format Document',
|
||||
precondition: EditorContextKeys.writable,
|
||||
precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasDocumentFormattingProvider, EditorContextKeys.hasMultipleDocumentFormattingProvider.toNegated()),
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.editorTextFocus,
|
||||
kbExpr: ContextKeyExpr.and(EditorContextKeys.editorTextFocus, EditorContextKeys.hasDocumentFormattingProvider),
|
||||
primary: KeyMod.Shift | KeyMod.Alt | KeyCode.KEY_F,
|
||||
// secondary: [KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_D)],
|
||||
linux: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.KEY_I },
|
||||
weight: KeybindingWeight.EditorContrib
|
||||
},
|
||||
@@ -343,26 +242,29 @@ export class FormatDocumentAction extends EditorAction {
|
||||
});
|
||||
}
|
||||
|
||||
run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> | void {
|
||||
async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {
|
||||
if (!editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
const workerService = accessor.get(IEditorWorkerService);
|
||||
const telemetryService = accessor.get(ITelemetryService);
|
||||
return formatDocument(telemetryService, workerService, editor, editor.getModel().getFormattingOptions(), CancellationToken.None);
|
||||
const instaService = accessor.get(IInstantiationService);
|
||||
const model = editor.getModel();
|
||||
const [provider] = getRealAndSyntheticDocumentFormattersOrdered(model);
|
||||
if (provider) {
|
||||
await instaService.invokeFunction(formatDocumentWithProvider, provider, editor, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
export class FormatSelectionAction extends EditorAction {
|
||||
class FormatSelectionAction extends EditorAction {
|
||||
|
||||
constructor() {
|
||||
super({
|
||||
id: 'editor.action.formatSelection',
|
||||
label: nls.localize('formatSelection.label', "Format Selection"),
|
||||
alias: 'Format Code',
|
||||
precondition: ContextKeyExpr.and(EditorContextKeys.writable),
|
||||
precondition: ContextKeyExpr.and(EditorContextKeys.writable, EditorContextKeys.hasDocumentSelectionFormattingProvider, EditorContextKeys.hasMultipleDocumentSelectionFormattingProvider.toNegated()),
|
||||
kbOpts: {
|
||||
kbExpr: EditorContextKeys.editorTextFocus,
|
||||
kbExpr: ContextKeyExpr.and(EditorContextKeys.editorTextFocus, EditorContextKeys.hasDocumentSelectionFormattingProvider),
|
||||
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyMod.CtrlCmd | KeyCode.KEY_F),
|
||||
weight: KeybindingWeight.EditorContrib
|
||||
},
|
||||
@@ -374,13 +276,19 @@ export class FormatSelectionAction extends EditorAction {
|
||||
});
|
||||
}
|
||||
|
||||
run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> | void {
|
||||
async run(accessor: ServicesAccessor, editor: ICodeEditor): Promise<void> {
|
||||
if (!editor.hasModel()) {
|
||||
return;
|
||||
}
|
||||
const workerService = accessor.get(IEditorWorkerService);
|
||||
const telemetryService = accessor.get(ITelemetryService);
|
||||
return formatDocumentRange(telemetryService, workerService, editor, FormatRangeType.Selection, editor.getModel().getFormattingOptions(), CancellationToken.None);
|
||||
const instaService = accessor.get(IInstantiationService);
|
||||
const [best] = DocumentRangeFormattingEditProviderRegistry.ordered(editor.getModel());
|
||||
if (best) {
|
||||
let range: Range = editor.getSelection();
|
||||
if (range.isEmpty()) {
|
||||
range = new Range(range.startLineNumber, 1, range.startLineNumber, editor.getModel().getLineMaxColumn(range.startLineNumber));
|
||||
}
|
||||
await instaService.invokeFunction(formatDocumentRangeWithProvider, best, editor, range, CancellationToken.None);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -391,17 +299,15 @@ registerEditorAction(FormatSelectionAction);
|
||||
|
||||
// this is the old format action that does both (format document OR format selection)
|
||||
// and we keep it here such that existing keybinding configurations etc will still work
|
||||
CommandsRegistry.registerCommand('editor.action.format', accessor => {
|
||||
CommandsRegistry.registerCommand('editor.action.format', async accessor => {
|
||||
const editor = accessor.get(ICodeEditorService).getFocusedCodeEditor();
|
||||
if (!editor || !editor.hasModel()) {
|
||||
return undefined;
|
||||
return;
|
||||
}
|
||||
const workerService = accessor.get(IEditorWorkerService);
|
||||
const telemetryService = accessor.get(ITelemetryService);
|
||||
|
||||
const commandService = accessor.get(ICommandService);
|
||||
if (editor.getSelection().isEmpty()) {
|
||||
return formatDocument(telemetryService, workerService, editor, editor.getModel().getFormattingOptions(), CancellationToken.None);
|
||||
await commandService.executeCommand('editor.action.formatDocument');
|
||||
} else {
|
||||
return formatDocumentRange(telemetryService, workerService, editor, FormatRangeType.Selection, editor.getModel().getFormattingOptions(), CancellationToken.None);
|
||||
await commandService.executeCommand('editor.action.formatSelection');
|
||||
}
|
||||
});
|
||||
|
||||
@@ -203,8 +203,8 @@ export class MarkerController implements editorCommon.IEditorContribution {
|
||||
}
|
||||
|
||||
private readonly _editor: ICodeEditor;
|
||||
private _model: MarkerModel | null;
|
||||
private _widget: MarkerNavigationWidget | null;
|
||||
private _model: MarkerModel | null = null;
|
||||
private _widget: MarkerNavigationWidget | null = null;
|
||||
private readonly _widgetVisible: IContextKey<boolean>;
|
||||
private _disposeOnClose: IDisposable[] = [];
|
||||
|
||||
|
||||
@@ -21,7 +21,7 @@ export class MoveLinesCommand implements ICommand {
|
||||
private readonly _autoIndent: boolean;
|
||||
|
||||
private _selectionId: string;
|
||||
private _moveEndPositionDown: boolean;
|
||||
private _moveEndPositionDown?: boolean;
|
||||
private _moveEndLineSelectionShrink: boolean;
|
||||
|
||||
constructor(selection: Selection, isMovingDown: boolean, autoIndent: boolean) {
|
||||
|
||||
@@ -196,10 +196,9 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
const endOfNonono = new Selection(5, 11, 5, 11);
|
||||
|
||||
editor.setSelections([beforeSecondWasoSelection, endOfBCCSelection, endOfNonono]);
|
||||
let selections;
|
||||
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
selections = editor.getSelections();
|
||||
let selections = editor.getSelections()!;
|
||||
|
||||
assert.equal(model.getLineContent(2), '');
|
||||
assert.equal(model.getLineContent(3), ' waso waso');
|
||||
@@ -227,7 +226,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
], [5, 1, 5, 1]);
|
||||
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
selections = editor.getSelections();
|
||||
selections = editor.getSelections()!;
|
||||
|
||||
assert.equal(model.getLineContent(1), 'hi my name is Carlos Matos waso waso');
|
||||
assert.equal(selections.length, 2);
|
||||
|
||||
@@ -21,6 +21,7 @@ import { Choice, Placeholder, SnippetParser, Text, TextmateSnippet } from './sni
|
||||
import { ClipboardBasedVariableResolver, CompositeSnippetVariableResolver, ModelBasedVariableResolver, SelectionBasedVariableResolver, TimeBasedVariableResolver, CommentBasedVariableResolver, WorkspaceBasedVariableResolver } from './snippetVariables';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import * as colors from 'vs/platform/theme/common/colorRegistry';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
|
||||
@@ -281,7 +282,7 @@ export class OneSnippet {
|
||||
let result: Range | undefined;
|
||||
const model = this._editor.getModel();
|
||||
this._placeholderDecorations.forEach((decorationId) => {
|
||||
const placeholderRange = model.getDecorationRange(decorationId) || undefined;
|
||||
const placeholderRange = withNullAsUndefined(model.getDecorationRange(decorationId));
|
||||
if (!result) {
|
||||
result = placeholderRange;
|
||||
} else {
|
||||
|
||||
@@ -18,8 +18,8 @@ export class SuggestAlternatives {
|
||||
private _index: number;
|
||||
private _model: CompletionModel | undefined;
|
||||
private _acceptNext: ((selected: ISelectedSuggestion) => any) | undefined;
|
||||
private _listener: IDisposable;
|
||||
private _ignore: boolean;
|
||||
private _listener: IDisposable | undefined;
|
||||
private _ignore: boolean | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly _editor: ICodeEditor,
|
||||
|
||||
@@ -63,16 +63,16 @@ export class Colorizer {
|
||||
// Send out the event to create the mode
|
||||
modeService.triggerMode(language);
|
||||
|
||||
let tokenizationSupport = TokenizationRegistry.get(language);
|
||||
const tokenizationSupport = TokenizationRegistry.get(language);
|
||||
if (tokenizationSupport) {
|
||||
return _colorize(lines, tabSize, tokenizationSupport);
|
||||
}
|
||||
|
||||
let tokenizationSupportPromise = TokenizationRegistry.getPromise(language);
|
||||
const tokenizationSupportPromise = TokenizationRegistry.getPromise(language);
|
||||
if (tokenizationSupportPromise) {
|
||||
// A tokenizer will be registered soon
|
||||
return new Promise<string>((resolve, reject) => {
|
||||
tokenizationSupportPromise!.then(tokenizationSupport => {
|
||||
tokenizationSupportPromise.then(tokenizationSupport => {
|
||||
_colorize(lines, tabSize, tokenizationSupport).then(resolve, reject);
|
||||
}, reject);
|
||||
});
|
||||
|
||||
@@ -280,7 +280,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
|
||||
}));
|
||||
}
|
||||
|
||||
public addDynamicKeybinding(commandId: string, _keybinding: number, handler: ICommandHandler, when: ContextKeyExpr | null): IDisposable {
|
||||
public addDynamicKeybinding(commandId: string, _keybinding: number, handler: ICommandHandler, when: ContextKeyExpr | undefined): IDisposable {
|
||||
const keybinding = createKeybinding(_keybinding, OS);
|
||||
if (!keybinding) {
|
||||
throw new Error(`Invalid keybinding`);
|
||||
@@ -342,7 +342,7 @@ export class StandaloneKeybindingService extends AbstractKeybindingService {
|
||||
private _toNormalizedKeybindingItems(items: IKeybindingItem[], isDefault: boolean): ResolvedKeybindingItem[] {
|
||||
let result: ResolvedKeybindingItem[] = [], resultLen = 0;
|
||||
for (const item of items) {
|
||||
const when = (item.when ? item.when.normalize() : null);
|
||||
const when = (item.when ? item.when.normalize() : undefined);
|
||||
const keybinding = item.keybinding;
|
||||
|
||||
if (!keybinding) {
|
||||
@@ -665,9 +665,5 @@ export class SimpleLayoutService implements ILayoutService {
|
||||
return this._container;
|
||||
}
|
||||
|
||||
get hasWorkbench(): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
constructor(private _container: HTMLElement) { }
|
||||
}
|
||||
|
||||
@@ -202,7 +202,12 @@ export class DynamicStandaloneServices extends Disposable {
|
||||
|
||||
let contextViewService = ensure(IContextViewService, () => this._register(new ContextViewService(layoutService)));
|
||||
|
||||
ensure(IContextMenuService, () => this._register(new ContextMenuService(layoutService, telemetryService, notificationService, contextViewService, keybindingService, themeService)));
|
||||
ensure(IContextMenuService, () => {
|
||||
const contextMenuService = new ContextMenuService(telemetryService, notificationService, contextViewService, keybindingService, themeService);
|
||||
contextMenuService.configure({ blockMouse: false }); // we do not want that in the standalone editor
|
||||
|
||||
return this._register(contextMenuService);
|
||||
});
|
||||
|
||||
ensure(IMenuService, () => new MenuService(commandService));
|
||||
|
||||
|
||||
@@ -39,7 +39,7 @@ suite('StandaloneKeybindingService', () => {
|
||||
let commandInvoked = false;
|
||||
keybindingService.addDynamicKeybinding('testCommand', KeyCode.F9, () => {
|
||||
commandInvoked = true;
|
||||
}, null);
|
||||
}, undefined);
|
||||
|
||||
keybindingService.testDispatch({
|
||||
_standardKeyboardEventBrand: true,
|
||||
|
||||
@@ -13,7 +13,7 @@ import { IResourceInput } from 'vs/platform/editor/common/editor';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export class TestCodeEditorService extends AbstractCodeEditorService {
|
||||
public lastInput: IResourceInput;
|
||||
public lastInput?: IResourceInput;
|
||||
public getActiveCodeEditor(): ICodeEditor | null { return null; }
|
||||
public openCodeEditor(input: IResourceInput, source: ICodeEditor | null, sideBySide?: boolean): Promise<ICodeEditor | null> {
|
||||
this.lastInput = input;
|
||||
|
||||
@@ -30,7 +30,7 @@ suite('OpenerService', function () {
|
||||
test('delegate to editorService, scheme:///fff', function () {
|
||||
const openerService = new OpenerService(editorService, NullCommandService);
|
||||
openerService.open(URI.parse('another:///somepath'));
|
||||
assert.equal(editorService.lastInput.options!.selection, undefined);
|
||||
assert.equal(editorService.lastInput!.options!.selection, undefined);
|
||||
});
|
||||
|
||||
test('delegate to editorService, scheme:///fff#L123', function () {
|
||||
@@ -38,22 +38,22 @@ suite('OpenerService', function () {
|
||||
const openerService = new OpenerService(editorService, NullCommandService);
|
||||
|
||||
openerService.open(URI.parse('file:///somepath#L23'));
|
||||
assert.equal(editorService.lastInput.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput.options!.selection!.startColumn, 1);
|
||||
assert.equal(editorService.lastInput.options!.selection!.endLineNumber, undefined);
|
||||
assert.equal(editorService.lastInput.options!.selection!.endColumn, undefined);
|
||||
assert.equal(editorService.lastInput.resource.fragment, '');
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 1);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||
assert.equal(editorService.lastInput!.resource.fragment, '');
|
||||
|
||||
openerService.open(URI.parse('another:///somepath#L23'));
|
||||
assert.equal(editorService.lastInput.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput.options!.selection!.startColumn, 1);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 1);
|
||||
|
||||
openerService.open(URI.parse('another:///somepath#L23,45'));
|
||||
assert.equal(editorService.lastInput.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput.options!.selection!.startColumn, 45);
|
||||
assert.equal(editorService.lastInput.options!.selection!.endLineNumber, undefined);
|
||||
assert.equal(editorService.lastInput.options!.selection!.endColumn, undefined);
|
||||
assert.equal(editorService.lastInput.resource.fragment, '');
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 45);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||
assert.equal(editorService.lastInput!.resource.fragment, '');
|
||||
});
|
||||
|
||||
test('delegate to editorService, scheme:///fff#123,123', function () {
|
||||
@@ -61,18 +61,18 @@ suite('OpenerService', function () {
|
||||
const openerService = new OpenerService(editorService, NullCommandService);
|
||||
|
||||
openerService.open(URI.parse('file:///somepath#23'));
|
||||
assert.equal(editorService.lastInput.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput.options!.selection!.startColumn, 1);
|
||||
assert.equal(editorService.lastInput.options!.selection!.endLineNumber, undefined);
|
||||
assert.equal(editorService.lastInput.options!.selection!.endColumn, undefined);
|
||||
assert.equal(editorService.lastInput.resource.fragment, '');
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 1);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||
assert.equal(editorService.lastInput!.resource.fragment, '');
|
||||
|
||||
openerService.open(URI.parse('file:///somepath#23,45'));
|
||||
assert.equal(editorService.lastInput.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput.options!.selection!.startColumn, 45);
|
||||
assert.equal(editorService.lastInput.options!.selection!.endLineNumber, undefined);
|
||||
assert.equal(editorService.lastInput.options!.selection!.endColumn, undefined);
|
||||
assert.equal(editorService.lastInput.resource.fragment, '');
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startLineNumber, 23);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.startColumn, 45);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endLineNumber, undefined);
|
||||
assert.equal(editorService.lastInput!.options!.selection!.endColumn, undefined);
|
||||
assert.equal(editorService.lastInput!.resource.fragment, '');
|
||||
});
|
||||
|
||||
test('delegate to commandsService, command:someid', function () {
|
||||
|
||||
Reference in New Issue
Block a user