Skip to content

Commit

Permalink
Bug fixes and cleanups suggested in PR 440
Browse files Browse the repository at this point in the history
  • Loading branch information
steveyegge committed Mar 20, 2024
1 parent 4c7fbaa commit e7f1b5a
Show file tree
Hide file tree
Showing 15 changed files with 137 additions and 230 deletions.
35 changes: 17 additions & 18 deletions CONTRIBUTING.md
Original file line number Diff line number Diff line change
Expand Up @@ -358,27 +358,26 @@ agent, to rebuild it first.

## Debugging VS Code

Sometimes, the Agent behaves differently when called from IntelliJ than
when called from VS Code, and you may need to debug the same code paths
through the Agent twice. First, when called from the JetBrains extension
side, and again when called from the VS Code extension side.

To accomplish the latter, you can use VSC to debug itself. It works very
similarly to how it works in JetBrains. There are predefined run
configurations for debugging VSC Cody in the file `.vscode/launch.json`
in `sourcegraph/cody`, such as `Launch VS Code Extension (Desktop)`.

You do not launch VSC run configurations from the command palette.
Sometimes, the TypeScript backend behaves differently when called from
IntelliJ via Agent than when the same code is called from the VS Code
extension, and you may need to debug the same code paths through the
Agent twice. First, when called from the JetBrains extension side, and
again when called from the VS Code extension side.

To accomplish the latter, you can use VS Code to debug itself. It works
very similarly to how it works in JetBrains. There are predefined run
configurations for debugging VS Code Cody in the file
`.vscode/launch.json` in `sourcegraph/cody`, such as `Launch VS Code
Extension (Desktop)`.

You do not launch VS Code run configurations from the command palette.
Instead, use ctrl-shift-D to open the Run and Debug view, and you can
see the configuration dropdown at the top.

## Known Issues

- Force-stopping the target often corrupts the indexes, requiring an
extra restart of the debugged target to fix them.
- Workaround is to exit the target gracefully by quitting each time.


- Force-stopping the target often corrupts IntelliJ's project indexes,
requiring an extra restart of the debugged target to fix them.
- Workaround is to exit the target gracefully by quitting each time,
using the menus or hotkeys, rather than force-stopping it.

One workaround is to quit the target instance gracefully from its
own menus/hotkeys (e.g. ⌘-Q), rather than force-stopping it.
20 changes: 0 additions & 20 deletions src/main/java/com/sourcegraph/cody/agent/CodyAgentClient.java
Original file line number Diff line number Diff line change
Expand Up @@ -42,9 +42,6 @@ public class CodyAgentClient {
// Callback for the "textDocument/edit" request from the agent.
@Nullable private Consumer<TextDocumentEditParams> onTextDocumentEdit;

// Callback for the "workspace/executeCommand" request from the agent.
@Nullable private Consumer<DisplayCodeLensParams> onDisplayCodeLens;

// Callback for the "workspace/edit" request from the agent.
@Nullable private Consumer<WorkspaceEditParams> onWorkspaceEdit;

Expand Down Expand Up @@ -99,23 +96,6 @@ public CompletableFuture<Boolean> textDocumentEdit(TextDocumentEditParams params
});
}

public void setOnDisplayCodeLens(@Nullable Consumer<DisplayCodeLensParams> callback) {
onDisplayCodeLens = callback;
}

@JsonNotification("codeLenses/display")
public void codeLensesDisplay(DisplayCodeLensParams params) {
onEventThread(
() -> {
if (onDisplayCodeLens != null) {
onDisplayCodeLens.accept(params);
} else {
logger.warn("No callback registered for codeLenses/display");
}
return null;
});
}

