-
Notifications
You must be signed in to change notification settings - Fork 279
Expand file tree
/
Copy pathusage_template.go
More file actions
100 lines (95 loc) · 2.74 KB
/
Copy pathusage_template.go
File metadata and controls
100 lines (95 loc) · 2.74 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
package kingpin
import (
"bytes"
"strings"
"text/template"
)
// templateRenderFunc executes usage rendering via text/template.
// This function is stored in Application.templateRenderer when
// UsageTemplate() or UsageFuncs() is called, ensuring that text/template
// is only linked into the binary when templates are actually used.
// Programs that only call UsageRenderer will not reference this function,
// allowing the linker to eliminate text/template and its reflect.MethodByName dependency.
func templateRenderFunc(a *Application, context *ParseContext, indent int, tmpl string) error {
width := guessWidth(a.usageWriter)
var selectedCommand *CmdModel
if context.SelectedCommand != nil {
selectedCommand = context.SelectedCommand.Model()
}
ctx := &UsageContext{
App: a.Model(),
Width: width,
Context: &UsageParseContext{
SelectedCommand: selectedCommand,
FlagGroupModel: context.flags.Model(),
ArgGroupModel: context.arguments.Model(),
},
}
funcs := template.FuncMap{
"Indent": func(level int) string {
return strings.Repeat(" ", level*indent)
},
"Wrap": func(indent int, s string) string {
return Wrap(width, indent, s)
},
"FormatFlag": FormatFlag,
"FormatFlagCompact": FormatFlagCompact,
"FlagsToTwoColumnsCompact": func(f []*FlagModel) [][2]string {
var rows [][2]string
haveShort := ShortFlagsPresent(f)
for _, flag := range f {
if !flag.Hidden {
rows = append(rows, [2]string{FormatFlagCompact(haveShort, flag), flag.Help})
}
}
return rows
},
"FlagsToTwoColumns": FlagsToTwoColumns,
"RequiredFlags": func(f []*FlagModel) []*FlagModel {
var out []*FlagModel
for _, flag := range f {
if flag.Required {
out = append(out, flag)
}
}
return out
},
"OptionalFlags": func(f []*FlagModel) []*FlagModel {
var out []*FlagModel
for _, flag := range f {
if !flag.Required {
out = append(out, flag)
}
}
return out
},
"ArgsToTwoColumns": ArgsToTwoColumns,
"FormatTwoColumns": func(rows [][2]string) string {
var buf bytes.Buffer
FormatTwoColumns(&buf, indent, 2, width, rows)
return buf.String()
},
"FormatTwoColumnsWithIndent": func(rows [][2]string, indent, padding int) string {
var buf bytes.Buffer
FormatTwoColumns(&buf, indent, padding, width, rows)
return buf.String()
},
"FormatAppUsage": formatAppUsage,
"FormatCommandUsage": formatCmdUsage,
"IsCumulative": func(value Value) bool {
r, ok := value.(repeatableFlag)
return ok && r.IsCumulative()
},
"Char": func(c rune) string {
return string(c)
},
}
for k, v := range a.usageFuncs {
funcs[k] = v
}
t, err := template.New("usage").Funcs(funcs).Parse(tmpl)
if err != nil {
return err
}
return t.Execute(a.usageWriter, ctx)
}