diff --git a/internal/client/config/config.go b/internal/client/config/config.go index 2353747..ce5a62a 100644 --- a/internal/client/config/config.go +++ b/internal/client/config/config.go @@ -3,20 +3,30 @@ package config import ( "encoding/json" "errors" + "fmt" "os" "path/filepath" + "reflect" ) type Config struct { - PrivateKeyPath string + PrivateKeyPath string `json:"private_key_path"` + InsertModeTabToSpace bool `json:"insert_mode_tab_to_space"` + InsertModeSpacesPerTab uint8 `json:"insert_mode_spaces_per_tab"` } func Default() Config { return Config{ - PrivateKeyPath: "", + PrivateKeyPath: "", + InsertModeTabToSpace: true, + InsertModeSpacesPerTab: 4, } } +func Verify(config *Config) error { + return nil +} + var ( config = Config{} Dir string @@ -45,12 +55,42 @@ func Load() error { return err } - err = json.Unmarshal(contents, &config) + var rawMap map[string]json.RawMessage + if err := json.Unmarshal(contents, &rawMap); err != nil { + return err + } + + defaultVal := reflect.ValueOf(Default()) + finalConfig := reflect.New(defaultVal.Type()).Elem() + finalConfig.Set(defaultVal) + + for i := 0; i < defaultVal.NumField(); i++ { + field := defaultVal.Type().Field(i) + jsonTag := field.Tag.Get("json") + if jsonTag == "" { + jsonTag = field.Name + } + + rawValue, found := rawMap[jsonTag] + fieldValue := finalConfig.Field(i) + if !found || !fieldValue.CanAddr() { + continue + } + + err := json.Unmarshal(rawValue, fieldValue.Addr().Interface()) + if err != nil { + return fmt.Errorf("error unmarshaling field %s: %w", field.Name, err) + } + } + + config = finalConfig.Interface().(Config) + + err = Verify(&config) if err != nil { return err } - return nil + return write() } func write() error { diff --git a/internal/client/ui/viminput/viminput.go b/internal/client/ui/viminput/viminput.go index 5017344..270cb73 100644 --- a/internal/client/ui/viminput/viminput.go +++ b/internal/client/ui/viminput/viminput.go @@ -7,6 +7,7 @@ import ( tea "github.com/charmbracelet/bubbletea" "github.com/charmbracelet/lipgloss" + "github.com/kyren223/eko/internal/client/config" "github.com/kyren223/eko/internal/client/ui/colors" "github.com/kyren223/eko/pkg/assert" ) @@ -608,6 +609,20 @@ func (m *Model) handleInsertModeKeys(key tea.KeyMsg) { return } + if key.Type == tea.KeyTab || key.Type == tea.KeyShiftTab { + conf := config.Read() + var runes []rune + if conf.InsertModeTabToSpace { + runes = []rune(strings.Repeat(" ", int(conf.InsertModeSpacesPerTab))) + } else { + runes = []rune{'\t'} + } + line := m.lines[m.cursorLine] + m.lines[m.cursorLine] = slices.Insert(line, m.cursorColumn, runes...) + m.SetCursorColumn(m.cursorColumn + len(runes)) + return + } + if key.Type == tea.KeyBackspace { line := m.lines[m.cursorLine] if m.cursorColumn == 0 && m.cursorLine != 0 {