Skip to content
Merged
Show file tree
Hide file tree
Changes from 10 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,12 @@
<applicationListeners>
<listener class="software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererUIChangeListener"
topic="software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupStateChangeListener"/>
<listener class="software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererUIChangeListenerNew"
topic="software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupStateChangeListener"/>
<listener class="software.aws.toolkits.jetbrains.services.codewhisperer.toolwindow.CodeWhispererCodeReferenceActionListener"
topic="software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererUserActionListener"/>
<listener class="software.aws.toolkits.jetbrains.services.codewhisperer.toolwindow.CodeWhispererCodeReferenceActionListenerNew"
topic="software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererUserActionListener"/>
</applicationListeners>

<projectListeners>
Expand Down Expand Up @@ -81,9 +85,32 @@
</group>

<action class="software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererRecommendationAction"
text="Show Code Suggestions">
text="Invoke Amazon Q Inline Suggestions">
<keyboard-shortcut keymap="$default" first-keystroke="alt C"/>
</action>
<action id="codewhisperer.inline.navigate.previous"
class="software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererNavigatePrevAction"
text="Navigate to Previous Inline Suggestion" description="Navigate to previous inline suggestion">
<keyboard-shortcut keymap="$default" first-keystroke="alt OPEN_BRACKET"/>
</action>
<action id="codewhisperer.inline.navigate.next"
class="software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererNavigateNextAction"
text="Navigate to Next Inline Suggestion" description="Navigate to next inline suggestion">
<keyboard-shortcut keymap="$default" first-keystroke="alt CLOSE_BRACKET"/>
</action>
<action id="codewhisperer.inline.accept"
class="software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererAcceptAction"
text="Accept the Current Inline Suggestion" description="Accept the current inline suggestions">
<keyboard-shortcut keymap="$default" first-keystroke="TAB"/>
</action>
<action id="codewhisperer.inline.force.accept"
class="software.aws.toolkits.jetbrains.services.codewhisperer.actions.CodeWhispererForceAcceptAction"
text="Force Accept the Current Inline Suggestion" description="Force accept the current inline suggestion">
<keyboard-shortcut keymap="Mac OS X" first-keystroke="alt TAB"/>
<keyboard-shortcut keymap="Mac OS X 10.5+" first-keystroke="alt TAB"/>
<keyboard-shortcut keymap="$default" first-keystroke="alt ENTER"/>
</action>

<group id="aws.toolkit.codewhisperer.toolbar.security">
<action
id="codewhisperer.toolbar.security.scan"
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.codewhisperer.actions

import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.DumbAware
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupManager
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatusNew
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererServiceNew
import software.aws.toolkits.resources.message

open class CodeWhispererAcceptAction(title: String = message("codewhisperer.inline.accept")) : AnAction(title), DumbAware {
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.EDT

override fun update(e: AnActionEvent) {
e.presentation.isEnabled = e.project != null && e.getData(CommonDataKeys.EDITOR) != null &&
CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()
}

override fun actionPerformed(e: AnActionEvent) {
val sessionContext = e.project?.getUserData(CodeWhispererServiceNew.KEY_SESSION_CONTEXT) ?: return
if (!CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()) return
ApplicationManager.getApplication().messageBus.syncPublisher(
CodeWhispererPopupManager.CODEWHISPERER_USER_ACTION_PERFORMED
).beforeAccept(sessionContext)
}
}

// A same accept action but different key shortcut and different promoter logic
class CodeWhispererForceAcceptAction(title: String = message("codewhisperer.inline.force.accept")) : CodeWhispererAcceptAction(title)
Original file line number Diff line number Diff line change
Expand Up @@ -3,16 +3,46 @@

package software.aws.toolkits.jetbrains.services.codewhisperer.actions

import com.intellij.codeInsight.lookup.impl.actions.ChooseItemAction
import com.intellij.openapi.actionSystem.ActionPromoter
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.DataContext
import com.intellij.openapi.editor.actionSystem.EditorAction
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.handlers.CodeWhispererPopupLeftArrowHandler
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.handlers.CodeWhispererPopupRightArrowHandler
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.handlers.CodeWhispererPopupTabHandler
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererFeatureConfigService
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatusNew

