CodeActionProvider.ts 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112
  1. import * as vscode from "vscode"
  2. import { EditorUtils } from "./EditorUtils"
  3. export const ACTION_NAMES = {
  4. EXPLAIN: "Roo Code: Explain Code",
  5. FIX: "Roo Code: Fix Code",
  6. FIX_LOGIC: "Roo Code: Fix Logic",
  7. IMPROVE: "Roo Code: Improve Code",
  8. ADD_TO_CONTEXT: "Roo Code: Add to Context",
  9. } as const
  10. export const COMMAND_IDS = {
  11. EXPLAIN: "roo-cline.explainCode",
  12. FIX: "roo-cline.fixCode",
  13. IMPROVE: "roo-cline.improveCode",
  14. ADD_TO_CONTEXT: "roo-cline.addToContext",
  15. } as const
  16. export class CodeActionProvider implements vscode.CodeActionProvider {
  17. public static readonly providedCodeActionKinds = [
  18. vscode.CodeActionKind.QuickFix,
  19. vscode.CodeActionKind.RefactorRewrite,
  20. ]
  21. private createAction(title: string, kind: vscode.CodeActionKind, command: string, args: any[]): vscode.CodeAction {
  22. const action = new vscode.CodeAction(title, kind)
  23. action.command = { command, title, arguments: args }
  24. return action
  25. }
  26. private createActionPair(
  27. baseTitle: string,
  28. kind: vscode.CodeActionKind,
  29. baseCommand: string,
  30. args: any[],
  31. ): vscode.CodeAction[] {
  32. return [
  33. this.createAction(`${baseTitle} in New Task`, kind, baseCommand, args),
  34. this.createAction(`${baseTitle} in Current Task`, kind, `${baseCommand}InCurrentTask`, args),
  35. ]
  36. }
  37. public provideCodeActions(
  38. document: vscode.TextDocument,
  39. range: vscode.Range | vscode.Selection,
  40. context: vscode.CodeActionContext,
  41. ): vscode.ProviderResult<(vscode.CodeAction | vscode.Command)[]> {
  42. try {
  43. const effectiveRange = EditorUtils.getEffectiveRange(document, range)
  44. if (!effectiveRange) {
  45. return []
  46. }
  47. const filePath = EditorUtils.getFilePath(document)
  48. const actions: vscode.CodeAction[] = []
  49. actions.push(
  50. ...this.createActionPair(ACTION_NAMES.EXPLAIN, vscode.CodeActionKind.QuickFix, COMMAND_IDS.EXPLAIN, [
  51. filePath,
  52. effectiveRange.text,
  53. ]),
  54. )
  55. if (context.diagnostics.length > 0) {
  56. const relevantDiagnostics = context.diagnostics.filter((d) =>
  57. EditorUtils.hasIntersectingRange(effectiveRange.range, d.range),
  58. )
  59. if (relevantDiagnostics.length > 0) {
  60. const diagnosticMessages = relevantDiagnostics.map(EditorUtils.createDiagnosticData)
  61. actions.push(
  62. ...this.createActionPair(ACTION_NAMES.FIX, vscode.CodeActionKind.QuickFix, COMMAND_IDS.FIX, [
  63. filePath,
  64. effectiveRange.text,
  65. diagnosticMessages,
  66. ]),
  67. )
  68. }
  69. } else {
  70. actions.push(
  71. ...this.createActionPair(ACTION_NAMES.FIX_LOGIC, vscode.CodeActionKind.QuickFix, COMMAND_IDS.FIX, [
  72. filePath,
  73. effectiveRange.text,
  74. ]),
  75. )
  76. }
  77. actions.push(
  78. ...this.createActionPair(
  79. ACTION_NAMES.IMPROVE,
  80. vscode.CodeActionKind.RefactorRewrite,
  81. COMMAND_IDS.IMPROVE,
  82. [filePath, effectiveRange.text],
  83. ),
  84. )
  85. actions.push(
  86. this.createAction(
  87. ACTION_NAMES.ADD_TO_CONTEXT,
  88. vscode.CodeActionKind.QuickFix,
  89. COMMAND_IDS.ADD_TO_CONTEXT,
  90. [filePath, effectiveRange.text],
  91. ),
  92. )
  93. return actions
  94. } catch (error) {
  95. console.error("Error providing code actions:", error)
  96. return []
  97. }
  98. }
  99. }