public void setOnWorkspaceEdit(@Nullable Consumer<WorkspaceEditParams> callback) {
onWorkspaceEdit = callback;
}
Expand Down
6 changes: 0 additions & 6 deletions src/main/kotlin/com/sourcegraph/cody/agent/CodyAgentServer.kt
Original file line number Diff line number Diff line change
Expand Up @@ -67,12 +67,6 @@ interface CodyAgentServer {
@JsonRequest("webview/receiveMessage")
fun webviewReceiveMessage(params: WebviewReceiveMessageParams): CompletableFuture<Any?>

@JsonRequest("editTask/accept") fun editTaskAccept(id: String): CompletableFuture<Any?>

@JsonRequest("editTask/undo") fun editTaskUndo(id: String): CompletableFuture<Any?>

@JsonRequest("editTask/cancel") fun editTaskCancel(id: String): CompletableFuture<Any?>

@JsonRequest("editTask/getFoldingRanges")
fun getFoldingRanges(params: GetFoldingRangeParams): CompletableFuture<GetFoldingRangeResult>

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,5 @@ data class ClientCapabilities(
var progressBars: String? = null,
var edit: String? = null,
var editWorkspace: String? = null,
var codeLenses: String? = null,
// 'lenses' for code lenses, must have codeLenses = 'enabled'
var fixupControls: String? = null,
var codeLenses: String? = null
)
Original file line number Diff line number Diff line change
@@ -1,22 +1,13 @@
package com.sourcegraph.cody.agent.protocol

enum class CodyTaskState(val id: Int) {
Idle(0),
Working(1),
Inserting(2),
Applying(3),
Formatting(4),
Applied(5),
Finished(6),
Error(7),
Pending(8)
Idle(1),
Working(2),
Inserting(3),
Applying(4),
Formatting(5),
Applied(6),
Finished(7),
Error(8),
Pending(9)
}

@Suppress("unused")
val CodyTaskState.isTerminal
get() =
when (this) {
CodyTaskState.Finished,
CodyTaskState.Error -> true
else -> false
}

This file was deleted.

This file was deleted.

This file was deleted.

13 changes: 0 additions & 13 deletions src/main/kotlin/com/sourcegraph/cody/agent/protocol/Range.kt
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package com.sourcegraph.cody.agent.protocol

import com.intellij.openapi.editor.Document

typealias RangePair = Pair<Int, Int>

data class Range(val start: Position, val end: Position) {
Expand All @@ -14,15 +12,4 @@ data class Range(val start: Position, val end: Position) {
fun toSearchRange(): RangePair = RangePair(start.line.plus(1), end.line)

fun length() = end.line - start.line + 1

fun toOffsets(document: Document): Pair<Int, Int> {
return Pair(start.toOffset(document), end.toOffset(document))
}

// Return true if the agent gave us all zeroes for the range.
fun isZero() = start.isZero() && end.isZero()

companion object {
fun nullRange() = Range(Position(0, 0), Position(0, 0))
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -22,11 +22,11 @@ class DocumentCodeActionHandler : EditorActionHandler() {
}

override fun doExecute(editor: Editor, where: Caret?, dataContext: DataContext?) {
val fixupService = editor.project?.getService(FixupService::class.java)
if (fixupService == null) {
logger.warn("FixupService not found")
val project = editor.project
if (project == null) {
logger.warn("No project found, cannot run DocumentCodeActionHandler::startDocumentCode")
} else {
fixupService.startDocumentCode(editor)
FixupService.getInstance(project).startDocumentCode(editor)
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -15,17 +15,16 @@ class DocumentCodeSession(controller: FixupService, editor: Editor) :
}

override fun retry() {
// TODO: The actual prompt is displayed as ghost text in the text input field.
// TODO: The actual prompt we sent is displayed as ghost text in the text input field, in VS
// Code.
// E.g. "Write a brief documentation comment for the selected code <etc.>"
// We need to send the prompt along with the lenses, so that the client can display it.
EditCommandPrompt(controller, editor, "Edit instructions and Retry").displayPromptUI()
}

// Brings up a diff view showing the changes the AI made.
override fun diff() {
// The FixupController issues a vscode.diff command to show the smart diff in the
// handler for cody.fixup.codelens.diff. TODO: Register a handler in the Agent
// and send a new RPC to the client to display the diff, maybe just a notification.
// TODO: Use DiffManager and bring up a diff of the changed region.
// You can see it in action now by clicking the green gutter to the left of Cody changes.
logger.warn("Code Lenses: Show Diff")
}

Expand Down
22 changes: 17 additions & 5 deletions src/main/kotlin/com/sourcegraph/cody/edit/EditCommandPrompt.kt
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,6 @@ package com.sourcegraph.cody.edit

import com.intellij.openapi.Disposable
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.diagnostic.Logger
import com.intellij.openapi.editor.Editor
import com.intellij.openapi.fileEditor.FileDocumentManager
import com.intellij.openapi.ui.ComboBox
Expand All @@ -25,7 +24,6 @@ import javax.swing.event.DocumentListener

/** Pop up a user interface for giving Cody instructions to fix up code at the cursor. */
class EditCommandPrompt(val controller: FixupService, val editor: Editor, val dialogTitle: String) {
private val logger = Logger.getInstance(EditCommandPrompt::class.java)
private val offset = editor.caretModel.primaryCaret.offset

private var dialog: EditCommandPrompt.InstructionsDialog? = null
Expand Down Expand Up @@ -60,6 +58,7 @@ class EditCommandPrompt(val controller: FixupService, val editor: Editor, val di

fun getText(): String = instructionsField.text

@RequiresEdt
private fun setupTextField() {
instructionsField.document.addDocumentListener(
object : DocumentListener {
Expand All @@ -84,10 +83,12 @@ class EditCommandPrompt(val controller: FixupService, val editor: Editor, val di
})
}

@RequiresEdt
private fun updateOkButtonState() {
dialog?.isOKActionEnabled = instructionsField.text.isNotBlank()
}

@RequiresEdt
private fun checkForInterruptions() {
if (editor.isDisposed || editor.isViewer || !editor.document.isWritable) {
dialog?.apply {
Expand All @@ -97,6 +98,7 @@ class EditCommandPrompt(val controller: FixupService, val editor: Editor, val di
}
}

@RequiresEdt
private fun setupKeyListener() {
instructionsField.addKeyListener(
object : KeyAdapter() {
Expand All @@ -110,14 +112,17 @@ class EditCommandPrompt(val controller: FixupService, val editor: Editor, val di
})
}

@RequiresEdt
private fun fetchPreviousHistoryItem() {
updateTextFromHistory(historyCursor.getPreviousHistoryItem())
}

@RequiresEdt
private fun fetchNextHistoryItem() {
updateTextFromHistory(historyCursor.getNextHistoryItem())
}

@RequiresEdt
private fun updateTextFromHistory(text: String) {
instructionsField.text = text
instructionsField.caretPosition = text.length
Expand All @@ -131,6 +136,7 @@ class EditCommandPrompt(val controller: FixupService, val editor: Editor, val di

fun getNextHistoryItem() = getHistoryItemByDelta(1)

@RequiresEdt
private fun getHistoryItemByDelta(delta: Int): String {
if (promptHistory.isNotEmpty()) {
historyIndex = (historyIndex + delta).coerceIn(0, promptHistory.size - 1)
Expand All @@ -152,12 +158,14 @@ class EditCommandPrompt(val controller: FixupService, val editor: Editor, val di

override fun getPreferredFocusedComponent() = instructionsField

@RequiresEdt
override fun createCenterPanel(): JComponent {
val result = generatePromptUI(offset)
updateOkButtonState()
return result
}

@RequiresEdt
override fun doOKAction() {
val text = instructionsField.text
val model = modelComboBox.item
Expand All @@ -169,13 +177,15 @@ class EditCommandPrompt(val controller: FixupService, val editor: Editor, val di
}
}

@RequiresEdt
override fun doCancelAction() {
super.doCancelAction()
dialog?.disposeIfNeeded()
dialog = null
}
} // InstructionsDialog

@RequiresEdt
private fun generatePromptUI(offset: Int): JPanel {
val root = JPanel(BorderLayout())

Expand Down Expand Up @@ -234,7 +244,7 @@ class EditCommandPrompt(val controller: FixupService, val editor: Editor, val di
inner class GhostTextField : ExpandableTextField(), FocusListener, Disposable {

init {
//Disposer.register(this@EditCommandPrompt, this@GhostTextField)
// Disposer.register(this@EditCommandPrompt, this@GhostTextField)
addFocusListener(this)
}

Expand All @@ -247,7 +257,10 @@ class EditCommandPrompt(val controller: FixupService, val editor: Editor, val di
g2.color = JBColor.GRAY
val fontMetrics = g2.fontMetrics
val x = insets.left + fontMetrics.charWidth('G')
val y = insets.top + (height - insets.top - insets.bottom - fontMetrics.height) / 2 + fontMetrics.ascent
val y =
insets.top +
(height - insets.top - insets.bottom - fontMetrics.height) / 2 +
fontMetrics.ascent
g2.drawString(GHOST_TEXT, x, y)
}
}
Expand All @@ -265,7 +278,6 @@ class EditCommandPrompt(val controller: FixupService, val editor: Editor, val di
}
}


companion object {
const val DEFAULT_TEXT_FIELD_WIDTH: Int = 620 // TODO: make this smarter

Expand Down
Loading

0 comments on commit e7f1b5a

Please sign in to comment.