Thursday, February 27, 2025

Adding color to man pages

How to colorize man pages in your terminal

Adding color highlighting to the man pages is similar to code syntax highlighting. I find adding color to the pages helps differentiate variables, strings, and reserved words and makes it easier to visually parse the information presented. I accomplish this by passing ANSI color code parameters to the less pager used in display the man pages.

Configuration Steps

  1. Open your .bashrc file in an editor and add the following lines: 
  2.  
    LESS_TERMCAP_mb=$(printf "\e[01;31m") # enter blinking mode(bold red)  
    export LESS_TERMCAP_mb  
    LESS_TERMCAP_md=$(printf '\e[01;38;5;75m') # enter double-bright mode  
    export LESS_TERMCAP_md  
    LESS_TERMCAP_me=$(printf "\e[0m") # turn off all appearance modes  
    export LESS_TERMCAP_me  
    LESS_TERMCAP_se=$(printf "\e[0m") # leave standout mode  
    export LESS_TERMCAP_se  
    LESS_TERMCAP_so=$(printf "\e[01;33m") # enter standout mode(bold yellow)  
    export LESS_TERMCAP_so  
    LESS_TERMCAP_ue=$(printf "\e[0m") # leave underline mode  
    export LESS_TERMCAP_ue  
    LESS_TERMCAP_us=$(printf '\e[04;38;5;200m') # enter underline mode (magenta)  
    export LESS_TERMCAP_us  
      
    # Turn off Select Graphic Rendition(SGR)  
    # export GROFF_NO_SGR=1  
    # Start with color output disabled (avoid unexpected color code output)  
    export MANROFFOPT="-c"  
      
    # Set options for how less will be used as a pager. 
    # The MANPAGER environment variable will override 
    # settings used by the more general PAGER settings.  
    # In this case, I want to show percentage of page 
    # completion for man pages  
    export MANPAGER='/usr/bin/less -s -M +Gg'  
    export PAGER='/usr/bin/less -s -M'
    
      

  3. Source the .bashrc file (source .bashrc) to read and execute the newly added commands into the current shell.

Notes on groff rendering

Two lines of note in the above configuration: export GROFF_NO_SGR=1 and export MANROFFOPT="-c". One of these is needed in the configuration in order for the man page colorization to work. As I learned this week, there is an issue with newer versions of groff(i.e. newer than 2023)

See the following for details:
Groff + most change in behaviour
Displaying a man page on a terminal with/without my favorite pager shows garbage

Alternate Color Theme

Here is a slightly different color theme:

 
export LESS_TERMCAP_mb=$(printf '\e[01;31m') # (red)
export LESS_TERMCAP_md=$(printf '\e[01;35m') # (bold, magenta)  
export LESS_TERMCAP_me=$(printf '\e[0m')  
export LESS_TERMCAP_se=$(printf '\e[0m') 
export LESS_TERMCAP_so=$(printf '\e[01;33m') # (yellow)  
export LESS_TERMCAP_ue=$(printf '\e[0m') # 
export LESS_TERMCAP_us=$(printf '\e[04;36m') # (cyan)  

Generally, I have come to prefer separating out the color variable definitions from the statements exporting the variable as shown in the first configuration example. This alternate theme example will also work; but, shellcheck gives me an error: SC2155: Declare and assign separately to avoid masking return values. I try to pay attention to tools that I use when they make recommendations that could improve my code and configurations.

See Shellcheck error SC2155 for additional details.

How it all works

To quote liberally from Russell Parker’s post Adding Colors to man

To understand how the above environment variables work it helps to review what steps normally happen when viewing a manpage:

  1. man renders a page from a (likely compressed) nroff or troff/groff document and pipes the result it into the pager program, usually less
  2. If the piped text indicates formatting that needs to be performed then less has to figure out how to accomplish this for terminal output
  3. less uses the (deprecated) termcap database to look up how to achieve effects like underline and bold. In reality it ends up using termcap’s successor, the terminfo database, which maintains support for the termcap interface. This gives back an escape string which corresponds to the specified effect for your particular terminal
  4. Using these nifty escape strings, less finally displays the manpage to the user

Manpages use formatting like bold (for sections) and underlines (for things like file names and arguments). These should already work out of the box when using the man command but will not change the text color.

ANSI Color Codes

To see the ANSI color codes and how they would look on your specific terminal, here is a bash script to print them out.

 
#!/bin/bash  
# name: ansi_codes.sh (see References for link to source)  
for x in {0..5};  
  do echo === && for z in 0 10 60 70;  
  do for y in {30..37};  
  do y=$((y + z)) && printf '\e[%d;%dm%-12s\e[0m' "$x" \
  "$y" "$(printf ' \\e[%d;%dm] ' "$x" "$y")" && printf ' '; 
  done && printf '\n';  
done;  
done

The References section below contains links to several color charts.

References

Thursday, February 20, 2025

Rust and Cargo Cheat sheet

Installing Rust, its crates and how to keep them up to date

Jump to the rust and crate management section for a list of commonly used commands.

Introduction

A couple of years ago, I found a utility called bat that I wanted to try out and possibly use as a partial replacement to the venerable print and concatenation tool named cat. It was written in a program language called Rust which I had heard about in passing and was curious about its rising popularity. The version that was currently available for my Debian system, at the time, lagged a few versions behind the one that I had read about and lacked some of the features that had initially piqued my interest.

