feat: prioritize "Add to Context" and add line number tracking (#2063)

- Move "Add to Context" to the top of submenu and code actions for improved accessibility
- Add line number tracking (startLine/endLine) to EditorContext and code actions
- Update templates in support-prompt.ts to include line numbers in file references
- Ensure backward compatibility with existing code

This change improves the UX by making the frequently used "Add to Context" action more accessible and enhances context awareness by tracking and displaying line numbers for selected code.
This commit is contained in:
Sam Hoang Van 2025-03-28 23:01:16 +07:00 committed by GitHub
parent b46f6adb78
commit e7e5511b65
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 53 additions and 27 deletions

View file

@ -185,19 +185,19 @@
],
"roo-code.contextMenu": [
{
"command": "roo-cline.explainCode",
"command": "roo-cline.addToContext",
"group": "1_actions@1"
},
{
"command": "roo-cline.fixCode",
"command": "roo-cline.explainCode",
"group": "1_actions@2"
},
{
"command": "roo-cline.improveCode",
"command": "roo-cline.fixCode",
"group": "1_actions@3"
},
{
"command": "roo-cline.addToContext",
"command": "roo-cline.improveCode",
"group": "1_actions@4"
}
],

View file

@ -53,20 +53,24 @@ const registerCodeAction = (
// Handle both code action and direct command cases.
let filePath: string
let selectedText: string
let startLine: number | undefined
let endLine: number | undefined
let diagnostics: any[] | undefined
if (args.length > 1) {
// Called from code action.
;[filePath, selectedText, diagnostics] = args
;[filePath, selectedText, startLine, endLine, diagnostics] = args
} else {
// Called directly from command palette.
const context = EditorUtils.getEditorContext()
if (!context) return
;({ filePath, selectedText, diagnostics } = context)
;({ filePath, selectedText, startLine, endLine, diagnostics } = context)
}
const params = {
...{ filePath, selectedText },
...(startLine !== undefined ? { startLine: startLine.toString() } : {}),
...(endLine !== undefined ? { endLine: endLine.toString() } : {}),
...(diagnostics ? { diagnostics } : {}),
...(userInput ? { userInput } : {}),
}

View file

@ -56,10 +56,26 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
const filePath = EditorUtils.getFilePath(document)
const actions: vscode.CodeAction[] = []
actions.push(
this.createAction(
ACTION_NAMES.ADD_TO_CONTEXT,
vscode.CodeActionKind.QuickFix,
COMMAND_IDS.ADD_TO_CONTEXT,
[
filePath,
effectiveRange.text,
effectiveRange.range.start.line + 1,
effectiveRange.range.end.line + 1,
],
),
)
actions.push(
...this.createActionPair(ACTION_NAMES.EXPLAIN, vscode.CodeActionKind.QuickFix, COMMAND_IDS.EXPLAIN, [
filePath,
effectiveRange.text,
effectiveRange.range.start.line + 1,
effectiveRange.range.end.line + 1,
]),
)
@ -74,6 +90,8 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
...this.createActionPair(ACTION_NAMES.FIX, vscode.CodeActionKind.QuickFix, COMMAND_IDS.FIX, [
filePath,
effectiveRange.text,
effectiveRange.range.start.line + 1,
effectiveRange.range.end.line + 1,
diagnosticMessages,
]),
)
@ -83,6 +101,8 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
...this.createActionPair(ACTION_NAMES.FIX_LOGIC, vscode.CodeActionKind.QuickFix, COMMAND_IDS.FIX, [
filePath,
effectiveRange.text,
effectiveRange.range.start.line + 1,
effectiveRange.range.end.line + 1,
]),
)
}
@ -92,16 +112,12 @@ export class CodeActionProvider implements vscode.CodeActionProvider {
ACTION_NAMES.IMPROVE,
vscode.CodeActionKind.RefactorRewrite,
COMMAND_IDS.IMPROVE,
[filePath, effectiveRange.text],
),
)
actions.push(
this.createAction(
ACTION_NAMES.ADD_TO_CONTEXT,
vscode.CodeActionKind.QuickFix,
COMMAND_IDS.ADD_TO_CONTEXT,
[filePath, effectiveRange.text],
[
filePath,
effectiveRange.text,
effectiveRange.range.start.line + 1,
effectiveRange.range.end.line + 1,
],
),
)

