mirror of
https://github.com/ckaczor/azuredatastudio.git
synced 2026-03-20 12:00:24 -04:00
Merge from vscode a234f13c45b40a0929777cb440ee011b7549eed2 (#8911)
* Merge from vscode a234f13c45b40a0929777cb440ee011b7549eed2 * update distro * fix layering * update distro * fix tests
This commit is contained in:
@@ -13,7 +13,7 @@ import { EditorAction, ServicesAccessor, registerEditorAction, registerEditorCon
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { IModelDeltaDecoration, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
@@ -103,7 +103,7 @@ class BracketsData {
|
||||
}
|
||||
}
|
||||
|
||||
export class BracketMatchingController extends Disposable implements editorCommon.IEditorContribution {
|
||||
export class BracketMatchingController extends Disposable implements IEditorContribution {
|
||||
public static readonly ID = 'editor.contrib.bracketMatchingController';
|
||||
|
||||
public static get(editor: ICodeEditor): BracketMatchingController {
|
||||
|
||||
@@ -6,16 +6,16 @@
|
||||
import { equals, flatten, isNonEmptyArray, mergeSort } from 'vs/base/common/arrays';
|
||||
import { CancellationToken } from 'vs/base/common/cancellation';
|
||||
import { illegalArgument, isPromiseCanceledError, onUnexpectedExternalError } from 'vs/base/common/errors';
|
||||
import { Disposable, DisposableStore, IDisposable } from 'vs/base/common/lifecycle';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { TextModelCancellationTokenSource } from 'vs/editor/browser/core/editorState';
|
||||
import { registerLanguageCommand } from 'vs/editor/browser/editorExtensions';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { CodeAction, CodeActionContext, CodeActionProviderRegistry, CodeActionTrigger as CodeActionTriggerKind } from 'vs/editor/common/modes';
|
||||
import * as modes from 'vs/editor/common/modes';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
import { CodeActionFilter, CodeActionKind, CodeActionTrigger, filtersAction, mayIncludeActionsOfKind } from './types';
|
||||
import { TextModelCancellationTokenSource } from 'vs/editor/browser/core/editorState';
|
||||
import { DisposableStore, IDisposable, Disposable } from 'vs/base/common/lifecycle';
|
||||
|
||||
export const codeActionCommandId = 'editor.action.codeAction';
|
||||
export const refactorCommandId = 'editor.action.refactor';
|
||||
@@ -24,14 +24,14 @@ export const organizeImportsCommandId = 'editor.action.organizeImports';
|
||||
export const fixAllCommandId = 'editor.action.fixAll';
|
||||
|
||||
export interface CodeActionSet extends IDisposable {
|
||||
readonly validActions: readonly CodeAction[];
|
||||
readonly allActions: readonly CodeAction[];
|
||||
readonly validActions: readonly modes.CodeAction[];
|
||||
readonly allActions: readonly modes.CodeAction[];
|
||||
readonly hasAutoFix: boolean;
|
||||
}
|
||||
|
||||
class ManagedCodeActionSet extends Disposable implements CodeActionSet {
|
||||
|
||||
private static codeActionsComparator(a: CodeAction, b: CodeAction): number {
|
||||
private static codeActionsComparator(a: modes.CodeAction, b: modes.CodeAction): number {
|
||||
if (isNonEmptyArray(a.diagnostics)) {
|
||||
if (isNonEmptyArray(b.diagnostics)) {
|
||||
return a.diagnostics[0].message.localeCompare(b.diagnostics[0].message);
|
||||
@@ -45,10 +45,10 @@ class ManagedCodeActionSet extends Disposable implements CodeActionSet {
|
||||
}
|
||||
}
|
||||
|
||||
public readonly validActions: readonly CodeAction[];
|
||||
public readonly allActions: readonly CodeAction[];
|
||||
public readonly validActions: readonly modes.CodeAction[];
|
||||
public readonly allActions: readonly modes.CodeAction[];
|
||||
|
||||
public constructor(actions: readonly CodeAction[], disposables: DisposableStore) {
|
||||
public constructor(actions: readonly modes.CodeAction[], disposables: DisposableStore) {
|
||||
super();
|
||||
this._register(disposables);
|
||||
this.allActions = mergeSort([...actions], ManagedCodeActionSet.codeActionsComparator);
|
||||
@@ -68,9 +68,9 @@ export function getCodeActions(
|
||||
): Promise<CodeActionSet> {
|
||||
const filter = trigger.filter || {};
|
||||
|
||||
const codeActionContext: CodeActionContext = {
|
||||
const codeActionContext: modes.CodeActionContext = {
|
||||
only: filter.include?.value,
|
||||
trigger: trigger.type === 'manual' ? CodeActionTriggerKind.Manual : CodeActionTriggerKind.Automatic
|
||||
trigger: trigger.type,
|
||||
};
|
||||
|
||||
const cts = new TextModelCancellationTokenSource(model, token);
|
||||
@@ -94,8 +94,8 @@ export function getCodeActions(
|
||||
}
|
||||
});
|
||||
|
||||
const listener = CodeActionProviderRegistry.onDidChange(() => {
|
||||
const newProviders = CodeActionProviderRegistry.all(model);
|
||||
const listener = modes.CodeActionProviderRegistry.onDidChange(() => {
|
||||
const newProviders = modes.CodeActionProviderRegistry.all(model);
|
||||
if (!equals(newProviders, providers)) {
|
||||
cts.cancel();
|
||||
}
|
||||
@@ -114,7 +114,7 @@ function getCodeActionProviders(
|
||||
model: ITextModel,
|
||||
filter: CodeActionFilter
|
||||
) {
|
||||
return CodeActionProviderRegistry.all(model)
|
||||
return modes.CodeActionProviderRegistry.all(model)
|
||||
// Don't include providers that we know will not return code actions of interest
|
||||
.filter(provider => {
|
||||
if (!provider.providedCodeActionKinds) {
|
||||
@@ -125,7 +125,7 @@ function getCodeActionProviders(
|
||||
});
|
||||
}
|
||||
|
||||
registerLanguageCommand('_executeCodeActionProvider', async function (accessor, args): Promise<ReadonlyArray<CodeAction>> {
|
||||
registerLanguageCommand('_executeCodeActionProvider', async function (accessor, args): Promise<ReadonlyArray<modes.CodeAction>> {
|
||||
const { resource, rangeOrSelection, kind } = args;
|
||||
if (!(resource instanceof URI)) {
|
||||
throw illegalArgument();
|
||||
@@ -149,7 +149,7 @@ registerLanguageCommand('_executeCodeActionProvider', async function (accessor,
|
||||
const codeActionSet = await getCodeActions(
|
||||
model,
|
||||
validatedRangeOrSelection,
|
||||
{ type: 'manual', filter: { includeSourceActions: true, include: kind && kind.value ? new CodeActionKind(kind.value) : undefined } },
|
||||
{ type: modes.CodeActionTriggerType.Manual, filter: { includeSourceActions: true, include: kind && kind.value ? new CodeActionKind(kind.value) : undefined } },
|
||||
CancellationToken.None);
|
||||
|
||||
setTimeout(() => codeActionSet.dispose(), 100);
|
||||
|
||||
@@ -15,22 +15,21 @@ import { IBulkEditService } from 'vs/editor/browser/services/bulkEditService';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { CodeAction } from 'vs/editor/common/modes';
|
||||
import { CodeActionSet, refactorCommandId, sourceActionCommandId, codeActionCommandId, organizeImportsCommandId, fixAllCommandId } from 'vs/editor/contrib/codeAction/codeAction';
|
||||
import { CodeAction, CodeActionTriggerType } from 'vs/editor/common/modes';
|
||||
import { codeActionCommandId, CodeActionSet, fixAllCommandId, organizeImportsCommandId, refactorCommandId, sourceActionCommandId } from 'vs/editor/contrib/codeAction/codeAction';
|
||||
import { CodeActionUi } from 'vs/editor/contrib/codeAction/codeActionUi';
|
||||
import { MessageController } from 'vs/editor/contrib/message/messageController';
|
||||
import * as nls from 'vs/nls';
|
||||
import { ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { ContextKeyExpr, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { IMarkerService } from 'vs/platform/markers/common/markers';
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { CodeActionModel, CodeActionsState, SUPPORTED_CODE_ACTIONS } from './codeActionModel';
|
||||
import { CodeActionAutoApply, CodeActionFilter, CodeActionKind, CodeActionTrigger, CodeActionCommandArgs } from './types';
|
||||
import { CodeActionAutoApply, CodeActionCommandArgs, CodeActionFilter, CodeActionKind, CodeActionTrigger } from './types';
|
||||
|
||||
function contextKeyForSupportedActions(kind: CodeActionKind) {
|
||||
return ContextKeyExpr.regex(
|
||||
@@ -83,10 +82,6 @@ export class QuickFixController extends Disposable implements IEditorContributio
|
||||
@IMarkerService markerService: IMarkerService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
@IEditorProgressService progressService: IEditorProgressService,
|
||||
@IContextMenuService contextMenuService: IContextMenuService,
|
||||
@IKeybindingService keybindingService: IKeybindingService,
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
) {
|
||||
super();
|
||||
@@ -102,7 +97,7 @@ export class QuickFixController extends Disposable implements IEditorContributio
|
||||
await this._applyCodeAction(action);
|
||||
} finally {
|
||||
if (retrigger) {
|
||||
this._trigger({ type: 'auto', filter: {} });
|
||||
this._trigger({ type: CodeActionTriggerType.Auto, filter: {} });
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -114,8 +109,8 @@ export class QuickFixController extends Disposable implements IEditorContributio
|
||||
this._ui.getValue().update(newState);
|
||||
}
|
||||
|
||||
public showCodeActions(actions: CodeActionSet, at: IAnchor | IPosition) {
|
||||
return this._ui.getValue().showCodeActionList(actions, at, { includeDisabledActions: false });
|
||||
public showCodeActions(trigger: CodeActionTrigger, actions: CodeActionSet, at: IAnchor | IPosition) {
|
||||
return this._ui.getValue().showCodeActionList(trigger, actions, at, { includeDisabledActions: false });
|
||||
}
|
||||
|
||||
public manualTriggerAtCurrentPosition(
|
||||
@@ -129,7 +124,7 @@ export class QuickFixController extends Disposable implements IEditorContributio
|
||||
|
||||
MessageController.get(this._editor).closeMessage();
|
||||
const triggerPosition = this._editor.getPosition();
|
||||
this._trigger({ type: 'manual', filter, autoApply, context: { notAvailableMessage, position: triggerPosition } });
|
||||
this._trigger({ type: CodeActionTriggerType.Manual, filter, autoApply, context: { notAvailableMessage, position: triggerPosition } });
|
||||
}
|
||||
|
||||
private _trigger(trigger: CodeActionTrigger) {
|
||||
@@ -137,21 +132,41 @@ export class QuickFixController extends Disposable implements IEditorContributio
|
||||
}
|
||||
|
||||
private _applyCodeAction(action: CodeAction): Promise<void> {
|
||||
return this._instantiationService.invokeFunction(applyCodeAction, action, this._bulkEditService, this._commandService, this._editor);
|
||||
return this._instantiationService.invokeFunction(applyCodeAction, action, this._editor);
|
||||
}
|
||||
}
|
||||
|
||||
export async function applyCodeAction(
|
||||
accessor: ServicesAccessor,
|
||||
action: CodeAction,
|
||||
bulkEditService: IBulkEditService,
|
||||
commandService: ICommandService,
|
||||
editor?: ICodeEditor,
|
||||
): Promise<void> {
|
||||
const bulkEditService = accessor.get(IBulkEditService);
|
||||
const commandService = accessor.get(ICommandService);
|
||||
const telemetryService = accessor.get(ITelemetryService);
|
||||
const notificationService = accessor.get(INotificationService);
|
||||
|
||||
type ApplyCodeActionEvent = {
|
||||
codeActionTitle: string;
|
||||
codeActionKind: string | undefined;
|
||||
codeActionIsPreferred: boolean;
|
||||
};
|
||||
type ApplyCodeEventClassification = {
|
||||
codeActionTitle: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
|
||||
codeActionKind: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
|
||||
codeActionIsPreferred: { classification: 'SystemMetaData', purpose: 'FeatureInsight' };
|
||||
};
|
||||
|
||||
telemetryService.publicLog2<ApplyCodeActionEvent, ApplyCodeEventClassification>('codeAction.applyCodeAction', {
|
||||
codeActionTitle: action.title,
|
||||
codeActionKind: action.kind,
|
||||
codeActionIsPreferred: !!action.isPreferred,
|
||||
});
|
||||
|
||||
if (action.edit) {
|
||||
await bulkEditService.apply(action.edit, { editor });
|
||||
}
|
||||
|
||||
if (action.command) {
|
||||
try {
|
||||
await commandService.executeCommand(action.command.id, ...(action.command.arguments || []));
|
||||
@@ -161,7 +176,6 @@ export async function applyCodeAction(
|
||||
typeof message === 'string'
|
||||
? message
|
||||
: nls.localize('applyCodeActionFailed', "An unknown error occurred while applying the code action"));
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,8 +4,9 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { getDomNodePagePosition } from 'vs/base/browser/dom';
|
||||
import { Separator } from 'vs/base/browser/ui/actionbar/actionbar';
|
||||
import { IAnchor } from 'vs/base/browser/ui/contextview/contextview';
|
||||
import { Action } from 'vs/base/common/actions';
|
||||
import { Action, IAction } from 'vs/base/common/actions';
|
||||
import { canceled } from 'vs/base/common/errors';
|
||||
import { ResolvedKeybinding } from 'vs/base/common/keyCodes';
|
||||
import { Lazy } from 'vs/base/common/lazy';
|
||||
@@ -13,9 +14,9 @@ import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IPosition, Position } from 'vs/editor/common/core/position';
|
||||
import { ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { CodeAction } from 'vs/editor/common/modes';
|
||||
import { CodeActionSet, refactorCommandId, sourceActionCommandId, codeActionCommandId, organizeImportsCommandId, fixAllCommandId } from 'vs/editor/contrib/codeAction/codeAction';
|
||||
import { CodeActionAutoApply, CodeActionCommandArgs, CodeActionKind } from 'vs/editor/contrib/codeAction/types';
|
||||
import { CodeAction, CodeActionProviderRegistry } from 'vs/editor/common/modes';
|
||||
import { codeActionCommandId, CodeActionSet, fixAllCommandId, organizeImportsCommandId, refactorCommandId, sourceActionCommandId } from 'vs/editor/contrib/codeAction/codeAction';
|
||||
import { CodeActionAutoApply, CodeActionCommandArgs, CodeActionKind, CodeActionTrigger } from 'vs/editor/contrib/codeAction/types';
|
||||
import { IContextMenuService } from 'vs/platform/contextview/browser/contextView';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { ResolvedKeybindingItem } from 'vs/platform/keybinding/common/resolvedKeybindingItem';
|
||||
@@ -67,7 +68,7 @@ export class CodeActionMenu extends Disposable {
|
||||
return this._visible;
|
||||
}
|
||||
|
||||
public async show(codeActions: CodeActionSet, at: IAnchor | IPosition, options: CodeActionShowOptions): Promise<void> {
|
||||
public async show(trigger: CodeActionTrigger, codeActions: CodeActionSet, at: IAnchor | IPosition, options: CodeActionShowOptions): Promise<void> {
|
||||
const actionsToShow = options.includeDisabledActions ? codeActions.allActions : codeActions.validActions;
|
||||
if (!actionsToShow.length) {
|
||||
this._visible = false;
|
||||
@@ -83,8 +84,7 @@ export class CodeActionMenu extends Disposable {
|
||||
this._visible = true;
|
||||
this._showingActions.value = codeActions;
|
||||
|
||||
const menuActions = actionsToShow.map(action =>
|
||||
new CodeActionAction(action, () => this._delegate.onSelectCodeAction(action)));
|
||||
const menuActions = this.getMenuActions(trigger, actionsToShow);
|
||||
|
||||
const anchor = Position.isIPosition(at) ? this._toCoords(at) : at || { x: 0, y: 0 };
|
||||
const resolver = this._keybindingResolver.getResolver();
|
||||
@@ -101,6 +101,31 @@ export class CodeActionMenu extends Disposable {
|
||||
});
|
||||
}
|
||||
|
||||
private getMenuActions(trigger: CodeActionTrigger, actionsToShow: readonly CodeAction[]): IAction[] {
|
||||
const toCodeActionAction = (action: CodeAction): CodeActionAction => new CodeActionAction(action, () => this._delegate.onSelectCodeAction(action));
|
||||
|
||||
const result: IAction[] = actionsToShow
|
||||
.map(toCodeActionAction);
|
||||
|
||||
|
||||
const model = this._editor.getModel();
|
||||
if (model && result.length) {
|
||||
for (const provider of CodeActionProviderRegistry.all(model)) {
|
||||
if (provider._getAdditionalMenuItems) {
|
||||
const items = provider._getAdditionalMenuItems({ trigger: trigger.type, only: trigger.filter?.include?.value }, actionsToShow);
|
||||
if (items.length) {
|
||||
result.push(new Separator(), ...items.map(command => toCodeActionAction({
|
||||
title: command.title,
|
||||
command: command,
|
||||
})));
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
private _toCoords(position: IPosition): { x: number, y: number } {
|
||||
if (!this._editor.hasModel()) {
|
||||
return { x: 0, y: 0 };
|
||||
|
||||
@@ -11,7 +11,7 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { CodeActionProviderRegistry } from 'vs/editor/common/modes';
|
||||
import { CodeActionProviderRegistry, CodeActionTriggerType } from 'vs/editor/common/modes';
|
||||
import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IMarkerService } from 'vs/platform/markers/common/markers';
|
||||
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
|
||||
@@ -56,14 +56,14 @@ class CodeActionOracle extends Disposable {
|
||||
|
||||
if (resources.some(resource => isEqual(resource, model.uri))) {
|
||||
this._autoTriggerTimer.cancelAndSet(() => {
|
||||
this.trigger({ type: 'auto' });
|
||||
this.trigger({ type: CodeActionTriggerType.Auto });
|
||||
}, this._delay);
|
||||
}
|
||||
}
|
||||
|
||||
private _onCursorChange(): void {
|
||||
this._autoTriggerTimer.cancelAndSet(() => {
|
||||
this.trigger({ type: 'auto' });
|
||||
this.trigger({ type: CodeActionTriggerType.Auto });
|
||||
}, this._delay);
|
||||
}
|
||||
|
||||
@@ -88,7 +88,7 @@ class CodeActionOracle extends Disposable {
|
||||
}
|
||||
const model = this._editor.getModel();
|
||||
const selection = this._editor.getSelection();
|
||||
if (selection.isEmpty() && trigger.type === 'auto') {
|
||||
if (selection.isEmpty() && trigger.type === CodeActionTriggerType.Auto) {
|
||||
const { lineNumber, column } = selection.getPosition();
|
||||
const line = model.getLineContent(lineNumber);
|
||||
if (line.length === 0) {
|
||||
@@ -214,14 +214,14 @@ export class CodeActionModel extends Disposable {
|
||||
}
|
||||
|
||||
const actions = createCancelablePromise(token => getCodeActions(model, trigger.selection, trigger.trigger, token));
|
||||
if (this._progressService && trigger.trigger.type === 'manual') {
|
||||
if (this._progressService && trigger.trigger.type === CodeActionTriggerType.Manual) {
|
||||
this._progressService.showWhile(actions, 250);
|
||||
}
|
||||
|
||||
this.setState(new CodeActionsState.Triggered(trigger.trigger, trigger.selection, trigger.position, actions));
|
||||
|
||||
}, undefined);
|
||||
this._codeActionOracle.value.trigger({ type: 'auto' });
|
||||
this._codeActionOracle.value.trigger({ type: CodeActionTriggerType.Auto });
|
||||
} else {
|
||||
this._supportedCodeActions.reset();
|
||||
}
|
||||
|
||||
@@ -10,14 +10,14 @@ import { Lazy } from 'vs/base/common/lazy';
|
||||
import { Disposable, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IPosition } from 'vs/editor/common/core/position';
|
||||
import { CodeAction } from 'vs/editor/common/modes';
|
||||
import { CodeAction, CodeActionTriggerType } from 'vs/editor/common/modes';
|
||||
import { CodeActionSet } from 'vs/editor/contrib/codeAction/codeAction';
|
||||
import { MessageController } from 'vs/editor/contrib/message/messageController';
|
||||
import { CodeActionsState } from './codeActionModel';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { CodeActionMenu, CodeActionShowOptions } from './codeActionMenu';
|
||||
import { CodeActionsState } from './codeActionModel';
|
||||
import { LightBulbWidget } from './lightBulbWidget';
|
||||
import { CodeActionAutoApply, CodeActionTrigger } from './types';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
|
||||
export class CodeActionUi extends Disposable {
|
||||
|
||||
@@ -46,7 +46,7 @@ export class CodeActionUi extends Disposable {
|
||||
|
||||
this._lightBulbWidget = new Lazy(() => {
|
||||
const widget = this._register(instantiationService.createInstance(LightBulbWidget, this._editor, quickFixActionId, preferredFixActionId));
|
||||
this._register(widget.onClick(e => this.showCodeActionList(e.actions, e, { includeDisabledActions: false })));
|
||||
this._register(widget.onClick(e => this.showCodeActionList(e.trigger, e.actions, e, { includeDisabledActions: false })));
|
||||
return widget;
|
||||
});
|
||||
}
|
||||
@@ -65,9 +65,9 @@ export class CodeActionUi extends Disposable {
|
||||
return;
|
||||
}
|
||||
|
||||
this._lightBulbWidget.getValue().update(actions, newState.position);
|
||||
this._lightBulbWidget.getValue().update(actions, newState.trigger, newState.position);
|
||||
|
||||
if (newState.trigger.type === 'manual') {
|
||||
if (newState.trigger.type === CodeActionTriggerType.Manual) {
|
||||
if (newState.trigger.filter?.include) { // Triggered for specific scope
|
||||
// Check to see if we want to auto apply.
|
||||
|
||||
@@ -103,7 +103,7 @@ export class CodeActionUi extends Disposable {
|
||||
}
|
||||
|
||||
this._activeCodeActions.value = actions;
|
||||
this._codeActionWidget.getValue().show(actions, newState.position, { includeDisabledActions });
|
||||
this._codeActionWidget.getValue().show(newState.trigger, actions, newState.position, { includeDisabledActions });
|
||||
} else {
|
||||
// auto magically triggered
|
||||
if (this._codeActionWidget.getValue().isVisible) {
|
||||
@@ -143,7 +143,7 @@ export class CodeActionUi extends Disposable {
|
||||
return undefined;
|
||||
}
|
||||
|
||||
public async showCodeActionList(actions: CodeActionSet, at: IAnchor | IPosition, options: CodeActionShowOptions): Promise<void> {
|
||||
this._codeActionWidget.getValue().show(actions, at, options);
|
||||
public async showCodeActionList(trigger: CodeActionTrigger, actions: CodeActionSet, at: IAnchor | IPosition, options: CodeActionShowOptions): Promise<void> {
|
||||
this._codeActionWidget.getValue().show(trigger, actions, at, options);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import { EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { editorLightBulbForeground, editorLightBulbAutoFixForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { Gesture } from 'vs/base/browser/touch';
|
||||
import type { CodeActionTrigger } from 'vs/editor/contrib/codeAction/types';
|
||||
|
||||
namespace LightBulbState {
|
||||
|
||||
@@ -33,6 +34,7 @@ namespace LightBulbState {
|
||||
|
||||
constructor(
|
||||
public readonly actions: CodeActionSet,
|
||||
public readonly trigger: CodeActionTrigger,
|
||||
public readonly editorPosition: IPosition,
|
||||
public readonly widgetPosition: IContentWidgetPosition,
|
||||
) { }
|
||||
@@ -48,7 +50,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
|
||||
|
||||
private readonly _domNode: HTMLDivElement;
|
||||
|
||||
private readonly _onClick = this._register(new Emitter<{ x: number; y: number; actions: CodeActionSet; }>());
|
||||
private readonly _onClick = this._register(new Emitter<{ x: number; y: number; actions: CodeActionSet; trigger: CodeActionTrigger }>());
|
||||
public readonly onClick = this._onClick.event;
|
||||
|
||||
private _state: LightBulbState.State = LightBulbState.Hidden;
|
||||
@@ -95,7 +97,8 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
|
||||
this._onClick.fire({
|
||||
x: e.posx,
|
||||
y: top + height + pad,
|
||||
actions: this.state.actions
|
||||
actions: this.state.actions,
|
||||
trigger: this.state.trigger,
|
||||
});
|
||||
}));
|
||||
this._register(dom.addDisposableListener(this._domNode, 'mouseenter', (e: MouseEvent) => {
|
||||
@@ -107,7 +110,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
|
||||
// showings until mouse is released
|
||||
this.hide();
|
||||
const monitor = new GlobalMouseMoveMonitor<IStandardMouseMoveEventData>();
|
||||
monitor.startMonitoring(standardMouseMoveMerger, () => { }, () => {
|
||||
monitor.startMonitoring(e.buttons, standardMouseMoveMerger, () => { }, () => {
|
||||
monitor.dispose();
|
||||
});
|
||||
}));
|
||||
@@ -139,7 +142,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
|
||||
return this._state.type === LightBulbState.Type.Showing ? this._state.widgetPosition : null;
|
||||
}
|
||||
|
||||
public update(actions: CodeActionSet, atPosition: IPosition) {
|
||||
public update(actions: CodeActionSet, trigger: CodeActionTrigger, atPosition: IPosition) {
|
||||
if (actions.validActions.length <= 0) {
|
||||
return this.hide();
|
||||
}
|
||||
@@ -177,7 +180,7 @@ export class LightBulbWidget extends Disposable implements IContentWidget {
|
||||
}
|
||||
}
|
||||
|
||||
this.state = new LightBulbState.Showing(actions, atPosition, {
|
||||
this.state = new LightBulbState.Showing(actions, trigger, atPosition, {
|
||||
position: { lineNumber: effectiveLineNumber, column: 1 },
|
||||
preference: LightBulbWidget._posPref
|
||||
});
|
||||
|
||||
@@ -69,7 +69,7 @@ suite('CodeAction', () => {
|
||||
bcd: {
|
||||
diagnostics: <IMarkerData[]>[],
|
||||
edit: new class implements modes.WorkspaceEdit {
|
||||
edits!: modes.ResourceTextEdit[];
|
||||
edits!: modes.WorkspaceTextEdit[];
|
||||
},
|
||||
title: 'abc'
|
||||
}
|
||||
@@ -125,7 +125,7 @@ suite('CodeAction', () => {
|
||||
testData.tsLint.abc
|
||||
];
|
||||
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: 'manual' }, CancellationToken.None);
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: modes.CodeActionTriggerType.Manual }, CancellationToken.None);
|
||||
assert.equal(actions.length, 6);
|
||||
assert.deepEqual(actions, expected);
|
||||
});
|
||||
@@ -140,20 +140,20 @@ suite('CodeAction', () => {
|
||||
disposables.add(modes.CodeActionProviderRegistry.register('fooLang', provider));
|
||||
|
||||
{
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: 'auto', filter: { include: new CodeActionKind('a') } }, CancellationToken.None);
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: modes.CodeActionTriggerType.Auto, filter: { include: new CodeActionKind('a') } }, CancellationToken.None);
|
||||
assert.equal(actions.length, 2);
|
||||
assert.strictEqual(actions[0].title, 'a');
|
||||
assert.strictEqual(actions[1].title, 'a.b');
|
||||
}
|
||||
|
||||
{
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: 'auto', filter: { include: new CodeActionKind('a.b') } }, CancellationToken.None);
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: modes.CodeActionTriggerType.Auto, filter: { include: new CodeActionKind('a.b') } }, CancellationToken.None);
|
||||
assert.equal(actions.length, 1);
|
||||
assert.strictEqual(actions[0].title, 'a.b');
|
||||
}
|
||||
|
||||
{
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: 'auto', filter: { include: new CodeActionKind('a.b.c') } }, CancellationToken.None);
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: modes.CodeActionTriggerType.Auto, filter: { include: new CodeActionKind('a.b.c') } }, CancellationToken.None);
|
||||
assert.equal(actions.length, 0);
|
||||
}
|
||||
});
|
||||
@@ -172,7 +172,7 @@ suite('CodeAction', () => {
|
||||
|
||||
disposables.add(modes.CodeActionProviderRegistry.register('fooLang', provider));
|
||||
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: 'auto', filter: { include: new CodeActionKind('a') } }, CancellationToken.None);
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: modes.CodeActionTriggerType.Auto, filter: { include: new CodeActionKind('a') } }, CancellationToken.None);
|
||||
assert.equal(actions.length, 1);
|
||||
assert.strictEqual(actions[0].title, 'a');
|
||||
});
|
||||
@@ -186,13 +186,13 @@ suite('CodeAction', () => {
|
||||
disposables.add(modes.CodeActionProviderRegistry.register('fooLang', provider));
|
||||
|
||||
{
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: 'auto' }, CancellationToken.None);
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: modes.CodeActionTriggerType.Auto }, CancellationToken.None);
|
||||
assert.equal(actions.length, 1);
|
||||
assert.strictEqual(actions[0].title, 'b');
|
||||
}
|
||||
|
||||
{
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: 'auto', filter: { include: CodeActionKind.Source, includeSourceActions: true } }, CancellationToken.None);
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), { type: modes.CodeActionTriggerType.Auto, filter: { include: CodeActionKind.Source, includeSourceActions: true } }, CancellationToken.None);
|
||||
assert.equal(actions.length, 1);
|
||||
assert.strictEqual(actions[0].title, 'a');
|
||||
}
|
||||
@@ -209,7 +209,7 @@ suite('CodeAction', () => {
|
||||
|
||||
{
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), {
|
||||
type: 'auto', filter: {
|
||||
type: modes.CodeActionTriggerType.Auto, filter: {
|
||||
include: CodeActionKind.Source.append('test'),
|
||||
excludes: [CodeActionKind.Source],
|
||||
includeSourceActions: true,
|
||||
@@ -234,7 +234,7 @@ suite('CodeAction', () => {
|
||||
disposables.add(modes.CodeActionProviderRegistry.register('fooLang', provider));
|
||||
|
||||
const { validActions: actions } = await getCodeActions(model, new Range(1, 1, 2, 1), {
|
||||
type: 'auto',
|
||||
type: modes.CodeActionTriggerType.Auto,
|
||||
filter: {
|
||||
include: CodeActionKind.QuickFix
|
||||
}
|
||||
|
||||
@@ -59,7 +59,7 @@ suite('CodeActionModel', () => {
|
||||
disposables.add(model.onDidChangeState((e: CodeActionsState.State) => {
|
||||
assertType(e.type === CodeActionsState.Type.Triggered);
|
||||
|
||||
assert.strictEqual(e.trigger.type, 'auto');
|
||||
assert.strictEqual(e.trigger.type, modes.CodeActionTriggerType.Auto);
|
||||
assert.ok(e.actions);
|
||||
|
||||
e.actions.then(fixes => {
|
||||
@@ -100,7 +100,7 @@ suite('CodeActionModel', () => {
|
||||
disposables.add(model.onDidChangeState((e: CodeActionsState.State) => {
|
||||
assertType(e.type === CodeActionsState.Type.Triggered);
|
||||
|
||||
assert.equal(e.trigger.type, 'auto');
|
||||
assert.equal(e.trigger.type, modes.CodeActionTriggerType.Auto);
|
||||
assert.ok(e.actions);
|
||||
e.actions.then(fixes => {
|
||||
model.dispose();
|
||||
@@ -138,7 +138,7 @@ suite('CodeActionModel', () => {
|
||||
disposables.add(model.onDidChangeState((e: CodeActionsState.State) => {
|
||||
assertType(e.type === CodeActionsState.Type.Triggered);
|
||||
|
||||
assert.equal(e.trigger.type, 'auto');
|
||||
assert.equal(e.trigger.type, modes.CodeActionTriggerType.Auto);
|
||||
const selection = <Selection>e.rangeOrSelection;
|
||||
assert.deepEqual(selection.selectionStartLineNumber, 1);
|
||||
assert.deepEqual(selection.selectionStartColumn, 1);
|
||||
@@ -163,7 +163,7 @@ suite('CodeActionModel', () => {
|
||||
disposables.add(model.onDidChangeState((e: CodeActionsState.State) => {
|
||||
assertType(e.type === CodeActionsState.Type.Triggered);
|
||||
|
||||
assert.equal(e.trigger.type, 'auto');
|
||||
assert.equal(e.trigger.type, modes.CodeActionTriggerType.Auto);
|
||||
++triggerCount;
|
||||
|
||||
// give time for second trigger before completing test
|
||||
|
||||
@@ -4,7 +4,7 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { startsWith } from 'vs/base/common/strings';
|
||||
import { CodeAction } from 'vs/editor/common/modes';
|
||||
import { CodeAction, CodeActionTriggerType } from 'vs/editor/common/modes';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
|
||||
export class CodeActionKind {
|
||||
@@ -102,7 +102,7 @@ export function filtersAction(filter: CodeActionFilter, action: CodeAction): boo
|
||||
}
|
||||
|
||||
export interface CodeActionTrigger {
|
||||
readonly type: 'auto' | 'manual';
|
||||
readonly type: CodeActionTriggerType;
|
||||
readonly filter?: CodeActionFilter;
|
||||
readonly autoApply?: CodeActionAutoApply;
|
||||
readonly context?: {
|
||||
|
||||
@@ -7,9 +7,9 @@ import { CancelablePromise, RunOnceScheduler, createCancelablePromise, disposabl
|
||||
import { onUnexpectedError, onUnexpectedExternalError } from 'vs/base/common/errors';
|
||||
import { toDisposable, DisposableStore, dispose } from 'vs/base/common/lifecycle';
|
||||
import { StableEditorScrollState } from 'vs/editor/browser/core/editorState';
|
||||
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import { ICodeEditor, MouseTargetType, IViewZoneChangeAccessor, IActiveCodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { IModelDecorationsChangeAccessor } from 'vs/editor/common/model';
|
||||
import { CodeLensProviderRegistry, CodeLens } from 'vs/editor/common/modes';
|
||||
import { CodeLensModel, getCodeLensData, CodeLensItem } from 'vs/editor/contrib/codelens/codelens';
|
||||
@@ -21,7 +21,7 @@ import { EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { createStyleSheet } from 'vs/base/browser/dom';
|
||||
import { hash } from 'vs/base/common/hash';
|
||||
|
||||
export class CodeLensContribution implements editorCommon.IEditorContribution {
|
||||
export class CodeLensContribution implements IEditorContribution {
|
||||
|
||||
public static readonly ID: string = 'css.editor.codeLens';
|
||||
|
||||
@@ -40,7 +40,7 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
|
||||
private _detectVisibleLenses: RunOnceScheduler | undefined;
|
||||
|
||||
constructor(
|
||||
private readonly _editor: editorBrowser.ICodeEditor,
|
||||
private readonly _editor: ICodeEditor,
|
||||
@ICommandService private readonly _commandService: ICommandService,
|
||||
@INotificationService private readonly _notificationService: INotificationService,
|
||||
@ICodeLensCache private readonly _codeLensCache: ICodeLensCache
|
||||
@@ -223,7 +223,7 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
|
||||
}
|
||||
}));
|
||||
this._localToDispose.add(this._editor.onMouseUp(e => {
|
||||
if (e.target.type !== editorBrowser.MouseTargetType.CONTENT_WIDGET) {
|
||||
if (e.target.type !== MouseTargetType.CONTENT_WIDGET) {
|
||||
return;
|
||||
}
|
||||
let target = e.target.element;
|
||||
@@ -243,7 +243,7 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
|
||||
scheduler.schedule();
|
||||
}
|
||||
|
||||
private _disposeAllLenses(decChangeAccessor: IModelDecorationsChangeAccessor | undefined, viewZoneChangeAccessor: editorBrowser.IViewZoneChangeAccessor | undefined): void {
|
||||
private _disposeAllLenses(decChangeAccessor: IModelDecorationsChangeAccessor | undefined, viewZoneChangeAccessor: IViewZoneChangeAccessor | undefined): void {
|
||||
const helper = new CodeLensHelper();
|
||||
for (const lens of this._lenses) {
|
||||
lens.dispose(helper, viewZoneChangeAccessor);
|
||||
@@ -300,7 +300,7 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
|
||||
groupsIndex++;
|
||||
codeLensIndex++;
|
||||
} else {
|
||||
this._lenses.splice(codeLensIndex, 0, new CodeLensWidget(groups[groupsIndex], <editorBrowser.IActiveCodeEditor>this._editor, this._styleClassName, helper, viewZoneAccessor, () => this._detectVisibleLenses && this._detectVisibleLenses.schedule()));
|
||||
this._lenses.splice(codeLensIndex, 0, new CodeLensWidget(groups[groupsIndex], <IActiveCodeEditor>this._editor, this._styleClassName, helper, viewZoneAccessor, () => this._detectVisibleLenses && this._detectVisibleLenses.schedule()));
|
||||
codeLensIndex++;
|
||||
groupsIndex++;
|
||||
}
|
||||
@@ -314,7 +314,7 @@ export class CodeLensContribution implements editorCommon.IEditorContribution {
|
||||
|
||||
// Create extra symbols
|
||||
while (groupsIndex < groups.length) {
|
||||
this._lenses.push(new CodeLensWidget(groups[groupsIndex], <editorBrowser.IActiveCodeEditor>this._editor, this._styleClassName, helper, viewZoneAccessor, () => this._detectVisibleLenses && this._detectVisibleLenses.schedule()));
|
||||
this._lenses.push(new CodeLensWidget(groups[groupsIndex], <IActiveCodeEditor>this._editor, this._styleClassName, helper, viewZoneAccessor, () => this._detectVisibleLenses && this._detectVisibleLenses.schedule()));
|
||||
groupsIndex++;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import 'vs/css!./codelensWidget';
|
||||
import * as dom from 'vs/base/browser/dom';
|
||||
import { renderCodicons } from 'vs/base/common/codicons';
|
||||
import { escape } from 'vs/base/common/strings';
|
||||
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import { IViewZone, IContentWidget, IActiveCodeEditor, IContentWidgetPosition, ContentWidgetPositionPreference, IViewZoneChangeAccessor } from 'vs/editor/browser/editorBrowser';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { IModelDecorationsChangeAccessor, IModelDeltaDecoration, ITextModel } from 'vs/editor/common/model';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
@@ -17,7 +17,7 @@ import { CodeLensItem } from 'vs/editor/contrib/codelens/codelens';
|
||||
import { editorActiveLinkForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
class CodeLensViewZone implements editorBrowser.IViewZone {
|
||||
class CodeLensViewZone implements IViewZone {
|
||||
|
||||
readonly heightInLines: number;
|
||||
readonly suppressMouseDown: boolean;
|
||||
@@ -47,7 +47,7 @@ class CodeLensViewZone implements editorBrowser.IViewZone {
|
||||
}
|
||||
}
|
||||
|
||||
class CodeLensContentWidget implements editorBrowser.IContentWidget {
|
||||
class CodeLensContentWidget implements IContentWidget {
|
||||
|
||||
private static _idPool: number = 0;
|
||||
|
||||
@@ -57,14 +57,14 @@ class CodeLensContentWidget implements editorBrowser.IContentWidget {
|
||||
|
||||
private readonly _id: string;
|
||||
private readonly _domNode: HTMLElement;
|
||||
private readonly _editor: editorBrowser.IActiveCodeEditor;
|
||||
private readonly _editor: IActiveCodeEditor;
|
||||
private readonly _commands = new Map<string, Command>();
|
||||
|
||||
private _widgetPosition?: editorBrowser.IContentWidgetPosition;
|
||||
private _widgetPosition?: IContentWidgetPosition;
|
||||
private _isEmpty: boolean = true;
|
||||
|
||||
constructor(
|
||||
editor: editorBrowser.IActiveCodeEditor,
|
||||
editor: IActiveCodeEditor,
|
||||
className: string,
|
||||
line: number,
|
||||
) {
|
||||
@@ -137,11 +137,11 @@ class CodeLensContentWidget implements editorBrowser.IContentWidget {
|
||||
const column = this._editor.getModel().getLineFirstNonWhitespaceColumn(line);
|
||||
this._widgetPosition = {
|
||||
position: { lineNumber: line, column: column },
|
||||
preference: [editorBrowser.ContentWidgetPositionPreference.ABOVE]
|
||||
preference: [ContentWidgetPositionPreference.ABOVE]
|
||||
};
|
||||
}
|
||||
|
||||
getPosition(): editorBrowser.IContentWidgetPosition | null {
|
||||
getPosition(): IContentWidgetPosition | null {
|
||||
return this._widgetPosition || null;
|
||||
}
|
||||
}
|
||||
@@ -181,7 +181,7 @@ export class CodeLensHelper {
|
||||
|
||||
export class CodeLensWidget {
|
||||
|
||||
private readonly _editor: editorBrowser.IActiveCodeEditor;
|
||||
private readonly _editor: IActiveCodeEditor;
|
||||
private readonly _className: string;
|
||||
private readonly _viewZone!: CodeLensViewZone;
|
||||
private readonly _viewZoneId!: string;
|
||||
@@ -193,10 +193,10 @@ export class CodeLensWidget {
|
||||
|
||||
constructor(
|
||||
data: CodeLensItem[],
|
||||
editor: editorBrowser.IActiveCodeEditor,
|
||||
editor: IActiveCodeEditor,
|
||||
className: string,
|
||||
helper: CodeLensHelper,
|
||||
viewZoneChangeAccessor: editorBrowser.IViewZoneChangeAccessor,
|
||||
viewZoneChangeAccessor: IViewZoneChangeAccessor,
|
||||
updateCallback: Function
|
||||
) {
|
||||
this._editor = editor;
|
||||
@@ -244,7 +244,7 @@ export class CodeLensWidget {
|
||||
}
|
||||
}
|
||||
|
||||
dispose(helper: CodeLensHelper, viewZoneChangeAccessor?: editorBrowser.IViewZoneChangeAccessor): void {
|
||||
dispose(helper: CodeLensHelper, viewZoneChangeAccessor?: IViewZoneChangeAccessor): void {
|
||||
this._decorationIds.forEach(helper.removeDecoration, helper);
|
||||
this._decorationIds = [];
|
||||
if (viewZoneChangeAccessor) {
|
||||
@@ -322,7 +322,7 @@ export class CodeLensWidget {
|
||||
return -1;
|
||||
}
|
||||
|
||||
update(viewZoneChangeAccessor: editorBrowser.IViewZoneChangeAccessor): void {
|
||||
update(viewZoneChangeAccessor: IViewZoneChangeAccessor): void {
|
||||
if (this.isValid()) {
|
||||
const range = this._editor.getModel().getDecorationRange(this._decorationIds[0]);
|
||||
if (range) {
|
||||
|
||||
@@ -163,7 +163,7 @@ class SaturationBox extends Disposable {
|
||||
this.onDidChangePosition(e.offsetX, e.offsetY);
|
||||
}
|
||||
|
||||
this.monitor.startMonitoring(standardMouseMoveMerger, event => this.onDidChangePosition(event.posx - origin.left, event.posy - origin.top), () => null);
|
||||
this.monitor.startMonitoring(e.buttons, standardMouseMoveMerger, event => this.onDidChangePosition(event.posx - origin.left, event.posy - origin.top), () => null);
|
||||
|
||||
const mouseUpListener = dom.addDisposableGenericMouseUpListner(document, () => {
|
||||
this._onColorFlushed.fire();
|
||||
@@ -270,7 +270,7 @@ abstract class Strip extends Disposable {
|
||||
this.onDidChangeTop(e.offsetY);
|
||||
}
|
||||
|
||||
monitor.startMonitoring(standardMouseMoveMerger, event => this.onDidChangeTop(event.posy - origin.top), () => null);
|
||||
monitor.startMonitoring(e.buttons, standardMouseMoveMerger, event => this.onDidChangeTop(event.posy - origin.top), () => null);
|
||||
|
||||
const mouseUpListener = dom.addDisposableGenericMouseUpListner(document, () => {
|
||||
this._onColorFlushed.fire();
|
||||
|
||||
@@ -8,11 +8,11 @@ import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ICommand, IEditOperationBuilder, ICursorStateComputerData } from 'vs/editor/common/editorCommon';
|
||||
import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/model';
|
||||
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
|
||||
|
||||
export class BlockCommentCommand implements editorCommon.ICommand {
|
||||
export class BlockCommentCommand implements ICommand {
|
||||
|
||||
private readonly _selection: Selection;
|
||||
private _usedEndToken: string | null;
|
||||
@@ -53,7 +53,7 @@ export class BlockCommentCommand implements editorCommon.ICommand {
|
||||
return true;
|
||||
}
|
||||
|
||||
private _createOperationsForBlockComment(selection: Range, startToken: string, endToken: string, model: ITextModel, builder: editorCommon.IEditOperationBuilder): void {
|
||||
private _createOperationsForBlockComment(selection: Range, startToken: string, endToken: string, model: ITextModel, builder: IEditOperationBuilder): void {
|
||||
const startLineNumber = selection.startLineNumber;
|
||||
const startColumn = selection.startColumn;
|
||||
const endLineNumber = selection.endLineNumber;
|
||||
@@ -164,7 +164,7 @@ export class BlockCommentCommand implements editorCommon.ICommand {
|
||||
return res;
|
||||
}
|
||||
|
||||
public getEditOperations(model: ITextModel, builder: editorCommon.IEditOperationBuilder): void {
|
||||
public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {
|
||||
const startLineNumber = this._selection.startLineNumber;
|
||||
const startColumn = this._selection.startColumn;
|
||||
|
||||
@@ -179,7 +179,7 @@ export class BlockCommentCommand implements editorCommon.ICommand {
|
||||
this._createOperationsForBlockComment(this._selection, config.blockCommentStartToken, config.blockCommentEndToken, model, builder);
|
||||
}
|
||||
|
||||
public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {
|
||||
const inverseEditOperations = helper.getInverseEditOperations();
|
||||
if (inverseEditOperations.length === 2) {
|
||||
const startTokenEditOperation = inverseEditOperations[0];
|
||||
|
||||
@@ -9,7 +9,7 @@ import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ICommand, IEditOperationBuilder, ICursorStateComputerData } from 'vs/editor/common/editorCommon';
|
||||
import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/model';
|
||||
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
|
||||
import { BlockCommentCommand } from 'vs/editor/contrib/comment/blockCommentCommand';
|
||||
@@ -47,7 +47,7 @@ export const enum Type {
|
||||
ForceRemove = 2
|
||||
}
|
||||
|
||||
export class LineCommentCommand implements editorCommon.ICommand {
|
||||
export class LineCommentCommand implements ICommand {
|
||||
|
||||
private readonly _selection: Selection;
|
||||
private _selectionId: string | null;
|
||||
@@ -187,7 +187,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
|
||||
/**
|
||||
* Given a successful analysis, execute either insert line comments, either remove line comments
|
||||
*/
|
||||
private _executeLineComments(model: ISimpleModel, builder: editorCommon.IEditOperationBuilder, data: IPreflightDataSupported, s: Selection): void {
|
||||
private _executeLineComments(model: ISimpleModel, builder: IEditOperationBuilder, data: IPreflightDataSupported, s: Selection): void {
|
||||
|
||||
let ops: IIdentifiedSingleEditOperation[];
|
||||
|
||||
@@ -266,7 +266,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
|
||||
/**
|
||||
* Given an unsuccessful analysis, delegate to the block comment command
|
||||
*/
|
||||
private _executeBlockComment(model: ITextModel, builder: editorCommon.IEditOperationBuilder, s: Selection): void {
|
||||
private _executeBlockComment(model: ITextModel, builder: IEditOperationBuilder, s: Selection): void {
|
||||
model.tokenizeIfCheap(s.startLineNumber);
|
||||
let languageId = model.getLanguageIdAtPosition(s.startLineNumber, 1);
|
||||
let config = LanguageConfigurationRegistry.getComments(languageId);
|
||||
@@ -307,7 +307,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
|
||||
}
|
||||
}
|
||||
|
||||
public getEditOperations(model: ITextModel, builder: editorCommon.IEditOperationBuilder): void {
|
||||
public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {
|
||||
|
||||
let s = this._selection;
|
||||
this._moveEndPositionDown = false;
|
||||
@@ -325,7 +325,7 @@ export class LineCommentCommand implements editorCommon.ICommand {
|
||||
return this._executeBlockComment(model, builder, s);
|
||||
}
|
||||
|
||||
public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {
|
||||
let result = helper.getTrackedSelection(this._selectionId!);
|
||||
|
||||
if (this._moveEndPositionDown) {
|
||||
@@ -381,7 +381,6 @@ export class LineCommentCommand implements editorCommon.ICommand {
|
||||
return res;
|
||||
}
|
||||
|
||||
// TODO@Alex -> duplicated in characterHardWrappingLineMapper
|
||||
private static nextVisibleColumn(currentVisibleColumn: number, tabSize: number, isTab: boolean, columnSize: number): number {
|
||||
if (isTab) {
|
||||
return currentVisibleColumn + (tabSize - (currentVisibleColumn % tabSize));
|
||||
|
||||
@@ -10,7 +10,7 @@ import { isMacintosh } from 'vs/base/common/platform';
|
||||
import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { ICodeEditor, IEditorMouseEvent, IMouseTarget, MouseTargetType, IPartialEditorMouseEvent } from 'vs/editor/browser/editorBrowser';
|
||||
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IEditorContribution, ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
@@ -29,7 +29,7 @@ function hasTriggerModifier(e: IKeyboardEvent | IMouseEvent): boolean {
|
||||
}
|
||||
}
|
||||
|
||||
export class DragAndDropController extends Disposable implements editorCommon.IEditorContribution {
|
||||
export class DragAndDropController extends Disposable implements IEditorContribution {
|
||||
|
||||
public static readonly ID = 'editor.contrib.dragAndDrop';
|
||||
|
||||
@@ -201,7 +201,7 @@ export class DragAndDropController extends Disposable implements editorCommon.IE
|
||||
}];
|
||||
|
||||
this._dndDecorationIds = this._editor.deltaDecorations(this._dndDecorationIds, newDecorations);
|
||||
this._editor.revealPosition(position, editorCommon.ScrollType.Immediate);
|
||||
this._editor.revealPosition(position, ScrollType.Immediate);
|
||||
}
|
||||
|
||||
private _removeDecoration(): void {
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ICommand, IEditOperationBuilder, ICursorStateComputerData } from 'vs/editor/common/editorCommon';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
|
||||
|
||||
export class DragAndDropCommand implements editorCommon.ICommand {
|
||||
export class DragAndDropCommand implements ICommand {
|
||||
|
||||
private readonly selection: Selection;
|
||||
private readonly targetPosition: Position;
|
||||
@@ -24,7 +24,7 @@ export class DragAndDropCommand implements editorCommon.ICommand {
|
||||
this.targetSelection = null;
|
||||
}
|
||||
|
||||
public getEditOperations(model: ITextModel, builder: editorCommon.IEditOperationBuilder): void {
|
||||
public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {
|
||||
let text = model.getValueInRange(this.selection);
|
||||
if (!this.copy) {
|
||||
builder.addEditOperation(this.selection, null);
|
||||
@@ -102,7 +102,7 @@ export class DragAndDropCommand implements editorCommon.ICommand {
|
||||
}
|
||||
}
|
||||
|
||||
public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {
|
||||
return this.targetSelection!;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,7 +10,7 @@ import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as strings from 'vs/base/common/strings';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { EditorAction, EditorCommand, ServicesAccessor, registerEditorAction, registerEditorCommand, registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { CONTEXT_FIND_INPUT_FOCUSED, CONTEXT_FIND_WIDGET_VISIBLE, FIND_IDS, FindModelBoundToEditorModel, ToggleCaseSensitiveKeybinding, ToggleRegexKeybinding, ToggleSearchScopeKeybinding, ToggleWholeWordKeybinding, CONTEXT_REPLACE_INPUT_FOCUSED } from 'vs/editor/contrib/find/findModel';
|
||||
import { FindOptionsWidget } from 'vs/editor/contrib/find/findOptionsWidget';
|
||||
@@ -68,7 +68,7 @@ export interface IFindStartOptions {
|
||||
updateSearchScope: boolean;
|
||||
}
|
||||
|
||||
export class CommonFindController extends Disposable implements editorCommon.IEditorContribution {
|
||||
export class CommonFindController extends Disposable implements IEditorContribution {
|
||||
|
||||
public static readonly ID = 'editor.contrib.findController';
|
||||
|
||||
|
||||
@@ -13,7 +13,7 @@ import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import { Constants } from 'vs/base/common/uint';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ScrollType, ICommand } from 'vs/editor/common/editorCommon';
|
||||
import { EndOfLinePreference, FindMatch, ITextModel } from 'vs/editor/common/model';
|
||||
import { SearchParams } from 'vs/editor/common/model/textModelSearch';
|
||||
import { FindDecorations } from 'vs/editor/contrib/find/findDecorations';
|
||||
@@ -209,7 +209,7 @@ export class FindModelBoundToEditorModel {
|
||||
let findScope = this._decorations.getFindScope();
|
||||
if (findScope) {
|
||||
// Reveal the selection so user is reminded that 'selection find' is on.
|
||||
this._editor.revealRangeInCenterIfOutsideViewport(findScope, editorCommon.ScrollType.Smooth);
|
||||
this._editor.revealRangeInCenterIfOutsideViewport(findScope, ScrollType.Smooth);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
@@ -225,7 +225,7 @@ export class FindModelBoundToEditorModel {
|
||||
);
|
||||
|
||||
this._editor.setSelection(match);
|
||||
this._editor.revealRangeInCenterIfOutsideViewport(match, editorCommon.ScrollType.Smooth);
|
||||
this._editor.revealRangeInCenterIfOutsideViewport(match, ScrollType.Smooth);
|
||||
}
|
||||
|
||||
private _prevSearchPosition(before: Position) {
|
||||
@@ -536,7 +536,7 @@ export class FindModelBoundToEditorModel {
|
||||
this._editor.setSelections(selections);
|
||||
}
|
||||
|
||||
private _executeEditorCommand(source: string, command: editorCommon.ICommand): void {
|
||||
private _executeEditorCommand(source: string, command: ICommand): void {
|
||||
try {
|
||||
this._ignoreModelContentChanged = true;
|
||||
this._editor.pushUndoStop();
|
||||
|
||||
@@ -908,7 +908,6 @@ export class FindWidget extends Widget implements IOverlayWidget, IHorizontalSas
|
||||
return null;
|
||||
}
|
||||
try {
|
||||
/* tslint:disable-next-line:no-unused-expression */
|
||||
new RegExp(value);
|
||||
return null;
|
||||
} catch (e) {
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
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 { ICommand, IEditOperationBuilder, ICursorStateComputerData } from 'vs/editor/common/editorCommon';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
|
||||
interface IEditOperation {
|
||||
@@ -13,7 +13,7 @@ interface IEditOperation {
|
||||
text: string;
|
||||
}
|
||||
|
||||
export class ReplaceAllCommand implements editorCommon.ICommand {
|
||||
export class ReplaceAllCommand implements ICommand {
|
||||
|
||||
private readonly _editorSelection: Selection;
|
||||
private _trackedEditorSelectionId: string | null;
|
||||
@@ -27,7 +27,7 @@ export class ReplaceAllCommand implements editorCommon.ICommand {
|
||||
this._trackedEditorSelectionId = null;
|
||||
}
|
||||
|
||||
public getEditOperations(model: ITextModel, builder: editorCommon.IEditOperationBuilder): void {
|
||||
public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {
|
||||
if (this._ranges.length > 0) {
|
||||
// Collect all edit operations
|
||||
let ops: IEditOperation[] = [];
|
||||
@@ -66,7 +66,7 @@ export class ReplaceAllCommand implements editorCommon.ICommand {
|
||||
this._trackedEditorSelectionId = builder.trackSelection(this._editorSelection);
|
||||
}
|
||||
|
||||
public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {
|
||||
return helper.getTrackedSelection(this._trackedEditorSelectionId!);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -14,12 +14,12 @@ import { ScrollType, IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
import { registerEditorAction, registerEditorContribution, ServicesAccessor, EditorAction, registerInstantiatedEditorAction } from 'vs/editor/browser/editorExtensions';
|
||||
import { ICodeEditor, IEditorMouseEvent, MouseTargetType } from 'vs/editor/browser/editorBrowser';
|
||||
import { FoldingModel, setCollapseStateAtLevel, CollapseMemento, setCollapseStateLevelsDown, setCollapseStateLevelsUp, setCollapseStateForMatchingLines, setCollapseStateForType, toggleCollapseState } from 'vs/editor/contrib/folding/foldingModel';
|
||||
import { FoldingModel, setCollapseStateAtLevel, CollapseMemento, setCollapseStateLevelsDown, setCollapseStateLevelsUp, setCollapseStateForMatchingLines, setCollapseStateForType, toggleCollapseState, setCollapseStateUp } from 'vs/editor/contrib/folding/foldingModel';
|
||||
import { FoldingDecorationProvider } from './foldingDecorations';
|
||||
import { FoldingRegions, FoldingRegion } from './foldingRanges';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { IMarginData, IEmptyContentData } from 'vs/editor/browser/controller/mouseTarget';
|
||||
import { IMarginData } from 'vs/editor/browser/controller/mouseTarget';
|
||||
import { HiddenRangeModel } from 'vs/editor/contrib/folding/hiddenRangeModel';
|
||||
import { IRange } from 'vs/editor/common/core/range';
|
||||
import { LanguageConfigurationRegistry } from 'vs/editor/common/modes/languageConfigurationRegistry';
|
||||
@@ -32,6 +32,8 @@ import { InitializingRangeProvider, ID_INIT_PROVIDER } from 'vs/editor/contrib/f
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { registerColor, editorSelectionBackground, transparent } from 'vs/platform/theme/common/colorRegistry';
|
||||
|
||||
const CONTEXT_FOLDING_ENABLED = new RawContextKey<boolean>('foldingEnabled', false);
|
||||
|
||||
@@ -59,7 +61,6 @@ export class FoldingController extends Disposable implements IEditorContribution
|
||||
|
||||
private readonly editor: ICodeEditor;
|
||||
private _isEnabled: boolean;
|
||||
private _autoHideFoldingControls: boolean;
|
||||
private _useFoldingProviders: boolean;
|
||||
|
||||
private readonly foldingDecorationProvider: FoldingDecorationProvider;
|
||||
@@ -89,7 +90,6 @@ export class FoldingController extends Disposable implements IEditorContribution
|
||||
this.editor = editor;
|
||||
const options = this.editor.getOptions();
|
||||
this._isEnabled = options.get(EditorOption.folding);
|
||||
this._autoHideFoldingControls = options.get(EditorOption.showFoldingControls) === 'mouseover';
|
||||
this._useFoldingProviders = options.get(EditorOption.foldingStrategy) !== 'indentation';
|
||||
|
||||
this.foldingModel = null;
|
||||
@@ -103,32 +103,30 @@ export class FoldingController extends Disposable implements IEditorContribution
|
||||
this.mouseDownInfo = null;
|
||||
|
||||
this.foldingDecorationProvider = new FoldingDecorationProvider(editor);
|
||||
this.foldingDecorationProvider.autoHideFoldingControls = this._autoHideFoldingControls;
|
||||
this.foldingDecorationProvider.autoHideFoldingControls = options.get(EditorOption.showFoldingControls) === 'mouseover';
|
||||
this.foldingDecorationProvider.showFoldingHighlights = options.get(EditorOption.foldingHighlight);
|
||||
this.foldingEnabled = CONTEXT_FOLDING_ENABLED.bindTo(this.contextKeyService);
|
||||
this.foldingEnabled.set(this._isEnabled);
|
||||
|
||||
this._register(this.editor.onDidChangeModel(() => this.onModelChanged()));
|
||||
|
||||
this._register(this.editor.onDidChangeConfiguration((e: ConfigurationChangedEvent) => {
|
||||
if (e.hasChanged(EditorOption.folding) || e.hasChanged(EditorOption.showFoldingControls) || e.hasChanged(EditorOption.foldingStrategy)) {
|
||||
let oldIsEnabled = this._isEnabled;
|
||||
if (e.hasChanged(EditorOption.folding)) {
|
||||
const options = this.editor.getOptions();
|
||||
this._isEnabled = options.get(EditorOption.folding);
|
||||
this.foldingEnabled.set(this._isEnabled);
|
||||
if (oldIsEnabled !== this._isEnabled) {
|
||||
this.onModelChanged();
|
||||
}
|
||||
let oldShowFoldingControls = this._autoHideFoldingControls;
|
||||
this._autoHideFoldingControls = options.get(EditorOption.showFoldingControls) === 'mouseover';
|
||||
if (oldShowFoldingControls !== this._autoHideFoldingControls) {
|
||||
this.foldingDecorationProvider.autoHideFoldingControls = this._autoHideFoldingControls;
|
||||
this.onModelContentChanged();
|
||||
}
|
||||
let oldUseFoldingProviders = this._useFoldingProviders;
|
||||
this.onModelChanged();
|
||||
}
|
||||
if (e.hasChanged(EditorOption.showFoldingControls) || e.hasChanged(EditorOption.foldingHighlight)) {
|
||||
const options = this.editor.getOptions();
|
||||
this.foldingDecorationProvider.autoHideFoldingControls = options.get(EditorOption.showFoldingControls) === 'mouseover';
|
||||
this.foldingDecorationProvider.showFoldingHighlights = options.get(EditorOption.foldingHighlight);
|
||||
this.onModelContentChanged();
|
||||
}
|
||||
if (e.hasChanged(EditorOption.foldingStrategy)) {
|
||||
const options = this.editor.getOptions();
|
||||
this._useFoldingProviders = options.get(EditorOption.foldingStrategy) !== 'indentation';
|
||||
if (oldUseFoldingProviders !== this._useFoldingProviders) {
|
||||
this.onFoldingStrategyChanged();
|
||||
}
|
||||
this.onFoldingStrategyChanged();
|
||||
}
|
||||
}));
|
||||
this.onModelChanged();
|
||||
@@ -366,15 +364,6 @@ export class FoldingController extends Disposable implements IEditorContribution
|
||||
|
||||
iconClicked = true;
|
||||
break;
|
||||
case MouseTargetType.CONTENT_EMPTY: {
|
||||
if (this.hiddenRangeModel.hasRanges()) {
|
||||
const data = e.target.detail as IEmptyContentData;
|
||||
if (!data.isAfterLines) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return;
|
||||
}
|
||||
case MouseTargetType.CONTENT_TEXT: {
|
||||
if (this.hiddenRangeModel.hasRanges()) {
|
||||
let model = this.editor.getModel();
|
||||
@@ -619,9 +608,10 @@ class FoldAction extends FoldingAction<FoldingArguments> {
|
||||
{
|
||||
name: 'Fold editor argument',
|
||||
description: `Property-value pairs that can be passed through this argument:
|
||||
* 'levels': Number of levels to fold. Defaults to 1.
|
||||
* 'levels': Number of levels to fold.
|
||||
* 'direction': If 'up', folds given number of levels up otherwise folds down.
|
||||
* 'selectionLines': The start lines (0-based) of the editor selections to apply the fold action to. If not set, the active selection(s) will be used.
|
||||
If no levels or direction is set, folds the region at the locations or if already collapsed, the first uncollapsed parent instead.
|
||||
`,
|
||||
constraint: foldingArgumentsConstraint,
|
||||
schema: {
|
||||
@@ -629,12 +619,10 @@ class FoldAction extends FoldingAction<FoldingArguments> {
|
||||
'properties': {
|
||||
'levels': {
|
||||
'type': 'number',
|
||||
'default': 1
|
||||
},
|
||||
'direction': {
|
||||
'type': 'string',
|
||||
'enum': ['up', 'down'],
|
||||
'default': 'down'
|
||||
},
|
||||
'selectionLines': {
|
||||
'type': 'array',
|
||||
@@ -651,12 +639,20 @@ class FoldAction extends FoldingAction<FoldingArguments> {
|
||||
}
|
||||
|
||||
invoke(_foldingController: FoldingController, foldingModel: FoldingModel, editor: ICodeEditor, args: FoldingArguments): void {
|
||||
let levels = args && args.levels || 1;
|
||||
let lineNumbers = this.getLineNumbers(args, editor);
|
||||
if (args && args.direction === 'up') {
|
||||
setCollapseStateLevelsUp(foldingModel, true, levels, lineNumbers);
|
||||
|
||||
const levels = args && args.levels;
|
||||
const direction = args && args.direction;
|
||||
|
||||
if (typeof levels !== 'number' && typeof direction !== 'string') {
|
||||
// fold the region at the location or if already collapsed, the first uncollapsed parent instead.
|
||||
setCollapseStateUp(foldingModel, true, lineNumbers);
|
||||
} else {
|
||||
setCollapseStateLevelsDown(foldingModel, true, levels, lineNumbers);
|
||||
if (direction === 'up') {
|
||||
setCollapseStateLevelsUp(foldingModel, true, levels || 1, lineNumbers);
|
||||
} else {
|
||||
setCollapseStateLevelsDown(foldingModel, true, levels || 1, lineNumbers);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -888,3 +884,12 @@ for (let i = 1; i <= 7; i++) {
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
export const foldBackgroundBackground = registerColor('editor.foldBackground', { light: transparent(editorSelectionBackground, 0.3), dark: transparent(editorSelectionBackground, 0.3), hc: null }, nls.localize('editorSelectionBackground', "Color of the editor selection."));
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
const foldBackground = theme.getColor(foldBackgroundBackground);
|
||||
if (foldBackground) {
|
||||
collector.addRule(`.monaco-editor .folded-background { background-color: ${foldBackground}; }`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -11,6 +11,12 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
export class FoldingDecorationProvider implements IDecorationProvider {
|
||||
|
||||
private static readonly COLLAPSED_VISUAL_DECORATION = ModelDecorationOptions.register({
|
||||
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
|
||||
afterContentClassName: 'inline-folded',
|
||||
linesDecorationsClassName: 'codicon codicon-chevron-right'
|
||||
});
|
||||
|
||||
private static readonly COLLAPSED_HIGHLIGHTED_VISUAL_DECORATION = ModelDecorationOptions.register({
|
||||
stickiness: TrackedRangeStickiness.NeverGrowsWhenTypingAtEdges,
|
||||
afterContentClassName: 'inline-folded',
|
||||
className: 'folded-background',
|
||||
@@ -30,12 +36,14 @@ export class FoldingDecorationProvider implements IDecorationProvider {
|
||||
|
||||
public autoHideFoldingControls: boolean = true;
|
||||
|
||||
public showFoldingHighlights: boolean = true;
|
||||
|
||||
constructor(private readonly editor: ICodeEditor) {
|
||||
}
|
||||
|
||||
getDecorationOption(isCollapsed: boolean): ModelDecorationOptions {
|
||||
if (isCollapsed) {
|
||||
return FoldingDecorationProvider.COLLAPSED_VISUAL_DECORATION;
|
||||
return this.showFoldingHighlights ? FoldingDecorationProvider.COLLAPSED_HIGHLIGHTED_VISUAL_DECORATION : FoldingDecorationProvider.COLLAPSED_VISUAL_DECORATION;
|
||||
} else if (this.autoHideFoldingControls) {
|
||||
return FoldingDecorationProvider.EXPANDED_AUTO_HIDE_VISUAL_DECORATION;
|
||||
} else {
|
||||
|
||||
@@ -6,9 +6,6 @@
|
||||
import { ITextModel, IModelDecorationOptions, IModelDeltaDecoration, IModelDecorationsChangeAccessor } from 'vs/editor/common/model';
|
||||
import { Event, Emitter } from 'vs/base/common/event';
|
||||
import { FoldingRegions, ILineRange, FoldingRegion } from './foldingRanges';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
import { registerColor, editorSelectionBackground, darken, lighten } from 'vs/platform/theme/common/colorRegistry';
|
||||
import * as nls from 'vs/nls';
|
||||
|
||||
export interface IDecorationProvider {
|
||||
getDecorationOption(isCollapsed: boolean): IModelDecorationOptions;
|
||||
@@ -276,7 +273,7 @@ export function toggleCollapseState(foldingModel: FoldingModel, levels: number,
|
||||
* @param levels The number of levels. Use 1 to only impact the regions at the location, use Number.MAX_VALUE for all levels.
|
||||
* @param lineNumbers the location of the regions to collapse or expand, or if not set, all regions in the model.
|
||||
*/
|
||||
export function setCollapseStateLevelsDown(foldingModel: FoldingModel, doCollapse: boolean, levels = Number.MAX_VALUE, lineNumbers?: number[]) {
|
||||
export function setCollapseStateLevelsDown(foldingModel: FoldingModel, doCollapse: boolean, levels = Number.MAX_VALUE, lineNumbers?: number[]): void {
|
||||
let toToggle: FoldingRegion[] = [];
|
||||
if (lineNumbers && lineNumbers.length > 0) {
|
||||
for (let lineNumber of lineNumbers) {
|
||||
@@ -302,9 +299,9 @@ export function setCollapseStateLevelsDown(foldingModel: FoldingModel, doCollaps
|
||||
* Collapse or expand the regions at the given locations including all parents.
|
||||
* @param doCollapse Wheter to collase or expand
|
||||
* @param levels The number of levels. Use 1 to only impact the regions at the location, use Number.MAX_VALUE for all levels.
|
||||
* @param lineNumbers the location of the regions to collapse or expand, or if not set, all regions in the model.
|
||||
* @param lineNumbers the location of the regions to collapse or expand.
|
||||
*/
|
||||
export function setCollapseStateLevelsUp(foldingModel: FoldingModel, doCollapse: boolean, levels: number, lineNumbers: number[]) {
|
||||
export function setCollapseStateLevelsUp(foldingModel: FoldingModel, doCollapse: boolean, levels: number, lineNumbers: number[]): void {
|
||||
let toToggle: FoldingRegion[] = [];
|
||||
for (let lineNumber of lineNumbers) {
|
||||
let regions = foldingModel.getAllRegionsAtLine(lineNumber, (region, level) => region.isCollapsed !== doCollapse && level <= levels);
|
||||
@@ -313,6 +310,22 @@ export function setCollapseStateLevelsUp(foldingModel: FoldingModel, doCollapse:
|
||||
foldingModel.toggleCollapseState(toToggle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Collapse or expand a region at the given locations. If the inner most region is already collapsed/expanded, uses the first parent instead.
|
||||
* @param doCollapse Wheter to collase or expand
|
||||
* @param lineNumbers the location of the regions to collapse or expand.
|
||||
*/
|
||||
export function setCollapseStateUp(foldingModel: FoldingModel, doCollapse: boolean, lineNumbers: number[]): void {
|
||||
let toToggle: FoldingRegion[] = [];
|
||||
for (let lineNumber of lineNumbers) {
|
||||
let regions = foldingModel.getAllRegionsAtLine(lineNumber, (region, ) => region.isCollapsed !== doCollapse);
|
||||
if (regions.length > 0) {
|
||||
toToggle.push(regions[0]);
|
||||
}
|
||||
}
|
||||
foldingModel.toggleCollapseState(toToggle);
|
||||
}
|
||||
|
||||
/**
|
||||
* Folds or unfolds all regions that have a given level, except if they contain one of the blocked lines.
|
||||
* @param foldLevel level. Level == 1 is the top level
|
||||
@@ -357,12 +370,3 @@ export function setCollapseStateForType(foldingModel: FoldingModel, type: string
|
||||
}
|
||||
foldingModel.toggleCollapseState(toToggle);
|
||||
}
|
||||
|
||||
export const foldBackgroundBackground = registerColor('editor.foldBackground', { light: lighten(editorSelectionBackground, 0.5), dark: darken(editorSelectionBackground, 0.5), hc: null }, nls.localize('editorSelectionBackground', "Color of the editor selection."));
|
||||
|
||||
registerThemingParticipant((theme, collector) => {
|
||||
const foldBackground = theme.getColor(foldBackgroundBackground);
|
||||
if (foldBackground) {
|
||||
collector.addRule(`.monaco-editor .folded-background { background-color: ${foldBackground}; }`);
|
||||
}
|
||||
});
|
||||
|
||||
@@ -66,7 +66,7 @@ export class RangesCollector {
|
||||
// reverse and create arrays of the exact length
|
||||
let startIndexes = new Uint32Array(this._length);
|
||||
let endIndexes = new Uint32Array(this._length);
|
||||
for (let i = this._length - 1, k = 0; i >= 0; i-- , k++) {
|
||||
for (let i = this._length - 1, k = 0; i >= 0; i--, k++) {
|
||||
startIndexes[k] = this._startIndexes[i];
|
||||
endIndexes[k] = this._endIndexes[i];
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the Source EULA. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
import * as assert from 'assert';
|
||||
import { FoldingModel, setCollapseStateAtLevel, setCollapseStateLevelsDown, setCollapseStateLevelsUp, setCollapseStateForMatchingLines } from 'vs/editor/contrib/folding/foldingModel';
|
||||
import { FoldingModel, setCollapseStateAtLevel, setCollapseStateLevelsDown, setCollapseStateLevelsUp, setCollapseStateForMatchingLines, setCollapseStateUp } from 'vs/editor/contrib/folding/foldingModel';
|
||||
import { TextModel, ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
import { computeRanges } from 'vs/editor/contrib/folding/indentRangeProvider';
|
||||
import { TrackedRangeStickiness, IModelDeltaDecoration, ITextModel, IModelDecorationsChangeAccessor } from 'vs/editor/common/model';
|
||||
@@ -587,6 +587,50 @@ suite('Folding Model', () => {
|
||||
|
||||
});
|
||||
|
||||
test('setCollapseStateUp', () => {
|
||||
let lines = [
|
||||
/* 1*/ '//#region',
|
||||
/* 2*/ '//#endregion',
|
||||
/* 3*/ 'class A {',
|
||||
/* 4*/ ' void foo() {',
|
||||
/* 5*/ ' if (true) {',
|
||||
/* 6*/ ' return;',
|
||||
/* 7*/ ' }',
|
||||
/* 8*/ '',
|
||||
/* 9*/ ' if (true) {',
|
||||
/* 10*/ ' return;',
|
||||
/* 11*/ ' }',
|
||||
/* 12*/ ' }',
|
||||
/* 13*/ '}'];
|
||||
|
||||
let textModel = TextModel.createFromString(lines.join('\n'));
|
||||
try {
|
||||
let foldingModel = new FoldingModel(textModel, new TestDecorationProvider(textModel));
|
||||
|
||||
let ranges = computeRanges(textModel, false, { start: /^\/\/#region$/, end: /^\/\/#endregion$/ });
|
||||
foldingModel.update(ranges);
|
||||
|
||||
let r1 = r(1, 2, false);
|
||||
let r2 = r(3, 12, false);
|
||||
let r3 = r(4, 11, false);
|
||||
let r4 = r(5, 6, false);
|
||||
let r5 = r(9, 10, false);
|
||||
assertRanges(foldingModel, [r1, r2, r3, r4, r5]);
|
||||
|
||||
setCollapseStateUp(foldingModel, true, [5]);
|
||||
assertFoldedRanges(foldingModel, [r4], '1');
|
||||
|
||||
setCollapseStateUp(foldingModel, true, [5]);
|
||||
assertFoldedRanges(foldingModel, [r3, r4], '2');
|
||||
|
||||
setCollapseStateUp(foldingModel, true, [4]);
|
||||
assertFoldedRanges(foldingModel, [r2, r3, r4], '2');
|
||||
} finally {
|
||||
textModel.dispose();
|
||||
}
|
||||
|
||||
});
|
||||
|
||||
|
||||
test('setCollapseStateForMatchingLines', () => {
|
||||
let lines = [
|
||||
|
||||
@@ -14,7 +14,7 @@ import { ServicesAccessor } from 'vs/editor/browser/editorExtensions';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ScrollType } 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';
|
||||
@@ -182,7 +182,7 @@ export async function formatDocumentRangeWithProvider(
|
||||
alertFormattingEdits(edits);
|
||||
editorOrModel.pushUndoStop();
|
||||
editorOrModel.focus();
|
||||
editorOrModel.revealPositionInCenterIfOutsideViewport(editorOrModel.getPosition(), editorCommon.ScrollType.Immediate);
|
||||
editorOrModel.revealPositionInCenterIfOutsideViewport(editorOrModel.getPosition(), ScrollType.Immediate);
|
||||
|
||||
} else {
|
||||
// use model to apply edits
|
||||
@@ -272,7 +272,7 @@ export async function formatDocumentWithProvider(
|
||||
alertFormattingEdits(edits);
|
||||
editorOrModel.pushUndoStop();
|
||||
editorOrModel.focus();
|
||||
editorOrModel.revealPositionInCenterIfOutsideViewport(editorOrModel.getPosition(), editorCommon.ScrollType.Immediate);
|
||||
editorOrModel.revealPositionInCenterIfOutsideViewport(editorOrModel.getPosition(), ScrollType.Immediate);
|
||||
}
|
||||
|
||||
} else {
|
||||
|
||||
@@ -12,7 +12,7 @@ import { EditorAction, registerEditorAction, registerEditorContribution, Service
|
||||
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 { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { DocumentRangeFormattingEditProviderRegistry, OnTypeFormattingEditProviderRegistry } from 'vs/editor/common/modes';
|
||||
import { IEditorWorkerService } from 'vs/editor/common/services/editorWorkerService';
|
||||
@@ -26,7 +26,7 @@ import { IInstantiationService } from 'vs/platform/instantiation/common/instanti
|
||||
import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
|
||||
class FormatOnType implements editorCommon.IEditorContribution {
|
||||
class FormatOnType implements IEditorContribution {
|
||||
|
||||
public static readonly ID = 'editor.contrib.autoFormat';
|
||||
|
||||
@@ -149,7 +149,7 @@ class FormatOnType implements editorCommon.IEditorContribution {
|
||||
}
|
||||
}
|
||||
|
||||
class FormatOnPaste implements editorCommon.IEditorContribution {
|
||||
class FormatOnPaste implements IEditorContribution {
|
||||
|
||||
public static readonly ID = 'editor.contrib.formatOnPaste';
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ import { RawContextKey, IContextKey, IContextKeyService } from 'vs/platform/cont
|
||||
import { IMarker, IMarkerService, MarkerSeverity } from 'vs/platform/markers/common/markers';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { registerEditorAction, registerEditorContribution, ServicesAccessor, IActionOptions, EditorAction, EditorCommand, registerEditorCommand } from 'vs/editor/browser/editorExtensions';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
@@ -189,7 +189,7 @@ class MarkerModel {
|
||||
}
|
||||
}
|
||||
|
||||
export class MarkerController implements editorCommon.IEditorContribution {
|
||||
export class MarkerController implements IEditorContribution {
|
||||
|
||||
public static readonly ID = 'editor.contrib.markerController';
|
||||
|
||||
@@ -240,8 +240,8 @@ export class MarkerController implements editorCommon.IEditorContribution {
|
||||
const prevMarkerKeybinding = this._keybindingService.lookupKeybinding(PrevMarkerAction.ID);
|
||||
const nextMarkerKeybinding = this._keybindingService.lookupKeybinding(NextMarkerAction.ID);
|
||||
const actions = [
|
||||
new Action(PrevMarkerAction.ID, PrevMarkerAction.LABEL + (prevMarkerKeybinding ? ` (${prevMarkerKeybinding.getLabel()})` : ''), 'show-previous-problem codicon-chevron-up', this._model.canNavigate(), async () => { if (this._model) { this._model.move(false, true); } }),
|
||||
new Action(NextMarkerAction.ID, NextMarkerAction.LABEL + (nextMarkerKeybinding ? ` (${nextMarkerKeybinding.getLabel()})` : ''), 'show-next-problem codicon-chevron-down', this._model.canNavigate(), async () => { if (this._model) { this._model.move(true, true); } })
|
||||
new Action(NextMarkerAction.ID, NextMarkerAction.LABEL + (nextMarkerKeybinding ? ` (${nextMarkerKeybinding.getLabel()})` : ''), 'show-next-problem codicon-chevron-down', this._model.canNavigate(), async () => { if (this._model) { this._model.move(true, true); } }),
|
||||
new Action(PrevMarkerAction.ID, PrevMarkerAction.LABEL + (prevMarkerKeybinding ? ` (${prevMarkerKeybinding.getLabel()})` : ''), 'show-previous-problem codicon-chevron-up', this._model.canNavigate(), async () => { if (this._model) { this._model.move(false, true); } })
|
||||
];
|
||||
this._widget = new MarkerNavigationWidget(this._editor, actions, this._themeService);
|
||||
this._widgetVisible.set(true);
|
||||
@@ -424,7 +424,7 @@ export class NextMarkerAction extends MarkerNavigationAction {
|
||||
label: NextMarkerAction.LABEL,
|
||||
alias: 'Go to Next Problem (Error, Warning, Info)',
|
||||
precondition: EditorContextKeys.writable,
|
||||
kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyMod.Alt | KeyCode.F8, weight: KeybindingWeight.EditorContrib }
|
||||
kbOpts: { kbExpr: EditorContextKeys.focus, primary: KeyMod.Alt | KeyCode.F8, weight: KeybindingWeight.EditorContrib }
|
||||
});
|
||||
}
|
||||
}
|
||||
@@ -438,7 +438,7 @@ class PrevMarkerAction extends MarkerNavigationAction {
|
||||
label: PrevMarkerAction.LABEL,
|
||||
alias: 'Go to Previous Problem (Error, Warning, Info)',
|
||||
precondition: EditorContextKeys.writable,
|
||||
kbOpts: { kbExpr: EditorContextKeys.editorTextFocus, primary: KeyMod.Shift | KeyMod.Alt | KeyCode.F8, weight: KeybindingWeight.EditorContrib }
|
||||
kbOpts: { kbExpr: EditorContextKeys.focus, primary: KeyMod.Shift | KeyMod.Alt | KeyCode.F8, weight: KeybindingWeight.EditorContrib }
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -228,7 +228,7 @@ export class MarkerNavigationWidget extends PeekViewWidget {
|
||||
|
||||
protected _fillHead(container: HTMLElement): void {
|
||||
super._fillHead(container);
|
||||
this._actionbarWidget!.push(this.actions, { label: false, icon: true });
|
||||
this._actionbarWidget!.push(this.actions, { label: false, icon: true, index: 0 });
|
||||
}
|
||||
|
||||
protected _fillTitleIcon(container: HTMLElement): void {
|
||||
@@ -237,7 +237,7 @@ export class MarkerNavigationWidget extends PeekViewWidget {
|
||||
|
||||
protected _getActionBarOptions(): IActionBarOptions {
|
||||
return {
|
||||
orientation: ActionsOrientation.HORIZONTAL_REVERSE
|
||||
orientation: ActionsOrientation.HORIZONTAL
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -27,7 +27,7 @@ import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegis
|
||||
import { INotificationService } from 'vs/platform/notification/common/notification';
|
||||
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
|
||||
import { getDefinitionsAtPosition, getImplementationsAtPosition, getTypeDefinitionsAtPosition, getDeclarationsAtPosition, getReferencesAtPosition } from './goToSymbol';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { CommandsRegistry, ICommandService } from 'vs/platform/commands/common/commands';
|
||||
import { EditorStateCancellationTokenSource, CodeEditorStateFlag } from 'vs/editor/browser/core/editorState';
|
||||
import { ISymbolNavigationService } from 'vs/editor/contrib/gotoSymbol/symbolNavigation';
|
||||
import { EditorOption, GoToLocationValues } from 'vs/editor/common/config/editorOptions';
|
||||
@@ -681,14 +681,11 @@ registerEditorAction(class PeekReferencesAction extends ReferencesAction {
|
||||
class GenericGoToLocationAction extends SymbolNavigationAction {
|
||||
|
||||
constructor(
|
||||
config: SymbolNavigationActionConfig,
|
||||
private readonly _references: Location[],
|
||||
private readonly _gotoMultipleBehaviour: GoToLocationValues | undefined
|
||||
private readonly _gotoMultipleBehaviour: GoToLocationValues | undefined,
|
||||
) {
|
||||
super({
|
||||
muteMessage: true,
|
||||
openInPeek: false,
|
||||
openToSide: false
|
||||
}, {
|
||||
super(config, {
|
||||
id: 'editor.action.goToLocation',
|
||||
label: nls.localize('label.generic', "Go To Any Symbol"),
|
||||
alias: 'Go To Any Symbol',
|
||||
@@ -725,11 +722,12 @@ CommandsRegistry.registerCommand({
|
||||
{ name: 'multiple', description: 'Define what to do when having multiple results, either `peek`, `gotoAndPeek`, or `goto' },
|
||||
]
|
||||
},
|
||||
handler: async (accessor: ServicesAccessor, resource: any, position: any, references: any, multiple?: any) => {
|
||||
handler: async (accessor: ServicesAccessor, resource: any, position: any, references: any, multiple?: any, openInPeek?: boolean) => {
|
||||
assertType(URI.isUri(resource));
|
||||
assertType(corePosition.Position.isIPosition(position));
|
||||
assertType(Array.isArray(references));
|
||||
assertType(typeof multiple === 'undefined' || typeof multiple === 'string');
|
||||
assertType(typeof openInPeek === 'undefined' || typeof openInPeek === 'boolean');
|
||||
|
||||
const editorService = accessor.get(ICodeEditorService);
|
||||
const editor = await editorService.openCodeEditor({ resource }, editorService.getFocusedCodeEditor());
|
||||
@@ -739,13 +737,29 @@ CommandsRegistry.registerCommand({
|
||||
editor.revealPositionInCenterIfOutsideViewport(position, ScrollType.Smooth);
|
||||
|
||||
return editor.invokeWithinContext(accessor => {
|
||||
const command = new GenericGoToLocationAction(references, multiple as GoToLocationValues);
|
||||
const command = new GenericGoToLocationAction({ muteMessage: true, openInPeek: Boolean(openInPeek), openToSide: false }, references, multiple as GoToLocationValues);
|
||||
accessor.get(IInstantiationService).invokeFunction(command.run.bind(command), editor);
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CommandsRegistry.registerCommand({
|
||||
id: 'editor.action.peekLocations',
|
||||
description: {
|
||||
description: 'Peek locations from a position in a file',
|
||||
args: [
|
||||
{ name: 'uri', description: 'The text document in which to start', constraint: URI },
|
||||
{ name: 'position', description: 'The position at which to start', constraint: corePosition.Position.isIPosition },
|
||||
{ name: 'locations', description: 'An array of locations.', constraint: Array },
|
||||
{ name: 'multiple', description: 'Define what to do when having multiple results, either `peek`, `gotoAndPeek`, or `goto' },
|
||||
]
|
||||
},
|
||||
handler: async (accessor: ServicesAccessor, resource: any, position: any, references: any, multiple?: any) => {
|
||||
accessor.get(ICommandService).executeCommand('editor.action.goToLocations', resource, position, references, multiple, true);
|
||||
}
|
||||
});
|
||||
|
||||
//#endregion
|
||||
|
||||
|
||||
@@ -776,6 +790,6 @@ CommandsRegistry.registerCommand({
|
||||
});
|
||||
|
||||
// use NEW command
|
||||
CommandsRegistry.registerCommandAlias('editor.action.showReferences', 'editor.action.goToLocations');
|
||||
CommandsRegistry.registerCommandAlias('editor.action.showReferences', 'editor.action.peekLocations');
|
||||
|
||||
//#endregion
|
||||
|
||||
@@ -11,7 +11,7 @@ import { onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { MarkdownString } from 'vs/base/common/htmlContent';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { Range, IRange } from 'vs/editor/common/core/range';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { DefinitionProviderRegistry, LocationLink } from 'vs/editor/common/modes';
|
||||
import { ICodeEditor, MouseTargetType } from 'vs/editor/browser/editorBrowser';
|
||||
import { registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
@@ -28,7 +28,7 @@ import { Position } from 'vs/editor/common/core/position';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { IKeyboardEvent } from 'vs/base/browser/keyboardEvent';
|
||||
|
||||
export class GotoDefinitionAtPositionEditorContribution implements editorCommon.IEditorContribution {
|
||||
export class GotoDefinitionAtPositionEditorContribution implements IEditorContribution {
|
||||
|
||||
public static readonly ID = 'editor.contrib.gotodefinitionatposition';
|
||||
static readonly MAX_SOURCE_PREVIEW_LINES = 8;
|
||||
|
||||
@@ -11,7 +11,7 @@ import { IInstantiationService, ServicesAccessor } from 'vs/platform/instantiati
|
||||
import { IContextKey, IContextKeyService, RawContextKey, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
|
||||
import { IStorageService, StorageScope } from 'vs/platform/storage/common/storage';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { ReferencesModel, OneReference } from '../referencesModel';
|
||||
import { ReferenceWidget, LayoutData } from './referencesWidget';
|
||||
@@ -24,10 +24,12 @@ import { getOuterEditor, PeekContext } from 'vs/editor/contrib/peekView/peekView
|
||||
import { IListService, WorkbenchListFocusContextKey } from 'vs/platform/list/browser/listService';
|
||||
import { KeybindingsRegistry, KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
import { KeyCode, KeyMod, KeyChord } from 'vs/base/common/keyCodes';
|
||||
import { CommandsRegistry } from 'vs/platform/commands/common/commands';
|
||||
import { EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
|
||||
export const ctxReferenceSearchVisible = new RawContextKey<boolean>('referenceSearchVisible', false);
|
||||
|
||||
export abstract class ReferencesController implements editorCommon.IEditorContribution {
|
||||
export abstract class ReferencesController implements IEditorContribution {
|
||||
|
||||
static readonly ID = 'editor.contrib.referencesController';
|
||||
|
||||
@@ -162,7 +164,11 @@ export abstract class ReferencesController implements editorCommon.IEditorContri
|
||||
let pos = new Position(range.startLineNumber, range.startColumn);
|
||||
let selection = this._model.nearestReference(uri, pos);
|
||||
if (selection) {
|
||||
return this._widget.setSelection(selection);
|
||||
return this._widget.setSelection(selection).then(() => {
|
||||
if (this._widget && this._editor.getOption(EditorOption.peekWidgetFocusInlineEditor)) {
|
||||
this._widget.focusOnPreviewEditor();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
@@ -200,10 +206,13 @@ export abstract class ReferencesController implements editorCommon.IEditorContri
|
||||
}
|
||||
const target = this._model.nextOrPreviousReference(source, fwd);
|
||||
const editorFocus = this._editor.hasTextFocus();
|
||||
const previewEditorFocus = this._widget.isPreviewEditorFocused();
|
||||
await this._widget.setSelection(target);
|
||||
await this._gotoReference(target);
|
||||
if (editorFocus) {
|
||||
this._editor.focus();
|
||||
} else if (this._widget && previewEditorFocus) {
|
||||
this._widget.focusOnPreviewEditor();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -292,7 +301,7 @@ function withController(accessor: ServicesAccessor, fn: (controller: ReferencesC
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'changePeekFocus',
|
||||
weight: KeybindingWeight.WorkbenchContrib + 50,
|
||||
weight: KeybindingWeight.EditorContrib,
|
||||
primary: KeyChord(KeyMod.CtrlCmd | KeyCode.KEY_K, KeyCode.F2),
|
||||
when: ContextKeyExpr.or(ctxReferenceSearchVisible, PeekContext.inPeekEditor),
|
||||
handler(accessor) {
|
||||
@@ -304,23 +313,10 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'goToNextReference',
|
||||
weight: KeybindingWeight.WorkbenchContrib + 50,
|
||||
weight: KeybindingWeight.EditorContrib - 10,
|
||||
primary: KeyCode.F4,
|
||||
secondary: [KeyCode.F12],
|
||||
when: ctxReferenceSearchVisible,
|
||||
handler(accessor) {
|
||||
withController(accessor, controller => {
|
||||
controller.goToNextOrPreviousReference(true);
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'goToNextReferenceFromEmbeddedEditor',
|
||||
weight: KeybindingWeight.EditorContrib + 50,
|
||||
primary: KeyCode.F4,
|
||||
secondary: [KeyCode.F12],
|
||||
when: PeekContext.inPeekEditor,
|
||||
when: ContextKeyExpr.or(ctxReferenceSearchVisible, PeekContext.inPeekEditor),
|
||||
handler(accessor) {
|
||||
withController(accessor, controller => {
|
||||
controller.goToNextOrPreviousReference(true);
|
||||
@@ -330,10 +326,10 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'goToPreviousReference',
|
||||
weight: KeybindingWeight.WorkbenchContrib + 50,
|
||||
weight: KeybindingWeight.EditorContrib - 10,
|
||||
primary: KeyMod.Shift | KeyCode.F4,
|
||||
secondary: [KeyMod.Shift | KeyCode.F12],
|
||||
when: ctxReferenceSearchVisible,
|
||||
when: ContextKeyExpr.or(ctxReferenceSearchVisible, PeekContext.inPeekEditor),
|
||||
handler(accessor) {
|
||||
withController(accessor, controller => {
|
||||
controller.goToNextOrPreviousReference(false);
|
||||
@@ -341,40 +337,31 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'goToPreviousReferenceFromEmbeddedEditor',
|
||||
weight: KeybindingWeight.EditorContrib + 50,
|
||||
primary: KeyMod.Shift | KeyCode.F4,
|
||||
secondary: [KeyMod.Shift | KeyCode.F12],
|
||||
when: PeekContext.inPeekEditor,
|
||||
handler(accessor) {
|
||||
withController(accessor, controller => {
|
||||
controller.goToNextOrPreviousReference(false);
|
||||
});
|
||||
}
|
||||
});
|
||||
// commands that aren't needed anymore because there is now ContextKeyExpr.OR
|
||||
CommandsRegistry.registerCommandAlias('goToNextReferenceFromEmbeddedEditor', 'goToNextReference');
|
||||
CommandsRegistry.registerCommandAlias('goToPreviousReferenceFromEmbeddedEditor', 'goToPreviousReference');
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
// close
|
||||
CommandsRegistry.registerCommandAlias('closeReferenceSearchEditor', 'closeReferenceSearch');
|
||||
CommandsRegistry.registerCommand(
|
||||
'closeReferenceSearch',
|
||||
accessor => withController(accessor, controller => controller.closeWidget())
|
||||
);
|
||||
KeybindingsRegistry.registerKeybindingRule({
|
||||
id: 'closeReferenceSearch',
|
||||
weight: KeybindingWeight.EditorContrib - 101,
|
||||
primary: KeyCode.Escape,
|
||||
secondary: [KeyMod.Shift | KeyCode.Escape],
|
||||
when: ContextKeyExpr.and(PeekContext.inPeekEditor, ContextKeyExpr.not('config.editor.stablePeek'))
|
||||
});
|
||||
KeybindingsRegistry.registerKeybindingRule({
|
||||
id: 'closeReferenceSearch',
|
||||
weight: KeybindingWeight.WorkbenchContrib + 50,
|
||||
primary: KeyCode.Escape,
|
||||
secondary: [KeyMod.Shift | KeyCode.Escape],
|
||||
when: ContextKeyExpr.and(ctxReferenceSearchVisible, ContextKeyExpr.not('config.editor.stablePeek')),
|
||||
handler(accessor: ServicesAccessor) {
|
||||
withController(accessor, controller => controller.closeWidget());
|
||||
}
|
||||
when: ContextKeyExpr.and(ctxReferenceSearchVisible, ContextKeyExpr.not('config.editor.stablePeek'))
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'closeReferenceSearchEditor',
|
||||
weight: KeybindingWeight.EditorContrib - 101,
|
||||
primary: KeyCode.Escape,
|
||||
secondary: [KeyMod.Shift | KeyCode.Escape],
|
||||
when: ContextKeyExpr.and(PeekContext.inPeekEditor, ContextKeyExpr.not('config.editor.stablePeek')),
|
||||
handler(accessor: ServicesAccessor) {
|
||||
withController(accessor, controller => controller.closeWidget());
|
||||
}
|
||||
});
|
||||
|
||||
KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
id: 'openReferenceToSide',
|
||||
@@ -392,3 +379,11 @@ KeybindingsRegistry.registerCommandAndKeybindingRule({
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
CommandsRegistry.registerCommand('openReference', (accessor) => {
|
||||
const listService = accessor.get(IListService);
|
||||
const focus = <any[]>listService.lastFocusedList?.getFocus();
|
||||
if (Array.isArray(focus) && focus[0] instanceof OneReference) {
|
||||
withController(accessor, controller => controller.openReference(focus[0], false));
|
||||
}
|
||||
});
|
||||
|
||||
@@ -17,7 +17,7 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { EmbeddedCodeEditorWidget } from 'vs/editor/browser/widget/embeddedCodeEditorWidget';
|
||||
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { IModelDeltaDecoration, TrackedRangeStickiness } from 'vs/editor/common/model';
|
||||
import { ModelDecorationOptions, TextModel } from 'vs/editor/common/model/textModel';
|
||||
import { Location } from 'vs/editor/common/modes';
|
||||
@@ -247,7 +247,7 @@ export class ReferenceWidget extends peekView.PeekViewWidget {
|
||||
}
|
||||
|
||||
show(where: IRange) {
|
||||
this.editor.revealRangeInCenterIfOutsideViewport(where, editorCommon.ScrollType.Smooth);
|
||||
this.editor.revealRangeInCenterIfOutsideViewport(where, ScrollType.Smooth);
|
||||
super.show(where, this.layoutData.heightInLines || 18);
|
||||
}
|
||||
|
||||
@@ -526,7 +526,7 @@ export class ReferenceWidget extends peekView.PeekViewWidget {
|
||||
// show in editor
|
||||
const model = ref.object;
|
||||
if (model) {
|
||||
const scrollType = this._preview.getModel() === model.textEditorModel ? editorCommon.ScrollType.Smooth : editorCommon.ScrollType.Immediate;
|
||||
const scrollType = this._preview.getModel() === model.textEditorModel ? ScrollType.Smooth : ScrollType.Immediate;
|
||||
const sel = Range.lift(reference.range).collapseToStart();
|
||||
this._previewModelReference = ref;
|
||||
this._preview.setModel(model.textEditorModel);
|
||||
|
||||
@@ -13,7 +13,7 @@ import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
import { DocumentColorProvider, Hover as MarkdownHover, HoverProviderRegistry, IColor, TokenizationRegistry } from 'vs/editor/common/modes';
|
||||
import { DocumentColorProvider, Hover as MarkdownHover, HoverProviderRegistry, IColor, TokenizationRegistry, CodeActionTriggerType } from 'vs/editor/common/modes';
|
||||
import { getColorPresentations } from 'vs/editor/contrib/colorPicker/color';
|
||||
import { ColorDetector } from 'vs/editor/contrib/colorPicker/colorDetector';
|
||||
import { ColorPickerModel } from 'vs/editor/contrib/colorPicker/colorPickerModel';
|
||||
@@ -34,7 +34,7 @@ import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
|
||||
import { getCodeActions, CodeActionSet } from 'vs/editor/contrib/codeAction/codeAction';
|
||||
import { QuickFixAction, QuickFixController } from 'vs/editor/contrib/codeAction/codeActionCommands';
|
||||
import { CodeActionKind } from 'vs/editor/contrib/codeAction/types';
|
||||
import { CodeActionKind, CodeActionTrigger } from 'vs/editor/contrib/codeAction/types';
|
||||
import { IModeService } from 'vs/editor/common/services/modeService';
|
||||
import { IIdentifiedSingleEditOperation } from 'vs/editor/common/model';
|
||||
import { EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
@@ -186,6 +186,11 @@ class ModesContentComputer implements IHoverComputer<HoverPart[]> {
|
||||
}
|
||||
}
|
||||
|
||||
const markerCodeActionTrigger: CodeActionTrigger = {
|
||||
type: CodeActionTriggerType.Manual,
|
||||
filter: { include: CodeActionKind.QuickFix }
|
||||
};
|
||||
|
||||
export class ModesContentHoverWidget extends ContentHoverWidget {
|
||||
|
||||
static readonly ID = 'editor.contrib.modesContentHoverWidget';
|
||||
@@ -575,7 +580,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
|
||||
showing = true;
|
||||
const controller = QuickFixController.get(this._editor);
|
||||
const elementPosition = dom.getDomNodePagePosition(target);
|
||||
controller.showCodeActions(actions, {
|
||||
controller.showCodeActions(markerCodeActionTrigger, actions, {
|
||||
x: elementPosition.left + 6,
|
||||
y: elementPosition.top + elementPosition.height + 6
|
||||
});
|
||||
@@ -592,7 +597,7 @@ export class ModesContentHoverWidget extends ContentHoverWidget {
|
||||
return getCodeActions(
|
||||
this._editor.getModel()!,
|
||||
new Range(marker.startLineNumber, marker.startColumn, marker.endLineNumber, marker.endColumn),
|
||||
{ type: 'manual', filter: { include: CodeActionKind.QuickFix } },
|
||||
markerCodeActionTrigger,
|
||||
cancellationToken);
|
||||
});
|
||||
}
|
||||
|
||||
@@ -4,11 +4,11 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ICommand, IEditOperationBuilder, ICursorStateComputerData } from 'vs/editor/common/editorCommon';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
|
||||
export class InPlaceReplaceCommand implements editorCommon.ICommand {
|
||||
export class InPlaceReplaceCommand implements ICommand {
|
||||
|
||||
private readonly _editRange: Range;
|
||||
private readonly _originalSelection: Selection;
|
||||
@@ -20,11 +20,11 @@ export class InPlaceReplaceCommand implements editorCommon.ICommand {
|
||||
this._text = text;
|
||||
}
|
||||
|
||||
public getEditOperations(model: ITextModel, builder: editorCommon.IEditOperationBuilder): void {
|
||||
public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {
|
||||
builder.addTrackedEditOperation(this._editRange, this._text);
|
||||
}
|
||||
|
||||
public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {
|
||||
const inverseEditOperations = helper.getInverseEditOperations();
|
||||
const srcRange = inverseEditOperations[0].range;
|
||||
|
||||
|
||||
@@ -5,10 +5,10 @@
|
||||
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection, SelectionDirection } from 'vs/editor/common/core/selection';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { ICommand, IEditOperationBuilder, ICursorStateComputerData } from 'vs/editor/common/editorCommon';
|
||||
import { ITextModel } from 'vs/editor/common/model';
|
||||
|
||||
export class CopyLinesCommand implements editorCommon.ICommand {
|
||||
export class CopyLinesCommand implements ICommand {
|
||||
|
||||
private readonly _selection: Selection;
|
||||
private readonly _isCopyingDown: boolean;
|
||||
@@ -27,7 +27,7 @@ export class CopyLinesCommand implements editorCommon.ICommand {
|
||||
this._endLineNumberDelta = 0;
|
||||
}
|
||||
|
||||
public getEditOperations(model: ITextModel, builder: editorCommon.IEditOperationBuilder): void {
|
||||
public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {
|
||||
let s = this._selection;
|
||||
|
||||
this._startLineNumberDelta = 0;
|
||||
@@ -61,7 +61,7 @@ export class CopyLinesCommand implements editorCommon.ICommand {
|
||||
this._selectionDirection = this._selection.getDirection();
|
||||
}
|
||||
|
||||
public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {
|
||||
let result = helper.getTrackedSelection(this._selectionId!);
|
||||
|
||||
if (this._startLineNumberDelta !== 0 || this._endLineNumberDelta !== 0) {
|
||||
|
||||
@@ -6,10 +6,10 @@
|
||||
import { EditOperation } from 'vs/editor/common/core/editOperation';
|
||||
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 { ICommand, IEditOperationBuilder, ICursorStateComputerData } from 'vs/editor/common/editorCommon';
|
||||
import { IIdentifiedSingleEditOperation, ITextModel } from 'vs/editor/common/model';
|
||||
|
||||
export class SortLinesCommand implements editorCommon.ICommand {
|
||||
export class SortLinesCommand implements ICommand {
|
||||
|
||||
private static _COLLATOR: Intl.Collator | null = null;
|
||||
public static getCollator(): Intl.Collator {
|
||||
@@ -29,7 +29,7 @@ export class SortLinesCommand implements editorCommon.ICommand {
|
||||
this.selectionId = null;
|
||||
}
|
||||
|
||||
public getEditOperations(model: ITextModel, builder: editorCommon.IEditOperationBuilder): void {
|
||||
public getEditOperations(model: ITextModel, builder: IEditOperationBuilder): void {
|
||||
let op = sortLines(model, this.selection, this.descending);
|
||||
if (op) {
|
||||
builder.addEditOperation(op.range, op.text);
|
||||
@@ -38,7 +38,7 @@ export class SortLinesCommand implements editorCommon.ICommand {
|
||||
this.selectionId = builder.trackSelection(this.selection);
|
||||
}
|
||||
|
||||
public computeCursorState(model: ITextModel, helper: editorCommon.ICursorStateComputerData): Selection {
|
||||
public computeCursorState(model: ITextModel, helper: ICursorStateComputerData): Selection {
|
||||
return helper.getTrackedSelection(this.selectionId!);
|
||||
}
|
||||
|
||||
|
||||
@@ -12,6 +12,19 @@ import { ITextModel } from 'vs/editor/common/model';
|
||||
import { TitleCaseAction, DeleteAllLeftAction, DeleteAllRightAction, IndentLinesAction, InsertLineAfterAction, InsertLineBeforeAction, JoinLinesAction, LowerCaseAction, SortLinesAscendingAction, SortLinesDescendingAction, TransposeAction, UpperCaseAction, DeleteLinesAction } from 'vs/editor/contrib/linesOperations/linesOperations';
|
||||
import { withTestCodeEditor } from 'vs/editor/test/browser/testCodeEditor';
|
||||
import { createTextModel } from 'vs/editor/test/common/editorTestUtils';
|
||||
import type { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { EditorAction } from 'vs/editor/browser/editorExtensions';
|
||||
|
||||
function assertSelection(editor: ICodeEditor, expected: Selection | Selection[]): void {
|
||||
if (!Array.isArray(expected)) {
|
||||
expected = [expected];
|
||||
}
|
||||
assert.deepEqual(editor.getSelections(), expected);
|
||||
}
|
||||
|
||||
function executeAction(action: EditorAction, editor: ICodeEditor): void {
|
||||
action.run(null!, editor, undefined);
|
||||
}
|
||||
|
||||
suite('Editor Contrib - Line Operations', () => {
|
||||
suite('SortLinesAscendingAction', () => {
|
||||
@@ -26,13 +39,13 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let sortLinesAscendingAction = new SortLinesAscendingAction();
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 3, 5));
|
||||
sortLinesAscendingAction.run(null!, editor);
|
||||
executeAction(sortLinesAscendingAction, editor);
|
||||
assert.deepEqual(model.getLinesContent(), [
|
||||
'alpha',
|
||||
'beta',
|
||||
'omicron'
|
||||
]);
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 3, 7).toString());
|
||||
assertSelection(editor, new Selection(1, 1, 3, 7));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -51,7 +64,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let sortLinesAscendingAction = new SortLinesAscendingAction();
|
||||
|
||||
editor.setSelections([new Selection(1, 1, 3, 5), new Selection(5, 1, 7, 5)]);
|
||||
sortLinesAscendingAction.run(null!, editor);
|
||||
executeAction(sortLinesAscendingAction, editor);
|
||||
assert.deepEqual(model.getLinesContent(), [
|
||||
'alpha',
|
||||
'beta',
|
||||
@@ -84,13 +97,13 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let sortLinesDescendingAction = new SortLinesDescendingAction();
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 3, 7));
|
||||
sortLinesDescendingAction.run(null!, editor);
|
||||
executeAction(sortLinesDescendingAction, editor);
|
||||
assert.deepEqual(model.getLinesContent(), [
|
||||
'omicron',
|
||||
'beta',
|
||||
'alpha'
|
||||
]);
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 3, 5).toString());
|
||||
assertSelection(editor, new Selection(1, 1, 3, 5));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -109,7 +122,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let sortLinesDescendingAction = new SortLinesDescendingAction();
|
||||
|
||||
editor.setSelections([new Selection(1, 1, 3, 7), new Selection(5, 1, 7, 7)]);
|
||||
sortLinesDescendingAction.run(null!, editor);
|
||||
executeAction(sortLinesDescendingAction, editor);
|
||||
assert.deepEqual(model.getLinesContent(), [
|
||||
'omicron',
|
||||
'beta',
|
||||
@@ -143,13 +156,13 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let deleteAllLeftAction = new DeleteAllLeftAction();
|
||||
|
||||
editor.setSelection(new Selection(1, 2, 1, 2));
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'ne', '001');
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'ne');
|
||||
|
||||
editor.setSelections([new Selection(2, 2, 2, 2), new Selection(3, 2, 3, 2)]);
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(2), 'wo', '002');
|
||||
assert.equal(model.getLineContent(3), 'hree', '003');
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
assert.equal(model.getLineContent(2), 'wo');
|
||||
assert.equal(model.getLineContent(3), 'hree');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -164,16 +177,16 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let deleteAllLeftAction = new DeleteAllLeftAction();
|
||||
|
||||
editor.setSelection(new Selection(2, 1, 2, 1));
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'onetwo', '001');
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'onetwo');
|
||||
|
||||
editor.setSelections([new Selection(1, 1, 1, 1), new Selection(2, 1, 2, 1)]);
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
assert.equal(model.getLinesContent()[0], 'onetwothree');
|
||||
assert.equal(model.getLinesContent().length, 1);
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 1, 1));
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
assert.equal(model.getLinesContent()[0], 'onetwothree');
|
||||
});
|
||||
});
|
||||
@@ -197,7 +210,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
|
||||
editor.setSelections([beforeSecondWasoSelection, endOfBCCSelection, endOfNonono]);
|
||||
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
let selections = editor.getSelections()!;
|
||||
|
||||
assert.equal(model.getLineContent(2), '');
|
||||
@@ -225,7 +238,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
selections[2].endColumn
|
||||
], [5, 1, 5, 1]);
|
||||
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
selections = editor.getSelections()!;
|
||||
|
||||
assert.equal(model.getLineContent(1), 'hi my name is Carlos Matos waso waso');
|
||||
@@ -263,24 +276,24 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let deleteAllLeftAction = new DeleteAllLeftAction();
|
||||
|
||||
editor.setSelections([new Selection(1, 2, 1, 2), new Selection(1, 4, 1, 4)]);
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'lo', '001');
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'lo');
|
||||
|
||||
editor.setSelections([new Selection(2, 2, 2, 2), new Selection(2, 4, 2, 5)]);
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(2), 'd', '002');
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
assert.equal(model.getLineContent(2), 'd');
|
||||
|
||||
editor.setSelections([new Selection(3, 2, 3, 5), new Selection(3, 7, 3, 7)]);
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(3), 'world', '003');
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
assert.equal(model.getLineContent(3), 'world');
|
||||
|
||||
editor.setSelections([new Selection(4, 3, 4, 3), new Selection(4, 5, 5, 4)]);
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(4), 'jour', '004');
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
assert.equal(model.getLineContent(4), 'jour');
|
||||
|
||||
editor.setSelections([new Selection(5, 3, 6, 3), new Selection(6, 5, 7, 5), new Selection(7, 7, 7, 7)]);
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(5), 'world', '005');
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
assert.equal(model.getLineContent(5), 'world');
|
||||
});
|
||||
});
|
||||
|
||||
@@ -300,7 +313,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
assert.equal(model.getLineContent(1), 'Typing some text here on line one');
|
||||
assert.deepEqual(editor.getSelection(), new Selection(1, 31, 1, 31));
|
||||
|
||||
deleteAllLeftAction.run(null!, editor);
|
||||
executeAction(deleteAllLeftAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'one');
|
||||
assert.deepEqual(editor.getSelection(), new Selection(1, 1, 1, 1));
|
||||
|
||||
@@ -331,29 +344,29 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let joinLinesAction = new JoinLinesAction();
|
||||
|
||||
editor.setSelection(new Selection(1, 2, 1, 2));
|
||||
joinLinesAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'hello world', '001');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 6, 1, 6).toString(), '002');
|
||||
executeAction(joinLinesAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'hello world');
|
||||
assertSelection(editor, new Selection(1, 6, 1, 6));
|
||||
|
||||
editor.setSelection(new Selection(2, 2, 2, 2));
|
||||
joinLinesAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(2), 'hello world', '003');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 7, 2, 7).toString(), '004');
|
||||
executeAction(joinLinesAction, editor);
|
||||
assert.equal(model.getLineContent(2), 'hello world');
|
||||
assertSelection(editor, new Selection(2, 7, 2, 7));
|
||||
|
||||
editor.setSelection(new Selection(3, 2, 3, 2));
|
||||
joinLinesAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(3), 'hello world', '005');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(3, 7, 3, 7).toString(), '006');
|
||||
executeAction(joinLinesAction, editor);
|
||||
assert.equal(model.getLineContent(3), 'hello world');
|
||||
assertSelection(editor, new Selection(3, 7, 3, 7));
|
||||
|
||||
editor.setSelection(new Selection(4, 2, 5, 3));
|
||||
joinLinesAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(4), 'hello world', '007');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(4, 2, 4, 8).toString(), '008');
|
||||
executeAction(joinLinesAction, editor);
|
||||
assert.equal(model.getLineContent(4), 'hello world');
|
||||
assertSelection(editor, new Selection(4, 2, 4, 8));
|
||||
|
||||
editor.setSelection(new Selection(5, 1, 7, 3));
|
||||
joinLinesAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(5), 'hello world', '009');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(5, 1, 5, 3).toString(), '010');
|
||||
executeAction(joinLinesAction, editor);
|
||||
assert.equal(model.getLineContent(5), 'hello world');
|
||||
assertSelection(editor, new Selection(5, 1, 5, 3));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -367,10 +380,10 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let joinLinesAction = new JoinLinesAction();
|
||||
|
||||
editor.setSelection(new Selection(2, 1, 2, 1));
|
||||
joinLinesAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'hello', '001');
|
||||
assert.equal(model.getLineContent(2), 'world', '002');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 6, 2, 6).toString(), '003');
|
||||
executeAction(joinLinesAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'hello');
|
||||
assert.equal(model.getLineContent(2), 'world');
|
||||
assertSelection(editor, new Selection(2, 6, 2, 6));
|
||||
});
|
||||
});
|
||||
|
||||
@@ -402,19 +415,16 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
new Selection(10, 1, 10, 1)
|
||||
]);
|
||||
|
||||
joinLinesAction.run(null!, editor);
|
||||
assert.equal(model.getLinesContent().join('\n'), 'hello world\nhello world\nhello world\nhello world\n\nhello world', '001');
|
||||
assert.deepEqual(editor.getSelections()!.toString(), [
|
||||
executeAction(joinLinesAction, editor);
|
||||
assert.equal(model.getLinesContent().join('\n'), 'hello world\nhello world\nhello world\nhello world\n\nhello world');
|
||||
assertSelection(editor, [
|
||||
/** primary cursor */
|
||||
new Selection(3, 4, 3, 8),
|
||||
new Selection(1, 6, 1, 6),
|
||||
new Selection(2, 2, 2, 8),
|
||||
new Selection(4, 5, 4, 9),
|
||||
new Selection(6, 1, 6, 1)
|
||||
].toString(), '002');
|
||||
|
||||
/** primary cursor */
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(3, 4, 3, 8).toString(), '003');
|
||||
]);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -433,7 +443,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
assert.equal(model.getLineContent(1), 'hello my dear');
|
||||
assert.deepEqual(editor.getSelection(), new Selection(1, 14, 1, 14));
|
||||
|
||||
joinLinesAction.run(null!, editor);
|
||||
executeAction(joinLinesAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'hello my dear world');
|
||||
assert.deepEqual(editor.getSelection(), new Selection(1, 14, 1, 14));
|
||||
|
||||
@@ -456,29 +466,29 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let transposeAction = new TransposeAction();
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 1, 1));
|
||||
transposeAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'hello world', '001');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 2, 1, 2).toString(), '002');
|
||||
executeAction(transposeAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'hello world');
|
||||
assertSelection(editor, new Selection(1, 2, 1, 2));
|
||||
|
||||
editor.setSelection(new Selection(1, 6, 1, 6));
|
||||
transposeAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'hell oworld', '003');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 7, 1, 7).toString(), '004');
|
||||
executeAction(transposeAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'hell oworld');
|
||||
assertSelection(editor, new Selection(1, 7, 1, 7));
|
||||
|
||||
editor.setSelection(new Selection(1, 12, 1, 12));
|
||||
transposeAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'hell oworl', '005');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 2, 2, 2).toString(), '006');
|
||||
executeAction(transposeAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'hell oworl');
|
||||
assertSelection(editor, new Selection(2, 2, 2, 2));
|
||||
|
||||
editor.setSelection(new Selection(3, 1, 3, 1));
|
||||
transposeAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(3), '', '007');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(4, 1, 4, 1).toString(), '008');
|
||||
executeAction(transposeAction, editor);
|
||||
assert.equal(model.getLineContent(3), '');
|
||||
assertSelection(editor, new Selection(4, 1, 4, 1));
|
||||
|
||||
editor.setSelection(new Selection(4, 2, 4, 2));
|
||||
transposeAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(4), ' ', '009');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(4, 3, 4, 3).toString(), '010');
|
||||
executeAction(transposeAction, editor);
|
||||
assert.equal(model.getLineContent(4), ' ');
|
||||
assertSelection(editor, new Selection(4, 3, 4, 3));
|
||||
}
|
||||
);
|
||||
|
||||
@@ -498,24 +508,24 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let transposeAction = new TransposeAction();
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 1, 1));
|
||||
transposeAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(2), '', '011');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 1, 2, 1).toString(), '012');
|
||||
executeAction(transposeAction, editor);
|
||||
assert.equal(model.getLineContent(2), '');
|
||||
assertSelection(editor, new Selection(2, 1, 2, 1));
|
||||
|
||||
editor.setSelection(new Selection(3, 6, 3, 6));
|
||||
transposeAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(4), 'oworld', '013');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(4, 2, 4, 2).toString(), '014');
|
||||
executeAction(transposeAction, editor);
|
||||
assert.equal(model.getLineContent(4), 'oworld');
|
||||
assertSelection(editor, new Selection(4, 2, 4, 2));
|
||||
|
||||
editor.setSelection(new Selection(6, 12, 6, 12));
|
||||
transposeAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(7), 'd', '015');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(7, 2, 7, 2).toString(), '016');
|
||||
executeAction(transposeAction, editor);
|
||||
assert.equal(model.getLineContent(7), 'd');
|
||||
assertSelection(editor, new Selection(7, 2, 7, 2));
|
||||
|
||||
editor.setSelection(new Selection(8, 12, 8, 12));
|
||||
transposeAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(8), 'hello world', '019');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(8, 12, 8, 12).toString(), '020');
|
||||
executeAction(transposeAction, editor);
|
||||
assert.equal(model.getLineContent(8), 'hello world');
|
||||
assertSelection(editor, new Selection(8, 12, 8, 12));
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -532,44 +542,44 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let titlecaseAction = new TitleCaseAction();
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 1, 12));
|
||||
uppercaseAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'HELLO WORLD', '001');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 1, 12).toString(), '002');
|
||||
executeAction(uppercaseAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'HELLO WORLD');
|
||||
assertSelection(editor, new Selection(1, 1, 1, 12));
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 1, 12));
|
||||
lowercaseAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'hello world', '003');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 1, 12).toString(), '004');
|
||||
executeAction(lowercaseAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'hello world');
|
||||
assertSelection(editor, new Selection(1, 1, 1, 12));
|
||||
|
||||
editor.setSelection(new Selection(1, 3, 1, 3));
|
||||
uppercaseAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'HELLO world', '005');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 3, 1, 3).toString(), '006');
|
||||
executeAction(uppercaseAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'HELLO world');
|
||||
assertSelection(editor, new Selection(1, 3, 1, 3));
|
||||
|
||||
editor.setSelection(new Selection(1, 4, 1, 4));
|
||||
lowercaseAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'hello world', '007');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 4, 1, 4).toString(), '008');
|
||||
executeAction(lowercaseAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'hello world');
|
||||
assertSelection(editor, new Selection(1, 4, 1, 4));
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 1, 12));
|
||||
titlecaseAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), 'Hello World', '009');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 1, 12).toString(), '010');
|
||||
executeAction(titlecaseAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'Hello World');
|
||||
assertSelection(editor, new Selection(1, 1, 1, 12));
|
||||
|
||||
editor.setSelection(new Selection(2, 1, 2, 6));
|
||||
uppercaseAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(2), 'ÖÇŞĞÜ', '011');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 1, 2, 6).toString(), '012');
|
||||
executeAction(uppercaseAction, editor);
|
||||
assert.equal(model.getLineContent(2), 'ÖÇŞĞÜ');
|
||||
assertSelection(editor, new Selection(2, 1, 2, 6));
|
||||
|
||||
editor.setSelection(new Selection(2, 1, 2, 6));
|
||||
lowercaseAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(2), 'öçşğü', '013');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 1, 2, 6).toString(), '014');
|
||||
executeAction(lowercaseAction, editor);
|
||||
assert.equal(model.getLineContent(2), 'öçşğü');
|
||||
assertSelection(editor, new Selection(2, 1, 2, 6));
|
||||
|
||||
editor.setSelection(new Selection(2, 1, 2, 6));
|
||||
titlecaseAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(2), 'Öçşğü', '015');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 1, 2, 6).toString(), '016');
|
||||
executeAction(titlecaseAction, editor);
|
||||
assert.equal(model.getLineContent(2), 'Öçşğü');
|
||||
assertSelection(editor, new Selection(2, 1, 2, 6));
|
||||
}
|
||||
);
|
||||
|
||||
@@ -586,27 +596,27 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let titlecaseAction = new TitleCaseAction();
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 1, 12));
|
||||
titlecaseAction.run(null!, editor);
|
||||
executeAction(titlecaseAction, editor);
|
||||
assert.equal(model.getLineContent(1), 'Foo Bar Baz');
|
||||
|
||||
editor.setSelection(new Selection(2, 1, 2, 12));
|
||||
titlecaseAction.run(null!, editor);
|
||||
executeAction(titlecaseAction, editor);
|
||||
assert.equal(model.getLineContent(2), 'Foo\'Bar\'Baz');
|
||||
|
||||
editor.setSelection(new Selection(3, 1, 3, 12));
|
||||
titlecaseAction.run(null!, editor);
|
||||
executeAction(titlecaseAction, editor);
|
||||
assert.equal(model.getLineContent(3), 'Foo[Bar]Baz');
|
||||
|
||||
editor.setSelection(new Selection(4, 1, 4, 12));
|
||||
titlecaseAction.run(null!, editor);
|
||||
executeAction(titlecaseAction, editor);
|
||||
assert.equal(model.getLineContent(4), 'Foo`Bar~Baz');
|
||||
|
||||
editor.setSelection(new Selection(5, 1, 5, 12));
|
||||
titlecaseAction.run(null!, editor);
|
||||
executeAction(titlecaseAction, editor);
|
||||
assert.equal(model.getLineContent(5), 'Foo^Bar%Baz');
|
||||
|
||||
editor.setSelection(new Selection(6, 1, 6, 12));
|
||||
titlecaseAction.run(null!, editor);
|
||||
executeAction(titlecaseAction, editor);
|
||||
assert.equal(model.getLineContent(6), 'Foo$Bar!Baz');
|
||||
}
|
||||
);
|
||||
@@ -621,24 +631,24 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let lowercaseAction = new LowerCaseAction();
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 1, 1));
|
||||
uppercaseAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), '', '013');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 1, 1).toString(), '014');
|
||||
executeAction(uppercaseAction, editor);
|
||||
assert.equal(model.getLineContent(1), '');
|
||||
assertSelection(editor, new Selection(1, 1, 1, 1));
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 1, 1));
|
||||
lowercaseAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(1), '', '015');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(1, 1, 1, 1).toString(), '016');
|
||||
executeAction(lowercaseAction, editor);
|
||||
assert.equal(model.getLineContent(1), '');
|
||||
assertSelection(editor, new Selection(1, 1, 1, 1));
|
||||
|
||||
editor.setSelection(new Selection(2, 2, 2, 2));
|
||||
uppercaseAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(2), ' ', '017');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 2, 2, 2).toString(), '018');
|
||||
executeAction(uppercaseAction, editor);
|
||||
assert.equal(model.getLineContent(2), ' ');
|
||||
assertSelection(editor, new Selection(2, 2, 2, 2));
|
||||
|
||||
editor.setSelection(new Selection(2, 2, 2, 2));
|
||||
lowercaseAction.run(null!, editor);
|
||||
assert.equal(model.getLineContent(2), ' ', '019');
|
||||
assert.deepEqual(editor.getSelection()!.toString(), new Selection(2, 2, 2, 2).toString(), '020');
|
||||
executeAction(lowercaseAction, editor);
|
||||
assert.equal(model.getLineContent(2), ' ');
|
||||
assertSelection(editor, new Selection(2, 2, 2, 2));
|
||||
}
|
||||
);
|
||||
});
|
||||
@@ -649,17 +659,17 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
const model = editor.getModel()!;
|
||||
const action = new DeleteAllRightAction();
|
||||
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['']);
|
||||
assert.deepEqual(editor.getSelections(), [new Selection(1, 1, 1, 1)]);
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 1, 1));
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['']);
|
||||
assert.deepEqual(editor.getSelections(), [new Selection(1, 1, 1, 1)]);
|
||||
|
||||
editor.setSelections([new Selection(1, 1, 1, 1), new Selection(1, 1, 1, 1), new Selection(1, 1, 1, 1)]);
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['']);
|
||||
assert.deepEqual(editor.getSelections(), [new Selection(1, 1, 1, 1)]);
|
||||
});
|
||||
@@ -674,17 +684,17 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
const action = new DeleteAllRightAction();
|
||||
|
||||
editor.setSelection(new Selection(1, 2, 1, 5));
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['ho', 'world']);
|
||||
assert.deepEqual(editor.getSelections(), [new Selection(1, 2, 1, 2)]);
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 2, 4));
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['ld']);
|
||||
assert.deepEqual(editor.getSelections(), [new Selection(1, 1, 1, 1)]);
|
||||
|
||||
editor.setSelection(new Selection(1, 1, 1, 3));
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['']);
|
||||
assert.deepEqual(editor.getSelections(), [new Selection(1, 1, 1, 1)]);
|
||||
});
|
||||
@@ -699,12 +709,12 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
const action = new DeleteAllRightAction();
|
||||
|
||||
editor.setSelection(new Selection(1, 3, 1, 3));
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['he', 'world']);
|
||||
assert.deepEqual(editor.getSelections(), [new Selection(1, 3, 1, 3)]);
|
||||
|
||||
editor.setSelection(new Selection(2, 1, 2, 1));
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['he', '']);
|
||||
assert.deepEqual(editor.getSelections(), [new Selection(2, 1, 2, 1)]);
|
||||
});
|
||||
@@ -719,17 +729,17 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
const action = new DeleteAllRightAction();
|
||||
|
||||
editor.setSelection(new Selection(1, 6, 1, 6));
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['helloworld']);
|
||||
assert.deepEqual(editor.getSelections(), [new Selection(1, 6, 1, 6)]);
|
||||
|
||||
editor.setSelection(new Selection(1, 6, 1, 6));
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['hello']);
|
||||
assert.deepEqual(editor.getSelections(), [new Selection(1, 6, 1, 6)]);
|
||||
|
||||
editor.setSelection(new Selection(1, 6, 1, 6));
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['hello']);
|
||||
assert.deepEqual(editor.getSelections(), [new Selection(1, 6, 1, 6)]);
|
||||
});
|
||||
@@ -749,34 +759,34 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
new Selection(1, 6, 1, 6),
|
||||
new Selection(3, 4, 3, 4),
|
||||
]);
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['hethere', 'wor']);
|
||||
assert.deepEqual(editor.getSelections(), [
|
||||
new Selection(1, 3, 1, 3),
|
||||
new Selection(2, 4, 2, 4)
|
||||
]);
|
||||
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['he', 'wor']);
|
||||
assert.deepEqual(editor.getSelections(), [
|
||||
new Selection(1, 3, 1, 3),
|
||||
new Selection(2, 4, 2, 4)
|
||||
]);
|
||||
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['hewor']);
|
||||
assert.deepEqual(editor.getSelections(), [
|
||||
new Selection(1, 3, 1, 3),
|
||||
new Selection(1, 6, 1, 6)
|
||||
]);
|
||||
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['he']);
|
||||
assert.deepEqual(editor.getSelections(), [
|
||||
new Selection(1, 3, 1, 3)
|
||||
]);
|
||||
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['he']);
|
||||
assert.deepEqual(editor.getSelections(), [
|
||||
new Selection(1, 3, 1, 3)
|
||||
@@ -798,7 +808,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
new Selection(1, 6, 1, 6),
|
||||
new Selection(3, 4, 3, 4),
|
||||
]);
|
||||
action.run(null!, editor);
|
||||
executeAction(action, editor);
|
||||
assert.deepEqual(model.getLinesContent(), ['hethere', 'wor']);
|
||||
assert.deepEqual(editor.getSelections(), [
|
||||
new Selection(1, 3, 1, 3),
|
||||
@@ -831,7 +841,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
editor.setPosition(new Position(lineNumber, column));
|
||||
let insertLineBeforeAction = new InsertLineBeforeAction();
|
||||
|
||||
insertLineBeforeAction.run(null!, editor);
|
||||
executeAction(insertLineBeforeAction, editor);
|
||||
callback(editor.getModel()!, cursor);
|
||||
});
|
||||
}
|
||||
@@ -872,7 +882,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
editor.setPosition(new Position(lineNumber, column));
|
||||
let insertLineAfterAction = new InsertLineAfterAction();
|
||||
|
||||
insertLineAfterAction.run(null!, editor);
|
||||
executeAction(insertLineAfterAction, editor);
|
||||
callback(editor.getModel()!, cursor);
|
||||
});
|
||||
}
|
||||
@@ -917,7 +927,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
let indentLinesAction = new IndentLinesAction();
|
||||
editor.setPosition(new Position(1, 2));
|
||||
|
||||
indentLinesAction.run(null!, editor);
|
||||
executeAction(indentLinesAction, editor);
|
||||
assert.equal(model.getLineContent(1), '\tfunction baz() {');
|
||||
assert.deepEqual(editor.getSelection(), new Selection(1, 3, 1, 3));
|
||||
|
||||
@@ -942,7 +952,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
const indentLinesAction = new IndentLinesAction();
|
||||
editor.setPosition(new Position(1, 1));
|
||||
|
||||
indentLinesAction.run(null!, editor);
|
||||
executeAction(indentLinesAction, editor);
|
||||
assert.equal(model.getLineContent(1), '\tSome text');
|
||||
assert.deepEqual(editor.getSelection(), new Selection(1, 2, 1, 2));
|
||||
});
|
||||
@@ -964,7 +974,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
new Selection(3, 4, 3, 4),
|
||||
]);
|
||||
const deleteLinesAction = new DeleteLinesAction();
|
||||
deleteLinesAction.run(null!, editor);
|
||||
executeAction(deleteLinesAction, editor);
|
||||
|
||||
assert.equal(editor.getValue(), 'a\nc');
|
||||
});
|
||||
@@ -976,7 +986,7 @@ suite('Editor Contrib - Line Operations', () => {
|
||||
withTestCodeEditor(initialText, {}, (editor) => {
|
||||
editor.setSelections(initialSelections);
|
||||
const deleteLinesAction = new DeleteLinesAction();
|
||||
deleteLinesAction.run(null!, editor);
|
||||
executeAction(deleteLinesAction, editor);
|
||||
|
||||
assert.equal(editor.getValue(), resultingText.join('\n'));
|
||||
assert.deepEqual(editor.getSelections(), resultingSelections);
|
||||
|
||||
@@ -14,7 +14,7 @@ import * as platform from 'vs/base/common/platform';
|
||||
import { ICodeEditor, MouseTargetType } from 'vs/editor/browser/editorBrowser';
|
||||
import { EditorAction, ServicesAccessor, registerEditorAction, registerEditorContribution } from 'vs/editor/browser/editorExtensions';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { IModelDecorationsChangeAccessor, IModelDeltaDecoration, TrackedRangeStickiness } from 'vs/editor/common/model';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
import { LinkProviderRegistry } from 'vs/editor/common/modes';
|
||||
@@ -97,7 +97,7 @@ class LinkOccurrence {
|
||||
}
|
||||
}
|
||||
|
||||
class LinkDetector implements editorCommon.IEditorContribution {
|
||||
class LinkDetector implements IEditorContribution {
|
||||
|
||||
public static readonly ID: string = 'editor.linkDetector';
|
||||
|
||||
|
||||
@@ -10,7 +10,7 @@ import { KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { IDisposable, Disposable, DisposableStore, MutableDisposable } from 'vs/base/common/lifecycle';
|
||||
import { alert } from 'vs/base/browser/ui/aria/aria';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IEditorContribution, ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { registerEditorContribution, EditorCommand, registerEditorCommand } from 'vs/editor/browser/editorExtensions';
|
||||
import { ICodeEditor, IContentWidget, IContentWidgetPosition, ContentWidgetPositionPreference } from 'vs/editor/browser/editorBrowser';
|
||||
import { IContextKeyService, RawContextKey, IContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
@@ -19,7 +19,7 @@ import { registerThemingParticipant, HIGH_CONTRAST } from 'vs/platform/theme/com
|
||||
import { inputValidationInfoBorder, inputValidationInfoBackground, inputValidationInfoForeground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { KeybindingWeight } from 'vs/platform/keybinding/common/keybindingsRegistry';
|
||||
|
||||
export class MessageController extends Disposable implements editorCommon.IEditorContribution {
|
||||
export class MessageController extends Disposable implements IEditorContribution {
|
||||
|
||||
public static readonly ID = 'editor.contrib.messageController';
|
||||
|
||||
@@ -144,7 +144,7 @@ class MessageWidget implements IContentWidget {
|
||||
constructor(editor: ICodeEditor, { lineNumber, column }: IPosition, text: string) {
|
||||
|
||||
this._editor = editor;
|
||||
this._editor.revealLinesInCenterIfOutsideViewport(lineNumber, lineNumber, editorCommon.ScrollType.Smooth);
|
||||
this._editor.revealLinesInCenterIfOutsideViewport(lineNumber, lineNumber, ScrollType.Smooth);
|
||||
this._position = { lineNumber, column: column - 1 };
|
||||
|
||||
this._domNode = document.createElement('div');
|
||||
|
||||
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#E8E8E8" d="M5.1 5l-.9.9 3.6 3.6 3.9-3.6-1-.9-3 2.7L5.1 5z"/></svg>
|
||||
|
Before Width: | Height: | Size: 139 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#424242" d="M5.1 5l-.9.9 3.6 3.6 3.9-3.6-1-.9-3 2.7L5.1 5z"/></svg>
|
||||
|
Before Width: | Height: | Size: 139 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#E8E8E8" d="M10.8 9.5l.9-.9L8.1 5 4.2 8.6l.9.9 3-2.7 2.7 2.7z"/></svg>
|
||||
|
Before Width: | Height: | Size: 142 B |
@@ -1 +0,0 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 16 16"><path fill="#424242" d="M10.8 9.5l.9-.9L8.1 5 4.2 8.6l.9.9 3-2.7 2.7 2.7z"/></svg>
|
||||
|
Before Width: | Height: | Size: 142 B |
@@ -54,7 +54,7 @@
|
||||
white-space: initial;
|
||||
}
|
||||
|
||||
.monaco-editor .parameter-hints-widget .docs .markdown-docs p code {
|
||||
.monaco-editor .parameter-hints-widget .docs .markdown-docs code {
|
||||
font-family: var(--monaco-monospace-font);
|
||||
}
|
||||
|
||||
@@ -89,11 +89,6 @@
|
||||
|
||||
.monaco-editor .parameter-hints-widget .button.previous {
|
||||
bottom: 24px;
|
||||
background-image: url('arrow-up.svg');
|
||||
}
|
||||
|
||||
.monaco-editor .parameter-hints-widget .button.next {
|
||||
background-image: url('arrow-down.svg');
|
||||
}
|
||||
|
||||
.monaco-editor .parameter-hints-widget .overloads {
|
||||
@@ -113,15 +108,3 @@
|
||||
font-weight: bold;
|
||||
margin-right: 0.5em;
|
||||
}
|
||||
|
||||
/*** VS Dark & High Contrast*/
|
||||
|
||||
.monaco-editor.hc-black .parameter-hints-widget .button.previous,
|
||||
.monaco-editor.vs-dark .parameter-hints-widget .button.previous {
|
||||
background-image: url('arrow-up-dark.svg');
|
||||
}
|
||||
|
||||
.monaco-editor.hc-black .parameter-hints-widget .button.next,
|
||||
.monaco-editor.vs-dark .parameter-hints-widget .button.next {
|
||||
background-image: url('arrow-down-dark.svg');
|
||||
}
|
||||
|
||||
@@ -78,9 +78,9 @@ export class ParameterHintsWidget extends Disposable implements IContentWidget {
|
||||
wrapper.tabIndex = -1;
|
||||
|
||||
const controls = dom.append(wrapper, $('.controls'));
|
||||
const previous = dom.append(controls, $('.button.previous'));
|
||||
const previous = dom.append(controls, $('.button.codicon.codicon-chevron-up'));
|
||||
const overloads = dom.append(controls, $('.overloads'));
|
||||
const next = dom.append(controls, $('.button.next'));
|
||||
const next = dom.append(controls, $('.button.codicon.codicon-chevron-down'));
|
||||
|
||||
const onPreviousClick = stop(domEvent(previous, 'click'));
|
||||
this._register(onPreviousClick(this.previous, this));
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import * as nls from 'vs/nls';
|
||||
import { illegalArgument, onUnexpectedError } from 'vs/base/common/errors';
|
||||
import { KeyMod, KeyCode } from 'vs/base/common/keyCodes';
|
||||
import { IContextKeyService, ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { ContextKeyExpr } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { IEditorProgressService } from 'vs/platform/progress/common/progress';
|
||||
import { registerEditorAction, registerEditorContribution, ServicesAccessor, EditorAction, EditorCommand, registerEditorCommand, registerDefaultLanguageCommand } from 'vs/editor/browser/editorExtensions';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
@@ -14,7 +14,6 @@ import { ITextModel } from 'vs/editor/common/model';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { ICodeEditor } from 'vs/editor/browser/editorBrowser';
|
||||
import { RenameInputField, CONTEXT_RENAME_INPUT_VISIBLE } from './renameInputField';
|
||||
import { IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { WorkspaceEdit, RenameProviderRegistry, RenameProvider, RenameLocation, Rejection } from 'vs/editor/common/modes';
|
||||
import { Position, IPosition } from 'vs/editor/common/core/position';
|
||||
import { alert } from 'vs/base/browser/ui/aria/aria';
|
||||
@@ -30,6 +29,11 @@ import { CancellationToken, CancellationTokenSource } from 'vs/base/common/cance
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { IdleValue, raceCancellation } from 'vs/base/common/async';
|
||||
import { withNullAsUndefined } from 'vs/base/common/types';
|
||||
import { ILogService } from 'vs/platform/log/common/log';
|
||||
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
|
||||
import { Registry } from 'vs/platform/registry/common/platform';
|
||||
import { IConfigurationRegistry, ConfigurationScope, Extensions } from 'vs/platform/configuration/common/configurationRegistry';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/textResourceConfigurationService';
|
||||
|
||||
class RenameSkeleton {
|
||||
|
||||
@@ -109,13 +113,14 @@ class RenameController implements IEditorContribution {
|
||||
|
||||
constructor(
|
||||
private readonly editor: ICodeEditor,
|
||||
@IInstantiationService private readonly _instaService: IInstantiationService,
|
||||
@INotificationService private readonly _notificationService: INotificationService,
|
||||
@IBulkEditService private readonly _bulkEditService: IBulkEditService,
|
||||
@IEditorProgressService private readonly _progressService: IEditorProgressService,
|
||||
@IContextKeyService private readonly _contextKeyService: IContextKeyService,
|
||||
@IThemeService private readonly _themeService: IThemeService,
|
||||
@ILogService private readonly _logService: ILogService,
|
||||
@ITextResourceConfigurationService private readonly _configService: ITextResourceConfigurationService,
|
||||
) {
|
||||
this._renameInputField = new IdleValue(() => this._dispoableStore.add(new RenameInputField(this.editor, this._themeService, this._contextKeyService)));
|
||||
this._renameInputField = this._dispoableStore.add(new IdleValue(() => this._dispoableStore.add(this._instaService.createInstance(RenameInputField, this.editor, ['acceptRenameInput', 'acceptRenameInputWithPreview']))));
|
||||
}
|
||||
|
||||
dispose(): void {
|
||||
@@ -174,11 +179,12 @@ class RenameController implements IEditorContribution {
|
||||
selectionEnd = Math.min(loc.range.endColumn, selection.endColumn) - loc.range.startColumn;
|
||||
}
|
||||
|
||||
const newNameOrFocusFlag = await this._renameInputField.getValue().getInput(loc.range, loc.text, selectionStart, selectionEnd);
|
||||
const supportPreview = this._configService.getValue<boolean>(this.editor.getModel().uri, 'editor.rename.enablePreview');
|
||||
const inputFieldResult = await this._renameInputField.getValue().getInput(loc.range, loc.text, selectionStart, selectionEnd, supportPreview);
|
||||
|
||||
|
||||
if (typeof newNameOrFocusFlag === 'boolean') {
|
||||
if (newNameOrFocusFlag) {
|
||||
// no result, only hint to focus the editor or not
|
||||
if (typeof inputFieldResult === 'boolean') {
|
||||
if (inputFieldResult) {
|
||||
this.editor.focus();
|
||||
}
|
||||
return undefined;
|
||||
@@ -186,7 +192,7 @@ class RenameController implements IEditorContribution {
|
||||
|
||||
this.editor.focus();
|
||||
|
||||
const renameOperation = raceCancellation(skeleton.provideRenameEdits(newNameOrFocusFlag, 0, [], this._cts.token), this._cts.token).then(async renameResult => {
|
||||
const renameOperation = raceCancellation(skeleton.provideRenameEdits(inputFieldResult.newName, 0, [], this._cts.token), this._cts.token).then(async renameResult => {
|
||||
|
||||
if (!renameResult || !this.editor.hasModel()) {
|
||||
return;
|
||||
@@ -197,16 +203,22 @@ class RenameController implements IEditorContribution {
|
||||
return;
|
||||
}
|
||||
|
||||
const editResult = await this._bulkEditService.apply(renameResult, { editor: this.editor });
|
||||
|
||||
// alert
|
||||
if (editResult.ariaSummary) {
|
||||
alert(nls.localize('aria', "Successfully renamed '{0}' to '{1}'. Summary: {2}", loc!.text, newNameOrFocusFlag, editResult.ariaSummary));
|
||||
}
|
||||
this._bulkEditService.apply(renameResult, {
|
||||
editor: this.editor,
|
||||
showPreview: inputFieldResult.wantsPreview,
|
||||
label: nls.localize('label', "Renaming '{0}'", loc?.text)
|
||||
}).then(result => {
|
||||
if (result.ariaSummary) {
|
||||
alert(nls.localize('aria', "Successfully renamed '{0}' to '{1}'. Summary: {2}", loc!.text, inputFieldResult.newName, result.ariaSummary));
|
||||
}
|
||||
}).catch(err => {
|
||||
this._notificationService.error(nls.localize('rename.failedApply', "Rename failed to apply edits"));
|
||||
this._logService.error(err);
|
||||
});
|
||||
|
||||
}, err => {
|
||||
this._notificationService.error(nls.localize('rename.failed', "Rename failed to execute."));
|
||||
return Promise.reject(err);
|
||||
this._notificationService.error(nls.localize('rename.failed', "Rename failed to compute edits"));
|
||||
this._logService.error(err);
|
||||
});
|
||||
|
||||
this._progressService.showWhile(renameOperation, 250);
|
||||
@@ -214,8 +226,8 @@ class RenameController implements IEditorContribution {
|
||||
|
||||
}
|
||||
|
||||
acceptRenameInput(): void {
|
||||
this._renameInputField.getValue().acceptInput();
|
||||
acceptRenameInput(wantsPreview: boolean): void {
|
||||
this._renameInputField.getValue().acceptInput(wantsPreview);
|
||||
}
|
||||
|
||||
cancelRenameInput(): void {
|
||||
@@ -282,7 +294,7 @@ const RenameCommand = EditorCommand.bindToContribution<RenameController>(RenameC
|
||||
registerEditorCommand(new RenameCommand({
|
||||
id: 'acceptRenameInput',
|
||||
precondition: CONTEXT_RENAME_INPUT_VISIBLE,
|
||||
handler: x => x.acceptRenameInput(),
|
||||
handler: x => x.acceptRenameInput(false),
|
||||
kbOpts: {
|
||||
weight: KeybindingWeight.EditorContrib + 99,
|
||||
kbExpr: EditorContextKeys.focus,
|
||||
@@ -290,6 +302,17 @@ registerEditorCommand(new RenameCommand({
|
||||
}
|
||||
}));
|
||||
|
||||
registerEditorCommand(new RenameCommand({
|
||||
id: 'acceptRenameInputWithPreview',
|
||||
precondition: ContextKeyExpr.and(CONTEXT_RENAME_INPUT_VISIBLE, ContextKeyExpr.has('config.editor.rename.enablePreview')),
|
||||
handler: x => x.acceptRenameInput(true),
|
||||
kbOpts: {
|
||||
weight: KeybindingWeight.EditorContrib + 99,
|
||||
kbExpr: EditorContextKeys.focus,
|
||||
primary: KeyMod.Shift + KeyCode.Enter
|
||||
}
|
||||
}));
|
||||
|
||||
registerEditorCommand(new RenameCommand({
|
||||
id: 'cancelRenameInput',
|
||||
precondition: CONTEXT_RENAME_INPUT_VISIBLE,
|
||||
@@ -311,3 +334,17 @@ registerDefaultLanguageCommand('_executeDocumentRenameProvider', function (model
|
||||
}
|
||||
return rename(model, position, newName);
|
||||
});
|
||||
|
||||
|
||||
//todo@joh use editor options world
|
||||
Registry.as<IConfigurationRegistry>(Extensions.Configuration).registerConfiguration({
|
||||
id: 'editor',
|
||||
properties: {
|
||||
'editor.rename.enablePreview': {
|
||||
scope: ConfigurationScope.RESOURCE_LANGUAGE,
|
||||
description: nls.localize('enablePreview', "Enabe/disable the ability to preview changes before renaming"),
|
||||
default: true,
|
||||
type: 'boolean'
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
@@ -8,6 +8,20 @@
|
||||
color: inherit;
|
||||
}
|
||||
|
||||
.monaco-editor .rename-box .rename-input {
|
||||
.monaco-editor .rename-box.preview {
|
||||
padding: 4px;
|
||||
}
|
||||
|
||||
.monaco-editor .rename-box .rename-input {
|
||||
padding: 4px;
|
||||
width: calc(100% - 8px);
|
||||
}
|
||||
|
||||
.monaco-editor .rename-box .rename-label {
|
||||
display: none;
|
||||
opacity: .8;
|
||||
}
|
||||
|
||||
.monaco-editor .rename-box.preview .rename-label {
|
||||
display: inherit;
|
||||
}
|
||||
|
||||
@@ -4,166 +4,185 @@
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import 'vs/css!./renameInputField';
|
||||
import { IDisposable, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition } from 'vs/editor/browser/editorBrowser';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { IRange, Range } from 'vs/editor/common/core/range';
|
||||
import { ScrollType } from 'vs/editor/common/editorCommon';
|
||||
import { localize } from 'vs/nls';
|
||||
import { IContextKey, IContextKeyService, RawContextKey } from 'vs/platform/contextkey/common/contextkey';
|
||||
import { inputBackground, inputBorder, inputForeground, widgetShadow } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { inputBackground, inputBorder, inputForeground, widgetShadow, editorWidgetBackground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { ITheme, IThemeService } from 'vs/platform/theme/common/themeService';
|
||||
import { EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { IKeybindingService } from 'vs/platform/keybinding/common/keybinding';
|
||||
import { toggleClass } from 'vs/base/browser/dom';
|
||||
|
||||
export const CONTEXT_RENAME_INPUT_VISIBLE = new RawContextKey<boolean>('renameInputVisible', false);
|
||||
|
||||
export class RenameInputField implements IContentWidget, IDisposable {
|
||||
export interface RenameInputFieldResult {
|
||||
newName: string;
|
||||
wantsPreview?: boolean;
|
||||
}
|
||||
|
||||
export class RenameInputField implements IContentWidget {
|
||||
|
||||
private _editor: ICodeEditor;
|
||||
private _position?: Position;
|
||||
private _domNode?: HTMLElement;
|
||||
private _inputField?: HTMLInputElement;
|
||||
private _input?: HTMLInputElement;
|
||||
private _label?: HTMLDivElement;
|
||||
private _visible?: boolean;
|
||||
private readonly _visibleContextKey: IContextKey<boolean>;
|
||||
private readonly _disposables = new DisposableStore();
|
||||
|
||||
// Editor.IContentWidget.allowEditorOverflow
|
||||
allowEditorOverflow: boolean = true;
|
||||
readonly allowEditorOverflow: boolean = true;
|
||||
|
||||
constructor(
|
||||
editor: ICodeEditor,
|
||||
private readonly themeService: IThemeService,
|
||||
contextKeyService: IContextKeyService,
|
||||
private readonly _editor: ICodeEditor,
|
||||
private readonly _acceptKeybindings: [string, string],
|
||||
@IThemeService private readonly _themeService: IThemeService,
|
||||
@IKeybindingService private readonly _keybindingService: IKeybindingService,
|
||||
@IContextKeyService contextKeyService: IContextKeyService,
|
||||
) {
|
||||
this._visibleContextKey = CONTEXT_RENAME_INPUT_VISIBLE.bindTo(contextKeyService);
|
||||
|
||||
this._editor = editor;
|
||||
this._editor.addContentWidget(this);
|
||||
|
||||
this._disposables.add(editor.onDidChangeConfiguration(e => {
|
||||
this._disposables.add(this._editor.onDidChangeConfiguration(e => {
|
||||
if (e.hasChanged(EditorOption.fontInfo)) {
|
||||
this.updateFont();
|
||||
this._updateFont();
|
||||
}
|
||||
}));
|
||||
|
||||
this._disposables.add(themeService.onThemeChange(theme => this.onThemeChange(theme)));
|
||||
this._disposables.add(_themeService.onThemeChange(this._updateStyles, this));
|
||||
}
|
||||
|
||||
private onThemeChange(theme: ITheme): void {
|
||||
this.updateStyles(theme);
|
||||
}
|
||||
|
||||
public dispose(): void {
|
||||
dispose(): void {
|
||||
this._disposables.dispose();
|
||||
this._editor.removeContentWidget(this);
|
||||
}
|
||||
|
||||
public getId(): string {
|
||||
getId(): string {
|
||||
return '__renameInputWidget';
|
||||
}
|
||||
|
||||
public getDomNode(): HTMLElement {
|
||||
getDomNode(): HTMLElement {
|
||||
if (!this._domNode) {
|
||||
this._inputField = document.createElement('input');
|
||||
this._inputField.className = 'rename-input';
|
||||
this._inputField.type = 'text';
|
||||
this._inputField.setAttribute('aria-label', localize('renameAriaLabel', "Rename input. Type new name and press Enter to commit."));
|
||||
this._domNode = document.createElement('div');
|
||||
this._domNode.style.height = `${this._editor.getOption(EditorOption.lineHeight)}px`;
|
||||
this._domNode.className = 'monaco-editor rename-box';
|
||||
this._domNode.appendChild(this._inputField);
|
||||
|
||||
this.updateFont();
|
||||
this.updateStyles(this.themeService.getTheme());
|
||||
this._input = document.createElement('input');
|
||||
this._input.className = 'rename-input';
|
||||
this._input.type = 'text';
|
||||
this._input.setAttribute('aria-label', localize('renameAriaLabel', "Rename input. Type new name and press Enter to commit."));
|
||||
this._domNode.appendChild(this._input);
|
||||
|
||||
this._label = document.createElement('div');
|
||||
this._label.className = 'rename-label';
|
||||
this._domNode.appendChild(this._label);
|
||||
const updateLabel = () => {
|
||||
const [accept, preview] = this._acceptKeybindings;
|
||||
this._keybindingService.lookupKeybinding(accept);
|
||||
this._label!.innerText = localize('label', "{0} to Rename, {1} to Preview", this._keybindingService.lookupKeybinding(accept)?.getLabel(), this._keybindingService.lookupKeybinding(preview)?.getLabel());
|
||||
};
|
||||
updateLabel();
|
||||
this._disposables.add(this._keybindingService.onDidUpdateKeybindings(updateLabel));
|
||||
|
||||
this._updateFont();
|
||||
this._updateStyles(this._themeService.getTheme());
|
||||
}
|
||||
return this._domNode;
|
||||
}
|
||||
|
||||
private updateStyles(theme: ITheme): void {
|
||||
if (!this._inputField) {
|
||||
private _updateStyles(theme: ITheme): void {
|
||||
if (!this._input || !this._domNode) {
|
||||
return;
|
||||
}
|
||||
|
||||
const background = theme.getColor(inputBackground);
|
||||
const foreground = theme.getColor(inputForeground);
|
||||
const widgetShadowColor = theme.getColor(widgetShadow);
|
||||
this._domNode.style.backgroundColor = String(theme.getColor(editorWidgetBackground) ?? '');
|
||||
this._domNode.style.boxShadow = widgetShadowColor ? ` 0 2px 8px ${widgetShadowColor}` : '';
|
||||
this._domNode.style.color = String(theme.getColor(inputForeground) ?? '');
|
||||
|
||||
this._input.style.backgroundColor = String(theme.getColor(inputBackground) ?? '');
|
||||
// this._input.style.color = String(theme.getColor(inputForeground) ?? '');
|
||||
const border = theme.getColor(inputBorder);
|
||||
|
||||
this._inputField.style.backgroundColor = background ? background.toString() : '';
|
||||
this._inputField.style.color = foreground ? foreground.toString() : null;
|
||||
|
||||
this._inputField.style.borderWidth = border ? '1px' : '0px';
|
||||
this._inputField.style.borderStyle = border ? 'solid' : 'none';
|
||||
this._inputField.style.borderColor = border ? border.toString() : 'none';
|
||||
|
||||
this._domNode!.style.boxShadow = widgetShadowColor ? ` 0 2px 8px ${widgetShadowColor}` : '';
|
||||
this._input.style.borderWidth = border ? '1px' : '0px';
|
||||
this._input.style.borderStyle = border ? 'solid' : 'none';
|
||||
this._input.style.borderColor = border?.toString() ?? 'none';
|
||||
}
|
||||
|
||||
private updateFont(): void {
|
||||
if (!this._inputField) {
|
||||
private _updateFont(): void {
|
||||
if (!this._input || !this._label) {
|
||||
return;
|
||||
}
|
||||
|
||||
const fontInfo = this._editor.getOption(EditorOption.fontInfo);
|
||||
this._inputField.style.fontFamily = fontInfo.fontFamily;
|
||||
this._inputField.style.fontWeight = fontInfo.fontWeight;
|
||||
this._inputField.style.fontSize = `${fontInfo.fontSize}px`;
|
||||
this._input.style.fontFamily = fontInfo.fontFamily;
|
||||
this._input.style.fontWeight = fontInfo.fontWeight;
|
||||
this._input.style.fontSize = `${fontInfo.fontSize}px`;
|
||||
|
||||
this._label.style.fontSize = `${fontInfo.fontSize * 0.8}px`;
|
||||
}
|
||||
|
||||
public getPosition(): IContentWidgetPosition | null {
|
||||
return this._visible
|
||||
? { position: this._position!, preference: [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE] }
|
||||
: null;
|
||||
getPosition(): IContentWidgetPosition | null {
|
||||
if (!this._visible) {
|
||||
return null;
|
||||
}
|
||||
return {
|
||||
position: this._position!,
|
||||
preference: [ContentWidgetPositionPreference.BELOW, ContentWidgetPositionPreference.ABOVE]
|
||||
};
|
||||
}
|
||||
|
||||
private _currentAcceptInput: (() => void) | null = null;
|
||||
private _currentCancelInput: ((focusEditor: boolean) => void) | null = null;
|
||||
private _currentAcceptInput?: (wantsPreview: boolean) => void;
|
||||
private _currentCancelInput?: (focusEditor: boolean) => void;
|
||||
|
||||
public acceptInput(): void {
|
||||
acceptInput(wantsPreview: boolean): void {
|
||||
if (this._currentAcceptInput) {
|
||||
this._currentAcceptInput();
|
||||
this._currentAcceptInput(wantsPreview);
|
||||
}
|
||||
}
|
||||
|
||||
public cancelInput(focusEditor: boolean): void {
|
||||
cancelInput(focusEditor: boolean): void {
|
||||
if (this._currentCancelInput) {
|
||||
this._currentCancelInput(focusEditor);
|
||||
}
|
||||
}
|
||||
|
||||
public getInput(where: IRange, value: string, selectionStart: number, selectionEnd: number): Promise<string | boolean> {
|
||||
getInput(where: IRange, value: string, selectionStart: number, selectionEnd: number, supportPreview: boolean): Promise<RenameInputFieldResult | boolean> {
|
||||
|
||||
toggleClass(this._domNode!, 'preview', supportPreview);
|
||||
|
||||
this._position = new Position(where.startLineNumber, where.startColumn);
|
||||
this._inputField!.value = value;
|
||||
this._inputField!.setAttribute('selectionStart', selectionStart.toString());
|
||||
this._inputField!.setAttribute('selectionEnd', selectionEnd.toString());
|
||||
this._inputField!.size = Math.max((where.endColumn - where.startColumn) * 1.1, 20);
|
||||
this._input!.value = value;
|
||||
this._input!.setAttribute('selectionStart', selectionStart.toString());
|
||||
this._input!.setAttribute('selectionEnd', selectionEnd.toString());
|
||||
this._input!.size = Math.max((where.endColumn - where.startColumn) * 1.1, 20);
|
||||
|
||||
const disposeOnDone = new DisposableStore();
|
||||
const always = () => {
|
||||
disposeOnDone.dispose();
|
||||
this._hide();
|
||||
};
|
||||
|
||||
return new Promise<string | boolean>(resolve => {
|
||||
return new Promise<RenameInputFieldResult | boolean>(resolve => {
|
||||
|
||||
this._currentCancelInput = (focusEditor) => {
|
||||
this._currentAcceptInput = null;
|
||||
this._currentCancelInput = null;
|
||||
this._currentAcceptInput = undefined;
|
||||
this._currentCancelInput = undefined;
|
||||
resolve(focusEditor);
|
||||
return true;
|
||||
};
|
||||
|
||||
this._currentAcceptInput = () => {
|
||||
if (this._inputField!.value.trim().length === 0 || this._inputField!.value === value) {
|
||||
this._currentAcceptInput = (wantsPreview) => {
|
||||
if (this._input!.value.trim().length === 0 || this._input!.value === value) {
|
||||
// empty or whitespace only or not changed
|
||||
this.cancelInput(true);
|
||||
return;
|
||||
}
|
||||
|
||||
this._currentAcceptInput = null;
|
||||
this._currentCancelInput = null;
|
||||
resolve(this._inputField!.value);
|
||||
this._currentAcceptInput = undefined;
|
||||
this._currentCancelInput = undefined;
|
||||
resolve({
|
||||
newName: this._input!.value,
|
||||
wantsPreview: supportPreview && wantsPreview
|
||||
});
|
||||
};
|
||||
|
||||
let onCursorChanged = () => {
|
||||
@@ -178,12 +197,9 @@ export class RenameInputField implements IContentWidget, IDisposable {
|
||||
|
||||
this._show();
|
||||
|
||||
}).then(newValue => {
|
||||
always();
|
||||
return newValue;
|
||||
}, err => {
|
||||
always();
|
||||
return Promise.reject(err);
|
||||
}).finally(() => {
|
||||
disposeOnDone.dispose();
|
||||
this._hide();
|
||||
});
|
||||
}
|
||||
|
||||
@@ -194,10 +210,10 @@ export class RenameInputField implements IContentWidget, IDisposable {
|
||||
this._editor.layoutContentWidget(this);
|
||||
|
||||
setTimeout(() => {
|
||||
this._inputField!.focus();
|
||||
this._inputField!.setSelectionRange(
|
||||
parseInt(this._inputField!.getAttribute('selectionStart')!),
|
||||
parseInt(this._inputField!.getAttribute('selectionEnd')!));
|
||||
this._input!.focus();
|
||||
this._input!.setSelectionRange(
|
||||
parseInt(this._input!.getAttribute('selectionStart')!),
|
||||
parseInt(this._input!.getAttribute('selectionEnd')!));
|
||||
}, 100);
|
||||
}
|
||||
|
||||
|
||||
@@ -605,7 +605,7 @@ export class SnippetParser {
|
||||
|
||||
// fill in values for placeholders. the first placeholder of an index
|
||||
// that has a value defines the value for all placeholders with that index
|
||||
const placeholderDefaultValues = new Map<number, Marker[]>();
|
||||
const placeholderDefaultValues = new Map<number, Marker[] | undefined>();
|
||||
const incompletePlaceholders: Placeholder[] = [];
|
||||
let placeholderCount = 0;
|
||||
snippet.walk(marker => {
|
||||
|
||||
@@ -162,7 +162,7 @@
|
||||
opacity: 0.66;
|
||||
text-decoration: unset;
|
||||
}
|
||||
.monaco-editor .suggest-widget .monaco-list .monaco-list-row .monaco-icon-label.deprecated > .monaco-icon-label-description-container {
|
||||
.monaco-editor .suggest-widget .monaco-list .monaco-list-row .monaco-icon-label.deprecated > .monaco-icon-label-container > .monaco-icon-name-container {
|
||||
text-decoration: line-through;
|
||||
}
|
||||
|
||||
|
||||
@@ -30,6 +30,7 @@ export class CompletionItem {
|
||||
_brand!: 'ISuggestionItem';
|
||||
|
||||
readonly resolve: (token: CancellationToken) => Promise<void>;
|
||||
isResolved: boolean = false;
|
||||
|
||||
//
|
||||
readonly editStart: IPosition;
|
||||
@@ -47,6 +48,9 @@ export class CompletionItem {
|
||||
idx?: number;
|
||||
word?: string;
|
||||
|
||||
//
|
||||
readonly isDetailsResolved: boolean;
|
||||
|
||||
constructor(
|
||||
readonly position: IPosition,
|
||||
readonly completion: modes.CompletionItem,
|
||||
@@ -70,18 +74,20 @@ export class CompletionItem {
|
||||
this.editReplaceEnd = new Position(completion.range.replace.endLineNumber, completion.range.replace.endColumn);
|
||||
}
|
||||
|
||||
this.isDetailsResolved = container.isDetailsResolved || typeof provider.resolveCompletionItem === 'undefined';
|
||||
|
||||
// create the suggestion resolver
|
||||
const { resolveCompletionItem } = provider;
|
||||
if (typeof resolveCompletionItem !== 'function') {
|
||||
this.resolve = () => Promise.resolve();
|
||||
this.isResolved = true;
|
||||
} else {
|
||||
let cached: Promise<void> | undefined;
|
||||
this.resolve = (token) => {
|
||||
if (!cached) {
|
||||
let isDone = false;
|
||||
cached = Promise.resolve(resolveCompletionItem.call(provider, model, position, completion, token)).then(value => {
|
||||
assign(completion, value);
|
||||
isDone = true;
|
||||
this.isResolved = true;
|
||||
}, err => {
|
||||
if (isPromiseCanceledError(err)) {
|
||||
// the IPC queue will reject the request with the
|
||||
@@ -90,7 +96,7 @@ export class CompletionItem {
|
||||
}
|
||||
});
|
||||
token.onCancellationRequested(() => {
|
||||
if (!isDone) {
|
||||
if (!this.isResolved) {
|
||||
// cancellation after the request has been
|
||||
// dispatched -> reset cache
|
||||
cached = undefined;
|
||||
|
||||
@@ -121,7 +121,7 @@ export class SuggestController implements IEditorContribution {
|
||||
this.editor = editor;
|
||||
this.model = new SuggestModel(this.editor, editorWorker);
|
||||
|
||||
this.widget = new IdleValue(() => {
|
||||
this.widget = this._toDispose.add(new IdleValue(() => {
|
||||
|
||||
const widget = this._instantiationService.createInstance(SuggestWidget, this.editor);
|
||||
|
||||
@@ -165,14 +165,27 @@ export class SuggestController implements IEditorContribution {
|
||||
}));
|
||||
this._toDispose.add(toDisposable(() => makesTextEdit.reset()));
|
||||
|
||||
this._toDispose.add(widget.onDetailsKeyDown(e => {
|
||||
// cmd + c on macOS, ctrl + c on Win / Linux
|
||||
if (
|
||||
e.toKeybinding().equals(new SimpleKeybinding(true, false, false, false, KeyCode.KEY_C)) ||
|
||||
(platform.isMacintosh && e.toKeybinding().equals(new SimpleKeybinding(false, false, false, true, KeyCode.KEY_C)))
|
||||
) {
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!e.toKeybinding().isModifierKey()) {
|
||||
this.editor.focus();
|
||||
}
|
||||
}));
|
||||
|
||||
return widget;
|
||||
});
|
||||
}));
|
||||
|
||||
this._alternatives = new IdleValue(() => {
|
||||
this._alternatives = this._toDispose.add(new IdleValue(() => {
|
||||
return this._toDispose.add(new SuggestAlternatives(this.editor, this._contextKeyService));
|
||||
});
|
||||
}));
|
||||
|
||||
this._toDispose.add(_instantiationService.createInstance(WordContextKey, editor));
|
||||
|
||||
@@ -198,21 +211,6 @@ export class SuggestController implements IEditorContribution {
|
||||
}
|
||||
}));
|
||||
|
||||
this._toDispose.add(this.widget.getValue().onDetailsKeyDown(e => {
|
||||
// cmd + c on macOS, ctrl + c on Win / Linux
|
||||
if (
|
||||
e.toKeybinding().equals(new SimpleKeybinding(true, false, false, false, KeyCode.KEY_C)) ||
|
||||
(platform.isMacintosh && e.toKeybinding().equals(new SimpleKeybinding(false, false, false, true, KeyCode.KEY_C)))
|
||||
) {
|
||||
e.stopPropagation();
|
||||
return;
|
||||
}
|
||||
|
||||
if (!e.toKeybinding().isModifierKey()) {
|
||||
this.editor.focus();
|
||||
}
|
||||
}));
|
||||
|
||||
// Manage the acceptSuggestionsOnEnter context key
|
||||
let acceptSuggestionsOnEnter = SuggestContext.AcceptSuggestionsOnEnter.bindTo(_contextKeyService);
|
||||
let updateFromConfig = () => {
|
||||
|
||||
@@ -22,7 +22,6 @@ import { ConfigurationChangedEvent, EditorOption } from 'vs/editor/common/config
|
||||
import { ContentWidgetPositionPreference, ICodeEditor, IContentWidget, IContentWidgetPosition, IEditorMouseEvent } from 'vs/editor/browser/editorBrowser';
|
||||
import { Context as SuggestContext, CompletionItem } from './suggest';
|
||||
import { CompletionModel } from './completionModel';
|
||||
import { alert } from 'vs/base/browser/ui/aria/aria';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
import { attachListStyler } from 'vs/platform/theme/common/styler';
|
||||
import { IThemeService, ITheme, registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
@@ -89,6 +88,10 @@ function canExpandCompletionItem(item: CompletionItem | null) {
|
||||
return (suggestion.detail && suggestion.detail !== suggestion.label);
|
||||
}
|
||||
|
||||
function getAriaId(index: number): string {
|
||||
return `suggest-aria-id:${index}`;
|
||||
}
|
||||
|
||||
class Renderer implements IListRenderer<CompletionItem, ISuggestionTemplateData> {
|
||||
|
||||
constructor(
|
||||
@@ -133,6 +136,7 @@ class Renderer implements IListRenderer<CompletionItem, ISuggestionTemplateData>
|
||||
const options = this.editor.getOptions();
|
||||
const fontInfo = options.get(EditorOption.fontInfo);
|
||||
const fontFamily = fontInfo.fontFamily;
|
||||
const fontFeatureSettings = fontInfo.fontFeatureSettings;
|
||||
const fontSize = options.get(EditorOption.suggestFontSize) || fontInfo.fontSize;
|
||||
const lineHeight = options.get(EditorOption.suggestLineHeight) || fontInfo.lineHeight;
|
||||
const fontWeight = fontInfo.fontWeight;
|
||||
@@ -142,6 +146,7 @@ class Renderer implements IListRenderer<CompletionItem, ISuggestionTemplateData>
|
||||
data.root.style.fontSize = fontSizePx;
|
||||
data.root.style.fontWeight = fontWeight;
|
||||
main.style.fontFamily = fontFamily;
|
||||
main.style.fontFeatureSettings = fontFeatureSettings;
|
||||
main.style.lineHeight = lineHeightPx;
|
||||
data.icon.style.height = lineHeightPx;
|
||||
data.icon.style.width = lineHeightPx;
|
||||
@@ -158,10 +163,11 @@ class Renderer implements IListRenderer<CompletionItem, ISuggestionTemplateData>
|
||||
return data;
|
||||
}
|
||||
|
||||
renderElement(element: CompletionItem, _index: number, templateData: ISuggestionTemplateData): void {
|
||||
renderElement(element: CompletionItem, index: number, templateData: ISuggestionTemplateData): void {
|
||||
const data = <ISuggestionTemplateData>templateData;
|
||||
const suggestion = (<CompletionItem>element).completion;
|
||||
|
||||
data.root.id = getAriaId(index);
|
||||
data.icon.className = 'icon ' + completionKindToCssClass(suggestion.kind);
|
||||
data.colorspan.style.backgroundColor = '';
|
||||
|
||||
@@ -250,7 +256,6 @@ class SuggestionDetails {
|
||||
private header: HTMLElement;
|
||||
private type: HTMLElement;
|
||||
private docs: HTMLElement;
|
||||
private ariaLabel: string | null;
|
||||
private readonly disposables: DisposableStore;
|
||||
private renderDisposeable?: IDisposable;
|
||||
private borderWidth: number = 1;
|
||||
@@ -279,7 +284,6 @@ class SuggestionDetails {
|
||||
this.type = append(this.header, $('p.type'));
|
||||
|
||||
this.docs = append(this.body, $('p.docs'));
|
||||
this.ariaLabel = null;
|
||||
|
||||
this.configureFont();
|
||||
|
||||
@@ -318,7 +322,6 @@ class SuggestionDetails {
|
||||
this.type.textContent = '';
|
||||
this.docs.textContent = '';
|
||||
addClass(this.el, 'no-docs');
|
||||
this.ariaLabel = null;
|
||||
return;
|
||||
}
|
||||
removeClass(this.el, 'no-docs');
|
||||
@@ -358,15 +361,6 @@ class SuggestionDetails {
|
||||
|
||||
this.body.scrollTop = 0;
|
||||
this.scrollbar.scanDomNode();
|
||||
|
||||
this.ariaLabel = strings.format(
|
||||
'{0}{1}',
|
||||
detail || '',
|
||||
documentation ? (typeof documentation === 'string' ? documentation : documentation.value) : '');
|
||||
}
|
||||
|
||||
getAriaLabel() {
|
||||
return this.ariaLabel;
|
||||
}
|
||||
|
||||
scrollDown(much = 8): void {
|
||||
@@ -409,6 +403,7 @@ class SuggestionDetails {
|
||||
|
||||
this.el.style.fontSize = fontSizePx;
|
||||
this.el.style.fontWeight = fontWeight;
|
||||
this.el.style.fontFeatureSettings = fontInfo.fontFeatureSettings;
|
||||
this.type.style.fontFamily = fontFamily;
|
||||
this.close.style.height = lineHeightPx;
|
||||
this.close.style.width = lineHeightPx;
|
||||
@@ -521,7 +516,22 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
|
||||
this.list = new List('SuggestWidget', this.listElement, this, [renderer], {
|
||||
useShadows: false,
|
||||
openController: { shouldOpen: () => false },
|
||||
mouseSupport: false
|
||||
mouseSupport: false,
|
||||
accessibilityProvider: {
|
||||
getAriaLabel: (item: CompletionItem) => {
|
||||
if (item.isResolved && this.expandDocsSettingFromStorage()) {
|
||||
const { documentation, detail } = item.completion;
|
||||
const docs = strings.format(
|
||||
'{0}{1}',
|
||||
detail || '',
|
||||
documentation ? (typeof documentation === 'string' ? documentation : documentation.value) : '');
|
||||
|
||||
return nls.localize('ariaCurrenttSuggestionReadDetails', "Item {0}, docs: {1}", item.completion.label, docs);
|
||||
} else {
|
||||
return item.completion.label;
|
||||
}
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
this.toDispose.add(attachListStyler(this.list, themeService, {
|
||||
@@ -610,25 +620,6 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
|
||||
this.editor.focus();
|
||||
}
|
||||
|
||||
private _getSuggestionAriaAlertLabel(item: CompletionItem): string {
|
||||
if (this.expandDocsSettingFromStorage()) {
|
||||
return nls.localize('ariaCurrenttSuggestionReadDetails', "Item {0}, docs: {1}", item.completion.label, this.details.getAriaLabel());
|
||||
} else {
|
||||
return item.completion.label;
|
||||
}
|
||||
}
|
||||
|
||||
private _lastAriaAlertLabel: string | null = null;
|
||||
private _ariaAlert(newAriaAlertLabel: string | null): void {
|
||||
if (this._lastAriaAlertLabel === newAriaAlertLabel) {
|
||||
return;
|
||||
}
|
||||
this._lastAriaAlertLabel = newAriaAlertLabel;
|
||||
if (this._lastAriaAlertLabel) {
|
||||
alert(this._lastAriaAlertLabel, true);
|
||||
}
|
||||
}
|
||||
|
||||
private onThemeChange(theme: ITheme) {
|
||||
const backgroundColor = theme.getColor(editorSuggestWidgetBackground);
|
||||
if (backgroundColor) {
|
||||
@@ -662,7 +653,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
|
||||
this.focusedItem = null;
|
||||
}
|
||||
|
||||
this._ariaAlert(null);
|
||||
this.editor.setAriaOptions({ activeDescendant: undefined });
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -711,7 +702,7 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
|
||||
removeClass(this.element, 'docs-side');
|
||||
}
|
||||
|
||||
this._ariaAlert(this._getSuggestionAriaAlertLabel(item));
|
||||
this.editor.setAriaOptions({ activeDescendant: getAriaId(index) });
|
||||
}).catch(onUnexpectedError);
|
||||
}
|
||||
|
||||
@@ -769,7 +760,6 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
|
||||
hide(this.messageElement);
|
||||
show(this.details.element, this.listElement);
|
||||
this.show();
|
||||
this._ariaAlert(this.details.getAriaLabel());
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -989,7 +979,6 @@ export class SuggestWidget implements IContentWidget, IListVirtualDelegate<Compl
|
||||
|
||||
this.updateExpandDocsSetting(true);
|
||||
this.showDetails(false);
|
||||
this._ariaAlert(this.details.getAriaLabel());
|
||||
this.telemetryService.publicLog2('suggestWidget:expandDetails');
|
||||
}
|
||||
}
|
||||
|
||||
@@ -16,7 +16,7 @@ import { CursorChangeReason, ICursorPositionChangedEvent } from 'vs/editor/commo
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Range } from 'vs/editor/common/core/range';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
import * as editorCommon from 'vs/editor/common/editorCommon';
|
||||
import { IEditorContribution } from 'vs/editor/common/editorCommon';
|
||||
import { EditorContextKeys } from 'vs/editor/common/editorContextKeys';
|
||||
import { IModelDeltaDecoration, ITextModel, OverviewRulerLane, TrackedRangeStickiness } from 'vs/editor/common/model';
|
||||
import { ModelDecorationOptions } from 'vs/editor/common/model/textModel';
|
||||
@@ -456,7 +456,7 @@ class WordHighlighter {
|
||||
}
|
||||
}
|
||||
|
||||
class WordHighlighterContribution extends Disposable implements editorCommon.IEditorContribution {
|
||||
class WordHighlighterContribution extends Disposable implements IEditorContribution {
|
||||
|
||||
public static readonly ID = 'editor.contrib.wordHighlighter';
|
||||
|
||||
|
||||
@@ -172,6 +172,7 @@ export class CursorWordLeftSelect extends WordLeftCommand {
|
||||
}
|
||||
}
|
||||
|
||||
// Accessibility navigation commands should only be enabled on windows since they are tuned to what NVDA expects
|
||||
export class CursorWordAccessibilityLeft extends WordLeftCommand {
|
||||
constructor() {
|
||||
super({
|
||||
@@ -181,8 +182,7 @@ export class CursorWordAccessibilityLeft extends WordLeftCommand {
|
||||
precondition: undefined,
|
||||
kbOpts: {
|
||||
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
|
||||
primary: KeyMod.CtrlCmd | KeyCode.LeftArrow,
|
||||
mac: { primary: KeyMod.Alt | KeyCode.LeftArrow },
|
||||
win: { primary: KeyMod.CtrlCmd | KeyCode.LeftArrow },
|
||||
weight: KeybindingWeight.EditorContrib + 1
|
||||
}
|
||||
});
|
||||
@@ -202,8 +202,7 @@ export class CursorWordAccessibilityLeftSelect extends WordLeftCommand {
|
||||
precondition: undefined,
|
||||
kbOpts: {
|
||||
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow,
|
||||
mac: { primary: KeyMod.Alt | KeyMod.Shift | KeyCode.LeftArrow },
|
||||
win: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.LeftArrow },
|
||||
weight: KeybindingWeight.EditorContrib + 1
|
||||
}
|
||||
});
|
||||
@@ -301,8 +300,7 @@ export class CursorWordAccessibilityRight extends WordRightCommand {
|
||||
precondition: undefined,
|
||||
kbOpts: {
|
||||
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
|
||||
primary: KeyMod.CtrlCmd | KeyCode.RightArrow,
|
||||
mac: { primary: KeyMod.Alt | KeyCode.RightArrow },
|
||||
win: { primary: KeyMod.CtrlCmd | KeyCode.RightArrow },
|
||||
weight: KeybindingWeight.EditorContrib + 1
|
||||
}
|
||||
});
|
||||
@@ -322,8 +320,7 @@ export class CursorWordAccessibilityRightSelect extends WordRightCommand {
|
||||
precondition: undefined,
|
||||
kbOpts: {
|
||||
kbExpr: ContextKeyExpr.and(EditorContextKeys.textInputFocus, CONTEXT_ACCESSIBILITY_MODE_ENABLED),
|
||||
primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.RightArrow,
|
||||
mac: { primary: KeyMod.Alt | KeyMod.Shift | KeyCode.RightArrow },
|
||||
win: { primary: KeyMod.CtrlCmd | KeyMod.Shift | KeyCode.RightArrow },
|
||||
weight: KeybindingWeight.EditorContrib + 1
|
||||
}
|
||||
});
|
||||
|
||||
Reference in New Issue
Block a user