| // Copyright IBM Corp. 2014, 2026 | |
| // SPDX-License-Identifier: BUSL-1.1 | |
| package format | |
| import ( | |
| "strings" | |
| "github.com/mitchellh/colorstring" | |
| wordwrap "github.com/mitchellh/go-wordwrap" | |
| ) | |
| // HorizontalRule returns a newline character followed by a number of | |
| // horizontal line characters to fill the given width. | |
| // | |
| // If the given colorize has colors enabled, the rule will also be given a | |
| // dark grey color to attempt to visually de-emphasize it for sighted users. | |
| // | |
| // This is intended for printing to the UI via hashicorp/cli.UI.Output, or | |
| // similar, which will automatically append a trailing newline too. | |
| func HorizontalRule(color *colorstring.Colorize, width int) string { | |
| if width <= 1 { | |
| return "\n" | |
| } | |
| rule := strings.Repeat("─", width-1) | |
| if color == nil { // sometimes unit tests don't populate this properly | |
| return "\n" + rule | |
| } | |
| return color.Color("[dark_gray]\n" + rule) | |
| } | |
| // WordWrap takes a string containing unbroken lines of text and inserts | |
| // newline characters to try to make the text fit within the given width. | |
| // | |
| // The string can already contain newline characters, for example if you are | |
| // trying to render multiple paragraphs of text. (In that case, our usual | |
| // style would be to have _two_ newline characters as the paragraph separator.) | |
| // | |
| // As a special case, any line that begins with at least one space will be left | |
| // unbroken. This allows including literal segments in the output, such as | |
| // code snippets or filenames, where word wrapping would be confusing. | |
| func WordWrap(str string, width int) string { | |
| if width <= 1 { | |
| // Silly edge case. We'll just return the original string to avoid | |
| // panicking or doing other weird stuff. | |
| return str | |
| } | |
| var buf strings.Builder | |
| lines := strings.Split(str, "\n") | |
| for i, line := range lines { | |
| if !strings.HasPrefix(line, " ") { | |
| line = wordwrap.WrapString(line, uint(width-1)) | |
| } | |
| if i > 0 { | |
| buf.WriteByte('\n') // reintroduce the newlines we skipped in Scan | |
| } | |
| buf.WriteString(line) | |
| } | |
| return buf.String() | |
| } |