Skip to content

Zero-dependency Ncdu 1.X themes patcher, written in Python.

License

Notifications You must be signed in to change notification settings

Midblyte/NcduColors

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

28 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

NcduColors preview

Install on PyPi

PyPI Dependencies: 0 License: MIT

Table of content

What is it?

NcduColors is a Python zero-dependency, pre-2.0 Ncdu themes patcher.

Ncdu (NCurses Disk Usage) is a text-user interface disk usage analyzer. It relies on the Ncurses library.

Why?

"I really don't see why anyone would spend time theming a disk usage analyzer they (probably) won't use every day, so I'm hesitant to bloat ncdu with even more config options." - Ncdu developer

Software accessibility is a great issue. Ncdu users know it, too.

The 3-bit and 4-bit basic terminal color palette is almost unusable. Every terminal software uses its own palette. No standard seems to be followed at all.

Because of this, the two colorful themes, dark and darkbg, are hardly usable for many.

Example of the mess of 3-bit and 4-bit colors compatibility has caused

Something is definitely off

Many users (first, second, third, and so on) complained about color issues. I thought it'd be nice to find a solution which could work for the many, not only for me. Also, I use Ncdu a lot, so this definitely was not a waste of time (at the very least, it was a fun learning experience!).

Why not just contributing to Ncdu or forking it?

Contributing or forking Ncdu was an option.

However, there are a few issues with this approach:

  • The Ncdu developer said he's quite hesitant to add more themes support to Ncdu.

  • Even if the needed changes were to be made now, many users on LTS distributions couldn't benefit for months or even years. Think of Debian and Ubuntu-based distributions.

  • Forks are harder to compile, to use, to install and to update for regular users. Also let's not fool ourselves, Linux package management is a mess.

  • Forks rely on developers who fork the original project and are more prone to become abandonware due to their nature, rightfully expected to be "secondary" compared to the mainline project.

Instead, NcduColors's approach allows you to change colors now and how you want, while still retaining the possibility to update Ncdu officially, using your package manager, whenever new versions are available (though you will have to re-patch it).

And: you can uninstall NcduColors while preserving your customised Ncdu.

What about changing the default color palette?

This approach was considered on Ncdu's side, but I think that there will always be someone who doesn't like it. You can't always satisfy everyone when it comes to accessibility issues.

Thus, allowing everybody to painlessy (more or less) patch their own copy of Ncdu seemed the right choice to me.

Also: not everyone loves the black and white (off) theme.

Installation

Install NcduColors from PyPI using Pip:

pip install ncducolors

How to use

