-
Notifications
You must be signed in to change notification settings - Fork 19
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Block further inline edits until previous one completes #1481
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -13,6 +13,10 @@ import com.intellij.openapi.project.Project | |
import com.intellij.ui.components.JBPanelWithEmptyText | ||
import com.sourcegraph.cody.commands.CommandId | ||
import com.sourcegraph.cody.config.CodyApplicationSettings | ||
import com.sourcegraph.cody.edit.FixupService | ||
import com.sourcegraph.cody.edit.actions.DocumentCodeAction | ||
import com.sourcegraph.cody.edit.actions.EditCodeAction | ||
import com.sourcegraph.cody.edit.actions.TestCodeAction | ||
import com.sourcegraph.cody.ignore.CommandPanelIgnoreBanner | ||
import com.sourcegraph.cody.ignore.IgnoreOracle | ||
import com.sourcegraph.cody.ignore.IgnorePolicy | ||
|
@@ -22,17 +26,21 @@ import java.awt.Dimension | |
import java.awt.GridLayout | ||
import javax.swing.BoxLayout | ||
import javax.swing.JButton | ||
import javax.swing.JComponent | ||
import javax.swing.plaf.ButtonUI | ||
|
||
class CommandsTabPanel( | ||
private val project: Project, | ||
private val executeCommand: (CommandId) -> Unit | ||
) : | ||
JBPanelWithEmptyText(GridLayout(/* rows = */ 0, /* cols = */ 1)), | ||
IgnoreOracle.FocusedFileIgnorePolicyListener { | ||
IgnoreOracle.FocusedFileIgnorePolicyListener, | ||
FixupService.ActiveFixupSessionStateListener { | ||
private val ignoreBanner = CommandPanelIgnoreBanner() | ||
private val buttons = mutableListOf<JComponent>() | ||
private val buttons = mutableMapOf<String, JButton>() | ||
|
||
@Volatile private var ignorePolicy: IgnorePolicy = IgnorePolicy.USE | ||
|
||
@Volatile private var isInlineEditInProgress: Boolean = false | ||
|
||
init { | ||
layout = BoxLayout(this, BoxLayout.Y_AXIS) | ||
|
@@ -41,25 +49,18 @@ class CommandsTabPanel( | |
|
||
if (ConfigUtil.isFeatureFlagEnabled("cody.feature.inline-edits") || | ||
CodyApplicationSettings.instance.isInlineEditionEnabled) { | ||
addInlineEditActionButton("cody.editCodeAction") | ||
addInlineEditActionButton("cody.documentCodeAction") | ||
addInlineEditActionButton("cody.testCodeAction") | ||
addInlineEditActionButton(EditCodeAction.ID) | ||
addInlineEditActionButton(DocumentCodeAction.ID) | ||
addInlineEditActionButton(TestCodeAction.ID) | ||
} | ||
|
||
addHierarchyListener { | ||
if (!project.isDisposed) { | ||
if (it.component.isShowing) { | ||
IgnoreOracle.getInstance(project).addListener(this) | ||
} else { | ||
IgnoreOracle.getInstance(project).removeListener(this) | ||
} | ||
} | ||
} | ||
IgnoreOracle.getInstance(project).addListener(this) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. @dominiccooney I simplified this, I do not see any reason to keep adding and removing this listener. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Should be fine... I was just keen to avoid references from something held on to by agent callbacks and the opaque JetBrains machinery. Seems like a recipe for leaks. |
||
FixupService.getInstance(project).addListener(this) | ||
} | ||
|
||
private fun addInlineEditActionButton(actionId: String) { | ||
val action = ActionManagerEx.getInstanceEx().getAction(actionId) | ||
addButton(action.templatePresentation.text, action.templatePresentation.mnemonic) { | ||
addButton(actionId, action.templatePresentation.text, action.templatePresentation.mnemonic) { | ||
val editor = FileEditorManager.getInstance(project).selectedTextEditor ?: return@addButton | ||
val dataContext = (editor as? EditorEx)?.dataContext ?: return@addButton | ||
val managerEx = ActionManagerEx.getInstanceEx() | ||
|
@@ -70,10 +71,10 @@ class CommandsTabPanel( | |
} | ||
|
||
private fun addCommandButton(commandId: CommandId) { | ||
addButton(commandId.displayName, commandId.mnemonic) { executeCommand(commandId) } | ||
addButton(commandId.id, commandId.displayName, commandId.mnemonic) { executeCommand(commandId) } | ||
} | ||
|
||
private fun addButton(displayName: String, mnemonic: Int, action: () -> Unit) { | ||
private fun addButton(actionId: String, displayName: String, mnemonic: Int, action: () -> Unit) { | ||
val button = JButton(displayName) | ||
button.mnemonic = mnemonic | ||
button.displayedMnemonicIndex = displayName.indexOfFirst { it.code == mnemonic } | ||
|
@@ -84,15 +85,21 @@ class CommandsTabPanel( | |
button.addActionListener { action() } | ||
add(button) | ||
|
||
buttons.add(button) | ||
buttons[actionId] = button | ||
} | ||
|
||
private fun update(policy: IgnorePolicy) { | ||
private fun update() { | ||
// Dis/enable all the buttons. | ||
for (button in buttons) { | ||
button.isEnabled = policy == IgnorePolicy.USE | ||
for ((actionId, button) in buttons) { | ||
// We block only DocumentCodeAction and TestCodeAction, for EditCodeAction we will block the | ||
// button on the edit dialog | ||
val shouldBlockInlineEditAction = | ||
isInlineEditInProgress && | ||
(actionId == DocumentCodeAction.ID || actionId == TestCodeAction.ID) | ||
button.isEnabled = ignorePolicy == IgnorePolicy.USE && !shouldBlockInlineEditAction | ||
} | ||
when (policy) { | ||
|
||
when (ignorePolicy) { | ||
IgnorePolicy.USE -> { | ||
remove(ignoreBanner) | ||
} | ||
|
@@ -105,6 +112,12 @@ class CommandsTabPanel( | |
} | ||
|
||
override fun focusedFileIgnorePolicyChanged(policy: IgnorePolicy) { | ||
runInEdt { update(policy) } | ||
this.ignorePolicy = policy | ||
runInEdt { update() } | ||
} | ||
|
||
override fun fixupSessionStateChanged(isInProgress: Boolean) { | ||
this.isInlineEditInProgress = isInProgress | ||
runInEdt { update() } | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
package com.sourcegraph.cody.edit.actions | ||
|
||
import com.intellij.openapi.project.DumbAware | ||
import com.sourcegraph.cody.autocomplete.action.CodyAction | ||
|
||
class DocumentCodeAction : | ||
EditCommandAction({ editor, fixupService -> fixupService.startDocumentCode(editor) }), | ||
CodyAction, | ||
DumbAware | ||
NonInteractiveEditCommandAction({ editor, fixupService -> | ||
fixupService.startDocumentCode(editor) | ||
}) { | ||
companion object { | ||
const val ID: String = "cody.documentCodeAction" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,8 @@ | ||
package com.sourcegraph.cody.edit.actions | ||
|
||
import com.intellij.openapi.project.DumbAware | ||
import com.sourcegraph.cody.autocomplete.action.CodyAction | ||
|
||
class EditCodeAction : | ||
EditCommandAction({ editor, fixupService -> fixupService.startCodeEdit(editor) }), | ||
CodyAction, | ||
DumbAware | ||
EditCommandAction({ editor, fixupService -> fixupService.startCodeEdit(editor) }) { | ||
companion object { | ||
const val ID: String = "cody.editCodeAction" | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,15 @@ | ||
package com.sourcegraph.cody.edit.actions | ||
|
||
import com.intellij.openapi.actionSystem.AnActionEvent | ||
import com.intellij.openapi.editor.Editor | ||
import com.sourcegraph.cody.edit.FixupService | ||
|
||
open class NonInteractiveEditCommandAction(runAction: (Editor, FixupService) -> Unit) : | ||
EditCommandAction(runAction) { | ||
override fun update(e: AnActionEvent) { | ||
super.update(e) | ||
|
||
val project = e.project ?: return | ||
e.presentation.isEnabled = !FixupService.getInstance(project).isEditInProgress() | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,9 +1,10 @@ | ||
package com.sourcegraph.cody.edit.actions | ||
|
||
import com.intellij.openapi.project.DumbAware | ||
import com.sourcegraph.cody.autocomplete.action.CodyAction | ||
|
||
class TestCodeAction : | ||
EditCommandAction({ editor, fixupService -> fixupService.startTestCode(editor) }), | ||
CodyAction, | ||
DumbAware | ||
NonInteractiveEditCommandAction({ editor, fixupService -> | ||
fixupService.startTestCode(editor) | ||
}) { | ||
companion object { | ||
const val ID: String = "cody.testCodeAction" | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
The class is
CommandId
and it hasid
field now. That leads tocommandId.id
which looks weird. Can we removeId
from the class name?There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Let me do this either on a separate PR or at the end of the reviews... it is used in a quite a few places, I do not want to introduced such amount of noise on this PR.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think this is acceptable. In fact, such naming seems to be rather common in Kotlin and Scala code.