View file

@ -38,6 +38,10 @@ export interface EditorContext {
filePath: string
/** The effective text selected or derived from the document. */
selectedText: string
/** The starting line number of the selected text (1-based). */
startLine: number
/** The ending line number of the selected text (1-based). */
endLine: number
/** Optional list of diagnostics associated with the effective range. */
diagnostics?: DiagnosticData[]
}
@ -194,6 +198,8 @@ export class EditorUtils {
return {
filePath,
selectedText: effectiveRange.text,
startLine: effectiveRange.range.start.line + 1, // Convert to 1-based line numbers
endLine: effectiveRange.range.end.line + 1, // Convert to 1-based line numbers
...(diagnostics.length > 0 ? { diagnostics } : {}),
}
} catch (error) {

View file

@ -75,13 +75,13 @@ describe("CodeActionProvider", () => {
const actions = provider.provideCodeActions(mockDocument, mockRange, mockContext)
expect(actions).toHaveLength(7) // 2 explain + 2 fix logic + 2 improve + 1 add to context
expect((actions as any)[0].title).toBe(`${ACTION_NAMES.EXPLAIN} in New Task`)
expect((actions as any)[1].title).toBe(`${ACTION_NAMES.EXPLAIN} in Current Task`)
expect((actions as any)[2].title).toBe(`${ACTION_NAMES.FIX_LOGIC} in New Task`)
expect((actions as any)[3].title).toBe(`${ACTION_NAMES.FIX_LOGIC} in Current Task`)
expect((actions as any)[4].title).toBe(`${ACTION_NAMES.IMPROVE} in New Task`)
expect((actions as any)[5].title).toBe(`${ACTION_NAMES.IMPROVE} in Current Task`)
expect((actions as any)[6].title).toBe(ACTION_NAMES.ADD_TO_CONTEXT)
expect((actions as any)[0].title).toBe(ACTION_NAMES.ADD_TO_CONTEXT)
expect((actions as any)[1].title).toBe(`${ACTION_NAMES.EXPLAIN} in New Task`)
expect((actions as any)[2].title).toBe(`${ACTION_NAMES.EXPLAIN} in Current Task`)
expect((actions as any)[3].title).toBe(`${ACTION_NAMES.FIX_LOGIC} in New Task`)
expect((actions as any)[4].title).toBe(`${ACTION_NAMES.FIX_LOGIC} in Current Task`)
expect((actions as any)[5].title).toBe(`${ACTION_NAMES.IMPROVE} in New Task`)
expect((actions as any)[6].title).toBe(`${ACTION_NAMES.IMPROVE} in Current Task`)
})
it("should provide fix action instead of fix logic when diagnostics exist", () => {

View file

@ -35,7 +35,7 @@ const supportPromptConfigs: Record<string, SupportPromptConfig> = {
\${userInput}`,
},
EXPLAIN: {
template: `Explain the following code from file path @/\${filePath}:
template: `Explain the following code from file path @/\${filePath} \${startLine}:\${endLine}
\${userInput}
\`\`\`
@ -48,7 +48,7 @@ Please provide a clear and concise explanation of what this code does, including
3. Important patterns or techniques used`,
},
FIX: {
template: `Fix any issues in the following code from file path @/\${filePath}
template: `Fix any issues in the following code from file path @/\${filePath} \${startLine}:\${endLine}
\${diagnosticText}
\${userInput}
@ -63,7 +63,7 @@ Please:
4. Explain what was fixed and why`,
},
IMPROVE: {
template: `Improve the following code from file path @/\${filePath}:
template: `Improve the following code from file path @/\${filePath} \${startLine}:\${endLine}
\${userInput}
\`\`\`
@ -79,7 +79,7 @@ Please suggest improvements for:
Provide the improved code along with explanations for each enhancement.`,
},
ADD_TO_CONTEXT: {
template: `\${filePath}:
template: `\${filePath}:\${startLine}:\${endLine}
\`\`\`
\${selectedText}
\`\`\``,