mirror of
https://github.com/Microsoft/vscode
synced 2024-10-04 02:14:06 +00:00
telemetry for lightbulb and move to code actions (#211323)
* first pass on new telemetry * change click condition to when there are 2 or fewer code actions, list out the code actions * remove excessive calls * cleanup * also log the code action providers * change owner to me * change title to provider
This commit is contained in:
parent
84d2ef91c5
commit
a8823c333e
|
@ -273,7 +273,7 @@ export async function applyCodeAction(
|
|||
codeActionKind: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The kind (refactor, quickfix) of the applied code action' };
|
||||
codeActionIsPreferred: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Was the code action marked as being a preferred action?' };
|
||||
reason: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The kind of action used to trigger apply code action.' };
|
||||
owner: 'mjbvz';
|
||||
owner: 'justschen';
|
||||
comment: 'Event used to gain insights into which code actions are being triggered';
|
||||
};
|
||||
|
||||
|
|
|
@ -39,6 +39,7 @@ import { registerThemingParticipant } from 'vs/platform/theme/common/themeServic
|
|||
import { CodeActionAutoApply, CodeActionFilter, CodeActionItem, CodeActionKind, CodeActionSet, CodeActionTrigger, CodeActionTriggerSource } from 'vs/editor/contrib/codeAction/common/types';
|
||||
import { CodeActionModel, CodeActionsState } from 'vs/editor/contrib/codeAction/browser/codeActionModel';
|
||||
import { HierarchicalKind } from 'vs/base/common/hierarchicalKind';
|
||||
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
|
||||
|
||||
|
||||
interface IActionShowOptions {
|
||||
|
@ -79,6 +80,7 @@ export class CodeActionController extends Disposable implements IEditorContribut
|
|||
@IConfigurationService private readonly _configurationService: IConfigurationService,
|
||||
@IActionWidgetService private readonly _actionWidgetService: IActionWidgetService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@ITelemetryService private readonly _telemetryService: ITelemetryService
|
||||
) {
|
||||
super();
|
||||
|
||||
|
@ -105,6 +107,29 @@ export class CodeActionController extends Disposable implements IEditorContribut
|
|||
}
|
||||
|
||||
private async showCodeActionsFromLightbulb(actions: CodeActionSet, at: IAnchor | IPosition): Promise<void> {
|
||||
|
||||
// Telemetry for showing code actions from lightbulb. Shows us how often it was clicked.
|
||||
type ShowCodeActionListEvent = {
|
||||
codeActionListLength: number;
|
||||
codeActions: string[];
|
||||
codeActionProviders: string[];
|
||||
};
|
||||
|
||||
type ShowListEventClassification = {
|
||||
codeActionListLength: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The length of the code action list from the lightbulb widget.' };
|
||||
codeActions: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The title of code actions in this menu.' };
|
||||
codeActionProviders: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The provider of code actions in this menu.' };
|
||||
owner: 'justschen';
|
||||
comment: 'Event used to gain insights into what code actions are being shown';
|
||||
};
|
||||
|
||||
this._telemetryService.publicLog2<ShowCodeActionListEvent, ShowListEventClassification>('codeAction.showCodeActionsFromLightbulb', {
|
||||
codeActionListLength: actions.validActions.length,
|
||||
codeActions: actions.validActions.map(action => action.action.title),
|
||||
codeActionProviders: actions.validActions.map(action => action.provider?.displayName ?? ''),
|
||||
});
|
||||
|
||||
|
||||
if (actions.allAIFixes && actions.validActions.length === 1) {
|
||||
const actionItem = actions.validActions[0];
|
||||
const command = actionItem.action.command;
|
||||
|
@ -280,13 +305,32 @@ export class CodeActionController extends Disposable implements IEditorContribut
|
|||
|
||||
const delegate: IActionListDelegate<CodeActionItem> = {
|
||||
onSelect: async (action: CodeActionItem, preview?: boolean) => {
|
||||
this._applyCodeAction(action, /* retrigger */ true, !!preview, ApplyCodeActionReason.FromCodeActions);
|
||||
this._actionWidgetService.hide();
|
||||
this._applyCodeAction(action, /* retrigger */ true, !!preview, options.fromLightbulb ? ApplyCodeActionReason.FromAILightbulb : ApplyCodeActionReason.FromCodeActions);
|
||||
this._actionWidgetService.hide(false);
|
||||
currentDecorations.clear();
|
||||
},
|
||||
onHide: () => {
|
||||
onHide: (didCancel?) => {
|
||||
this._editor?.focus();
|
||||
currentDecorations.clear();
|
||||
// Telemetry for showing code actions here. only log on `showLightbulb`. Logs when code action list is quit out.
|
||||
if (options.fromLightbulb && didCancel !== undefined) {
|
||||
type ShowCodeActionListEvent = {
|
||||
codeActionListLength: number;
|
||||
didCancel: boolean;
|
||||
};
|
||||
|
||||
type ShowListEventClassification = {
|
||||
codeActionListLength: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'The length of the code action list when quit out. Can be from any code action menu.' };
|
||||
didCancel: { classification: 'SystemMetaData'; purpose: 'FeatureInsight'; comment: 'Whether the code action was cancelled or selected.' };
|
||||
owner: 'justschen';
|
||||
comment: 'Event used to gain insights into how many valid code actions are being shown';
|
||||
};
|
||||
|
||||
this._telemetryService.publicLog2<ShowCodeActionListEvent, ShowListEventClassification>('codeAction.showCodeActionList.onHide', {
|
||||
codeActionListLength: actions.validActions.length,
|
||||
didCancel: didCancel,
|
||||
});
|
||||
}
|
||||
},
|
||||
onHover: async (action: CodeActionItem, token: CancellationToken) => {
|
||||
if (token.isCancellationRequested) {
|
||||
|
|
|
@ -36,7 +36,7 @@ export interface IActionWidgetService {
|
|||
|
||||
show<T>(user: string, supportsPreview: boolean, items: readonly IActionListItem<T>[], delegate: IActionListDelegate<T>, anchor: IAnchor, container: HTMLElement | undefined, actionBarActions?: readonly IAction[]): void;
|
||||
|
||||
hide(): void;
|
||||
hide(didCancel?: boolean): void;
|
||||
|
||||
readonly isVisible: boolean;
|
||||
}
|
||||
|
@ -87,8 +87,8 @@ class ActionWidgetService extends Disposable implements IActionWidgetService {
|
|||
this._list?.value?.focusNext();
|
||||
}
|
||||
|
||||
hide() {
|
||||
this._list.value?.hide();
|
||||
hide(didCancel?: boolean) {
|
||||
this._list.value?.hide(didCancel);
|
||||
this._list.clear();
|
||||
}
|
||||
|
||||
|
@ -139,7 +139,7 @@ class ActionWidgetService extends Disposable implements IActionWidgetService {
|
|||
widget.style.width = `${width}px`;
|
||||
|
||||
const focusTracker = renderDisposables.add(dom.trackFocus(element));
|
||||
renderDisposables.add(focusTracker.onDidBlur(() => this.hide()));
|
||||
renderDisposables.add(focusTracker.onDidBlur(() => this.hide(true)));
|
||||
|
||||
return renderDisposables;
|
||||
}
|
||||
|
@ -179,7 +179,7 @@ registerAction2(class extends Action2 {
|
|||
}
|
||||
|
||||
run(accessor: ServicesAccessor): void {
|
||||
accessor.get(IActionWidgetService).hide();
|
||||
accessor.get(IActionWidgetService).hide(true);
|
||||
}
|
||||
});
|
||||
|
||||
|
|
Loading…
Reference in a new issue