Skip to content

Commit 04fb256

Browse files
authored
refactor(settings): Optimize the code for messages resource bundle and support dynamic translation without restarting the IDE (#224)
1 parent 56b0b26 commit 04fb256

24 files changed

+236
-104
lines changed

exts/ext-git/src/main/kotlin/cc/unitmesh/git/actions/vcs/CodeReviewAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package cc.unitmesh.git.actions.vcs
22

3-
import cc.unitmesh.devti.AutoDevBundle
43
import cc.unitmesh.devti.AutoDevNotifications
54
import cc.unitmesh.devti.actions.chat.base.ChatBaseAction
65
import cc.unitmesh.devti.flow.kanban.impl.GitHubIssue
@@ -12,6 +11,7 @@ import cc.unitmesh.devti.provider.context.ChatContextProvider
1211
import cc.unitmesh.devti.provider.context.ChatCreationContext
1312
import cc.unitmesh.devti.provider.context.ChatOrigin
1413
import cc.unitmesh.devti.settings.AutoDevSettingsState
14+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
1515
import cc.unitmesh.devti.template.GENIUS_PRACTISES
1616
import cc.unitmesh.devti.template.TemplateRender
1717
import cc.unitmesh.devti.template.context.TemplateContext
@@ -35,8 +35,7 @@ val githubUrlRegex: Regex = Regex("^(https?://|git://)?(www\\.)?github\\.com/[\\
3535
open class CodeReviewAction : ChatBaseAction() {
3636

3737
init{
38-
val presentation = getTemplatePresentation()
39-
presentation.text = AutoDevBundle.message("settings.autodev.others.codeReview")
38+
presentationText("settings.autodev.others.codeReview", templatePresentation)
4039
}
4140
override fun getActionType(): ChatActionType = ChatActionType.CODE_REVIEW
4241

exts/ext-git/src/main/kotlin/cc/unitmesh/git/actions/vcs/CommitMessageSuggestionAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,10 +1,10 @@
11
package cc.unitmesh.git.actions.vcs
22

3-
import cc.unitmesh.devti.AutoDevBundle
43
import cc.unitmesh.devti.AutoDevNotifications
54
import cc.unitmesh.devti.actions.chat.base.ChatBaseAction
65
import cc.unitmesh.devti.gui.chat.ChatActionType
76
import cc.unitmesh.devti.llms.LlmFactory
7+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
88
import cc.unitmesh.devti.template.GENIUS_PRACTISES
99
import cc.unitmesh.devti.vcs.VcsPrompting
1010
import cc.unitmesh.devti.statusbar.AutoDevStatus
@@ -34,8 +34,7 @@ import kotlinx.coroutines.flow.*
3434
class CommitMessageSuggestionAction : ChatBaseAction() {
3535

3636
init{
37-
val presentation = getTemplatePresentation()
38-
presentation.text = AutoDevBundle.message("settings.autodev.others.commitMessage")
37+
presentationText("settings.autodev.others.commitMessage", templatePresentation)
3938
}
4039
override fun getActionUpdateThread(): ActionUpdateThread {
4140
return ActionUpdateThread.BGT

exts/ext-git/src/main/kotlin/cc/unitmesh/git/actions/vcs/PrepushReviewAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
package cc.unitmesh.git.actions.vcs
22

3-
import cc.unitmesh.devti.AutoDevBundle
3+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
44
import cc.unitmesh.devti.vcs.VcsPrompting
55
import com.intellij.openapi.actionSystem.ActionUpdateThread
66
import com.intellij.openapi.actionSystem.AnActionEvent
@@ -11,8 +11,7 @@ import com.intellij.openapi.vcs.changes.Change
1111
class PrepushReviewAction : CodeReviewAction() {
1212

1313
init{
14-
val presentation = getTemplatePresentation()
15-
presentation.text = AutoDevBundle.message("settings.autodev.others.prepushReviewAction")
14+
presentationText("settings.autodev.others.prepushReviewAction", templatePresentation)
1615
}
1716
override fun update(e: AnActionEvent) {
1817
val data = e.getData(VcsDataKeys.CHANGES)

exts/ext-git/src/main/kotlin/cc/unitmesh/git/actions/vcs/ReleaseNoteSuggestionAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package cc.unitmesh.git.actions.vcs
22

3-
import cc.unitmesh.devti.AutoDevBundle
43
import cc.unitmesh.devti.gui.AutoDevToolWindowFactory
54
import cc.unitmesh.devti.gui.chat.ChatActionType
65
import cc.unitmesh.devti.gui.chat.ChatCodingPanel
76
import cc.unitmesh.devti.gui.chat.ChatCodingService
87
import cc.unitmesh.devti.provider.ContextPrompter
8+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
99
import com.intellij.openapi.actionSystem.AnAction
1010
import com.intellij.openapi.actionSystem.AnActionEvent
1111
import com.intellij.vcs.log.VcsLogDataKeys
@@ -14,8 +14,7 @@ import com.intellij.vcs.log.VcsLogDataKeys
1414
class ReleaseNoteSuggestionAction : AnAction() {
1515

1616
init{
17-
val presentation = getTemplatePresentation()
18-
presentation.text = AutoDevBundle.message("settings.autodev.others.generateReleaseNote")
17+
presentationText("settings.autodev.others.generateReleaseNote", templatePresentation)
1918
}
2019
override fun actionPerformed(e: AnActionEvent) {
2120
val project = e.project ?: return
Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,21 @@
11
package cc.unitmesh.devti
22

33
import cc.unitmesh.devti.settings.AutoDevSettingsState
4+
import cc.unitmesh.devti.settings.LanguageChangedCallback
5+
import com.intellij.BundleBase
46
import com.intellij.DynamicBundle
5-
import com.intellij.openapi.diagnostic.logger
7+
import com.intellij.util.ArrayUtilRt
68
import org.jetbrains.annotations.NonNls
79
import org.jetbrains.annotations.PropertyKey
8-
import java.lang.invoke.MethodHandles
9-
import java.util.*
10+
import java.util.function.Supplier
1011

1112
@NonNls
1213
private const val BUNDLE = "messages.AutoDevBundle"
1314

1415
object AutoDevBundle : DynamicBundle(BUNDLE) {
16+
17+
private val myBundleClassLoader = AutoDevBundle::class.java.classLoader
18+
1519
@Suppress("SpreadOperator")
1620
@JvmStatic
1721
fun message(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) = getMessage(key, *params)
@@ -21,32 +25,45 @@ object AutoDevBundle : DynamicBundle(BUNDLE) {
2125
fun messagePointer(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) =
2226
getLazyMessage(key, *params)
2327

24-
val log = logger<AutoDevBundle>()
25-
override fun findBundle(
26-
@NonNls pathToBundle: String,
27-
loader: ClassLoader,
28-
control: ResourceBundle.Control
29-
): ResourceBundle {
30-
val base = super.findBundle(pathToBundle, loader, control)
31-
// load your bundle from baseName_<language>.properties, e.g. "baseName_zh.properties"
32-
val localizedPath = pathToBundle + "_" + AutoDevSettingsState.language
33-
val localeBundle = super.findBundle(
34-
localizedPath,
35-
AutoDevBundle::class.java.getClassLoader(), control
28+
@Suppress("SpreadOperator")
29+
@JvmStatic
30+
fun messageWithLanguageFromLLMSetting(@PropertyKey(resourceBundle = BUNDLE) key: String, vararg params: Any) =
31+
messageWithLanguage(key, LanguageChangedCallback.language, *params)
32+
33+
@Suppress("SpreadOperator")
34+
@JvmStatic
35+
fun messageWithLanguage(@PropertyKey(resourceBundle = BUNDLE) key: String, language: String, vararg params: Any) =
36+
getMessage(key, language, *params)
37+
38+
@Suppress("SpreadOperator", "unused")
39+
@JvmStatic
40+
fun messagePointerWithLanguage(
41+
@PropertyKey(resourceBundle = BUNDLE) key: String,
42+
language: String,
43+
vararg params: Any
44+
) = getLazyMessage(key, language, *params)
45+
46+
override fun getMessage(key: String, vararg params: Any?): String {
47+
return getMessage(key, AutoDevSettingsState.language, *params)
48+
}
49+
50+
override fun getLazyMessage(key: String, vararg params: Any?): Supplier<String> {
51+
return getLazyMessage(key, AutoDevSettingsState.language, *params)
52+
}
53+
54+
private fun getMessage(key: String, language: String, vararg params: Any?): String {
55+
return BundleBase.messageOrDefault(
56+
getResourceBundle(myBundleClassLoader, buildPathToBundle(language)),
57+
key,
58+
null,
59+
*params
3660
)
37-
if (base != localeBundle) {
38-
setParent(localeBundle, base)
39-
return localeBundle
40-
}
41-
return base
4261
}
43-
private fun setParent(localeBundle: ResourceBundle, base: ResourceBundle) {
44-
try {
45-
val method = ResourceBundle::class.java.getDeclaredMethod("setParent", ResourceBundle::class.java)
46-
method.isAccessible = true
47-
MethodHandles.lookup().unreflect(method).bindTo(localeBundle).invoke(base)
48-
} catch (e: Throwable) {
49-
log.error("Failed to set parent", e)
50-
}
62+
63+
private fun getLazyMessage(key: String, language: String, vararg params: Any?): Supplier<String> =
64+
Supplier { getMessage(key, language, if (params.size == 0) ArrayUtilRt.EMPTY_OBJECT_ARRAY else params); }
65+
66+
private fun buildPathToBundle(language: String): String {
67+
return BUNDLE + "_" + language;
5168
}
5269
}

src/main/kotlin/cc/unitmesh/devti/actions/EditSettingsAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
package cc.unitmesh.devti.actions
22

3-
import cc.unitmesh.devti.AutoDevBundle
43
import cc.unitmesh.devti.settings.AutoDevSettingsConfigurable
4+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
55
import com.intellij.openapi.actionSystem.ActionUpdateThread
66
import com.intellij.openapi.actionSystem.AnAction
77
import com.intellij.openapi.actionSystem.AnActionEvent
88
import com.intellij.openapi.options.ShowSettingsUtil
99

1010
class EditSettingsAction : AnAction() {
1111
init{
12-
val presentation = getTemplatePresentation()
13-
presentation.text = AutoDevBundle.message("settings.autodev.others.editSettings")
12+
presentationText("settings.autodev.others.editSettings", templatePresentation)
1413
}
1514
override fun actionPerformed(event: AnActionEvent) {
1615
val project = event.project ?: return

src/main/kotlin/cc/unitmesh/devti/actions/chat/ChatWithThisAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,18 +1,17 @@
11
package cc.unitmesh.devti.actions.chat
22

3-
import cc.unitmesh.devti.AutoDevBundle
43
import cc.unitmesh.devti.actions.chat.base.ChatBaseAction
54
import cc.unitmesh.devti.gui.chat.ChatActionType
65
import cc.unitmesh.devti.gui.sendToChatWindow
6+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
77
import com.intellij.openapi.actionSystem.AnActionEvent
88
import com.intellij.openapi.actionSystem.CommonDataKeys
99
import com.intellij.temporary.getElementToAction
1010

1111
class ChatWithThisAction : ChatBaseAction() {
1212

1313
init{
14-
val presentation = getTemplatePresentation()
15-
presentation.text = AutoDevBundle.message("settings.autodev.rightClick.chat")
14+
presentationText("settings.autodev.rightClick.chat", templatePresentation)
1615
}
1716
override fun getActionType(): ChatActionType = ChatActionType.CHAT
1817

src/main/kotlin/cc/unitmesh/devti/actions/chat/CodeCompleteChatAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,12 +1,12 @@
11
package cc.unitmesh.devti.actions.chat
22

3-
import cc.unitmesh.devti.AutoDevBundle
43
import cc.unitmesh.devti.gui.AutoDevToolWindowFactory
54
import cc.unitmesh.devti.gui.chat.ChatActionType
65
import cc.unitmesh.devti.gui.chat.ChatCodingPanel
76
import cc.unitmesh.devti.gui.chat.ChatCodingService
87
import cc.unitmesh.devti.gui.chat.ChatContext
98
import cc.unitmesh.devti.provider.ContextPrompter
9+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
1010
import com.intellij.openapi.actionSystem.ActionUpdateThread
1111
import com.intellij.openapi.actionSystem.AnAction
1212
import com.intellij.openapi.actionSystem.AnActionEvent
@@ -20,8 +20,7 @@ import com.intellij.temporary.getElementToAction
2020
class CodeCompleteChatAction : AnAction() {
2121

2222
init{
23-
val presentation = getTemplatePresentation()
24-
presentation.text = AutoDevBundle.message("settings.autodev.others.codeComplete")
23+
presentationText("settings.autodev.others.codeComplete", templatePresentation)
2524
}
2625

2726
override fun getActionUpdateThread(): ActionUpdateThread {

src/main/kotlin/cc/unitmesh/devti/actions/chat/ExplainThisAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,13 +1,12 @@
11
package cc.unitmesh.devti.actions.chat
22

3-
import cc.unitmesh.devti.AutoDevBundle
43
import cc.unitmesh.devti.actions.chat.base.ChatBaseAction
54
import cc.unitmesh.devti.gui.chat.ChatActionType
5+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
66

77
class ExplainThisAction() : ChatBaseAction() {
88
init{
9-
val presentation = getTemplatePresentation()
10-
presentation.text = AutoDevBundle.message("settings.autodev.rightClick.explain")
9+
presentationText("settings.autodev.rightClick.explain", templatePresentation)
1110
}
1211

1312
override fun getActionType(): ChatActionType = ChatActionType.EXPLAIN

src/main/kotlin/cc/unitmesh/devti/actions/chat/FixThisAction.kt

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,15 +1,15 @@
11
package cc.unitmesh.devti.actions.chat
22

3-
import cc.unitmesh.devti.AutoDevBundle
43
import cc.unitmesh.devti.actions.chat.base.collectElementProblemAsSting
54
import cc.unitmesh.devti.gui.chat.ChatActionType
5+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
66
import com.intellij.openapi.editor.Editor
77
import com.intellij.openapi.project.Project
88
import com.intellij.psi.PsiElement
99

1010
class FixThisAction : RefactorThisAction() {
1111
init {
12-
getTemplatePresentation().text = AutoDevBundle.message("settings.autodev.rightClick.fixthis")
12+
presentationText("settings.autodev.rightClick.fixthis", templatePresentation)
1313
}
1414

1515
override fun getActionType(): ChatActionType = ChatActionType.FIX_ISSUE

src/main/kotlin/cc/unitmesh/devti/actions/chat/GenerateApiTestAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,15 @@
11
package cc.unitmesh.devti.actions.chat
22

3-
import cc.unitmesh.devti.AutoDevBundle
43
import cc.unitmesh.devti.actions.chat.base.ChatBaseAction
54
import cc.unitmesh.devti.gui.chat.ChatActionType
5+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
66
import com.intellij.openapi.editor.Editor
77
import com.intellij.openapi.project.Project
88
import com.intellij.psi.PsiElement
99

1010
class GenerateApiTestAction : ChatBaseAction() {
1111
init {
12-
val presentation = getTemplatePresentation()
13-
presentation.text = AutoDevBundle.message("settings.autodev.rightClick.genApiTest")
12+
presentationText("settings.autodev.rightClick.genApiTest", templatePresentation)
1413
}
1514

1615
override fun getActionType(): ChatActionType = ChatActionType.GENERATE_TEST_DATA

src/main/kotlin/cc/unitmesh/devti/actions/chat/RefactorThisAction.kt

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,7 @@ import cc.unitmesh.devti.actions.chat.base.commentPrefix
77
import cc.unitmesh.devti.gui.chat.ChatActionType
88
import cc.unitmesh.devti.gui.chat.ChatCodingPanel
99
import cc.unitmesh.devti.provider.RefactoringTool
10+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
1011
import com.intellij.openapi.actionSystem.ActionUpdateThread
1112
import com.intellij.openapi.actionSystem.AnActionEvent
1213
import com.intellij.openapi.actionSystem.CommonDataKeys
@@ -16,7 +17,7 @@ import com.intellij.psi.PsiElement
1617

1718
open class RefactorThisAction : ChatBaseAction() {
1819
init {
19-
getTemplatePresentation().text = AutoDevBundle.message("settings.autodev.rightClick.refactor")
20+
presentationText("settings.autodev.rightClick.refactor", templatePresentation)
2021
}
2122

2223
override fun getActionUpdateThread(): ActionUpdateThread = ActionUpdateThread.BGT

src/main/kotlin/cc/unitmesh/devti/actions/console/FixThisAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,11 @@
11
package cc.unitmesh.devti.actions.console
22

3-
import cc.unitmesh.devti.AutoDevBundle
43
import cc.unitmesh.devti.actions.chat.base.ChatBaseAction
54
import cc.unitmesh.devti.gui.chat.ChatActionType
65
import cc.unitmesh.devti.gui.sendToChatWindow
76
import cc.unitmesh.devti.prompting.TextTemplatePrompt
87
import cc.unitmesh.devti.provider.ContextPrompter
8+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
99
import com.intellij.openapi.actionSystem.AnActionEvent
1010
import com.intellij.openapi.actionSystem.CommonDataKeys
1111
import com.intellij.openapi.diagnostic.logger
@@ -16,8 +16,7 @@ import com.intellij.temporary.error.ErrorPromptBuilder
1616

1717
class FixThisAction : ChatBaseAction() {
1818
init{
19-
val presentation = getTemplatePresentation()
20-
presentation.text = AutoDevBundle.message("settings.autodev.others.fixThis")
19+
presentationText("settings.autodev.others.fixThis", templatePresentation)
2120
}
2221

2322
override fun getActionType(): ChatActionType = ChatActionType.FIX_ISSUE

src/main/kotlin/cc/unitmesh/devti/actions/quick/QuickAssistantAction.kt

Lines changed: 2 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
package cc.unitmesh.devti.actions.quick
22

3-
import cc.unitmesh.devti.AutoDevBundle
43
import cc.unitmesh.devti.custom.TeamPromptBaseIntention
54
import cc.unitmesh.devti.custom.team.TeamPromptAction
65
import cc.unitmesh.devti.custom.team.TeamPromptsBuilder
@@ -9,6 +8,7 @@ import cc.unitmesh.devti.gui.quick.QuickPromptField.Companion.QUICK_ASSISTANT_CA
98
import cc.unitmesh.devti.gui.quick.QuickPromptField.Companion.QUICK_ASSISTANT_SUBMIT_ACTION
109
import cc.unitmesh.devti.intentions.action.task.BaseCompletionTask
1110
import cc.unitmesh.devti.intentions.action.task.CodeCompletionRequest
11+
import cc.unitmesh.devti.settings.LanguageChangedCallback.presentationText
1212
import com.intellij.openapi.actionSystem.*
1313
import com.intellij.openapi.application.runReadAction
1414
import com.intellij.openapi.components.service
@@ -34,8 +34,7 @@ import javax.swing.AbstractAction
3434
*/
3535
open class QuickAssistantAction : AnAction() {
3636
init{
37-
val presentation = getTemplatePresentation()
38-
presentation.text = AutoDevBundle.message("settings.autodev.others.quickAssistant")
37+
presentationText("settings.autodev.others.quickAssistant", templatePresentation)
3938
}
4039

4140
override fun actionPerformed(e: AnActionEvent) {

src/main/kotlin/cc/unitmesh/devti/agent/configurable/CoUnitToolConfigurable.kt

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@ import cc.unitmesh.devti.AutoDevBundle
44
import cc.unitmesh.devti.custom.schema.CUSTOM_AGENT_FILE_NAME
55
import cc.unitmesh.devti.fullWidthCell
66
import cc.unitmesh.devti.gui.component.JsonLanguageField
7+
import cc.unitmesh.devti.settings.LanguageChangedCallback.componentStateChanged
8+
import cc.unitmesh.devti.settings.LanguageChangedCallback.placeholder
79
import com.intellij.openapi.Disposable
810
import com.intellij.openapi.components.service
911
import com.intellij.openapi.options.BoundConfigurable
@@ -18,15 +20,20 @@ class CoUnitToolConfigurable(val project: Project) : BoundConfigurable(AutoDevBu
1820
override fun createPanel(): DialogPanel = panel {
1921
row {
2022
checkBox(AutoDevBundle.message("counit.agent.enable.label")).bindSelected(state::enableCustomRag)
23+
.apply { componentStateChanged("counit.agent.enable.label", this.component){ c,k ->
24+
c.text = k} }
2125
}
2226

2327
row {
2428
val languageField = JsonLanguageField(
2529
project,
2630
state::agentJsonConfig.toString(),
27-
AutoDevBundle.message("counit.agent.json.placeholder"),
31+
AutoDevBundle.messageWithLanguageFromLLMSetting("counit.agent.json.placeholder"),
2832
CUSTOM_AGENT_FILE_NAME
2933
)
34+
.apply {
35+
placeholder("counit.agent.json.placeholder", this)
36+
}
3037
fullWidthCell(languageField)
3138
.bind(
3239
componentGet = { it.text },

0 commit comments

Comments
 (0)