I was already using pyenv to manage my Python releases and, I wondered if I could do the same for Rust. I haven’t really had the time, or inclination to become a Rust programmer; but, there were some applications written in Rust that I wanted to use. I wasn’t planning on installing many applications or updating them very frequently, so I needed a place to keep commands that my muscle memory hadn’t yet absorbed.

That’s how this cheat sheet initally started.

This is a very brief guide for installing Rust and managing those crates(applications, packages, or libraries) for people who are not Rust developers and who do not use Rust on a daily basis. It is not intended as a tutorial(see the Resources section for helpful links).

Getting Started

  • The Rust Getting Started page is a good place to begin learning about Rust, its eco-system, and how to create new Rust projects. Here, I’m just going to focus on getting Rust installed and the basics of using cargo, the Rust package manager, to install and upgrade crates. I’ve only used the commands on this page with Debian Linux. So, if you have any issues using them, I would strongly recommend looking at the official Getting Started page for additional information.

Common Rust applications

  • rustc - Rust interpreter
  • rustup - Rust tool chain installer & version management tool
  • cargo - Rust build tool & package manager
  • crates.io - A Rust community registry of libraries and applications

Rust Installation

From your command prompt, run the following:

~$ curl --proto '=https' --tlsv1.2 -sSf https://sh.rustup.rs | sh

By installing this way, rustup will install itself, the Rust tool chain, as well as the cargo package manager. Rust can be uninstalled at any time using the rustup self uninstall command and these changes will be reverted.

Default directories

Rustup metadata and toolchains are installed into the Rustup home directory, located at ~/.rustup. This location can be modified with the RUSTUP_HOME environment variable.

The Cargo home directory is located at ~/.cargo. This location can be modified using the CARGO_HOME environment variable.

The cargo, rustc, rustup and other binaries are added to Cargo’s bin directory, located at ~/.cargo/bin.

Rust and crate management

Steps for upgrading Rust

  • Check the currently installed Rust version
    rustc -V
  • Update Rust
    rustup update
  • Update rustup
    rustup self update

Updating crates

As of Rust 1.41.0, cargo install <crate> will detect if a package is installed. It will upgrade if there is a newer version, or do nothing if the crate is considered up to date. The command will always uninstall, download, and compile the latest version of the crate - even if there is no newer version available.

The cargo-update crate

This crate creates a cargo subcommand for checking and applying updates to installed executables. It helps simplify crate management.

  • cargo-update home page
  • Install cargo-update
    cargo install cargo-update
  • Check for newer versions and update selected packages
    cargo install-update -a

Steps for installing and upgrading crates

  • List installed crates
    cargo install --list
    • Or, add an alias to .bashrc or bash_aliases:
      alias rust_list='cargo install --list
  • Install a crate
    cargo install <package_name>
  • Update all crates
    cargo install-update -a
  • Check for newer versions and update selected packages
    cargo install-update crate1 crate2 ...

Currently Installed Crates

Crates that I have currently on my system and find useful

  • bat A cat(1) clone with syntax highlighting and Git integration.
  • cargo Cargo downloads your Rust project’s dependencies and compiles your project.
  • cargo-update A cargo subcommand for checking and applying updates to installed executables
  • csview A high performance csv viewer with cjk/emoji support
  • htmlq A lightweight, command-line HTML processor
  • iamb A Matrix chat client that uses Vim keybindings
  • zizmor A Static analysis tool for GitHub Actions

Resources

Tuesday, February 11, 2025

Our cat's medical bills

I wasn't expecting the subject of my first post here to be about my cat Anu;
but, if this is the impetus to get me to writing more publicly then I'll use
that as my motivation.

Early last week our cat, Anu, had to be taken in to the emergency care clinic
for surgery to save her life. We had noticed a slight loss of appetite and a
bit of lethargy. My partner got home from work around 7 o'clock on Monday and
noticed some pus/discharge. I had seen her a couple hours before and she had
seemed fine. We remained at the clinic until around four in the morning after
Anu had come out of surgery and we were given a positive prognosis. Much of the
detail of the night is pretty emotional and jumbled, for me, since everything
happened so quickly.

One of the decisions we had to make was having to sign and agree to payment
before most Anu's medical care could proceed. We wouldn't have made a different
decision; but, having to do that in the midst of an already highly emotional
event was frustrating to say the least. We are now looking at a medical bill
of around nine thousand dollars that we really cannot afford. This is the
reason for my posting today. We could really use some financial assistance to
help us get by.

It's been a week since Anu came home. She seems to be recovering well.
We've completed her course of antibiotics and kitty sedatives. She's not eating
as much as I like; but, I think much of that may be due to her cone-of-shame
somewhat hindering her mobility. We've got a follow up appointment with her
regular veterinarian tomorrow.

So I am asking anyone reading to consider helping us out financially to pay down
this bill. Any amount will help and will be deeply appreciated.

I was intending for my posts here to focus more on my technical, open source
contributions and work. Hopefully, with your help, I can start to do that in
the future.

Thanks for reading this. I appreciate it.

My ko-fi page
My LiberaPay page