nushell/crates/nu-table/src/table_theme.rs
German David cb133ed387
feat(table): Add new 'single' table mode (#15672)
<!--
if this PR closes one or more issues, you can automatically link the PR
with
them by using one of the [*linking
keywords*](https://docs.github.com/en/issues/tracking-your-work-with-issues/linking-a-pull-request-to-an-issue#linking-a-pull-request-to-an-issue-using-a-keyword),
e.g.
- this PR should close #xxxx
- fixes #xxxx

you can also mention related issues, PRs or discussions!
-->
closes #15381

# Description
<!--
Thank you for improving Nushell. Please, check our [contributing
guide](../CONTRIBUTING.md) and talk to the core team before making major
changes.

Description of your pull request goes here. **Provide examples and/or
screenshots** if your changes affect the user experience.
-->
Adds a new table mode called `single`, it looks like the `heavy` mode,
but the key difference is that it uses thinner lines. I decided on the
name `single` because it's one of the border styles Neovim uses, and
they look practically the same.

# User-Facing Changes
<!-- List of all changes that impact the user experience here. This
helps us keep track of breaking changes. -->

New config option:

```nushell
$env.config.table.mode = 'single'
```

# Tests + Formatting
<!--
Don't forget to add tests that cover your changes.

Make sure you've run and fixed any issues with these commands:

- `cargo fmt --all -- --check` to check standard code formatting (`cargo
fmt --all` applies these changes)
- `cargo clippy --workspace -- -D warnings -D clippy::unwrap_used` to
check that you're using the standard code style
- `cargo test --workspace` to check that all tests pass (on Windows make
sure to [enable developer
mode](https://learn.microsoft.com/en-us/windows/apps/get-started/developer-mode-features-and-debugging))
- `cargo run -- -c "use toolkit.nu; toolkit test stdlib"` to run the
tests for the standard library

> **Note**
> from `nushell` you can also use the `toolkit` as follows
> ```bash
> use toolkit.nu # or use an `env_change` hook to activate it
automatically
> toolkit check pr
> ```
-->
Added new tests in `crates/nu-table/tests/style.rs` to cover the single
table mode.

# After Submitting
<!-- If your PR had any user-facing changes, update [the
documentation](https://github.com/nushell/nushell.github.io) after the
PR is merged, if necessary. This will help us keep the docs up to date.
-->
2025-05-01 15:30:57 -05:00

181 lines
4.8 KiB
Rust

use tabled::settings::{
style::{HorizontalLine, Style},
themes::Theme,
};
#[derive(Debug, Clone)]
pub struct TableTheme {
base: Theme,
full: Theme,
}
impl TableTheme {
fn new(base: impl Into<Theme>, full: impl Into<Theme>) -> Self {
Self {
base: base.into(),
full: full.into(),
}
}
pub fn basic() -> TableTheme {
Self::new(Style::ascii(), Style::ascii())
}
pub fn thin() -> TableTheme {
Self::new(Style::modern(), Style::modern())
}
pub fn light() -> TableTheme {
let mut theme = Theme::from_style(Style::blank());
theme.insert_horizontal_line(1, HorizontalLine::new('─').intersection('─'));
Self::new(theme, Style::modern())
}
pub fn psql() -> TableTheme {
Self::new(Style::psql(), Style::psql())
}
pub fn markdown() -> TableTheme {
Self::new(Style::markdown(), Style::markdown())
}
pub fn dots() -> TableTheme {
let theme = Style::dots().remove_horizontal();
Self::new(theme, Style::dots())
}
pub fn restructured() -> TableTheme {
Self::new(Style::re_structured_text(), Style::re_structured_text())
}
pub fn ascii_rounded() -> TableTheme {
Self::new(Style::ascii_rounded(), Style::ascii_rounded())
}
pub fn basic_compact() -> TableTheme {
let theme = Style::ascii().remove_horizontal();
Self::new(theme, Style::ascii())
}
pub fn compact() -> TableTheme {
let hline = HorizontalLine::inherit(Style::modern().remove_left().remove_right());
let theme = Style::modern()
.remove_left()
.remove_right()
.remove_horizontal()
.horizontals([(1, hline)]);
Self::new(theme, Style::modern())
}
pub fn with_love() -> TableTheme {
let theme = Style::empty()
.top('❤')
.bottom('❤')
.vertical('❤')
.horizontals([(1, HorizontalLine::new('❤').intersection('❤'))]);
let full_theme = Style::empty()
.top('❤')
.bottom('❤')
.vertical('❤')
.horizontal('❤')
.left('❤')
.right('❤')
.intersection_top('❤')
.corner_top_left('❤')
.corner_top_right('❤')
.intersection_bottom('❤')
.corner_bottom_left('❤')
.corner_bottom_right('❤')
.intersection_right('❤')
.intersection_left('❤')
.intersection('❤');
Self::new(theme, full_theme)
}
pub fn compact_double() -> TableTheme {
let hline = HorizontalLine::inherit(Style::extended())
.remove_left()
.remove_right();
let theme = Style::extended()
.remove_left()
.remove_right()
.remove_horizontal()
.horizontals([(1, hline)]);
Self::new(theme, Style::extended())
}
pub fn rounded() -> TableTheme {
let full = Style::modern()
.corner_top_left('╭')
.corner_top_right('╮')
.corner_bottom_left('╰')
.corner_bottom_right('╯');
Self::new(Style::rounded(), full)
}
pub fn reinforced() -> TableTheme {
let full = Style::modern()
.corner_top_left('┏')
.corner_top_right('┓')
.corner_bottom_left('┗')
.corner_bottom_right('┛');
Self::new(full.clone().remove_horizontal(), full)
}
pub fn heavy() -> TableTheme {
let theme = Style::empty()
.top('━')
.bottom('━')
.vertical('┃')
.left('┃')
.right('┃')
.intersection_top('┳')
.intersection_bottom('┻')
.corner_top_left('┏')
.corner_top_right('┓')
.corner_bottom_left('┗')
.corner_bottom_right('┛')
.horizontals([(1, HorizontalLine::full('━', '╋', '┣', '┫'))]);
let full = theme
.clone()
.remove_horizontals()
.horizontal('━')
.intersection_left('┣')
.intersection_right('┫')
.intersection('╋');
Self::new(theme, full)
}
pub fn single() -> TableTheme {
let full = Style::modern()
.corner_top_left('┌')
.corner_top_right('┐')
.corner_bottom_left('└')
.corner_bottom_right('┘');
Self::new(Style::sharp(), full)
}
pub fn none() -> TableTheme {
Self::new(Style::blank(), Style::blank())
}
pub fn as_full(&self) -> &Theme {
&self.full
}
pub fn as_base(&self) -> &Theme {
&self.base
}
}