Skip to content

Commit 9ee32a3

Browse files
committed
refactor(config): migrate language setting from global config to prompts config file
1 parent e6f0c39 commit 9ee32a3

3 files changed

Lines changed: 108 additions & 80 deletions

File tree

cmd/config.go

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -103,14 +103,19 @@ func runInteractiveConfig() {
103103

104104
// Language configuration
105105
currentLanguage := config.GetLanguage()
106+
languageOptions := []string{"English", "Spanish", "Other..."}
106107
languagePrompt := &survey.Select{
107108
Message: "Choose a language for commit messages:",
108-
Options: []string{"English (en)", "Español (es)"},
109+
Options: languageOptions,
109110
Default: func() string {
110-
if currentLanguage == "es" {
111-
return "Español (es)"
111+
switch currentLanguage {
112+
case "Spanish":
113+
return "Spanish"
114+
case "English":
115+
return "English"
116+
default:
117+
return "Other..."
112118
}
113-
return "English (en)"
114119
}(),
115120
}
116121
var selectedLanguage string
@@ -120,19 +125,31 @@ func runInteractiveConfig() {
120125
return
121126
}
122127

123-
// Extract language code from selection
124-
langCode := "en"
125-
if selectedLanguage == "Español (es)" {
126-
langCode = "es"
128+
var langValue string
129+
switch selectedLanguage {
130+
case "Spanish":
131+
langValue = "Spanish"
132+
case "English":
133+
langValue = "English"
134+
case "Other...":
135+
otherPrompt := &survey.Input{
136+
Message: "Enter language name (e.g., 'Arabic', 'Korean', 'French'):",
137+
Default: currentLanguage,
138+
}
139+
err = survey.AskOne(otherPrompt, &langValue)
140+
if err != nil {
141+
fmt.Println(err.Error())
142+
return
143+
}
127144
}
128145

129-
if langCode != currentLanguage {
130-
err := config.SetLanguage(langCode)
146+
if langValue != "" && langValue != currentLanguage {
147+
err := config.SetLanguage(langValue)
131148
if err != nil {
132149
fmt.Printf("Error setting language: %v\n", err)
133150
return
134151
}
135-
fmt.Printf("Language set to: %s\n", langCode)
152+
fmt.Printf("Language set to: %s\n", langValue)
136153
}
137154

138155
// API key configuration - skip for copilot and anthropic

internal/config/config.go

Lines changed: 0 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,6 @@ type ProviderConfig struct {
2323
type Config struct {
2424
Providers map[string]ProviderConfig `mapstructure:"providers"`
2525
ActiveProvider string `mapstructure:"active_provider"`
26-
Language string `mapstructure:"language"`
2726
}
2827

2928
var cfg *Config
@@ -46,8 +45,6 @@ func InitConfig() {
4645

4746
viper.SetDefault("providers.anthropic.model", "claude-haiku-4-5")
4847
viper.SetDefault("providers.anthropic.num_suggestions", 10)
49-
viper.SetDefault("language", "en")
50-
5148
viper.AutomaticEnv()
5249

5350
if err := viper.ReadInConfig(); err != nil {
@@ -287,25 +284,6 @@ func SetNumSuggestions(provider, numSuggestions string) error {
287284
return viper.WriteConfig()
288285
}
289286

290-
func GetLanguage() string {
291-
if cfg == nil {
292-
InitConfig()
293-
}
294-
if cfg.Language == "" {
295-
return "en" // Default to English
296-
}
297-
return cfg.Language
298-
}
299-
300-
func SetLanguage(language string) error {
301-
if cfg == nil {
302-
InitConfig()
303-
}
304-
cfg.Language = language
305-
viper.Set("language", language)
306-
return viper.WriteConfig()
307-
}
308-
309287
func getConfigDir() string {
310288
if xdgConfig := os.Getenv("XDG_CONFIG_HOME"); xdgConfig != "" {
311289
return xdgConfig

internal/config/prompts.go

Lines changed: 80 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@ import (
66
"path/filepath"
77

88
"github.com/m7medvision/lazycommit/internal/git"
9+
"github.com/spf13/viper"
910
"gopkg.in/yaml.v3"
1011
)
1112

@@ -18,64 +19,79 @@ type PromptConfig struct {
1819

1920
var promptsCfg *PromptConfig
2021

21-
// InitPromptConfig initializes the prompt configuration
2222
func InitPromptConfig() {
2323
if promptsCfg != nil {
2424
return
2525
}
2626

27-
promptsFile := filepath.Join(getConfigDir(), ".lazycommit.prompts.yaml")
27+
globalPromptsFile := filepath.Join(getConfigDir(), ".lazycommit.prompts.yaml")
28+
globalPrompts := loadPromptConfigFromFile(globalPromptsFile)
29+
30+
if globalPrompts.Language == "" {
31+
legacyLanguage := viper.GetString("language")
32+
if legacyLanguage != "" {
33+
globalPrompts.Language = legacyLanguage
34+
_ = savePromptConfig(globalPromptsFile, globalPrompts)
35+
}
36+
}
37+
38+
effectivePrompts := globalPrompts
2839

2940
if repoRoot, err := git.GetRepoRoot(); err == nil {
3041
localPromptsFile := filepath.Join(repoRoot, ".lazycommit.prompts.yaml")
3142
if _, err := os.Stat(localPromptsFile); err == nil {
32-
promptsFile = localPromptsFile
43+
localPrompts := loadPromptConfigFromFile(localPromptsFile)
44+
effectivePrompts = mergePromptConfigs(globalPrompts, localPrompts)
3345
}
3446
}
3547

36-
if _, err := os.Stat(promptsFile); os.IsNotExist(err) {
37-
// Create default prompts file
38-
defaultConfig := getDefaultPromptConfig()
39-
if err := savePromptConfig(promptsFile, defaultConfig); err != nil {
40-
fmt.Printf("Error creating default prompts file: %v\n", err)
41-
fmt.Printf("Using default prompts\n")
42-
} else {
43-
fmt.Printf("Created default prompts config at %s\n", promptsFile)
44-
}
45-
promptsCfg = defaultConfig
46-
return
48+
promptsCfg = effectivePrompts
49+
}
50+
51+
func loadPromptConfigFromFile(path string) *PromptConfig {
52+
if _, err := os.Stat(path); os.IsNotExist(err) {
53+
return getDefaultPromptConfig()
4754
}
4855

49-
// Load existing prompts file
50-
data, err := os.ReadFile(promptsFile)
56+
data, err := os.ReadFile(path)
5157
if err != nil {
52-
fmt.Printf("Error reading prompts file: %v\n", err)
53-
fmt.Printf("Using default prompts\n")
54-
promptsCfg = getDefaultPromptConfig()
55-
return
58+
return getDefaultPromptConfig()
5659
}
5760

5861
var config PromptConfig
5962
if err := yaml.Unmarshal(data, &config); err != nil {
60-
fmt.Printf("Error parsing prompts file: %v\n", err)
61-
fmt.Printf("Using default prompts\n")
62-
promptsCfg = getDefaultPromptConfig()
63-
return
63+
return getDefaultPromptConfig()
6464
}
6565

66-
promptsCfg = &config
66+
return &config
67+
}
68+
69+
func mergePromptConfigs(global, local *PromptConfig) *PromptConfig {
70+
merged := *global
71+
if local.SystemMessage != "" {
72+
merged.SystemMessage = local.SystemMessage
73+
}
74+
if local.CommitMessageTemplate != "" {
75+
merged.CommitMessageTemplate = local.CommitMessageTemplate
76+
}
77+
if local.PRTitleTemplate != "" {
78+
merged.PRTitleTemplate = local.PRTitleTemplate
79+
}
80+
if local.Language != "" {
81+
merged.Language = local.Language
82+
}
83+
return &merged
6784
}
6885

69-
// getDefaultPromptConfig returns the default prompt configuration
7086
func getDefaultPromptConfig() *PromptConfig {
7187
return &PromptConfig{
7288
SystemMessage: "You are a helpful assistant that generates git commit messages, and pull request titles.",
7389
CommitMessageTemplate: "Based on the following git diff, generate 10 conventional commit messages. Each message should be on a new line, without any numbering or bullet points:\n\n%s",
7490
PRTitleTemplate: "Based on the following git diff, generate 10 pull request title suggestions. Each title should be on a new line, without any numbering or bullet points:\n\n%s",
91+
Language: "English",
7592
}
7693
}
7794

78-
// savePromptConfig saves the prompt configuration to a file
7995
func savePromptConfig(filename string, config *PromptConfig) error {
8096
data, err := yaml.Marshal(config)
8197
if err != nil {
@@ -89,56 +105,73 @@ func savePromptConfig(filename string, config *PromptConfig) error {
89105
return nil
90106
}
91107

92-
// GetPromptConfig returns the current prompt configuration
93108
func GetPromptConfig() *PromptConfig {
94109
if promptsCfg == nil {
95110
InitPromptConfig()
96111
}
97112
return promptsCfg
98113
}
99114

100-
// GetSystemMessageFromConfig returns the system message from configuration
101115
func GetSystemMessageFromConfig() string {
102116
config := GetPromptConfig()
103117
if config.SystemMessage != "" {
104118
return config.SystemMessage
105119
}
106-
// Fallback to hardcoded default
107120
return "You are a helpful assistant that generates git commit messages."
108121
}
109122

110-
// GetCommitMessagePromptFromConfig returns the commit message prompt from configuration
123+
func getLanguageInstruction(language string) string {
124+
if language == "" {
125+
return ""
126+
}
127+
128+
return fmt.Sprintf("\n\nIMPORTANT: Generate all content in %s.", language)
129+
}
130+
111131
func GetCommitMessagePromptFromConfig(diff string) string {
112132
config := GetPromptConfig()
113133
var basePrompt string
114134
if config.CommitMessageTemplate != "" {
115135
basePrompt = fmt.Sprintf(config.CommitMessageTemplate, diff)
116136
} else {
117-
// Fallback to hardcoded default
118137
basePrompt = fmt.Sprintf("Based on the following git diff, generate 10 conventional commit messages. Each message should be on a new line, without any numbering or bullet points:\n\n%s", diff)
119138
}
120139

121-
// Add language instruction based on configuration
122-
language := config.Language
123-
if language == "" {
124-
language = GetLanguage()
125-
}
126-
127-
if language == "es" {
128-
basePrompt += "\n\nIMPORTANT: Generate all commit messages in Spanish."
129-
} else if language == "en" {
130-
basePrompt += "\n\nIMPORTANT: Generate all commit messages in English."
131-
}
140+
basePrompt += getLanguageInstruction(config.Language)
132141

133142
return basePrompt
134143
}
135144

136-
// GetPRTitlePromptFromConfig returns the pull request title prompt from configuration
137145
func GetPRTitlePromptFromConfig(diff string) string {
138146
config := GetPromptConfig()
147+
var basePrompt string
139148
if config.PRTitleTemplate != "" {
140-
return fmt.Sprintf(config.PRTitleTemplate, diff)
149+
basePrompt = fmt.Sprintf(config.PRTitleTemplate, diff)
150+
} else {
151+
basePrompt = fmt.Sprintf("Based on the following git diff, generate 10 pull request title suggestions. Each title should be on a new line, without any numbering or bullet points:\n\n%s", diff)
152+
}
153+
154+
basePrompt += getLanguageInstruction(config.Language)
155+
156+
return basePrompt
157+
}
158+
159+
func SetLanguage(language string) error {
160+
globalPromptsFile := filepath.Join(getConfigDir(), ".lazycommit.prompts.yaml")
161+
globalPrompts := loadPromptConfigFromFile(globalPromptsFile)
162+
globalPrompts.Language = language
163+
err := savePromptConfig(globalPromptsFile, globalPrompts)
164+
if err != nil {
165+
return err
166+
}
167+
168+
if promptsCfg != nil {
169+
promptsCfg.Language = language
141170
}
142-
// Fallback to hardcoded default
143-
return fmt.Sprintf("Based on the following git diff, generate 10 pull request title suggestions. Each title should be on a new line, without any numbering or bullet points:\n\n%s", diff)
171+
172+
return nil
173+
}
174+
175+
func GetLanguage() string {
176+
return GetPromptConfig().Language
144177
}

0 commit comments

Comments
 (0)