Skip to content

Commit 5797dab

Browse files
committed
update readme for BindParsers
1 parent aa1c62c commit 5797dab

2 files changed

Lines changed: 61 additions & 11 deletions

File tree

README.md

Lines changed: 32 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -643,7 +643,7 @@ source `start --completion`
643643

644644
Completion will register to your shell by your program name, so you `MUST` give your program a fix name
645645

646-
#### 13. Hide Entry [ >= 1.3.0 ]
646+
#### 13. Hide Entry [ >= 1.3 ]
647647

648648
Sometimes, you want to hide some entry from user, because they should not see or are not necessary to know the entry, but you can still use the entry. Situations like:
649649

@@ -685,7 +685,7 @@ Which will have effect on `Shell Completion Script`
685685

686686
[example](examples/hide-help-entry/main.go)
687687

688-
#### 14. Invoked & InvokeAction [ >= 1.4.0 ]
688+
#### 14. Invoked & InvokeAction [ >= 1.4 ]
689689

690690
When there is valid match for main parser or sub parser, `Parser.Invoked` will be set true. If `Parser.InvokeAction` is set, it will be executed with the state `Parser.Invoked`.
691691

@@ -716,7 +716,7 @@ if e := p.Parse(nil); e != nil {
716716
fmt.Println(p.Invoked, sub.Invoked, subNo2.Invoked)
717717
```
718718

719-
#### 15. Limit args header length [ >= 1.7.0 ]
719+
#### 15. Limit args header length [ >= 1.7 ]
720720

721721
When argument is too long, you can set `ParserConfig.MaxHeaderLength` to a reasonable length.
722722

@@ -748,11 +748,11 @@ options:
748748

749749
[example](examples/long-args/main.go)
750750

751-
#### 16. Inheriable argument [ >= 1.8.0 ]
751+
#### 16. Inheriable argument [ >= 1.8 ]
752752

753753
When some argument represent the same thing among root parser and sub parsers, such as `debug`, `verbose` .... and you don't want to write dumplicate argument code for too many times, you have two recommended ways:
754754

755-
before *v1.8.0*, as all sub parsers are the same type as root parser, use a `for` loop with `Action` to do it.
755+
before *v1.8*, as all sub parsers are the same type as root parser, use a `for` loop with `Action` to do it.
756756

757757
```go
758758
parser := argparse.NewParser("", "", nil)
@@ -773,7 +773,7 @@ if e := parser.Parse(nil); e != nil {
773773
print(url)
774774
```
775775

776-
The code might be less clean, and there comes `Inheritable` , which is an `argument option` . When argument with `&argparse.Option{Inheritable: true}`, sub parsers added __after__ the argument will be able to inherit this argument or override it.
776+
The code might be less clean, and there comes `Inheritable` , which is an `argument option` . When argument with __`&argparse.Option{Inheritable: true}`__, sub parsers added __after__ the argument will be able to inherit this argument or override it.
777777

778778
```go
779779
parser := argparse.NewParser("", "", nil)
@@ -789,6 +789,32 @@ As a result, sub parser `local` will inhert `verbose` as a `Flag`, when pass us
789789
790790
[example](examples/inherit/main.go)
791791

792+
#### 17. Bind given parsers for an argument [ >= 1.9 ]
793+
794+
This is a very flexable way to create argument for multiple parsers. Create one argument using the main parser, and provide a series of parsers by setting the option when you create the argument:
795+
796+
__`Option{BindParsers: []*Parser{a, b, ...}}`__.
797+
798+
```go
799+
parser := argparse.NewParser("", "", nil)
800+
a := parser.AddCommand("a", "", nil)
801+
b := parser.AddCommand("b", "", nil)
802+
c := parser.AddCommand("c", "", nil)
803+
804+
ab := parser.String("", "ab", &argparse.Option{
805+
BindParsers: []*argparse.Parser{a, b},
806+
})
807+
bc := parser.String("", "bc", &argparse.Option{
808+
BindParsers: []*argparse.Parser{b, c},
809+
})
810+
```
811+
812+
As a result, subparser `a` & `b` will bind a `String` argument with entry `--ab` and referred to by var `ab` , subparser `b` & `c` will bind a `String` argument with entry `--bc` and referred to by var `bc`.
813+
814+
__Note__ that both arguments are detached from main `parser`, because you've given the `BindParsers`. If you still want to bind the argument to the main parser, append it to `BindParsers`, like `BindParsers: []*argparse.Parser{b, c, parser}`.
815+
816+
This is one way two share a single argument among different parsers. Be aware that creating argument like this still need to go through conflict check, if there's already a `--ab` exist in `a` or `b` parser, there will be a panic to notice the programer.
817+
792818
##### Argument Process Flow Map
793819

794820
```

docs/cn.md

Lines changed: 29 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -636,7 +636,7 @@ source `start --completion`
636636

637637
命令补全会将命令的名字作为注册入口注册到脚本环境,所以你最好给你的程序一个固定的名字
638638

639-
#### 13. 隐藏入口 [ >= 1.3.0 ]
639+
#### 13. 隐藏入口 [ >= 1.3 ]
640640

641641
有时候, 你可能想要对用户隐藏一些入口, 因为用户不应该知道这些入口或不需要知道,但你依然需要使用这些入口
642642

@@ -680,7 +680,7 @@ options:
680680

681681
[example](../examples/hide-help-entry/main.go)
682682

683-
#### 14. 匹配状态与匹配动作 [ >= 1.4.0 ]
683+
#### 14. 匹配状态与匹配动作 [ >= 1.4 ]
684684

685685
当主解析或子命令解析被匹配到时,`Parser.Invoked` 会设置为 true ,如果设置了 `Parser.InvokeAction` ,那么它会接受`Parser.Invoked` 作为参数被执行
686686

@@ -711,7 +711,7 @@ if e := p.Parse(nil); e != nil {
711711
fmt.Println(p.Invoked, sub.Invoked, subNo2.Invoked)
712712
```
713713

714-
#### 15. 限制参数头部长度 [ >= 1.7.0 ]
714+
#### 15. 限制参数头部长度 [ >= 1.7 ]
715715

716716
如果参数过长,可以设置 `ParserConfig.MaxHeaderLength` 到一个合理的长度。
717717

@@ -743,11 +743,11 @@ options:
743743

744744
[example](../examples/long-args/main.go)
745745

746-
#### 16. 可继承参数 [ >= 1.8.0 ]
746+
#### 16. 可继承参数 [ >= 1.8 ]
747747

748748
如果有参数在根命令和子命令中都表示同样的意思,比如 `debug` (调试状态), `verbose` (回显模式) 等,并且你也不想写太多次重复代码,有两种推荐方式来简化该过程:
749749

750-
*v1.8.0* 以前,由于根命令和子命令的类型都是相同的,可以在 `for` 循环中使用 `Action` 来实现。
750+
*v1.8* 以前,由于根命令和子命令的类型都是相同的,可以在 `for` 循环中使用 `Action` 来实现。
751751

752752
```go
753753
parser := argparse.NewParser("", "", nil)
@@ -786,6 +786,30 @@ version := service.Int("v", "version", &argparse.Option{Help: "version choice"})
786786
787787
[example](../examples/inherit/main.go)
788788

789+
#### 17. 为参数指定绑定命令解析 [ >= 1.9 ]
790+
791+
通过这种方式可以灵活的为多个命令解析器绑定同一个参数。首先通过主命令解析器创建一个参数,然后通过__`Option{BindParsers: []*Parser{a, b, ...}}`__ 为其提供一系列的命令解析器即可。
792+
793+
```go
794+
parser := argparse.NewParser("", "", nil)
795+
a := parser.AddCommand("a", "", nil)
796+
b := parser.AddCommand("b", "", nil)
797+
c := parser.AddCommand("c", "", nil)
798+
799+
ab := parser.String("", "ab", &argparse.Option{
800+
BindParsers: []*argparse.Parser{a, b},
801+
})
802+
bc := parser.String("", "bc", &argparse.Option{
803+
BindParsers: []*argparse.Parser{b, c},
804+
})
805+
```
806+
807+
如此这般,子解析器 `a``b` 将绑定一个入口为 `--ab``String` 类型的参数,通过变量 `ab` 来引用;子解析器 `b``c` 将绑定一个入口为 `--bc``String` 类型参数,通过变量 `bc` 来引用。
808+
809+
__注意__ 两个参数都已经和主解析器解绑了,因为你已经主动指定了 `BindParsers`。如果你依然想要把这个参数绑定到主解析器上,那么就把主解析器追加到 `BindParsers` 即可,如: `BindParsers: []*argparse.Parser{b, c, parser}`
810+
811+
通过这种方式可以在不同的解析器之间共享一个参数。但是注意这种创建方式依然需要进行冲突检测,如果 `a` 或者 `b` 已经绑定了一个 `--ab` 的参数,那么程序员就会收到一个panic。
812+
789813
##### 参数解析流图
790814

791815
```

0 commit comments

Comments
 (0)