Revert "Fix #15394 for table -e wrapping issue" (#15498)

Reverts nushell/nushell#15407
Reopens https://github.com/nushell/nushell/issues/15394

@zhiburt Reverting due to some strange coloring I didn't notice before.
Notice the last row. This is the command that produced this table `help
commands | group-by command_type | get external`

![image](https://github.com/user-attachments/assets/ea2d14e3-0efd-4ef2-a3a9-bccbf41a3eae)

This is what it looks like after the revert. Notice the column header
colors. Wrapping is also a little bit different even though my terminal
size didn't change. Notice `search_terms` was kind of eaten above.

![image](https://github.com/user-attachments/assets/526eb8e2-eb87-4aeb-89c1-b88f65354368)
This commit is contained in:
Darren Schroeder 2025-04-05 09:24:16 -05:00 committed by GitHub
parent a72f94f452
commit f25525be6c
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
5 changed files with 408 additions and 523 deletions

View File

@ -1333,15 +1333,7 @@ fn test_expand_big_0() {
"│ target │ {record 3 fields} │",
"│ dev-dependencies │ {record 9 fields} │",
"│ features │ {record 8 fields} │",
"│ │ ╭───┬─────┬─────╮ │",
"│ bin │ │ # │ nam │ pat │ │",
"│ │ │ │ e │ h │ │",
"│ │ ├───┼─────┼─────┤ │",
"│ │ │ 0 │ nu │ src │ │",
"│ │ │ │ │ /ma │ │",
"│ │ │ │ │ in. │ │",
"│ │ │ │ │ rs │ │",
"│ │ ╰───┴─────┴─────╯ │",
"│ bin │ [table 1 row] │",
"│ │ ╭───────────┬───╮ │",
"│ patch │ │ crates-io │ { │ │",
"│ │ │ │ r │ │",
@ -1360,16 +1352,7 @@ fn test_expand_big_0() {
"│ │ │ │ d │ │",
"│ │ │ │ } │ │",
"│ │ ╰───────────┴───╯ │",
"│ │ ╭───┬─────┬─────╮ │",
"│ bench │ │ # │ nam │ har │ │",
"│ │ │ │ e │ nes │ │",
"│ │ │ │ │ s │ │",
"│ │ ├───┼─────┼─────┤ │",
"│ │ │ 0 │ ben │ fal │ │",
"│ │ │ │ chm │ se │ │",
"│ │ │ │ ark │ │ │",
"│ │ │ │ s │ │ │",
"│ │ ╰───┴─────┴─────╯ │",
"│ bench │ [table 1 row] │",
"╰──────────────────┴───────────────────╯",
]);
@ -1383,8 +1366,6 @@ fn table_expande_with_no_header_internally_0() {
let actual = nu!(format!("{} | table --expand --width 141", nu_value.trim()));
_print_lines(&actual.out, 141);
assert_eq!(
actual.out,
join_lines([
@ -1551,191 +1532,71 @@ fn table_expande_with_no_header_internally_0() {
"│ │ │ │ │ │ ╰─────┴──────────╯ │ │ │",
"│ │ │ │ │ display_output │ │ │ │",
"│ │ │ │ ╰────────────────┴────────────────────╯ │ │",
"│ │ │ │ ╭───┬───────────────────────────┬────────────────────────┬────────┬───┬─────╮ │ │",
"│ │ │ menus │ │ # │ name │ only_buffer_difference │ marker │ t │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ y │ │ │ │",
"│ │ │ │ │ │ │ │ │ p │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ ├───┼───────────────────────────┼────────────────────────┼────────┼───┼─────┤ │ │",
"│ │ │ │ │ 0 │ completion_menu │ false │ | │ { │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ │ │ │ │ │ c │ │ │ │",
"│ │ │ │ │ │ │ │ │ o │ │ │ │",
"│ │ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ │ │ │ │ │ d │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ 4 │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ f │ │ │ │",
"│ │ │ │ │ │ │ │ │ i │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ │ │ │ │ │ l │ │ │ │",
"│ │ │ │ │ │ │ │ │ d │ │ │ │",
"│ │ │ │ │ │ │ │ │ s │ │ │ │",
"│ │ │ │ │ │ │ │ │ } │ │ │ │",
"│ │ │ │ │ 1 │ history_menu │ true │ ? │ { │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ │ │ │ │ │ c │ │ │ │",
"│ │ │ │ │ │ │ │ │ o │ │ │ │",
"│ │ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ │ │ │ │ │ d │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ 2 │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ f │ │ │ │",
"│ │ │ │ │ │ │ │ │ i │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ │ │ │ │ │ l │ │ │ │",
"│ │ │ │ │ │ │ │ │ d │ │ │ │",
"│ │ │ │ │ │ │ │ │ s │ │ │ │",
"│ │ │ │ │ │ │ │ │ } │ │ │ │",
"│ │ │ │ │ 2 │ help_menu │ true │ ? │ { │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ │ │ │ │ │ c │ │ │ │",
"│ │ │ │ │ │ │ │ │ o │ │ │ │",
"│ │ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ │ │ │ │ │ d │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ 6 │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ f │ │ │ │",
"│ │ │ │ │ │ │ │ │ i │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ │ │ │ │ │ l │ │ │ │",
"│ │ │ │ │ │ │ │ │ d │ │ │ │",
"│ │ │ │ │ │ │ │ │ s │ │ │ │",
"│ │ │ │ │ │ │ │ │ } │ │ │ │",
"│ │ │ │ │ 3 │ commands_menu │ false │ # │ { │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ │ │ │ │ │ c │ │ │ │",
"│ │ │ │ │ │ │ │ │ o │ │ │ │",
"│ │ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ │ │ │ │ │ d │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ 4 │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ f │ │ │ │",
"│ │ │ │ │ │ │ │ │ i │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ │ │ │ │ │ l │ │ │ │",
"│ │ │ │ │ │ │ │ │ d │ │ │ │",
"│ │ │ │ │ │ │ │ │ s │ │ │ │",
"│ │ │ │ │ │ │ │ │ } │ │ │ │",
"│ │ │ │ │ 4 │ vars_menu │ true │ # │ { │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ │ │ │ │ │ c │ │ │ │",
"│ │ │ │ │ │ │ │ │ o │ │ │ │",
"│ │ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ │ │ │ │ │ d │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ 2 │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ f │ │ │ │",
"│ │ │ │ │ │ │ │ │ i │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ │ │ │ │ │ l │ │ │ │",
"│ │ │ │ │ │ │ │ │ d │ │ │ │",
"│ │ │ │ │ │ │ │ │ s │ │ │ │",
"│ │ │ │ │ │ │ │ │ } │ │ │ │",
"│ │ │ │ │ 5 │ commands_with_description │ true │ # │ { │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ │ │ │ │ │ c │ │ │ │",
"│ │ │ │ │ │ │ │ │ o │ │ │ │",
"│ │ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ │ │ │ │ │ d │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ 6 │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ f │ │ │ │",
"│ │ │ │ │ │ │ │ │ i │ │ │ │",
"│ │ │ │ │ │ │ │ │ e │ │ │ │",
"│ │ │ │ │ │ │ │ │ l │ │ │ │",
"│ │ │ │ │ │ │ │ │ d │ │ │ │",
"│ │ │ │ │ │ │ │ │ s │ │ │ │",
"│ │ │ │ │ │ │ │ │ } │ │ │ │",
"│ │ │ │ ╰───┴───────────────────────────┴────────────────────────┴────────┴───┴─────╯ │ │",
"│ │ │ │ ╭───┬───────────────────────────┬────────────────────────┬────────┬─────╮ │ │",
"│ │ │ menus │ │ # │ name │ only_buffer_difference │ marker │ ... │ │ │",
"│ │ │ │ ├───┼───────────────────────────┼────────────────────────┼────────┼─────┤ │ │",
"│ │ │ │ │ 0 │ completion_menu │ false │ | │ ... │ │ │",
"│ │ │ │ │ 1 │ history_menu │ true │ ? │ ... │ │ │",
"│ │ │ │ │ 2 │ help_menu │ true │ ? │ ... │ │ │",
"│ │ │ │ │ 3 │ commands_menu │ false │ # │ ... │ │ │",
"│ │ │ │ │ 4 │ vars_menu │ true │ # │ ... │ │ │",
"│ │ │ │ │ 5 │ commands_with_description │ true │ # │ ... │ │ │",
"│ │ │ │ ╰───┴───────────────────────────┴────────────────────────┴────────┴─────╯ │ │",
"│ │ │ │ ╭────┬───────────────────────────┬──────────┬─────────┬───────────────┬─────╮ │ │",
"│ │ │ keybindings │ │ # │ name │ modifier │ keycode │ mode │ eve │ │ │",
"│ │ │ │ │ │ │ │ │ │ nt │ │ │",
"│ │ │ keybindings │ │ # │ name │ modifier │ keycode │ mode │ ... │ │ │",
"│ │ │ │ ├────┼───────────────────────────┼──────────┼─────────┼───────────────┼─────┤ │ │",
"│ │ │ │ │ 0 │ completion_menu │ none │ tab │ ╭───┬───────╮ │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ } │ │ │",
"│ │ │ │ │ 0 │ completion_menu │ none │ tab │ ╭───┬───────╮ │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ ╰───┴───────╯ │ │ │ │",
"│ │ │ │ │ 1 │ completion_previous │ shift │ backtab │ ╭───┬───────╮ │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ } │ │ │",
"│ │ │ │ │ 1 │ completion_previous │ shift │ backtab │ ╭───┬───────╮ │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ ╰───┴───────╯ │ │ │ │",
"│ │ │ │ │ 2 │ history_menu │ control │ char_r │ emacs │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 2 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ s} │ │ │",
"│ │ │ │ │ 3 │ next_page │ control │ char_x │ emacs │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ } │ │ │",
"│ │ │ │ │ 4 │ undo_or_previous_page │ control │ char_z │ emacs │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ } │ │ │",
"│ │ │ │ │ 5 │ yank │ control │ char_y │ emacs │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ } │ │ │",
"│ │ │ │ │ 6 │ unix-line-discard │ control │ char_u │ ╭───┬───────╮ │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ } │ │ │",
"│ │ │ │ │ 2 │ history_menu │ control │ char_r │ emacs │ ... │ │ │",
"│ │ │ │ │ 3 │ next_page │ control │ char_x │ emacs │ ... │ │ │",
"│ │ │ │ │ 4 │ undo_or_previous_page │ control │ char_z │ emacs │ ... │ │ │",
"│ │ │ │ │ 5 │ yank │ control │ char_y │ emacs │ ... │ │ │",
"│ │ │ │ │ 6 │ unix-line-discard │ control │ char_u │ ╭───┬───────╮ │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ ╰───┴───────╯ │ │ │ │",
"│ │ │ │ │ 7 │ kill-line │ control │ char_k │ ╭───┬───────╮ │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ } │ │ │",
"│ │ │ │ │ 7 │ kill-line │ control │ char_k │ ╭───┬───────╮ │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ ╰───┴───────╯ │ │ │ │",
"│ │ │ │ │ 8 │ commands_menu │ control │ char_t │ ╭───┬───────╮ │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ d 2 │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ s} │ │ │",
"│ │ │ │ │ 8 │ commands_menu │ control │ char_t │ ╭───┬───────╮ │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ ╰───┴───────╯ │ │ │ │",
"│ │ │ │ │ 9 │ vars_menu │ alt │ char_o │ ╭───┬───────╮ │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ d 2 │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ s} │ │ │",
"│ │ │ │ │ 9 │ vars_menu │ alt │ char_o │ ╭───┬───────╮ │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ ╰───┴───────╯ │ │ │ │",
"│ │ │ │ │ 10 │ commands_with_description │ control │ char_s │ ╭───┬───────╮ │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ d 2 │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ s} │ │ │",
"│ │ │ │ │ 10 │ commands_with_description │ control │ char_s │ ╭───┬───────╮ │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ │ 0 │ emacs │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 1 │ vi_no │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ rmal │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ 2 │ vi_in │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ │ │ sert │ │ │ │ │",
"│ │ │ │ │ │ │ │ │ ╰───┴───────╯ │ │ │ │",
"│ │ │ │ ╰────┴───────────────────────────┴──────────┴─────────┴───────────────┴─────╯ │ │",
"│ │ ╰──────────────────────────────────┴───────────────────────────────────────────────────────────────────────────────╯ │",
@ -1750,8 +1611,6 @@ fn table_expande_with_no_header_internally_1() {
let actual = nu!(format!("{} | table --expand --width 136", nu_value.trim()));
_print_lines(&actual.out, 136);
assert_eq!(
actual.out,
join_lines([
@ -1918,87 +1777,37 @@ fn table_expande_with_no_header_internally_1() {
"│ │ │ │ │ │ ╰─────┴──────────╯ │ │ │",
"│ │ │ │ │ display_output │ │ │ │",
"│ │ │ │ ╰────────────────┴────────────────────╯ │ │",
"│ │ │ │ ╭───┬───────────────────────────┬────────────────────────┬───────┬─────╮ │ │",
"│ │ │ menus │ │ # │ name │ only_buffer_difference │ marke │ ... │ │ │",
"│ │ │ │ │ │ │ │ r │ │ │ │",
"│ │ │ │ ├───┼───────────────────────────┼────────────────────────┼───────┼─────┤ │ │",
"│ │ │ │ │ 0 │ completion_menu │ false │ | │ ... │ │ │",
"│ │ │ │ │ 1 │ history_menu │ true │ ? │ ... │ │ │",
"│ │ │ │ │ 2 │ help_menu │ true │ ? │ ... │ │ │",
"│ │ │ │ │ 3 │ commands_menu │ false │ # │ ... │ │ │",
"│ │ │ │ │ 4 │ vars_menu │ true │ # │ ... │ │ │",
"│ │ │ │ │ 5 │ commands_with_description │ true │ # │ ... │ │ │",
"│ │ │ │ ╰───┴───────────────────────────┴────────────────────────┴───────┴─────╯ │ │",
"│ │ │ │ ╭───┬───────────────────────────┬────────────────────────┬─────╮ │ │",
"│ │ │ menus │ │ # │ name │ only_buffer_difference │ ... │ │ │",
"│ │ │ │ ├───┼───────────────────────────┼────────────────────────┼─────┤ │ │",
"│ │ │ │ │ 0 │ completion_menu │ false │ ... │ │ │",
"│ │ │ │ │ 1 │ history_menu │ true │ ... │ │ │",
"│ │ │ │ │ 2 │ help_menu │ true │ ... │ │ │",
"│ │ │ │ │ 3 │ commands_menu │ false │ ... │ │ │",
"│ │ │ │ │ 4 │ vars_menu │ true │ ... │ │ │",
"│ │ │ │ │ 5 │ commands_with_description │ true │ ... │ │ │",
"│ │ │ │ ╰───┴───────────────────────────┴────────────────────────┴─────╯ │ │",
"│ │ │ │ ╭────┬───────────────────────────┬──────────┬─────────┬──────────┬─────╮ │ │",
"│ │ │ keybindings │ │ # │ name │ modifier │ keycode │ mode │ eve │ │ │",
"│ │ │ │ │ │ │ │ │ │ nt │ │ │",
"│ │ │ keybindings │ │ # │ name │ modifier │ keycode │ mode │ ... │ │ │",
"│ │ │ │ ├────┼───────────────────────────┼──────────┼─────────┼──────────┼─────┤ │ │",
"│ │ │ │ │ 0 │ completion_menu │ none │ tab │ [list 3 │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ } │ │ │",
"│ │ │ │ │ 1 │ completion_previous │ shift │ backtab │ [list 3 │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ } │ │ │",
"│ │ │ │ │ 2 │ history_menu │ control │ char_r │ emacs │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 2 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ s} │ │ │",
"│ │ │ │ │ 3 │ next_page │ control │ char_x │ emacs │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ } │ │ │",
"│ │ │ │ │ 4 │ undo_or_previous_page │ control │ char_z │ emacs │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ } │ │ │",
"│ │ │ │ │ 5 │ yank │ control │ char_y │ emacs │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ } │ │ │",
"│ │ │ │ │ 6 │ unix-line-discard │ control │ char_u │ [list 3 │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ } │ │ │",
"│ │ │ │ │ 7 │ kill-line │ control │ char_k │ [list 3 │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 1 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ } │ │ │",
"│ │ │ │ │ 8 │ commands_menu │ control │ char_t │ [list 3 │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 2 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ s} │ │ │",
"│ │ │ │ │ 9 │ vars_menu │ alt │ char_o │ [list 3 │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 2 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ s} │ │ │",
"│ │ │ │ │ 10 │ commands_with_description │ control │ char_s │ [list 3 │ {re │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ cor │ │ │",
"│ │ │ │ │ │ │ │ │ │ d 2 │ │ │",
"│ │ │ │ │ │ │ │ │ │ fi │ │ │",
"│ │ │ │ │ │ │ │ │ │ eld │ │ │",
"│ │ │ │ │ │ │ │ │ │ s} │ │ │",
"│ │ │ │ │ 0 │ completion_menu │ none │ tab │ [list 3 │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ │ │ │",
"│ │ │ │ │ 1 │ completion_previous │ shift │ backtab │ [list 3 │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ │ │ │",
"│ │ │ │ │ 2 │ history_menu │ control │ char_r │ emacs │ ... │ │ │",
"│ │ │ │ │ 3 │ next_page │ control │ char_x │ emacs │ ... │ │ │",
"│ │ │ │ │ 4 │ undo_or_previous_page │ control │ char_z │ emacs │ ... │ │ │",
"│ │ │ │ │ 5 │ yank │ control │ char_y │ emacs │ ... │ │ │",
"│ │ │ │ │ 6 │ unix-line-discard │ control │ char_u │ [list 3 │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ │ │ │",
"│ │ │ │ │ 7 │ kill-line │ control │ char_k │ [list 3 │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ │ │ │",
"│ │ │ │ │ 8 │ commands_menu │ control │ char_t │ [list 3 │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ │ │ │",
"│ │ │ │ │ 9 │ vars_menu │ alt │ char_o │ [list 3 │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ │ │ │",
"│ │ │ │ │ 10 │ commands_with_description │ control │ char_s │ [list 3 │ ... │ │ │",
"│ │ │ │ │ │ │ │ │ items] │ │ │ │",
"│ │ │ │ ╰────┴───────────────────────────┴──────────┴─────────┴──────────┴─────╯ │ │",
"│ │ ╰──────────────────────────────────┴──────────────────────────────────────────────────────────────────────────╯ │",
"╰────────────────────┴─────────────────────────────────────────────────────────────────────────────────────────────────────────────────╯",
@ -2712,7 +2521,6 @@ fn table_theme_on_border_with_love() {
fn table_theme_on_border_thin() {
assert_eq!(
create_theme_output("thin"),
// ["┌─#─┬a_looooooong_name┬─b─┬─c─┐│ 0 │ 1 │ 2 │ 3 │└─#─┴a_looooooong_name┴─b─┴─c─┘"]
[
"┌─#─┬─a─┬─b─┬───────c────────┐│ 0 │ 1 │ 2 │ 3 │├───┼───┼───┼────────────────┤│ 1 │ 4 │ 5 │ [list 3 items] │└───┴───┴───┴────────────────┘",
"┌─#─┬─a─┬─b─┬───────c────────┐│ 0 │ 1 │ 2 │ 3 │├───┼───┼───┼────────────────┤│ 1 │ 4 │ 5 │ [list 3 items] │└─#─┴─a─┴─b─┴───────c────────┘",
@ -3341,21 +3149,3 @@ fn table_index_expand() {
"
);
}
#[test]
fn table_expand_big_header() {
let actual = nu!("
let column_name = (('' | fill -c 'a' --width 81))
[{ $column_name: 'contents' }] | table -e --width=80
");
assert_eq!(
actual.out,
"╭───┬──────────────────────────────────────────────────────────────────────────╮\
# aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa \
aaaaaaaaa \
\
0 contents \
"
);
}

View File

@ -3,30 +3,33 @@ use std::{cmp::min, collections::HashMap};
use nu_ansi_term::Style;
use nu_color_config::TextStyle;
use nu_protocol::{TableIndent, TrimStrategy};
use nu_utils::strip_ansi_unlikely;
use tabled::{
builder::Builder,
grid::{
ansi::ANSIBuf,
colors::Colors,
config::{AlignmentHorizontal, ColoredConfig, Entity, Position},
dimension::CompleteDimensionVecRecords,
records::{
vec_records::{Cell, Text, VecRecords},
ExactRecords, Records,
ExactRecords, Records, Resizable,
},
},
settings::{
format::FormatContent,
formatting::AlignmentStrategy,
object::{Columns, Rows},
object::{Columns, Row, Rows},
peaker::Priority,
themes::ColumnNames,
width::Truncate,
Alignment, Color, Modify, Padding, TableOption, Width,
Alignment, Color, Format, Modify, ModifyList, Padding, Settings, TableOption, Width,
},
Table,
};
use crate::{convert_style, is_color_empty, string_width, table_theme::TableTheme};
use crate::{convert_style, is_color_empty, table_theme::TableTheme};
pub type NuRecords = VecRecords<NuRecordsValue>;
pub type NuRecordsValue = Text<String>;
@ -241,41 +244,14 @@ impl TableStructure {
}
}
#[derive(Debug, Clone)]
struct HeadInfo {
values: Vec<String>,
align: AlignmentHorizontal,
color: Option<Color>,
}
fn build_table(mut t: NuTable, termwidth: usize) -> Option<String> {
if t.count_columns() == 0 || t.count_rows() == 0 {
return Some(String::new());
}
let mut head = None;
if is_header_on_border(&t) {
head = Some(remove_header(&mut t));
} else {
table_insert_footer(&mut t);
}
let widths = table_truncate(&mut t, head.clone(), termwidth)?;
if let Some(head) = head.as_mut() {
if head.values.len() > widths.len() {
head.values[widths.len() - 1] = String::from("...");
}
}
draw_table(t, widths, head, termwidth)
}
fn is_header_on_border(t: &NuTable) -> bool {
let structure = get_table_structure(&t.data, &t.config);
let is_configured = structure.with_header && t.config.header_on_border;
let has_horizontal = t.config.theme.as_base().borders_has_top()
|| t.config.theme.as_base().get_horizontal_line(1).is_some();
is_configured && has_horizontal
let widths = table_truncate(&mut t, termwidth)?;
table_insert_footer(&mut t);
draw_table(t, widths, termwidth)
}
fn table_insert_footer(t: &mut NuTable) {
@ -284,8 +260,9 @@ fn table_insert_footer(t: &mut NuTable) {
}
}
fn table_truncate(t: &mut NuTable, head: Option<HeadInfo>, termwidth: usize) -> Option<Vec<usize>> {
let widths = maybe_truncate_columns(&mut t.data, &t.config, head, termwidth);
fn table_truncate(t: &mut NuTable, termwidth: usize) -> Option<Vec<usize>> {
let pad = t.config.indent.left + t.config.indent.right;
let widths = maybe_truncate_columns(&mut t.data, &t.config, termwidth, pad);
if widths.is_empty() {
return None;
}
@ -293,52 +270,10 @@ fn table_truncate(t: &mut NuTable, head: Option<HeadInfo>, termwidth: usize) ->
Some(widths)
}
fn remove_header(t: &mut NuTable) -> HeadInfo {
let head: Vec<String> = t
.data
.remove(0)
.into_iter()
.map(|s| s.to_string())
.collect();
let align = t.alignments.header;
let color = is_color_empty(&t.styles.header).then(|| t.styles.header.clone());
// move settings by one row down
t.alignments.cells = t
.alignments
.cells
.drain()
.filter(|(k, _)| k.0 != 0)
.map(|(k, v)| ((k.0 - 1, k.1), v))
.collect();
// move settings by one row down
t.styles.cells = t
.styles
.cells
.drain()
.filter(|(k, _)| k.0 != 0)
.map(|(k, v)| ((k.0 - 1, k.1), v))
.collect();
HeadInfo {
values: head,
align,
color,
}
}
fn draw_table(
t: NuTable,
widths: Vec<usize>,
head: Option<HeadInfo>,
termwidth: usize,
) -> Option<String> {
let mut structure = get_table_structure(&t.data, &t.config);
fn draw_table(t: NuTable, widths: Vec<usize>, termwidth: usize) -> Option<String> {
let structure = get_table_structure(&t.data, &t.config);
let sep_color = t.config.border_color;
if head.is_some() {
structure.with_header = false;
}
let border_header = structure.with_header && t.config.header_on_border;
let data: Vec<Vec<_>> = t.data.into();
let mut table = Builder::from_vec(data).build();
@ -347,51 +282,15 @@ fn draw_table(
load_theme(&mut table, &t.config.theme, &structure, sep_color);
align_table(&mut table, t.alignments, &structure);
colorize_table(&mut table, t.styles, &structure);
truncate_table(&mut table, t.config.clone(), widths, termwidth);
table_set_border_header(&mut table, head, &t.config.theme, structure);
let pad = indent_sum(t.config.indent);
let width_ctrl = WidthCtrl::new(widths, t.config, termwidth, pad);
adjust_table(&mut table, width_ctrl, border_header, structure.with_footer);
table_to_string(table, termwidth)
}
fn table_set_border_header(
table: &mut Table,
head: Option<HeadInfo>,
theme: &TableTheme,
structure: TableStructure,
) {
let head = match head {
Some(head) => head,
None => return,
};
let mut widths = GetDims(Vec::new());
table.with(&mut widths);
if !theme.as_base().borders_has_top() {
let line = theme.as_base().get_horizontal_line(1);
if let Some(line) = line.cloned() {
table.get_config_mut().insert_horizontal_line(0, line);
if structure.with_footer {
let last_row = table.count_rows();
table
.get_config_mut()
.insert_horizontal_line(last_row, line);
}
};
}
if structure.with_footer {
let last_row = table.count_rows();
table.with(SetLineHeaders::new(last_row, head.clone()));
}
table.with(SetLineHeaders::new(0, head));
}
fn truncate_table(table: &mut Table, cfg: TableConfig, widths: Vec<usize>, termwidth: usize) {
table.with(WidthCtrl::new(widths, cfg, termwidth));
}
fn indent_sum(indent: TableIndent) -> usize {
indent.left + indent.right
}
@ -404,10 +303,75 @@ fn get_table_structure(data: &VecRecords<Text<String>>, cfg: &TableConfig) -> Ta
TableStructure::new(with_index, with_header, with_footer)
}
fn adjust_table(table: &mut Table, width_ctrl: WidthCtrl, border_header: bool, with_footer: bool) {
if border_header {
if with_footer {
set_border_head_with_footer(table, width_ctrl);
} else {
set_border_head(table, width_ctrl);
}
} else {
table.with(width_ctrl);
}
}
fn set_indent(table: &mut Table, indent: TableIndent) {
table.with(Padding::new(indent.left, indent.right, 0, 0));
}
fn set_border_head(table: &mut Table, wctrl: WidthCtrl) {
let mut row = GetRow(0, Vec::new());
let mut row_opts = GetRowSettings(0, AlignmentHorizontal::Left, None);
table.with(&mut row);
table.with(&mut row_opts);
table.with(
Settings::default()
.with(strip_color_from_row(0))
.with(wctrl)
.with(MoveRowNext::new(0, 0))
.with(SetLineHeaders::new(0, row.1, row_opts.1, row_opts.2)),
);
}
fn set_border_head_with_footer(table: &mut Table, wctrl: WidthCtrl) {
// note: funnily last and row must be equal at this point but we do not rely on it just in case.
let count_rows = table.count_rows();
let last_row_index = count_rows - 1;
let mut first_row = GetRow(0, Vec::new());
let mut head_settings = GetRowSettings(0, AlignmentHorizontal::Left, None);
let mut last_row = GetRow(last_row_index, Vec::new());
table.with(&mut first_row);
table.with(&mut head_settings);
table.with(&mut last_row);
let head = first_row.1;
let footer = last_row.1;
let alignment = head_settings.1;
let head_color = head_settings.2.clone();
let footer_color = head_settings.2;
table.with(
Settings::default()
.with(strip_color_from_row(0))
.with(strip_color_from_row(count_rows - 1))
.with(wctrl)
.with(MoveRowNext::new(0, 0))
.with(MoveRowPrev::new(last_row_index - 1, last_row_index))
.with(SetLineHeaders::new(0, head, alignment, head_color))
.with(SetLineHeaders::new(
last_row_index - 1,
footer,
alignment,
footer_color,
)),
);
}
fn table_to_string(table: Table, termwidth: usize) -> Option<String> {
let total_width = table.total_width();
@ -423,14 +387,16 @@ struct WidthCtrl {
width: Vec<usize>,
cfg: TableConfig,
width_max: usize,
pad: usize,
}
impl WidthCtrl {
fn new(width: Vec<usize>, cfg: TableConfig, max: usize) -> Self {
fn new(width: Vec<usize>, cfg: TableConfig, max: usize, pad: usize) -> Self {
Self {
width,
cfg,
width_max: max,
pad,
}
}
}
@ -448,9 +414,8 @@ impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for
if need_truncation {
let has_header = self.cfg.structure.with_header && rec.count_rows() > 1;
let as_head = has_header && self.cfg.header_on_border;
let pad = indent_sum(self.cfg.indent);
let trim = TableTrim::new(self.width, self.width_max, self.cfg.trim, as_head, pad);
let trim = TableTrim::new(self.width, self.width_max, self.cfg.trim, as_head, self.pad);
trim.change(rec, cfg, dim);
return;
}
@ -698,22 +663,24 @@ fn load_theme(
fn maybe_truncate_columns(
data: &mut NuRecords,
cfg: &TableConfig,
head: Option<HeadInfo>,
termwidth: usize,
pad: usize,
) -> Vec<usize> {
const TERMWIDTH_THRESHOLD: usize = 120;
let pad = cfg.indent.left + cfg.indent.right;
let preserve_content = termwidth > TERMWIDTH_THRESHOLD;
let has_header = cfg.structure.with_header && data.count_rows() > 1;
let is_header_on_border = has_header && cfg.header_on_border;
if let Some(head) = head {
truncate_columns_by_head(data, &cfg.theme, head, pad, termwidth)
let truncate = if is_header_on_border {
truncate_columns_by_head
} else if preserve_content {
truncate_columns_by_columns(data, &cfg.theme, pad, termwidth)
truncate_columns_by_columns
} else {
truncate_columns_by_content(data, &cfg.theme, pad, termwidth)
}
truncate_columns_by_content
};
truncate(data, &cfg.theme, pad, termwidth)
}
// VERSION where we are showing AS LITTLE COLUMNS AS POSSIBLE but WITH AS MUCH CONTENT AS POSSIBLE.
@ -868,76 +835,51 @@ fn truncate_columns_by_columns(
widths
}
// VERSION where we are showing AS LITTLE COLUMNS AS POSSIBLE but
// WITH AS MUCH CONTENT AS POSSIBLE BY ACCOUNTED BY HEADERS.
// VERSION where we are showing AS LITTLE COLUMNS AS POSSIBLE but WITH AS MUCH CONTENT AS POSSIBLE.
fn truncate_columns_by_head(
data: &mut NuRecords,
theme: &TableTheme,
head: HeadInfo,
pad: usize,
termwidth: usize,
) -> Vec<usize> {
const MIN_ACCEPTABLE_WIDTH: usize = 3;
const TRAILING_COLUMN_WIDTH: usize = 5;
if data.is_empty() {
return vec![0; data.count_columns()];
let config = create_config(theme, false, None);
let mut widths = build_width(&*data, pad);
let total_width = get_total_width2(&widths, &config);
if total_width <= termwidth {
return widths;
}
let mut widths = build_width(data, pad);
if data.is_empty() {
return widths;
}
let head = &data[0];
let config = create_config(theme, false, None);
let borders = config.get_borders();
let has_vertical = borders.has_vertical();
let mut width = borders.has_left() as usize + borders.has_right() as usize;
let mut truncate_pos = 0;
for (i, head) in head.values.iter().enumerate() {
let head_width = string_width(head);
let col_width = widths[i];
if head_width + pad <= col_width {
let move_width = head_width + pad + (i > 0 && has_vertical) as usize;
if width + move_width >= termwidth {
break;
}
for (i, column_header) in head.iter().enumerate() {
let column_header_width = Cell::width(column_header);
width += column_header_width + pad;
width += move_width;
truncate_pos += 1;
continue;
if i > 0 {
width += has_vertical as usize;
}
// NOTE: So header is bigger then a column
// Therefore we must try to expand the column to head text width as much as possible.
//
// The kicker is that we will truncate the header if we can't fit it totally.
// Therefore it's not guaranteed that the column will be expanded to exactly head width.
widths[i] = head_width + pad;
let col_width = widths[i];
let move_width = col_width + (i > 0 && has_vertical) as usize;
if width + move_width >= termwidth {
let mut used_width = width + pad + (i > 0 && has_vertical) as usize;
if i + 1 != widths.len() {
used_width += TRAILING_COLUMN_WIDTH;
}
let available = termwidth.saturating_sub(used_width);
if available > MIN_ACCEPTABLE_WIDTH {
width += available;
widths[i] = available;
truncate_pos += 1;
}
if width >= termwidth {
width -= column_header_width + (i > 0 && has_vertical) as usize + pad;
break;
}
width += move_width;
truncate_pos += 1;
}
// we don't need any truncation then (is it possible?)
if truncate_pos == head.values.len() {
if truncate_pos == head.len() {
return widths;
}
@ -1049,16 +991,63 @@ fn build_width(records: &NuRecords, pad: usize) -> Vec<usize> {
widths
}
struct GetRow(usize, Vec<String>);
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for &mut GetRow {
fn change(
self,
recs: &mut NuRecords,
_: &mut ColoredConfig,
_: &mut CompleteDimensionVecRecords<'_>,
) {
let row = self.0;
self.1 = recs[row].iter().map(|c| c.as_ref().to_owned()).collect();
}
}
struct GetRowSettings(usize, AlignmentHorizontal, Option<Color>);
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>>
for &mut GetRowSettings
{
fn change(
self,
_: &mut NuRecords,
cfg: &mut ColoredConfig,
_: &mut CompleteDimensionVecRecords<'_>,
) {
let row = self.0;
self.1 = *cfg.get_alignment_horizontal(Entity::Row(row));
self.2 = cfg
.get_colors()
.get_color((row, 0))
.cloned()
.map(Color::from);
}
}
// It's laverages a use of guuaranted cached widths before hand
// to speed up things a bit.
struct SetLineHeaders {
line: usize,
head: HeadInfo,
columns: Vec<String>,
alignment: AlignmentHorizontal,
color: Option<Color>,
}
impl SetLineHeaders {
fn new(line: usize, head: HeadInfo) -> Self {
Self { line, head }
fn new(
line: usize,
columns: Vec<String>,
alignment: AlignmentHorizontal,
color: Option<Color>,
) -> Self {
Self {
line,
columns,
alignment,
color,
}
}
}
@ -1082,8 +1071,7 @@ impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for
};
let columns: Vec<_> = self
.head
.values
.columns
.into_iter()
.zip(widths.iter().cloned()) // it must be always safe to do
.map(|(s, width)| Truncate::truncate(&s, width).into_owned())
@ -1091,8 +1079,8 @@ impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for
let mut names = ColumnNames::new(columns)
.line(self.line)
.alignment(Alignment::from(self.head.align));
if let Some(color) = self.head.color {
.alignment(Alignment::from(self.alignment));
if let Some(color) = self.color {
names = names.color(color);
}
@ -1104,25 +1092,163 @@ impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for
}
}
fn theme_copy_horizontal_line(theme: &mut tabled::settings::Theme, from: usize, to: usize) {
if let Some(line) = theme.get_horizontal_line(from) {
theme.insert_horizontal_line(to, *line);
struct MoveRowNext {
row: usize,
line: usize,
}
impl MoveRowNext {
fn new(row: usize, line: usize) -> Self {
Self { row, line }
}
}
struct GetDims(Vec<usize>);
struct MoveRowPrev {
row: usize,
line: usize,
}
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for &mut GetDims {
impl MoveRowPrev {
fn new(row: usize, line: usize) -> Self {
Self { row, line }
}
}
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for MoveRowNext {
fn change(
self,
_: &mut NuRecords,
_: &mut ColoredConfig,
dims: &mut CompleteDimensionVecRecords<'_>,
recs: &mut NuRecords,
cfg: &mut ColoredConfig,
_: &mut CompleteDimensionVecRecords<'_>,
) {
self.0 = dims.get_widths().expect("expected to get it").to_vec();
row_shift_next(recs, cfg, self.row, self.line);
}
fn hint_change(&self) -> Option<Entity> {
None
}
}
impl TableOption<NuRecords, ColoredConfig, CompleteDimensionVecRecords<'_>> for MoveRowPrev {
fn change(
self,
recs: &mut NuRecords,
cfg: &mut ColoredConfig,
_: &mut CompleteDimensionVecRecords<'_>,
) {
row_shift_prev(recs, cfg, self.row, self.line);
}
fn hint_change(&self) -> Option<Entity> {
None
}
}
fn row_shift_next(recs: &mut NuRecords, cfg: &mut ColoredConfig, row: usize, line: usize) {
let count_rows = recs.count_rows();
let count_columns = recs.count_columns();
let has_line = cfg.has_horizontal(line, count_rows);
let has_next_line = cfg.has_horizontal(line + 1, count_rows);
if !has_line && !has_next_line {
return;
}
recs.remove_row(row);
let count_rows = recs.count_rows();
shift_alignments_down(cfg, row, count_rows, count_columns);
shift_colors_down(cfg, row, count_rows, count_columns);
if !has_line {
shift_lines_up(cfg, count_rows, &[line + 1]);
} else {
remove_lines(cfg, count_rows, &[line + 1]);
}
shift_lines_up(cfg, count_rows, &[count_rows]);
}
fn row_shift_prev(recs: &mut NuRecords, cfg: &mut ColoredConfig, row: usize, line: usize) {
let mut count_rows = recs.count_rows();
let count_columns = recs.count_columns();
let has_line = cfg.has_horizontal(line, count_rows);
let has_prev_line = cfg.has_horizontal(line - 1, count_rows);
if !has_line && !has_prev_line {
return;
}
recs.remove_row(row);
if !has_line {
return;
}
count_rows -= 1;
shift_alignments_down(cfg, row, count_rows, count_columns);
shift_colors_down(cfg, row, count_rows, count_columns);
remove_lines(cfg, count_rows, &[line - 1]);
}
fn remove_lines(cfg: &mut ColoredConfig, count_rows: usize, line: &[usize]) {
for &line in line {
cfg.remove_horizontal_line(line, count_rows)
}
}
fn shift_alignments_down(
cfg: &mut ColoredConfig,
row: usize,
count_rows: usize,
count_columns: usize,
) {
for row in row..count_rows {
for col in 0..count_columns {
let pos = (row + 1, col).into();
let posn = (row, col).into();
let align = *cfg.get_alignment_horizontal(pos);
cfg.set_alignment_horizontal(posn, align);
}
let align = *cfg.get_alignment_horizontal(Entity::Row(row + 1));
cfg.set_alignment_horizontal(Entity::Row(row), align);
}
}
fn shift_colors_down(cfg: &mut ColoredConfig, row: usize, count_rows: usize, count_columns: usize) {
for row in row..count_rows {
for col in 0..count_columns {
let pos = (row + 1, col);
let posn = (row, col).into();
let color = cfg.get_colors().get_color(pos).cloned();
if let Some(color) = color {
cfg.set_color(posn, color);
}
}
}
}
fn shift_lines_up(cfg: &mut ColoredConfig, count_rows: usize, lines: &[usize]) {
for &i in lines {
let line = cfg.get_horizontal_line(i).cloned();
if let Some(line) = line {
cfg.insert_horizontal_line(i - 1, line);
cfg.remove_horizontal_line(i, count_rows);
}
}
}
fn theme_copy_horizontal_line(theme: &mut tabled::settings::Theme, from: usize, to: usize) {
if let Some(line) = theme.get_horizontal_line(from) {
theme.insert_horizontal_line(to, *line);
}
}
#[allow(clippy::type_complexity)]
fn strip_color_from_row(row: usize) -> ModifyList<Row, FormatContent<fn(&str) -> String>> {
fn foo(s: &str) -> String {
strip_ansi_unlikely(s).into_owned()
}
Modify::new(Rows::single(row)).with(Format::content(foo))
}

View File

@ -240,7 +240,7 @@ fn expand_list(input: &[Value], cfg: Cfg<'_>) -> TableResult {
}
let mut available = available_width - pad_space;
let mut column_width = 0;
let mut column_width = string_width(&header);
if !is_last_column {
// we need to make sure that we have a space for a next column if we use available width
@ -293,18 +293,9 @@ fn expand_list(input: &[Value], cfg: Cfg<'_>) -> TableResult {
column_rows = column_rows.saturating_add(cell.size);
}
let mut head_width = string_width(&header);
let mut header = header;
if head_width > available {
header = wrap_text(&header, available, cfg.opts.config);
head_width = available;
}
let head_cell = NuRecordsValue::new(header);
data[0].push(head_cell);
column_width = max(column_width, head_width);
if column_width > available {
// remove the column we just inserted
for row in &mut data {

View File

@ -31,27 +31,6 @@ pub fn string_wrap(text: &str, width: usize, keep_words: bool) -> String {
Wrap::wrap(text, width, keep_words)
}
pub fn string_expand(text: &str, width: usize) -> String {
use std::{borrow::Cow, iter::repeat};
use tabled::grid::util::string::{get_line_width, get_lines};
get_lines(text)
.map(|line| {
let length = get_line_width(&line);
if length < width {
let mut line = line.into_owned();
let remain = width - length;
line.extend(repeat(' ').take(remain));
Cow::Owned(line)
} else {
line
}
})
.collect::<Vec<_>>()
.join("\n")
}
pub fn string_truncate(text: &str, width: usize) -> String {
let line = match text.lines().next() {
Some(line) => line,

View File

@ -1,7 +1,6 @@
[files]
extend-exclude = [
".git/",
"crates/nu-command/tests/commands/table.rs",
"crates/nu-cmd-extra/assets/228_themes.json",
"tests/fixtures/formats/",
]