diff --git a/src/string_width.gleam b/src/string_width.gleam index 378c1f8..419727e 100644 --- a/src/string_width.gleam +++ b/src/string_width.gleam @@ -519,10 +519,13 @@ pub fn limit_with( // tab has a different width depending on whether or not we will wrap let curr_col = limit_state_col(state) let width = case curr_col <= max_col { - True -> tab(options, curr_col) - False -> - tab(options, state.non_spaces_width + state.overflow_width) + True -> tab(options, options.tab_offset + curr_col) + False -> { + let wrapped_col = state.non_spaces_width + state.overflow_width + tab(options, options.tab_offset + wrapped_col) + } } + commit(max_col, state, piece, width) } diff --git a/test/columns.gleam b/test/columns.gleam index f157060..9cb1db6 100644 --- a/test/columns.gleam +++ b/test/columns.gleam @@ -1,17 +1,40 @@ +import gleam/int import gleam/io +import gleam/list import gleam/string import string_width.{Left, Right, Size, Top} -const max_width = 60 +const max_width = 49 const tab_width = 2 +const left_width = 7 + pub fn main() { - // loop(10_000) - columnate( - left: "\u{1b}[34mhelp\u{1b}[m", - right: "Nihil dolorem eum \u{1b}[31mmagni\u{1b}[m ut et consectetur. Est nisi molestiae occecati iusto\t\taspernatur\tofficiis. Voluptate id dolor vel doloribus eligendi dignissimos recusandae. Consequatur et impedit maiores asperiores qui accusamus. Ea eum dolorem minima veniam suscipit dignissimos animi qui.", + let options = + string_width.new() + //|> string_width.at_tab_offset(int.min(end_col, start_col)) + |> string_width.at_tab_offset(left_width + tab_width) + + string_width.limit_with( + "Nabis sit vel \u{1b}[31mpraesentium\u{1b}[m quod provident hic.\t\taliquid harum perferendis", + to: Size(rows: 500, columns: 40), + ellipsis: "", + using: options, ) + |> string_width.tabs_to_spaces_with(options) + |> io.println + + [ + #( + "\u{1b}[34mabcde\u{1b}[m", + // "Nihil dolorem eum \u{1b}[31mmagni\u{1b}[m ut et consectetur. Est nisi molestiae occecati iusto\t\taspernatur\tofficiis. Voluptate id dolor vel doloribus eligendi dignissimos recusandae. Consequatur et impedit maiores asperiores qui accusamus. Ea eum dolorem minima veniam suscipit dignissimos animi qui.", + "Nabis sit vel \u{1b}[31mpraesentium\u{1b}[m quod provident hic.\t\taliquid harum perferendis qui aut occaecati. Itaque veritatis repellat dolor qui. Ullam cum esse ad eos beatae qui suscipit sint. Nam sum similique culpa consectetur vel vel.", + ), + #("xyz", "12345"), + ] + |> list.map(fn(pair) { columnate(left: pair.0, right: pair.1) }) + |> string.join("\n") |> io.println } @@ -29,14 +52,43 @@ fn loop(i: Int) { } fn columnate(left left: String, right right: String) { - let left_width = string_width.line(left) - let right_width = max_width - left_width - tab_width left <> right - |> string_width.limit(to: Size(rows: 500, columns: right_width), ellipsis: "") - |> string_width.position(Size(rows: 0, columns: right_width), Left, Top, ".") - |> string_width.position(Size(rows: 0, columns: max_width), Right, Top, "-") - |> fast_drop_left(left_width) + |> wrap(from: left_width + tab_width, to: max_width) + |> align(Left, within: max_width - left_width - tab_width, with: ".") + |> align(Right, within: max_width, with: "-") + |> fast_drop_left(string_width.line(left)) +} + +fn align( + str: String, + horizontally: string_width.Alignment, + within width: Int, + with with: String, +) { + let options = + string_width.new() + //|> string_width.at_tab_offset(int.min(end_col, start_col)) + |> string_width.at_tab_offset(left_width + tab_width) + + string_width.position_with( + str, + with: with, + vertical: Top, + horizontal: horizontally, + using: options, + in: Size(rows: 0, columns: width), + ) +} + +fn wrap(str: String, from start_col: Int, to end_col: Int) { + let size = Size(rows: 500, columns: int.absolute_value(end_col - start_col)) + let options = + string_width.new() + //|> string_width.at_tab_offset(int.min(end_col, start_col)) + |> string_width.at_tab_offset(left_width + tab_width) + + string_width.limit_with(str, to: size, using: options, ellipsis: "...") } fn fast_drop_left(str: String, count: Int) { diff --git a/test/layout_test.gleam b/test/layout_test.gleam index 1379b2b..80b9025 100644 --- a/test/layout_test.gleam +++ b/test/layout_test.gleam @@ -54,6 +54,20 @@ pub fn limit_tabs_test() { // would expand to 6 spaces limit("oh hello, hi\tmark", Size(500, 10), "") |> should.equal("oh hello,\nhi\nmark") + + let options = + string_width.new() + |> string_width.at_tab_offset(9) + + string_width.limit_with( + "Nabis sit vel \u{1b}[31mpraesentium\u{1b}[m quod provident hic.\t\taliquid harum perferendis", + to: Size(rows: 500, columns: 40), + ellipsis: "", + using: options, + ) + |> should.equal( + "Nabis sit vel \u{1b}[31mpraesentium\u{1b}[m quod provident\nhic.\t\taliquid harum perferendis", + ) } pub fn tabs_to_spaces_test() {