github.com/opentofu/opentofu@v1.7.1/internal/command/format/trivia.go (about) 1 // Copyright (c) The OpenTofu Authors 2 // SPDX-License-Identifier: MPL-2.0 3 // Copyright (c) 2023 HashiCorp, Inc. 4 // SPDX-License-Identifier: MPL-2.0 5 6 package format 7 8 import ( 9 "strings" 10 11 "github.com/mitchellh/colorstring" 12 wordwrap "github.com/mitchellh/go-wordwrap" 13 ) 14 15 // HorizontalRule returns a newline character followed by a number of 16 // horizontal line characters to fill the given width. 17 // 18 // If the given colorize has colors enabled, the rule will also be given a 19 // dark grey color to attempt to visually de-emphasize it for sighted users. 20 // 21 // This is intended for printing to the UI via mitchellh/cli.UI.Output, or 22 // similar, which will automatically append a trailing newline too. 23 func HorizontalRule(color *colorstring.Colorize, width int) string { 24 if width <= 1 { 25 return "\n" 26 } 27 rule := strings.Repeat("─", width-1) 28 if color == nil { // sometimes unit tests don't populate this properly 29 return "\n" + rule 30 } 31 return color.Color("[dark_gray]\n" + rule) 32 } 33 34 // WordWrap takes a string containing unbroken lines of text and inserts 35 // newline characters to try to make the text fit within the given width. 36 // 37 // The string can already contain newline characters, for example if you are 38 // trying to render multiple paragraphs of text. (In that case, our usual 39 // style would be to have _two_ newline characters as the paragraph separator.) 40 // 41 // As a special case, any line that begins with at least one space will be left 42 // unbroken. This allows including literal segments in the output, such as 43 // code snippets or filenames, where word wrapping would be confusing. 44 func WordWrap(str string, width int) string { 45 if width <= 1 { 46 // Silly edge case. We'll just return the original string to avoid 47 // panicking or doing other weird stuff. 48 return str 49 } 50 51 var buf strings.Builder 52 lines := strings.Split(str, "\n") 53 for i, line := range lines { 54 if !strings.HasPrefix(line, " ") { 55 line = wordwrap.WrapString(line, uint(width-1)) 56 } 57 if i > 0 { 58 buf.WriteByte('\n') // reintroduce the newlines we skipped in Scan 59 } 60 buf.WriteString(line) 61 } 62 return buf.String() 63 }