diff --git a/kittens/diff/render.go b/kittens/diff/render.go index bf6daf262..5771798e7 100644 --- a/kittens/diff/render.go +++ b/kittens/diff/render.go @@ -488,7 +488,7 @@ func lines_for_context_chunk(data *DiffData, hunk_num int, chunk *Chunk, chunk_n } func splitlines(text string, width int) []string { - return style.WrapTextAsLines(text, "", width) + return style.WrapTextAsLines(text, width, style.WrapOptions{}) } func render_half_line(line_number int, line, ltype string, available_cols int, center Center, ans []HalfScreenLine) []HalfScreenLine { diff --git a/kittens/unicode_input/main.go b/kittens/unicode_input/main.go index b1c15f10f..372a2c7c7 100644 --- a/kittens/unicode_input/main.go +++ b/kittens/unicode_input/main.go @@ -339,7 +339,7 @@ func (self *handler) draw_screen() { sz, _ := self.lp.ScreenSize() write_help := func(x string) { - lines := style.WrapTextAsLines(x, "", int(sz.WidthCells)-1) + lines := style.WrapTextAsLines(x, int(sz.WidthCells)-1, style.WrapOptions{}) for _, line := range lines { if line != "" { writeln(self.dim_formatter(line)) diff --git a/tools/cli/help.go b/tools/cli/help.go index 55b3fd6f6..33e298cb5 100644 --- a/tools/cli/help.go +++ b/tools/cli/help.go @@ -35,7 +35,7 @@ func (self *Command) ShowVersion() { } func format_with_indent(output io.Writer, text string, indent string, screen_width int) { - indented := style.WrapText(text, indent, screen_width, "#placeholder_for_formatting#") + indented := style.WrapText(text, screen_width, style.WrapOptions{Indent: indent, Ignore_lines_containing: "#placeholder_for_formatting#", Trim_whitespace: true}) io.WriteString(output, indented) io.WriteString(output, "\n") } diff --git a/tools/cli/zsh.go b/tools/cli/zsh.go index fb4723c1d..1674524d2 100644 --- a/tools/cli/zsh.go +++ b/tools/cli/zsh.go @@ -86,7 +86,7 @@ func (self *Match) FormatForCompletionList(max_word_len int, f *markup.Context, word += strings.Repeat(" ", max_word_len-word_len) } if wcswidth.Stringwidth(desc) > max_desc_len { - desc = style.WrapTextAsLines(desc, "", max_desc_len-2)[0] + "…" + desc = style.WrapTextAsLines(desc, max_desc_len-2, style.WrapOptions{})[0] + "…" } if multiline { return word + "\n" + strings.Repeat(" ", max_word_len+2) + desc diff --git a/tools/utils/style/indent-and-wrap.go b/tools/utils/style/indent-and-wrap.go index cfb8a6d5d..e4c5091d7 100644 --- a/tools/utils/style/indent-and-wrap.go +++ b/tools/utils/style/indent-and-wrap.go @@ -468,9 +468,12 @@ func (self *wrapper) wrap_text(text string) []string { return self.lines } -func new_wrapper(indent string, width int) *wrapper { +func new_wrapper(opts WrapOptions, width int) *wrapper { width = utils.Max(2, width) - ans := wrapper{indent: indent, width: width, indent_width: wcswidth.Stringwidth(indent)} + ans := wrapper{indent: opts.Indent, width: width, indent_width: wcswidth.Stringwidth(opts.Indent)} + if opts.Ignore_lines_containing != "" { + ans.ignore_lines_containing = utils.Splitlines(opts.Ignore_lines_containing) + } ans.ep.HandleRune = ans.handle_rune ans.ep.HandleCSI = ans.handle_csi ans.ep.HandleOSC = ans.handle_osc @@ -480,12 +483,17 @@ func new_wrapper(indent string, width int) *wrapper { return &ans } -func WrapTextAsLines(text string, indent string, width int, ignore_lines_containing ...string) []string { - w := new_wrapper(indent, width) - w.ignore_lines_containing = ignore_lines_containing +type WrapOptions struct { + Ignore_lines_containing string + Trim_whitespace bool // trim whitespace at the start and end of lines (start is after indent) + Indent string +} + +func WrapTextAsLines(text string, width int, opts WrapOptions) []string { + w := new_wrapper(opts, width) return w.wrap_text(text) } -func WrapText(text string, indent string, width int, ignore_lines_containing ...string) string { - return strings.Join(WrapTextAsLines(text, indent, width, ignore_lines_containing...), "\n") +func WrapText(text string, width int, opts WrapOptions) string { + return strings.Join(WrapTextAsLines(text, width, opts), "\n") } diff --git a/tools/utils/style/indent-and-wrap_test.go b/tools/utils/style/indent-and-wrap_test.go index 6f94a922e..8878a510f 100644 --- a/tools/utils/style/indent-and-wrap_test.go +++ b/tools/utils/style/indent-and-wrap_test.go @@ -9,28 +9,29 @@ import ( func TestFormatWithIndent(t *testing.T) { - screen_width, indent := 0, "" + screen_width := 0 + opts := WrapOptions{} tx := func(text string, expected ...string) { - q := indent + strings.Join(expected, "") - actual := WrapText(text, indent, screen_width) + q := opts.Indent + strings.Join(expected, "") + actual := WrapText(text, screen_width, opts) if actual != q { t.Fatalf("\nFailed for: %#v\nexpected: %#v\nactual: %#v", text, q, actual) } } - indent = "" + opts.Indent = "" screen_width = 4 tx("one two", "one \ntwo") tx("a b", "a b") screen_width = 3 tx("one tw", "one\n tw") - indent = "__" + opts.Indent = "__" screen_width = 11 tx("testing\n\ntwo", "testing\n\n__two") tx("testing\n \ntwo", "testing\n__ \n__two") - a := strings.Repeat("a", screen_width-len(indent)-1) + a := strings.Repeat("a", screen_width-len(opts.Indent)-1) tx(a+" b", a+" \n__b") tx("123456 \x1b[31m789a", "123456 \n__\x1b[31m789a") @@ -40,7 +41,8 @@ func TestFormatWithIndent(t *testing.T) { tx( "\x1b[31;4:3m\x1b]8;;XXX\x1b\\combined using\x1b]8;;\x1b\\ operators", "\x1b[31;4:3m\x1b]8;;XXX\x1b\\combined \n\x1b[4:0;39m\x1b]8;;\x1b\\__\x1b[4:3;31m\x1b]8;;XXX\x1b\\using\x1b]8;;\x1b\\ \n\x1b[4:0;39m__\x1b[4:3;31moperators") - indent = "" + + opts.Indent = "" screen_width = 3 tx("one", "one") tx("four", "fou\nr")