| 151 | } |
| 152 | |
| 153 | const render = (self: Usage.Usage, config: CliConfig.CliConfig): Array<Span.Span> => { |
| 154 | switch (self._tag) { |
| 155 | case "Empty": { |
| 156 | return Arr.of(InternalSpan.text("")) |
| 157 | } |
| 158 | case "Mixed": { |
| 159 | return Arr.of(InternalSpan.text("<command>")) |
| 160 | } |
| 161 | case "Named": { |
| 162 | const typeInfo = config.showTypes |
| 163 | ? Option.match(self.acceptedValues, { |
| 164 | onNone: () => InternalSpan.empty, |
| 165 | onSome: (s) => InternalSpan.concat(InternalSpan.space, InternalSpan.text(s)) |
| 166 | }) |
| 167 | : InternalSpan.empty |
| 168 | const namesToShow = config.showAllNames |
| 169 | ? self.names |
| 170 | : self.names.length > 1 |
| 171 | ? pipe( |
| 172 | Arr.filter(self.names, (name) => name.startsWith("--")), |
| 173 | Arr.head, |
| 174 | Option.map(Arr.of), |
| 175 | Option.getOrElse(() => self.names) |
| 176 | ) |
| 177 | : self.names |
| 178 | const nameInfo = InternalSpan.text(Arr.join(namesToShow, ", ")) |
| 179 | return config.showAllNames && self.names.length > 1 |
| 180 | ? Arr.of(InternalSpan.spans([ |
| 181 | InternalSpan.text("("), |
| 182 | nameInfo, |
| 183 | typeInfo, |
| 184 | InternalSpan.text(")") |
| 185 | ])) |
| 186 | : Arr.of(InternalSpan.concat(nameInfo, typeInfo)) |
| 187 | } |
| 188 | case "Optional": { |
| 189 | return Arr.map(render(self.usage, config), (span) => |
| 190 | InternalSpan.spans([ |
| 191 | InternalSpan.text("["), |
| 192 | span, |
| 193 | InternalSpan.text("]") |
| 194 | ])) |
| 195 | } |
| 196 | case "Repeated": { |
| 197 | return Arr.map( |
| 198 | render(self.usage, config), |
| 199 | (span) => InternalSpan.concat(span, InternalSpan.text("...")) |
| 200 | ) |
| 201 | } |
| 202 | case "Alternation": { |
| 203 | if ( |
| 204 | self.left._tag === "Repeated" || |
| 205 | self.right._tag === "Repeated" || |
| 206 | self.left._tag === "Concat" || |
| 207 | self.right._tag === "Concat" |
| 208 | ) { |
| 209 | return Arr.appendAll( |
| 210 | render(self.left, config), |