You have two choices:

  • You can patch a copy of Ncdu (you won't - usually - need root permissions)

  • You can patch Ncdu in-place (you'll - most likely - need root permissions)

0. If you want to patch a copy of Ncdu

You need to copy ncdu - namely $(command -v ncdu) - into another $PATH directory.

A safe choice could be /usr/local/bin - you can view all of them running tr : '\n' <<< "$PATH" (beware of the order of priority)

Actually, you can copy Ncdu wherever you want.

A $PATH directory is needed just to be able to run Ncdu from anywhere.

From now on, all the steps are in common. Don't forget to specify --ncdu <PATH_TO_NCDU> in the arguments.

1. Extract the default configuration

Run:

ncducolors extract-default-config ncdu-config.json

In case of failure, please open an issue.

1.1 Make a backup

It's a good practice to always make backups, even if not strictly needed.

cp ncdu-config.json ncdu-defaults.json

2. Edit the configuration file

Use your editor of choice to edit the values. Don't edit the offset: it could corrupt the binary.

xdg-open ncdu-config.json

Have a look to the table of reference for some help.

Once finished, save and go ahead.

3. Apply the new configuration

This is the first and only "dangerous" step - well, not really, since you can always fix Ncdu.

Close Ncdu before applying the new configuration, or it won't work.

ncducolors apply-config ncdu-config.json

If you are editing Ncdu in-place, you may need to run NcduColors as root (and, if you installed NcduColors as an unprivileged user, this fixes the "command not found" error).

sudo -E env "PATH=$PATH" ncducolors apply-config ncdu-config.json

4. Done

That's all. You can now run ncdu (or ./path/to/your/copy/of/ncdu).

You can now either:

  • Continue to improve your theme jumping back to step 2.
  • Revert to your default installation.
  • Uninstall NcduColors.

Reverting and recovering from errors

In case something goes wrong, or you just want the plain old Ncdu, don't worry. You can fix it quite easily.

  1. Try to apply the default config using ncducolors apply-config ./ncdu-defaults.json
  2. Try to revert using ncducolors revert --config ./ncdu-config.json (the config is needed just to obtain the offset - in fact, you can use ncducolors revert --offset N too)
  3. If you did a backup, use cp backup-of-ncdu "$(command -v ncdu)" (you may need to be root).
  4. Reinstall Ncdu using your package manager of choice.

Table of reference

Config object

key type notes
ncdu Path (as string) Overridden by --ncdu; autoresolved if null
offset Integer Depends on the binary
off Theme Black and white theme
dark Theme Dark, colorful theme
darkbg Theme (if available) Like dark with forced black background (Ncdu 1.17+)

Theme object

key type notes
default Key Used for most of the UI:
- file names (unselected)
- help pages
box_title Key Used for windows titles:
- "ncdu help"
- "Item info"
- "Confirm delete"
hd Key - Header base text
- Footer base text
- Help page title (selected)
sel Key File row (selected)
num Key Numbers only, without unit:
- file size (unselected)
- size in percentage (unselected)
- child items count (unselected)
- disk usage (Item view)
- apparent size (Item view)
num_hd Key Numbers only, without unit (footer)
num_sel Key Numbers only, without unit:
- file size (selected)
- size in percentage (selected)
key Key Highlighted keys ("Item info", "ncdu help")
key_hd Key - "?" (header)
- "1", "2", "3" ("ncdu help"; selected)
dir Key - File name (directories; unselected)
- Current directory (under the header)
dir_sel Key File name (directories; selected)
flag Key - File rows's leftmost character (unselected)
- Flags ("ncdu help" -> "2:Format")
flag_sel Key File rows's leftmost character (selected)
graph Key Graphical size percentage (unselected)
graph_sel Key Graphical size percentage (selected)

Key object

key type notes
fg Color Foreground color
bg Color Background color
a Attribute Attribute flags

Color object

3-bit and 4-bit colors

Standard colors and high intensity colors - have a look here - 3-bit and 4-bit colors are terminal-dependent, thus their usage is discouraged (prefer 8-bit colors, if possible).

name bit value
Black 0
Red 1
Green 2
Yellow 3
Blue 4
Magenta 5
Cyan 6
White 7
Bright_Black ("Gray") 8
Bright_Red 9
Bright_Green 10
Bright_Yellow 11
Bright_Blue 12
Bright_Magenta 13
Bright_Cyan 14
Bright_White 15

Note: these first 16 colors are aliased to Color0, Color1, and so on, until Color15. In other words, each of the first 16 colors can be represented in two different ways.

This way, Color0 is Black, Color8 is Bright_Black (or Gray), and so on.

8-bit colors

Even 8-bit colors are serialized in the format ColorN, where N is any number from 0 to 255.

8-bit 216 colors cube (3D)

  • Colors 0 to 15 are the 3-bit and 4-bit colors, so nothing new there;
  • Colors 16 to 231 are:
    • part of a 6 × 6 × 6 RGB cube (216 colors in total);
    • mathematical formula: $${\textbf{N} = 36 \cdot {\color{red}{\textbf{R}}} + 6 \cdot {\color{green}{\textbf{G}}} + {\color{blue}{\textbf{B}}} + 16 \hspace{1em} \text{where} \space 0 \le {\color{red}{\textbf{R}}}, {\color{green}{\textbf{G}}}, {\color{blue}{\textbf{B}}} \le 5}$$
    • look to this nice palette for more information and for the lookup-table;
  • Colors 232 to 255 are a grayscale from dark gray (Color232) to light gray (Color255) in 24 steps.
    • Color232 (Dark gray) is aliased to Gray1, while Color255 (Light gray) is aliased to Gray24, and so on for the colors in the middle.

24-bit colors

Seems like there's no simple way to support them (without recreating the entire binary): NcduColors can only allocate 16 bits for the foreground color and 16 bits for the background color.

Default colors

It's the case of null value (preferred) or any other unknown color name.

For example, in a white over black terminal, foreground color becomes white and background color becomes black.

Attribute object

name bit value notes does it work?
Standout 216 Best highlighting mode of the terminal yes
Underline 217 Underlining yes
Reverse 218 Reverse video yes
Blink 219 Blinking yes
Dim 220 Half bright yes
Bold 221 Extra bright or bold yes
Altcharset 222 Alternate character set theoretical support only
Invisible 223 Invisible or blank mode yes
Protect 224 Protected mode ("selective erase") theoretical support only
Horizontal 225 theoretical support only
Left 226 theoretical support only
Low 227 theoretical support only
Right 228 theoretical support only
Top 229 theoretical support only
Vertical 230 theoretical support only

Internally, the attributes are expressed as the sum of each single flag, stored in a 4-bit long unsigned integer.

When serialized as a string, the object is expressed as each attribute's name concatenated by the plus ('+') character.

A value of null resets all attributes.

Note: some texts might appear to be dimmed, but since their attributes are hardencoded elsewhere, they can't be edited via NcduColors.

Remember: not every terminal supports all the available attributes, and sometimes they might deliberately decide to ignore them (e.g. Blink), while others may support it but with different behavior.

Examples

Check the examples/ subdirectory.

What has changed?

Using the colordiff and xxd packages, you can compare your patched Ncdu binary with the old one.

export NC_LENGTH=360       # or 240, for older versions of Ncdu (pre-1.7)
export NC_THEMES_NUMBER=3  # or 2, for older versions of Ncdu (pre-1.7)
export NC_OFFSET=$(printf '0x%x' 123456)  # offset
export NC_BACKUP="/path/to/unpatched/ncdu"
export NC_CURRENT="$(command -v ncdu)"

colordiff -y \
  <(xxd -c $NC_THEMES_NUMBER -s $NC_OFFSET -l $NC_LENGTH $NC_BACKUP) \
  <(xxd -c $NC_THEMES_NUMBER -s $NC_OFFSET -l $NC_LENGTH $NC_CURRENT)

This will output a 15-rows long hex dump, wide 2 or 3 columns (in groups of 2x4 bytes).

Colordiff used to compare two binary sequences

Example - Ncdu 1.15.1 defaults compared to a custom theme

Tests

You need to install autoreconf, autoupdate and a C compiler to run the tests; gcc is recommended.

Future improvements

  • Add support for Ncdu2 (the newer Zig version).

License

MIT License.

This means you can use it everywhere, in both private and commercial contexts, for every possible purpose (you can even re-distribute it), as long as you preserve copyright and license notices.

About

Zero-dependency Ncdu 1.X themes patcher, written in Python.

Topics

Resources

License

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published

Languages