From 2ddbe2a2bcf3a289811ab5c2dd4091bb476a1252 Mon Sep 17 00:00:00 2001 From: Kovid Goyal Date: Wed, 21 Sep 2022 05:31:19 +0530 Subject: [PATCH] Automatically camel-case destination --- tools/cli/option-from-string.go | 24 ++++++++++++++++++------ tools/cli/types.go | 7 ++++--- tools/utils/strings.go | 20 ++++++++++++++++++++ 3 files changed, 42 insertions(+), 9 deletions(-) create mode 100644 tools/utils/strings.go diff --git a/tools/cli/option-from-string.go b/tools/cli/option-from-string.go index 44713d05b..ab86ab6a3 100644 --- a/tools/cli/option-from-string.go +++ b/tools/cli/option-from-string.go @@ -5,6 +5,7 @@ package cli import ( "bufio" "fmt" + "kitty/tools/utils" "regexp" "strconv" "strings" @@ -12,19 +13,28 @@ import ( var _ = fmt.Print +func camel_case_dest(x string) string { + x = strings.ReplaceAll(strings.ReplaceAll(x, "-", "_"), ",", "") + parts := strings.Split(x, "_") + for i, p := range parts { + parts[i] = utils.Capitalize(p) + } + return strings.Join(parts, "") +} + /* -Create an [Option] from a string. Syntax is:: +Create an [Option] from a string. Syntax is: --option-name, --option-alias, -s type: string dest: destination choices: choice1, choice2, choice 3 depth: 0 - Help text on multiple lines. Indented lines are peserved as indented blocks. Blank lines + Help text on multiple lines. Indented lines are preserved as indented blocks. Blank lines are preserved as blank lines. #placeholder_for_formatting# is replaced by the empty string. Available types are: string, str, list, int, float, count, bool-set, bool-reset, choices -The default dest is the first --option-name which must be a long option. +The default dest is the first --option-name which must be a long option. The destination is automatically CamelCased from snake_case. If choices are specified type is set to choices automatically. If depth is negative option is added to all subcommands. If depth is positive option is added to sub-commands upto the specified depth. @@ -43,14 +53,16 @@ func OptionFromString(entries ...string) (*Option, error) { prev_indent := 0 help := strings.Builder{} help.Grow(2048) + default_was_set := false indent_of_line := func(x string) int { return len(x) - len(strings.TrimLeft(x, " \n\t\v\f")) } set_default := func(x string) { - if ans.Default == "" { + if !default_was_set { ans.Default = x + default_was_set = true } } @@ -59,7 +71,7 @@ func OptionFromString(entries ...string) (*Option, error) { if ans.Aliases == nil { if strings.HasPrefix(line, "--") { parts := strings.Split(line, " ") - ans.Name = strings.ReplaceAll(parts[0], "-", "_") + ans.Name = camel_case_dest(parts[0]) ans.Aliases = make([]Alias, 0, len(parts)) for i, x := range parts { ans.Aliases[i] = Alias{NameWithoutHyphens: strings.TrimLeft(x, "-"), IsShort: !strings.HasPrefix(x, "--")} @@ -108,7 +120,7 @@ func OptionFromString(entries ...string) (*Option, error) { case "default": ans.Default = v case "dest": - ans.Name = v + ans.Name = camel_case_dest(v) case "depth": depth, err := strconv.ParseInt(v, 0, 0) if err != nil { diff --git a/tools/cli/types.go b/tools/cli/types.go index f2393e42b..363cbfb46 100644 --- a/tools/cli/types.go +++ b/tools/cli/types.go @@ -9,6 +9,8 @@ import ( "regexp" "strconv" "strings" + + "kitty/tools/utils" ) var _ = fmt.Print @@ -381,8 +383,7 @@ func (self *Command) GetOptionValues(pointer_to_options_struct interface{}) erro m := make(map[string]*Option, 128) for _, g := range self.OptionGroups { for _, o := range g.Options { - field_name := strings.ReplaceAll(strings.ToUpper(o.Name[:1]+o.Name[1:]), "-", "_") - m[field_name] = o + m[o.Name] = o } } val := reflect.ValueOf(pointer_to_options_struct).Elem() @@ -392,7 +393,7 @@ func (self *Command) GetOptionValues(pointer_to_options_struct interface{}) erro for i := 0; i < val.NumField(); i++ { f := val.Field(i) field_name := val.Type().Field(i).Name - if strings.ToUpper(field_name[:1]) != field_name[:1] || !f.CanSet() { + if utils.Capitalize(field_name) != field_name || !f.CanSet() { continue } opt := m[field_name] diff --git a/tools/utils/strings.go b/tools/utils/strings.go new file mode 100644 index 000000000..0b0587b39 --- /dev/null +++ b/tools/utils/strings.go @@ -0,0 +1,20 @@ +// License: GPLv3 Copyright: 2022, Kovid Goyal, + +package utils + +import ( + "fmt" + "strings" + "unicode/utf8" +) + +var _ = fmt.Print + +func Capitalize(x string) string { + if x == "" { + return x + } + s, sz := utf8.DecodeRuneInString(x) + cr := strings.ToUpper(string(s)) + return cr + x[sz:] +}