Skip to content

Commit f8019d9

Browse files
authored
feat(inline-chat): handle ESC key to close panel (#302)
Add EscHandler to manage editor escape events. Closes inline chat panel when pressing ESC without selection/multiple-carets, preserves default behavior otherwise. close #301
1 parent 3059127 commit f8019d9

File tree

1 file changed

+53
-1
lines changed

1 file changed

+53
-1
lines changed

core/src/main/kotlin/cc/unitmesh/devti/inline/AutoDevInlineChatPanel.kt

Lines changed: 53 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -8,14 +8,21 @@ import cc.unitmesh.devti.util.AutoDevCoroutineScope
88
import com.intellij.icons.AllIcons
99
import com.intellij.ide.KeyboardAwareFocusOwner
1010
import com.intellij.openapi.Disposable
11+
import com.intellij.openapi.actionSystem.DataContext
12+
import com.intellij.openapi.actionSystem.IdeActions
1113
import com.intellij.openapi.actionSystem.Presentation
1214
import com.intellij.openapi.actionSystem.impl.ActionButton
1315
import com.intellij.openapi.application.ApplicationManager
1416
import com.intellij.openapi.application.invokeLater
1517
import com.intellij.openapi.application.runInEdt
18+
import com.intellij.openapi.editor.Caret
19+
import com.intellij.openapi.editor.CaretModel
1620
import com.intellij.openapi.editor.Editor
1721
import com.intellij.openapi.editor.EditorCustomElementRenderer
1822
import com.intellij.openapi.editor.Inlay
23+
import com.intellij.openapi.editor.SelectionModel
24+
import com.intellij.openapi.editor.actionSystem.EditorActionHandler
25+
import com.intellij.openapi.editor.actionSystem.EditorActionManager
1926
import com.intellij.openapi.editor.markup.TextAttributes
2027
import com.intellij.openapi.project.DumbAwareAction
2128
import com.intellij.openapi.wm.IdeFocusManager
@@ -184,6 +191,8 @@ class AutoDevInlineChatInput(
184191

185192
private var btnPresentation: Presentation? = null
186193

194+
private var escHandler: EscHandler? = null
195+
187196
init {
188197
layout = BorderLayout()
189198
textArea = object : JBTextArea(), KeyboardAwareFocusOwner {
@@ -222,6 +231,11 @@ class AutoDevInlineChatInput(
222231
}
223232
})
224233
textArea.inputMap.put(KeyStroke.getKeyStroke(KeyEvent.VK_ENTER, KeyEvent.SHIFT_DOWN_MASK), "newlineAction")
234+
escHandler = EscHandler(autoDevInlineChatPanel.editor, {
235+
cancel()
236+
AutoDevInlineChatService.getInstance().closeInlineChat(autoDevInlineChatPanel.editor)
237+
escHandler?.dispose()
238+
})
225239

226240
btnPresentation = Presentation()
227241
setPresentationTextAndIcon(false)
@@ -246,7 +260,7 @@ class AutoDevInlineChatInput(
246260
view = onSubmit(trimText) {
247261
it.addProcessListener(object : SketchProcessListener {
248262
override fun onBefore() = setPresentationTextAndIcon(true)
249-
override fun onAfter() = setPresentationTextAndIcon(false)
263+
override fun onAfter() = setPresentationTextAndIcon(false)
250264
})
251265
}
252266

@@ -283,3 +297,41 @@ fun <T : JComponent> Cell<T>.fullWidth(): Cell<T> {
283297
fun <T : JComponent> Cell<T>.fullHeight(): Cell<T> {
284298
return this.align(AlignY.FILL)
285299
}
300+
301+
302+
/**
303+
* 监听编辑器的 ESC 按键事件,并在非选中或多光标等需要取消前一状态的状态下执行 [action]
304+
*/
305+
class EscHandler(private val targetEditor: Editor, private val action: () -> Unit) : EditorActionHandler(), Disposable {
306+
307+
private var oldHandler: EditorActionHandler? = null
308+
309+
init {
310+
val editorManager = EditorActionManager.getInstance()
311+
oldHandler = editorManager.getActionHandler(IdeActions.ACTION_EDITOR_ESCAPE)
312+
editorManager.setActionHandler(IdeActions.ACTION_EDITOR_ESCAPE, this)
313+
}
314+
315+
override fun doExecute(
316+
editor: Editor,
317+
caret: Caret?,
318+
context: DataContext,
319+
) {
320+
if (editor == targetEditor) {
321+
val caretModel: CaretModel = editor.caretModel
322+
val hasMultiCaret = caretModel.caretCount > 1
323+
val hasSelection = caretModel.allCarets.any { it.hasSelection() }
324+
if (hasMultiCaret || hasSelection) {
325+
oldHandler?.execute(editor, caret, context)
326+
} else {
327+
action()
328+
}
329+
}
330+
}
331+
332+
override fun dispose() {
333+
oldHandler?.let {
334+
EditorActionManager.getInstance().setActionHandler(IdeActions.ACTION_EDITOR_ESCAPE, it)
335+
}
336+
}
337+
}

0 commit comments

Comments
 (0)