Skip to content

Commit

Permalink
Scrollable tab-bar (#437)
Browse files Browse the repository at this point in the history
This implements a scrollable tab bar, like discussed in #233.

This makes tabs easier to read, better utilizes the space in the top-bar
and makes handling many tabs way easier.

The display of the current directory has been removed.
The current tab will show the directory always in full form.
The directories of other tabs will be shown in full form if there is
enough space, otherwise, they will be shown in a short form.
If the available space in the top-bar is still not sufficient, scroll
tags will be added at each end.

The long-form is currently defined as the full, absolute path.
The short-form is currently defined as the last directory element of the
path.

The tab-bar is configurable in terms of font styling and style character
(like dividers, prefixes, and postfixes).

Documentation has been created in a separate file.

Collateral impact:
* The `tilde_in_titlebar` option for `[display]` in `joshuto.toml`
  has been removed.
  (Because the "current dir display" has been removed.)
* The `display_mode` option for `[tabs]` in `joshuto.toml`
  has been removed and with it, also the `tab_bar_mode` command.
  The appearance of index-numbers in tags is not configurable anymore.
  Numbers are shown if and only if there are more than one tab.
  This feature can be re-introduced later in some other form if still
  desired with the new tab-bar.
  With the new tab-bar, this configuration option did not make sense the
  way it was designed.
* The `max_len` option for `[tabs]` in `joshuto.toml`
  has been removed. (Because tabs don't have a fixed width anymore.)
* The function/feature of shortening paths by replacing heading path
  elements with their first character only has been removed.
  (Because I expect that this hard-to-interpret representation of a path
  will rarely be beneficial, now that there is a better space utilization in
  the top bar.)
* The "old" tab-bar configuration options have been removed.
* A `AppStyleOptionsRaw` struct has been introduced to allow handling of
  more complex default styling logic. Each styling attribute is defined
  there as an `Option` to indicate if a styling option has been
  set by the user or not.
* A `PathStyleIfSome` trait is now available in "utils" to patch ratatui
  styles with another, _optional_ style.
  • Loading branch information
DLFW authored Oct 9, 2023
1 parent 55d5092 commit 8412f05
Show file tree
Hide file tree
Showing 33 changed files with 1,714 additions and 416 deletions.
1 change: 0 additions & 1 deletion config/joshuto.toml
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,6 @@ scroll_offset = 6
show_borders = true
show_hidden = false
show_icons = true
tilde_in_titlebar = true
# none, absolute, relative
line_number_style = "none"

Expand Down
28 changes: 23 additions & 5 deletions config/theme.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,30 @@
## Tabs
##########################################

# Inactive tabs
[tabs.inactive]
[tabs]
[tabs.styles]

# Active tabs
[tabs.active]
invert=true
# Style of active tab & current directory
[tabs.styles.active]
bg = "light_blue"
fg = "black"
bold = true

# Style of inactive tabs
[tabs.styles.inactive]

# Style of the left/front tab scroll tag (when tabs overflow)
[tabs.styles.scroll_front]
fg = "yellow"
bold = true

# Style of the right/back tab scroll tag (when tabs overflow)
[tabs.styles.scroll_back]
fg = "yellow"
bold = true

# There are more style options and strings to configure
# the tab-bar theme.

##########################################
## File List - Selections
Expand Down
8 changes: 0 additions & 8 deletions docs/configuration/joshuto.toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -119,14 +119,6 @@ fzf_case_sensitivity = "insensitive"
# ...

[tab]

# Options include
# - num
# - dir
# - all
# also can be changed with the 'tab_bar_mode' command
display_mode = "all"

# inherit, home, root
home_page = "home"
```
264 changes: 264 additions & 0 deletions docs/configuration/tabbar/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,264 @@
# Theming the Tab-Bar
The tab bar in the title row can be configured in various aspects.
This page explains the tab-related configuration options and gives
configuration examples at the end.

## Elements of the Tab-Bar
Of course, the tab-bar is composed from one or more tabs.
Tabs are separated by a _divider_, and if there are more tabs than fit into the window,
there will be _scroll tags_ at the beginning and at the end of the tab bar.
The scroll tags indicate that there are more tabs and each end's scroll tag shows the number
of tabs that did not fit into the tab-bar on that particular side.

The right scroll tag is always right-aligned.
The space between the right scroll tag and the right-most tab is filled by a "padding" segment.

Furthermore, each tab, the padding segment, and the scroll tags, all have a _prefix_ and a _postfix_.
Prefixes and postfixes are additional sub-elements that
help to better visualize the tabs and
allow for some more styling options.


The following list shows an example sequence with four tabs
that includes all the possible segments of a tab-bar.

* <div style="font-family: monospace;">
<span style="background:#BB0505">&nbsp;[pre]&nbsp;</span>
<span style="background:#EE2222">&nbsp;[scroll-f]&nbsp;</span>
<span style="background:#BB0505">&nbsp;[post]&nbsp;</span>&nbsp;&nbsp;(left scroll tag)
</div>
* <div style="font-family: monospace;">
<span style="background:#888888">&nbsp;[pre]&nbsp;</span>
<span style="background:#AAAAAA">&nbsp;[tab 1]&nbsp;</span>
<span style="background:#888888">&nbsp;[post]&nbsp;</span>&nbsp;&nbsp;(inactive tab)
</div>
* <div style="font-family: monospace;">
<span style="background:#779999">&nbsp;[ii]&nbsp;</span>&nbsp;&nbsp;(divider between two inactive tabs)
</div>
* <div style="font-family: monospace;">
<span style="background:#888888">&nbsp;[pre]&nbsp;</span>
<span style="background:#AAAAAA">&nbsp;[tab 2]&nbsp;</span>
<span style="background:#888888">&nbsp;[post]&nbsp;</span>&nbsp;&nbsp;(inactive tab)
</div>
* <div style="font-family: monospace;">
<span style="background:#77AA77">&nbsp;[ia]&nbsp;</span>&nbsp;&nbsp;(divider before active tab)
</div>
* <div style="font-family: monospace;">
<span style="background:#8888BB">&nbsp;[pre]&nbsp;</span>
<span style="background:#9090F0">&nbsp;[tab 3]&nbsp;</span>
<span style="background:#8888BB">&nbsp;[post]&nbsp;</span>&nbsp;&nbsp;(active tab)
</div>
* <div style="font-family: monospace;">
<span style="background:#77AA77">&nbsp;[ai]&nbsp;</span>&nbsp;&nbsp;(divider after active tab)
</div>
* <div style="font-family: monospace;">
<span style="background:#888888">&nbsp;[pre]&nbsp;</span>
<span style="background:#AAAAAA"> tab 4</span>
<span style="background:#888888">&nbsp;[post]&nbsp;</span>&nbsp;&nbsp;(inactive tab)
</div>
* <div style="font-family: monospace;">
<span style="background:#CCBB55">&nbsp;[pre]&nbsp;</span>
<span style="background:#EEDD99">&nbsp;[pad]&nbsp;</span>
<span style="background:#CCBB55">&nbsp;[post]&nbsp;</span>&nbsp;&nbsp;(padding)
</div>
* <div style="font-family: monospace;">
<span style="background:#BB0505">&nbsp;[pre]&nbsp;</span>
<span style="background:#EE2222">&nbsp;[scroll-b]&nbsp;</span>
<span style="background:#BB0505">&nbsp;[post]&nbsp;</span>&nbsp;&nbsp;(right scroll tag)

<!--
<pre>
<span style="background:#BB0505"> pre </span>
<span style="background:#EE2222"> scroll-f </span>
<span style="background:#BB0505"> post </span>
<span style="background:#888888"> pre </span>
<span style="background:#AAAAAA"> tab 1 </span>
<span style="background:#888888"> post </span>
<span style="background:#779999"> ii </span>
<span style="background:#888888"> pre </span>
<span style="background:#AAAAAA"> tab 2 </span>
<span style="background:#888888"> post </span>
<span style="background:#77AA77"> ia </span>
<span style="background:#8888BB"> pre </span>
<span style="background:#9090F0"> tab 3 </span>
<span style="background:#8888BB"> post </span>
<span style="background:#77AA77"> ai </span>
<span style="background:#888888"> pre </span>
<span style="background:#AAAAAA"> tab 4</span>
<span style="background:#888888"> post </span>
<span style="background:#CCBB55"> pre </span>
<span style="background:#EEDD99"> pad </span>
<span style="background:#CCBB55"> post </span>
<span style="background:#BB0505"> pre </span>
<span style="background:#EE2222"> scroll-b </span>
<span style="background:#BB0505"> post </span>
</pre>
-->

## Configuring the Characters
Characters for prefixes, postfixes and some other elements can be configured under a `[tabs.chars]`
section.
This is a complete example for the configuration of the default values:
```toml
[tabs.chars]
active_prefix = " "
active_postfix = " "
inactive_prefix = "["
inactive_postfix = "]"
divider = " "
scroll_front_prefix = ""
scroll_front_postfix = ""
scroll_front_prestring = "«"
scroll_front_poststring = " "
scroll_back_prefix = ""
scroll_back_postfix = ""
scroll_back_prestring = " "
scroll_back_poststring = "»"
padding_prefix = " "
padding_postfix = " "
padding_fill = " "
```
Be aware that all elements for the padding segment are chars and can't be of zero length
or `None`, while the other pre- and postfixes are strings and can also be an empty string.

Further note that the scroll tags also have a `prestring` and `poststring`,
which are strings shown before and after the number in the scroll tag but are still part of the
tag's "body". While the pre- and postfix can have a separate font style (e.g. color),
the pre- and post-string are styled just as the number.

## Configuring Styles (Colors and Font Styles)
Each element of the tab-bar can be configured with a separate style.
The divider can even be configured with three different styles,
one for dividers between two inactive tabs (`divider_ii`),
one for the divider before the active tab (`divider_ia`),
and one for the divider after the active tab (`divider_ai`).

All styles are sub-elements of `[tabs.styles]`.

To ease configuration, most styles are derived from another style and one only
has to specify the deviation.

The following image visualizes all styles and how they are derived from others.

```mermaid
classDiagram
direction LR
active <|-- prefix_active
prefix_active <|-- postfix_active
inactive <|-- prefix_inactive
prefix_inactive <|-- postfix_inactive
divider_ii <|-- divider_ia
divider_ia <|-- divider_ai
scroll_front <|-- scroll_front_prefix
scroll_front_prefix <|-- scroll_front_postfix
scroll_back <|-- scroll_back_prefix
scroll_back_prefix <|-- scroll_back_postfix
padding_fill <|-- padding_prefix
padding_prefix <|-- padding_postfix
```
The left-most styles in the diagram are basic styles which are not
derived from another style.
The default configuration uses these:

```toml
[tabs.styles]

[tabs.styles.active]
bg = "light_blue"
fg = "black"
bold = true

[tabs.styles.scroll_front]
fg = "yellow"
bold = true

[tabs.styles.scroll_back]
fg = "yellow"
bold = true
```

The remaining base styles use the terminal default background and foreground.
The derived styles are all empty by default and therewith equal to their "root-style".

Hint: If one changes even only one attribute of one of the base styles, the default
is not used anymore. For example, if only `[tabs.styles.active.bg]` is set in
`theme.toml`, the two other defaults (`fg` and `bold`) are not used anymore
from the default configuration and need to be specified explicitly if wanted.
If they are specified, they will fall back to the terminal default style.

## Examples

### Rounded Tabs with Arrow-like Scroll Tags
This styling requires a **nerdfont** being used by the terminal.

![Fancy Tab-Bar with Nerdfont](nerdfont_bar_1.png)

This is the configuration that can be copied to `theme.toml`:
```toml
[tabs]

[tabs.chars]
divider = " "
active_prefix = ""
active_postfix = ""
inactive_prefix = ""
inactive_postfix = ""
scroll_front_prefix = ""
scroll_front_postfix = ""
scroll_front_prestring = ""
scroll_front_poststring = ""
scroll_back_prefix = ""
scroll_back_postfix = ""
scroll_back_prestring = ""
scroll_back_poststring = ""

[tabs.styles]

[tabs.styles.active]
fg = "black"
bg = "light_blue"
bold = true

[tabs.styles.active_prefix]
fg = "light_blue"
bg = "reset"

[tabs.styles.inactive]
fg = "black"
bg = "gray"

[tabs.styles.inactive_prefix]
fg = "gray"
bg = "reset"

[tabs.styles.scroll_front]
fg = "black"
bg = "yellow"
bold = true

[tabs.styles.scroll_front_prefix]
fg = "yellow"
bg = "reset"

[tabs.styles.scroll_front_postfix]
invert = true

[tabs.styles.scroll_back]
fg = "black"
bg = "yellow"
bold = true

[tabs.styles.scroll_back_prefix]
fg = "yellow"
bg = "reset"
invert = true

[tabs.styles.scroll_back_postfix]
invert = false
```
Binary file added docs/configuration/tabbar/nerdfont_bar_1.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
2 changes: 2 additions & 0 deletions docs/configuration/theme.toml.md
Original file line number Diff line number Diff line change
Expand Up @@ -61,3 +61,5 @@ a specific style that overrides the former file-type-styles.
Last but not least, there are styles for _selected_ files which override all the former
styles.

## Theming the Tab-Bar
Theming of the tab-bar is described [here](tabbar/README.md).
1 change: 0 additions & 1 deletion src/commands/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -40,7 +40,6 @@ pub mod show_tasks;
pub mod sort;
pub mod sub_process;
pub mod subdir_fzf;
pub mod tab_bar_mode;
pub mod tab_ops;
pub mod touch_file;
pub mod uimodes;
Expand Down
11 changes: 0 additions & 11 deletions src/commands/tab_bar_mode.rs

This file was deleted.

7 changes: 0 additions & 7 deletions src/config/clean/app/display/config.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,6 @@ pub struct DisplayOption {
pub _show_borders: bool,
pub _show_hidden: bool,
pub _show_icons: bool,
pub _tilde_in_titlebar: bool,
pub _line_nums: LineNumberStyle,
pub column_ratio: (usize, usize, usize),
pub default_layout: [Constraint; 3],
Expand Down Expand Up @@ -71,7 +70,6 @@ impl From<DisplayOptionRaw> for DisplayOption {
_show_borders: raw.show_borders,
_show_hidden: raw.show_hidden,
_show_icons: raw.show_icons,
_tilde_in_titlebar: raw.tilde_in_titlebar,
_line_nums,

column_ratio,
Expand Down Expand Up @@ -120,10 +118,6 @@ impl DisplayOption {
self._show_hidden = show_hidden;
}

pub fn tilde_in_titlebar(&self) -> bool {
self._tilde_in_titlebar
}

pub fn line_nums(&self) -> LineNumberStyle {
self._line_nums
}
Expand Down Expand Up @@ -164,7 +158,6 @@ impl std::default::Default for DisplayOption {
_show_borders: true,
_show_hidden: false,
_show_icons: false,
_tilde_in_titlebar: true,
_line_nums: LineNumberStyle::None,
default_layout,
no_preview_layout,
Expand Down
Loading

0 comments on commit 8412f05

Please sign in to comment.