class CodeWhispererActionPromoter : ActionPromoter {
override fun promote(actions: MutableList<out AnAction>, context: DataContext): MutableList<AnAction> {
if (CodeWhispererFeatureConfigService.getInstance().getNewAutoTriggerUX()) {
val results = actions.toMutableList()
if (!CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()) return results

results.sortWith { a, b ->
if (isCodeWhispererForceAction(a)) {
return@sortWith -1
} else if (isCodeWhispererForceAction(b)) {
return@sortWith 1
}

if (a is ChooseItemAction) {
return@sortWith -1
} else if (b is ChooseItemAction) {
return@sortWith 1
}

if (isCodeWhispererAcceptAction(a)) {
return@sortWith -1
} else if (isCodeWhispererAcceptAction(b)) {
return@sortWith 1
}

0
}
return results
}
val results = actions.toMutableList()
results.sortWith { a, b ->
if (isCodeWhispererPopupAction(a)) {
Expand All @@ -27,14 +57,28 @@ class CodeWhispererActionPromoter : ActionPromoter {
}

private fun isCodeWhispererAcceptAction(action: AnAction): Boolean =
action is EditorAction && action.handler is CodeWhispererPopupTabHandler
if (CodeWhispererFeatureConfigService.getInstance().getNewAutoTriggerUX()) {
action is CodeWhispererAcceptAction
} else {
action is EditorAction && action.handler is CodeWhispererPopupTabHandler
}

private fun isCodeWhispererForceAcceptAction(action: AnAction): Boolean =
action is CodeWhispererForceAcceptAction

private fun isCodeWhispererNavigateAction(action: AnAction): Boolean =
action is EditorAction && (
action.handler is CodeWhispererPopupRightArrowHandler ||
action.handler is CodeWhispererPopupLeftArrowHandler
)
if (CodeWhispererFeatureConfigService.getInstance().getNewAutoTriggerUX()) {
action is CodeWhispererNavigateNextAction || action is CodeWhispererNavigatePrevAction
} else {
action is EditorAction && (
action.handler is CodeWhispererPopupRightArrowHandler ||
action.handler is CodeWhispererPopupLeftArrowHandler
)
}

private fun isCodeWhispererPopupAction(action: AnAction): Boolean =
isCodeWhispererAcceptAction(action) || isCodeWhispererNavigateAction(action)

private fun isCodeWhispererForceAction(action: AnAction): Boolean =
isCodeWhispererForceAcceptAction(action) || isCodeWhispererNavigateAction(action)
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.codewhisperer.actions

import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.DumbAware
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupManager
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatusNew
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererServiceNew
import software.aws.toolkits.resources.message

class CodeWhispererNavigateNextAction : AnAction(message("codewhisperer.inline.navigate.next")), DumbAware {
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.EDT

override fun update(e: AnActionEvent) {
e.presentation.isEnabled = e.project != null &&
e.getData(CommonDataKeys.EDITOR) != null &&
CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()
}

override fun actionPerformed(e: AnActionEvent) {
val sessionContext = e.project?.getUserData(CodeWhispererServiceNew.KEY_SESSION_CONTEXT) ?: return
if (!CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()) return
ApplicationManager.getApplication().messageBus.syncPublisher(
CodeWhispererPopupManager.CODEWHISPERER_USER_ACTION_PERFORMED
).navigateNext(sessionContext)
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
// Copyright 2024 Amazon.com, Inc. or its affiliates. All Rights Reserved.
// SPDX-License-Identifier: Apache-2.0

package software.aws.toolkits.jetbrains.services.codewhisperer.actions

import com.intellij.openapi.actionSystem.ActionUpdateThread
import com.intellij.openapi.actionSystem.AnAction
import com.intellij.openapi.actionSystem.AnActionEvent
import com.intellij.openapi.actionSystem.CommonDataKeys
import com.intellij.openapi.application.ApplicationManager
import com.intellij.openapi.project.DumbAware
import software.aws.toolkits.jetbrains.services.codewhisperer.popup.CodeWhispererPopupManager
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererInvocationStatusNew
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererServiceNew
import software.aws.toolkits.resources.message

class CodeWhispererNavigatePrevAction : AnAction(message("codewhisperer.inline.navigate.previous")), DumbAware {
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.EDT

override fun update(e: AnActionEvent) {
e.presentation.isEnabled = e.project != null &&
e.getData(CommonDataKeys.EDITOR) != null &&
CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()
}

override fun actionPerformed(e: AnActionEvent) {
val sessionContext = e.project?.getUserData(CodeWhispererServiceNew.KEY_SESSION_CONTEXT) ?: return
if (!CodeWhispererInvocationStatusNew.getInstance().isDisplaySessionActive()) return
ApplicationManager.getApplication().messageBus.syncPublisher(
CodeWhispererPopupManager.CODEWHISPERER_USER_ACTION_PERFORMED
).navigatePrevious(sessionContext)
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,9 @@ import kotlinx.coroutines.Job
import software.aws.toolkits.jetbrains.services.codewhisperer.model.LatencyContext
import software.aws.toolkits.jetbrains.services.codewhisperer.model.TriggerTypeInfo
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererAutomatedTriggerType
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererFeatureConfigService
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererService
import software.aws.toolkits.jetbrains.services.codewhisperer.service.CodeWhispererServiceNew
import software.aws.toolkits.resources.message
import software.aws.toolkits.telemetry.CodewhispererTriggerType
import java.util.concurrent.atomic.AtomicReference
Expand All @@ -30,12 +32,23 @@ class CodeWhispererRecommendationAction : AnAction(message("codewhisperer.trigge
latencyContext.codewhispererPreprocessingStart = System.nanoTime()
latencyContext.codewhispererEndToEndStart = System.nanoTime()
val editor = e.getRequiredData(CommonDataKeys.EDITOR)
if (!CodeWhispererService.getInstance().canDoInvocation(editor, CodewhispererTriggerType.OnDemand)) {
if (!(
if (CodeWhispererFeatureConfigService.getInstance().getNewAutoTriggerUX()) {
CodeWhispererServiceNew.getInstance().canDoInvocation(editor, CodewhispererTriggerType.OnDemand)
} else {
CodeWhispererService.getInstance().canDoInvocation(editor, CodewhispererTriggerType.OnDemand)
}
)
) {
return
}

val triggerType = TriggerTypeInfo(CodewhispererTriggerType.OnDemand, CodeWhispererAutomatedTriggerType.Unknown())
val job = CodeWhispererService.getInstance().showRecommendationsInPopup(editor, triggerType, latencyContext)
val job = if (CodeWhispererFeatureConfigService.getInstance().getNewAutoTriggerUX()) {
CodeWhispererServiceNew.getInstance().showRecommendationsInPopup(editor, triggerType, latencyContext)
} else {
CodeWhispererService.getInstance().showRecommendationsInPopup(editor, triggerType, latencyContext)
}
Comment on lines +35 to +51
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

can avoid working around typecast issues if you declare a common interface


e.getData(CommonDataKeys.EDITOR)?.getUserData(ACTION_JOB_KEY)?.set(job)
}
Expand Down

This file was deleted.

Loading
Loading