mirror of
https://github.com/microsoft/vscode.git
synced 2026-04-24 02:28:34 +01:00
Support addNameToNamelessParameter, refactor copilot code
Not done switching quick fix code to use CompositeCommand instead of passing a followup to ApplyCodeActionCommand.
This commit is contained in:
@@ -18,80 +18,7 @@ import { DiagnosticsManager } from './diagnostics';
|
||||
import FileConfigurationManager from './fileConfigurationManager';
|
||||
import { applyCodeActionCommands, getEditForCodeAction } from './util/codeAction';
|
||||
import { conditionalRegistration, requireSomeCapability } from './util/dependentRegistration';
|
||||
|
||||
type EditorChatReplacementCommand_args = {
|
||||
readonly message: string;
|
||||
readonly document: vscode.TextDocument;
|
||||
readonly diagnostic: vscode.Diagnostic;
|
||||
};
|
||||
|
||||
class EditorChatReplacementCommand implements Command {
|
||||
public static readonly ID = '_typescript.quickFix.editorChatReplacement';
|
||||
public readonly id = EditorChatReplacementCommand.ID;
|
||||
|
||||
constructor( private readonly client: ITypeScriptServiceClient, private readonly diagnosticManager: DiagnosticsManager) {
|
||||
}
|
||||
|
||||
async execute({ message, document, diagnostic }: EditorChatReplacementCommand_args) {
|
||||
this.diagnosticManager.deleteDiagnostic(document.uri, diagnostic);
|
||||
await editorChat(this.client, document, diagnostic.range.start.line, message);
|
||||
}
|
||||
}
|
||||
|
||||
class EditorChatFollowUp implements Command {
|
||||
|
||||
id: string = '_typescript.quickFix.editorChatFollowUp';
|
||||
|
||||
constructor(private readonly prompt: string, private readonly document: vscode.TextDocument, private readonly range: vscode.Range, private readonly client: ITypeScriptServiceClient) {
|
||||
}
|
||||
|
||||
async execute() {
|
||||
await editorChat(this.client, this.document, this.range.start.line, this.prompt);
|
||||
const filepath = this.client.toOpenTsFilePath(this.document);
|
||||
if (!filepath) {
|
||||
return;
|
||||
}
|
||||
const response = await this.client.execute('navtree', { file: filepath }, nulToken);
|
||||
if (response.type !== 'response' || !response.body?.childItems) {
|
||||
return;
|
||||
}
|
||||
const startLine = this.range.start.line;
|
||||
const enclosingRange = findScopeEndLineFromNavTree(startLine, response.body.childItems);
|
||||
if (!enclosingRange) {
|
||||
return;
|
||||
}
|
||||
await vscode.commands.executeCommand('vscode.editorChat.start', { initialRange: enclosingRange, message: this.prompt, autoSend: true });
|
||||
}
|
||||
}
|
||||
|
||||
function findScopeEndLineFromNavTree(startLine: number, navigationTree: Proto.NavigationTree[]): vscode.Range | undefined {
|
||||
for (const node of navigationTree) {
|
||||
const range = typeConverters.Range.fromTextSpan(node.spans[0]);
|
||||
if (startLine === range.start.line) {
|
||||
return range;
|
||||
} else if (startLine > range.start.line && startLine <= range.end.line && node.childItems) {
|
||||
return findScopeEndLineFromNavTree(startLine, node.childItems);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
async function editorChat(client: ITypeScriptServiceClient, document: vscode.TextDocument, startLine: number, message: string) {
|
||||
const filepath = client.toOpenTsFilePath(document);
|
||||
if (!filepath) {
|
||||
return;
|
||||
}
|
||||
const response = await client.execute('navtree', { file: filepath }, nulToken);
|
||||
if (response.type !== 'response' || !response.body?.childItems) {
|
||||
return;
|
||||
}
|
||||
const initialRange = findScopeEndLineFromNavTree(startLine, response.body.childItems);
|
||||
if (!initialRange) {
|
||||
return;
|
||||
}
|
||||
|
||||
await vscode.commands.executeCommand('vscode.editorChat.start', { initialRange, message, autoSend: true });
|
||||
}
|
||||
import { ChatPanelFollowup, EditorChatFollowUp, EditorChatReplacementCommand1, CompositeCommand } from './util/copilot';
|
||||
|
||||
type ApplyCodeActionCommand_args = {
|
||||
readonly document: vscode.TextDocument;
|
||||
@@ -293,9 +220,11 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider<VsCodeCode
|
||||
private readonly diagnosticsManager: DiagnosticsManager,
|
||||
telemetryReporter: TelemetryReporter
|
||||
) {
|
||||
commandManager.register(new CompositeCommand());
|
||||
commandManager.register(new ApplyCodeActionCommand(client, diagnosticsManager, telemetryReporter));
|
||||
commandManager.register(new ApplyFixAllCodeAction(client, telemetryReporter));
|
||||
commandManager.register(new EditorChatReplacementCommand(client, diagnosticsManager));
|
||||
commandManager.register(new EditorChatReplacementCommand1(client, diagnosticsManager));
|
||||
commandManager.register(new ChatPanelFollowup(client));
|
||||
|
||||
this.supportedCodeActionProvider = new SupportedCodeActionProvider(client);
|
||||
}
|
||||
@@ -393,24 +322,51 @@ class TypeScriptQuickFixProvider implements vscode.CodeActionProvider<VsCodeCode
|
||||
tsAction: Proto.CodeFixAction
|
||||
): VsCodeCodeAction[] {
|
||||
const actions: VsCodeCodeAction[] = [];
|
||||
const aiQuickFixEnabled = vscode.workspace.getConfiguration('typescript').get('experimental.aiQuickFix');
|
||||
let followupAction: Command | undefined;
|
||||
if (aiQuickFixEnabled && tsAction.fixName === fixNames.classIncorrectlyImplementsInterface) {
|
||||
followupAction = new EditorChatFollowUp('Implement the class using the interface', document, diagnostic.range, this.client);
|
||||
}
|
||||
else if (aiQuickFixEnabled && tsAction.fixName === fixNames.inferFromUsage) {
|
||||
const inferFromBody = new VsCodeCodeAction(tsAction, 'Copilot: Infer and add types', vscode.CodeActionKind.QuickFix);
|
||||
inferFromBody.edit = new vscode.WorkspaceEdit();
|
||||
inferFromBody.diagnostics = [diagnostic];
|
||||
inferFromBody.command = {
|
||||
command: EditorChatReplacementCommand.ID,
|
||||
arguments: [<EditorChatReplacementCommand_args>{
|
||||
message: 'Add types to this code. Add separate interfaces when possible. Do not change the code except for adding types.',
|
||||
diagnostic,
|
||||
document }],
|
||||
title: ''
|
||||
};
|
||||
actions.push(inferFromBody);
|
||||
if (vscode.workspace.getConfiguration('typescript').get('experimental.aiQuickFix')) {
|
||||
if(tsAction.fixName === fixNames.classIncorrectlyImplementsInterface) {
|
||||
followupAction = new EditorChatFollowUp('Implement the class using the interface', document, diagnostic.range, this.client);
|
||||
}
|
||||
else if (tsAction.fixName === fixNames.inferFromUsage) {
|
||||
const inferFromBody = new VsCodeCodeAction(tsAction, 'Copilot: Infer and add types', vscode.CodeActionKind.QuickFix);
|
||||
inferFromBody.edit = new vscode.WorkspaceEdit();
|
||||
inferFromBody.diagnostics = [diagnostic];
|
||||
inferFromBody.command = {
|
||||
command: EditorChatReplacementCommand1.ID,
|
||||
arguments: [<EditorChatReplacementCommand1.Args>{
|
||||
message: 'Add types to this code. Add separate interfaces when possible. Do not change the code except for adding types.',
|
||||
diagnostic,
|
||||
document }],
|
||||
title: ''
|
||||
};
|
||||
actions.push(inferFromBody);
|
||||
}
|
||||
else if (tsAction.fixName === fixNames.addNameToNamelessParameter) {
|
||||
followupAction = new EditorChatFollowUp('Suggest a better name for this parameter', document, diagnostic.range, this.client);
|
||||
const suggestName = new VsCodeCodeAction(tsAction, 'Add parameter name', vscode.CodeActionKind.QuickFix);
|
||||
suggestName.edit = getEditForCodeAction(this.client, tsAction);
|
||||
suggestName.command = {
|
||||
command: CompositeCommand.ID,
|
||||
arguments: [{
|
||||
command: ApplyCodeActionCommand.ID,
|
||||
arguments: [<ApplyCodeActionCommand_args>{ action: tsAction, diagnostic, document }],
|
||||
title: ''
|
||||
}, {
|
||||
command: ChatPanelFollowup.ID,
|
||||
arguments: [<ChatPanelFollowup.Args>{
|
||||
prompt: `Suggest 5 normal-sounding, useful names for the parameter
|
||||
\`\`\`
|
||||
${document.getText(diagnostic.range)}
|
||||
\`\`\` `,
|
||||
range: diagnostic.range,
|
||||
expand: 'navtree-function',
|
||||
document }],
|
||||
title: ''
|
||||
}],
|
||||
title: '',
|
||||
}
|
||||
return [suggestName]
|
||||
}
|
||||
}
|
||||
const codeAction = new VsCodeCodeAction(tsAction, tsAction.description, vscode.CodeActionKind.QuickFix);
|
||||
codeAction.edit = getEditForCodeAction(this.client, tsAction);
|
||||
|
||||
@@ -20,6 +20,7 @@ import { coalesce } from '../utils/arrays';
|
||||
import { nulToken } from '../utils/cancellation';
|
||||
import FormattingOptionsManager from './fileConfigurationManager';
|
||||
import { conditionalRegistration, requireSomeCapability } from './util/dependentRegistration';
|
||||
import { ChatPanelFollowup, EditorChatReplacementCommand2, CompositeCommand } from './util/copilot';
|
||||
|
||||
function toWorkspaceEdit(client: ITypeScriptServiceClient, edits: readonly Proto.FileCodeEdits[]): vscode.WorkspaceEdit {
|
||||
const workspaceEdit = new vscode.WorkspaceEdit();
|
||||
@@ -34,17 +35,6 @@ function toWorkspaceEdit(client: ITypeScriptServiceClient, edits: readonly Proto
|
||||
}
|
||||
|
||||
|
||||
class CompositeCommand implements Command {
|
||||
public static readonly ID = '_typescript.compositeCommand';
|
||||
public readonly id = CompositeCommand.ID;
|
||||
|
||||
public async execute(...commands: vscode.Command[]): Promise<void> {
|
||||
for (const command of commands) {
|
||||
await vscode.commands.executeCommand(command.command, ...(command.arguments ?? []));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace DidApplyRefactoringCommand {
|
||||
export interface Args {
|
||||
readonly action: string;
|
||||
@@ -396,6 +386,7 @@ class InlinedCodeAction extends vscode.CodeAction {
|
||||
if (response.body.renameLocation) {
|
||||
// Disable renames in interactive playground https://github.com/microsoft/vscode/issues/75137
|
||||
if (this.document.uri.scheme !== fileSchemes.walkThroughSnippet) {
|
||||
console.log("!!!!!!!!!!!!!!!!!!!!!!!!!!" + this.bonus?.command + "!!!!!!!!!!!!!!!!!!")
|
||||
this.command = {
|
||||
command: CompositeCommand.ID,
|
||||
title: '',
|
||||
@@ -467,92 +458,11 @@ class InferTypesAction extends vscode.CodeAction {
|
||||
super(title, vscode.CodeActionKind.Refactor);
|
||||
this.command = {
|
||||
title,
|
||||
command: EditorChatReplacementCommand.ID,
|
||||
arguments: [<EditorChatReplacementCommand.Args>{ message: 'Add types to this code. Add separate interfaces when possible. Do not change the code except for adding types.', document, rangeOrSelection }]
|
||||
command: EditorChatReplacementCommand2.ID,
|
||||
arguments: [<EditorChatReplacementCommand2.Args>{ message: 'Add types to this code. Add separate interfaces when possible. Do not change the code except for adding types.', document, rangeOrSelection }]
|
||||
};
|
||||
}
|
||||
}
|
||||
class EditorChatReplacementCommand implements Command {
|
||||
public static readonly ID = "_typescript.quickFix.editorChatReplacement";
|
||||
public readonly id = EditorChatReplacementCommand.ID;
|
||||
constructor(
|
||||
private readonly client: ITypeScriptServiceClient,
|
||||
) {
|
||||
}
|
||||
async execute({ message, document, rangeOrSelection }: EditorChatReplacementCommand.Args) {
|
||||
// TODO: "this code" is not specific; might get better results with a more specific referent
|
||||
// TODO: Doesn't work in JS files? Is this the span-finder's fault? Try falling back to startLine plus something.
|
||||
// TODO: Need to emit jsdoc in JS files once it's working at all
|
||||
// TODO: When there are "enough" types around, leave off the "Add separate interfaces when possible" because it's not helpful.
|
||||
// (brainstorming: enough non-primitives, or evidence of type aliases in the same file, or imported)
|
||||
await editorChat(this.client, document, rangeOrSelection.start.line, message)
|
||||
}
|
||||
}
|
||||
namespace EditorChatReplacementCommand {
|
||||
export interface Args {
|
||||
readonly message: string;
|
||||
readonly document: vscode.TextDocument;
|
||||
readonly rangeOrSelection: vscode.Range | vscode.Selection;
|
||||
}
|
||||
}
|
||||
function findScopeEndLineFromNavTree(startLine: number, navigationTree: Proto.NavigationTree[]): vscode.Range | undefined {
|
||||
for (const node of navigationTree) {
|
||||
const range = typeConverters.Range.fromTextSpan(node.spans[0]);
|
||||
if (startLine === range.start.line) {
|
||||
return range;
|
||||
} else if (startLine > range.start.line && startLine <= range.end.line && node.childItems) {
|
||||
return findScopeEndLineFromNavTree(startLine, node.childItems);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
async function editorChat(client: ITypeScriptServiceClient, document: vscode.TextDocument, startLine: number, message: string) {
|
||||
const filepath = client.toOpenTsFilePath(document);
|
||||
if (!filepath) {
|
||||
return;
|
||||
}
|
||||
const response = await client.execute('navtree', { file: filepath }, nulToken);
|
||||
if (response.type !== 'response' || !response.body?.childItems) {
|
||||
return;
|
||||
}
|
||||
const initialRange = findScopeEndLineFromNavTree(startLine, response.body.childItems);
|
||||
if (!initialRange) {
|
||||
return;
|
||||
}
|
||||
|
||||
await vscode.commands.executeCommand('vscode.editorChat.start', { initialRange, message, autoSend: true });
|
||||
}
|
||||
namespace ChatPanelFollowup {
|
||||
export interface Args {
|
||||
readonly prompt: string;
|
||||
readonly document: vscode.TextDocument;
|
||||
readonly range: vscode.Range;
|
||||
readonly expand: Expand;
|
||||
}
|
||||
// assuming there is an ast to walk, I'm convinced I can do a more consistent job than the navtree code.
|
||||
export type Expand = 'none' | 'navtree-function' | 'statement' | 'ast-statement'
|
||||
}
|
||||
class ChatPanelFollowup implements Command {
|
||||
public readonly id = ChatPanelFollowup.ID;
|
||||
public static readonly ID: string = '_typescript.refactor.chatPanelFollowUp';
|
||||
|
||||
constructor(private readonly client: ITypeScriptServiceClient) {
|
||||
}
|
||||
|
||||
async execute({ prompt, document, range, expand }: ChatPanelFollowup.Args) {
|
||||
const filepath = this.client.toOpenTsFilePath(document);
|
||||
if (!filepath) {
|
||||
return;
|
||||
}
|
||||
const response = await this.client.execute('navtree', { file: filepath }, nulToken);
|
||||
if (response.type !== 'response' || !response.body?.childItems) {
|
||||
return;
|
||||
}
|
||||
const enclosingRange = expand === 'navtree-function' && findScopeEndLineFromNavTree(range.start.line, response.body.childItems) || range;
|
||||
console.log(JSON.stringify(enclosingRange))
|
||||
vscode.interactive.sendInteractiveRequestToProvider('copilot', { message: prompt, autoSend: true, initialRange: enclosingRange } as any)
|
||||
}
|
||||
}
|
||||
|
||||
type TsCodeAction = InlinedCodeAction | MoveToFileCodeAction | SelectCodeAction | InferTypesAction;
|
||||
|
||||
@@ -568,7 +478,7 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider<TsCodeActi
|
||||
commandManager.register(new CompositeCommand());
|
||||
commandManager.register(new SelectRefactorCommand(this.client));
|
||||
commandManager.register(new MoveToFileRefactorCommand(this.client, didApplyRefactoringCommand));
|
||||
commandManager.register(new EditorChatReplacementCommand(this.client));
|
||||
commandManager.register(new EditorChatReplacementCommand2(this.client));
|
||||
commandManager.register(new ChatPanelFollowup(this.client));
|
||||
}
|
||||
|
||||
@@ -686,27 +596,28 @@ class TypeScriptRefactorProvider implements vscode.CodeActionProvider<TsCodeActi
|
||||
} else {
|
||||
let bonus: vscode.Command | undefined
|
||||
if (vscode.workspace.getConfiguration('typescript', null).get('experimental.aiQuickFix')) {
|
||||
const actionPrefix = action.name.startsWith("constant_")
|
||||
|| action.name.startsWith("function_")
|
||||
|| action.name.startsWith("Extract to")
|
||||
if (actionPrefix) {
|
||||
const kind = action.name.startsWith("constant_") ? "expression"
|
||||
: action.name.startsWith("function_") ? "function"
|
||||
: action.name.startsWith("Extract to") ? "type"
|
||||
: "code";
|
||||
if (action.name.startsWith('constant_')
|
||||
|| action.name.startsWith('function_')
|
||||
|| action.name.startsWith('Extract to')
|
||||
|| action.name.startsWith('Infer function return')) {
|
||||
const kind = action.name.startsWith('constant_') ? 'expression'
|
||||
: action.name.startsWith('function_') ? 'function'
|
||||
: action.name.startsWith('Extract to') ? 'type'
|
||||
: action.name.startsWith('Infer function return') ? 'type'
|
||||
: 'code';
|
||||
bonus = {
|
||||
command: ChatPanelFollowup.ID,
|
||||
arguments: [<ChatPanelFollowup.Args>{
|
||||
prompt: `Suggest 5 names for the ${kind}
|
||||
\`\`\`
|
||||
${document.getText(rangeOrSelection)}.
|
||||
\`\`\`
|
||||
`,
|
||||
\`\`\`
|
||||
${document.getText(rangeOrSelection)}.
|
||||
\`\`\` `,
|
||||
range: rangeOrSelection,
|
||||
expand: 'navtree-function',
|
||||
document }],
|
||||
title: ''
|
||||
}
|
||||
if (action.name.startsWith('Infer function return')) console.log(JSON.stringify(bonus))
|
||||
}
|
||||
}
|
||||
codeAction = new InlinedCodeAction(this.client, document, refactor, action, rangeOrSelection, bonus);
|
||||
|
||||
@@ -0,0 +1,129 @@
|
||||
import * as vscode from 'vscode';
|
||||
import { Command } from '../../commands/commandManager';
|
||||
import { nulToken } from '../../utils/cancellation';
|
||||
import { DiagnosticsManager } from '../diagnostics';
|
||||
import type * as Proto from '../../tsServer/protocol/protocol';
|
||||
import * as typeConverters from '../../typeConverters';
|
||||
import { ITypeScriptServiceClient } from '../../typescriptService';
|
||||
|
||||
// TODO: quick fix version needs to delete the diagnostic (because maybe the followup interferes with it?)
|
||||
// so it needs a diagnostic manager and a diagnostic. The refactor version doesn't need this
|
||||
// (there is tiny bits of code overall so maybe there's a different way to write this)
|
||||
export namespace EditorChatReplacementCommand1 {
|
||||
export type Args = {
|
||||
readonly message: string;
|
||||
readonly document: vscode.TextDocument;
|
||||
readonly diagnostic: vscode.Diagnostic;
|
||||
};
|
||||
}
|
||||
export class EditorChatReplacementCommand1 implements Command {
|
||||
public static readonly ID = '_typescript.quickFix.editorChatReplacement';
|
||||
public readonly id = EditorChatReplacementCommand1.ID;
|
||||
|
||||
constructor( private readonly client: ITypeScriptServiceClient, private readonly diagnosticManager: DiagnosticsManager) {
|
||||
}
|
||||
|
||||
async execute({ message, document, diagnostic }: EditorChatReplacementCommand1.Args) {
|
||||
this.diagnosticManager.deleteDiagnostic(document.uri, diagnostic);
|
||||
const initialRange = await findScopeEndLineFromNavTree(this.client, document, diagnostic.range.start.line);
|
||||
await vscode.commands.executeCommand('vscode.editorChat.start', { initialRange, message, autoSend: true });
|
||||
}
|
||||
}
|
||||
export class EditorChatReplacementCommand2 implements Command {
|
||||
public static readonly ID = "_typescript.quickFix.editorChatReplacement";
|
||||
public readonly id = EditorChatReplacementCommand2.ID;
|
||||
constructor(
|
||||
private readonly client: ITypeScriptServiceClient,
|
||||
) {
|
||||
}
|
||||
async execute({ message, document, rangeOrSelection }: EditorChatReplacementCommand2.Args) {
|
||||
// TODO: "this code" is not specific; might get better results with a more specific referent
|
||||
// TODO: Doesn't work in JS files? Is this the span-finder's fault? Try falling back to startLine plus something.
|
||||
// TODO: Need to emit jsdoc in JS files once it's working at all
|
||||
// TODO: When there are "enough" types around, leave off the "Add separate interfaces when possible" because it's not helpful.
|
||||
// (brainstorming: enough non-primitives, or evidence of type aliases in the same file, or imported)
|
||||
const initialRange = await findScopeEndLineFromNavTree(this.client, document, rangeOrSelection.start.line)
|
||||
await vscode.commands.executeCommand('vscode.editorChat.start', { initialRange, message, autoSend: true });
|
||||
}
|
||||
}
|
||||
export namespace EditorChatReplacementCommand2 {
|
||||
export interface Args {
|
||||
readonly message: string;
|
||||
readonly document: vscode.TextDocument;
|
||||
readonly rangeOrSelection: vscode.Range | vscode.Selection;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
export class EditorChatFollowUp implements Command {
|
||||
|
||||
id: string = '_typescript.quickFix.editorChatFollowUp';
|
||||
|
||||
constructor(private readonly prompt: string, private readonly document: vscode.TextDocument, private readonly range: vscode.Range, private readonly client: ITypeScriptServiceClient) {
|
||||
}
|
||||
|
||||
async execute() {
|
||||
const initialRange = await findScopeEndLineFromNavTree(this.client, this.document, this.range.start.line);
|
||||
await vscode.commands.executeCommand('vscode.editorChat.start', { initialRange, message: this.prompt, autoSend: true });
|
||||
}
|
||||
}
|
||||
|
||||
export function findScopeEndLineFromNavTreeWorker(startLine: number, navigationTree: Proto.NavigationTree[]): vscode.Range | undefined {
|
||||
for (const node of navigationTree) {
|
||||
const range = typeConverters.Range.fromTextSpan(node.spans[0]);
|
||||
if (startLine === range.start.line) {
|
||||
return range;
|
||||
} else if (startLine > range.start.line && startLine <= range.end.line && node.childItems) {
|
||||
return findScopeEndLineFromNavTreeWorker(startLine, node.childItems);
|
||||
}
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export async function findScopeEndLineFromNavTree(client: ITypeScriptServiceClient, document: vscode.TextDocument, startLine: number) {
|
||||
const filepath = client.toOpenTsFilePath(document);
|
||||
if (!filepath) {
|
||||
return;
|
||||
}
|
||||
const response = await client.execute('navtree', { file: filepath }, nulToken);
|
||||
if (response.type !== 'response' || !response.body?.childItems) {
|
||||
return;
|
||||
}
|
||||
return findScopeEndLineFromNavTreeWorker(startLine, response.body.childItems);
|
||||
}
|
||||
|
||||
export namespace ChatPanelFollowup {
|
||||
export interface Args {
|
||||
readonly prompt: string;
|
||||
readonly document: vscode.TextDocument;
|
||||
readonly range: vscode.Range;
|
||||
readonly expand: Expand;
|
||||
}
|
||||
// assuming there is an ast to walk, I'm convinced I can do a more consistent job than the navtree code.
|
||||
export type Expand = 'none' | 'navtree-function' | 'statement' | 'ast-statement'
|
||||
}
|
||||
export class ChatPanelFollowup implements Command {
|
||||
public readonly id = ChatPanelFollowup.ID;
|
||||
public static readonly ID: string = '_typescript.refactor.chatPanelFollowUp';
|
||||
|
||||
constructor(private readonly client: ITypeScriptServiceClient) {
|
||||
}
|
||||
|
||||
async execute({ prompt, document, range, expand }: ChatPanelFollowup.Args) {
|
||||
console.log("-------------------------------" + prompt + "------------------------------")
|
||||
const enclosingRange = expand === 'navtree-function' && findScopeEndLineFromNavTree(this.client, document, range.start.line) || range;
|
||||
vscode.interactive.sendInteractiveRequestToProvider('copilot', { message: prompt, autoSend: true, initialRange: enclosingRange } as any)
|
||||
}
|
||||
}
|
||||
|
||||
export class CompositeCommand implements Command {
|
||||
public static readonly ID = '_typescript.compositeCommand';
|
||||
public readonly id = CompositeCommand.ID;
|
||||
|
||||
public async execute(...commands: vscode.Command[]): Promise<void> {
|
||||
for (const command of commands) {
|
||||
await vscode.commands.executeCommand(command.command, ...(command.arguments ?? []));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,5 +17,6 @@ export const forgottenThisPropertyAccess = 'forgottenThisPropertyAccess';
|
||||
export const removeUnnecessaryAwait = 'removeUnnecessaryAwait';
|
||||
export const spelling = 'spelling';
|
||||
export const inferFromUsage = 'inferFromUsage';
|
||||
export const addNameToNamelessParameter = 'addNameToNamelessParameter';
|
||||
export const unreachableCode = 'fixUnreachableCode';
|
||||
export const unusedIdentifier = 'unusedIdentifier';
|
||||
|
||||
Reference in New Issue
Block a user