Skip to main content

LESSOPEN filter for Markdown rendering and syntax highlighting with less

Project description

richless

A LESSOPEN filter for automatically rendering Markdown files and syntax highlighting source code when using less. View your Markdown documents with beautiful formatting and programming language files with syntax highlighting directly in the terminal, without changing how you use less.

Quick Start

# 1. Install richless via Homebrew (macOS or Linux)
brew install DavidJBianco/tools/richless

# 2. Add shell integration to your ~/.bashrc or ~/.zshrc
# (brew will print the exact path after install)
source $(brew --prefix)/share/richless/richless-init.sh

# 3. Reload your shell
source ~/.bashrc  # or ~/.zshrc

# 4. Try it!
less README.md       # View rendered Markdown
less richless.py     # View syntax-highlighted Python

Features

  • Seamless Integration: Works transparently with less via LESSOPEN
  • Automatic Markdown Rendering: Recognizes .md and .markdown files automatically and renders them beautifully
  • Rich Terminal Formatting: Beautiful rendering with headers, lists, code blocks, tables, and more
  • Data Format Highlighting: Syntax highlighting for JSON, JSONL, YAML, and XML files with automatic detection
  • Code Highlighting: Syntax highlighting for 500+ programming languages (Python, JavaScript, Go, Rust, and more)
  • Works with Wildcards: less *.md or less *.py just works
  • Correct Filenames: Shows actual filenames in less, not temporary files
  • Powered by rich and Pygments: Leverages rich for beautiful terminal output and Pygments for syntax highlighting

Installation

Homebrew (Preferred — macOS and Linux)

brew install DavidJBianco/tools/richless

After installation, add the shell integration to your ~/.bashrc or ~/.zshrc:

source $(brew --prefix)/share/richless/richless-init.sh

Then reload your shell:

source ~/.bashrc  # or source ~/.zshrc

pip / uv (Alternative)

If you prefer not to use Homebrew, you can install from PyPI:

# With uv
uv tool install richless

# Or with pip
pip install richless

Then copy the shell integration script and source it:

# Download the init script
curl -o ~/.richless-init.sh https://raw.githubusercontent.com/DavidJBianco/richless/main/richless-init.sh

# Add to your ~/.bashrc or ~/.zshrc
echo 'source ~/.richless-init.sh' >> ~/.bashrc  # or ~/.zshrc

# Reload your shell
source ~/.bashrc  # or source ~/.zshrc

Note: If you see a warning about PATH after uv tool install, run:

export PATH="$HOME/.local/bin:$PATH"
# Add this line to your ~/.bashrc or ~/.zshrc to make it permanent

Shell Integration Options

The shell integration script (sourced above) provides the full-featured transparent wrapper around less. This is the recommended setup and what Quick Start uses.

What you get:

  • ✅ Automatic Markdown rendering when you run less file.md
  • ✅ Syntax highlighting for programming language source files (Python, JavaScript, etc.)
  • ✅ Works with wildcards: less *.md or less *.py
  • ✅ Piped input works: cat file.md | less renders markdown
  • ✅ Force markdown flag: less --md document.txt forces rendering
  • ✅ Auto-detection: Intelligently detects markdown in piped content
  • ✅ Backward compatible: Acts like normal less when not needed

Note: The shell integration file is compatible with sh, bash, and zsh.

Minimal Setup (without shell wrapper)

If you prefer not to use the shell wrapper, you can manually set two environment variables instead. Add these lines to your ~/.bashrc, ~/.zshrc, or ~/.profile:

export LESSOPEN="|richless %s"
export LESS="-R"

This gives you automatic Markdown rendering and syntax highlighting for files, but piped input (cat file.md | less) and the --md flag won't work.

Usage

Once configured, just use less normally! Markdown files will be automatically rendered, and source code files will be syntax highlighted.

Basic Usage (Both Options)

# View a Markdown file (automatically rendered)
less README.md

# View multiple Markdown files
less *.md

# View with wildcards
less docs/**/*.md

# Source code files get syntax highlighting automatically
less script.py           # Python
less app.js              # JavaScript
less main.go             # Go
less config.json         # JSON
less styles.css          # CSS

# All standard less options work
less -N README.md        # Show line numbers
less -i script.py        # Case-insensitive search
less +50 README.md       # Start at line 50

Additional Features (Option 2 / Quick Start)

If you followed the Quick Start or are using Option 2, you also get these features:

# Force Markdown rendering on non-.md files
less --md document.txt
less -m notes.txt

# Piped input works!
cat file.md | less
echo "# Hello\n**World**" | less --md

# Pipe from other commands
curl https://example.com/README.md | less --md
grep -A 50 "## Section" doc.md | less

# Auto-detection: if piped content looks like markdown, it renders automatically
cat file.md | less  # Detects markdown syntax and renders

Direct richless Usage

You can also call richless directly if needed:

# Render and pipe to less
richless document.md | less -R

# Force markdown rendering
richless --md document.txt | less -R

# Read from stdin
cat file.md | richless --md - | less -R
echo "# Test" | richless --md - | less -R

Standard less Commands

All standard less commands work normally inside the pager:

  • /pattern - Search forward
  • ?pattern - Search backward
  • n / N - Next/previous match
  • g / G - Go to start/end
  • q - Quit
  • h - Help

How It Works

Basic Mode (Option 1):

  1. When you run less file.md, the LESSOPEN environment variable tells less to run richless file.md first
  2. richless detects the .md extension and uses the rich library to render the Markdown
  3. rich renders the Markdown to beautifully formatted ANSI text with proper table support
  4. The formatted output is piped to less for viewing
  5. For programming language source files (.py, .js, .java, etc.), rich automatically provides syntax highlighting using Pygments

Transparent Wrapper (Option 2):

  • The shell function intercepts calls to less before they execute
  • For regular files, it passes through to the basic LESSOPEN mechanism
  • For piped input or when --md is specified, it saves the content to a temp file and renders it
  • Auto-detection checks piped content for markdown patterns (headers, lists, links, etc.)

Troubleshooting

"richless: command not found"

Make sure ~/.local/bin is in your PATH:

export PATH="$HOME/.local/bin:$PATH"
# Add this to your ~/.bashrc or ~/.zshrc

Piped input doesn't work

If you're using Option 1 (Basic LESSOPEN), piped input won't work. Either:

  • Switch to Option 2 / Quick Start for piped input support
  • Or use: cat file.md | richless --md - | less -R

Colors don't show up

If you're using Option 1 (manual setup), make sure you have the -R flag set:

export LESS="-R"

The init script (Option 2 / Quick Start) sets this automatically.

Shell function not loading

Make sure you're sourcing the init script, not executing it:

source ~/.richless-init.sh  # Correct
./richless-init.sh          # Wrong - this won't define the function in your shell

After sourcing, "less file.md" shows an error

Make sure you've reinstalled richless after any updates:

uv tool uninstall richless
uv tool install .
source ~/.richless-init.sh  # Re-source to pick up changes

Updating

# Homebrew
brew upgrade richless

# uv
uv tool upgrade richless

Uninstalling

# Homebrew
brew uninstall richless

# uv
uv tool uninstall richless
rm ~/.richless-init.sh

After uninstalling, remove the source ...richless-init.sh line from your ~/.bashrc or ~/.zshrc.

Development

# Clone the repository
git clone https://github.com/DavidJBianco/richless.git
cd richless

# Install dependencies
uv sync

# Install in development mode
uv tool install --editable .

# Make changes, then reinstall
uv tool install --editable . --force

# Test it
less README.md

# Run tests
uv run pytest tests/test_richless.py -v

Dependencies

  • rich - Python library for rich terminal output, Markdown rendering, and syntax highlighting
  • Pygments - Syntax highlighting library
  • Python 3.12+

Comparison to Alternatives

vs. glow / mdcat / bat:

  • richless integrates directly with less, so you use your familiar pager commands
  • Works transparently - no need to remember a different command
  • Supports all standard less features (search, navigation, etc.)

vs. vimpager:

  • Lighter weight, doesn't require Vim
  • Uses rich library's excellent Markdown rendering with full table support
  • Simple LESSOPEN integration

License

See LICENSE file for details.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

richless-0.2.3.tar.gz (10.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

richless-0.2.3-py3-none-any.whl (8.0 kB view details)

Uploaded Python 3

File details

Details for the file richless-0.2.3.tar.gz.

File metadata

  • Download URL: richless-0.2.3.tar.gz
  • Upload date:
  • Size: 10.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for richless-0.2.3.tar.gz
Algorithm Hash digest
SHA256 9d3640131b213331bcc21838ad0367dd2ecd243b7f1ab51a1c1d4a315310602b
MD5 fc75a5fac9422c891c5848b5e955d924
BLAKE2b-256 a80fa48269e327619d9334316322a170d0b9b2fafc81b1e8c91225805d686509

See more details on using hashes here.

Provenance

The following attestation bundles were made for richless-0.2.3.tar.gz:

Publisher: publish.yml on DavidJBianco/richless

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file richless-0.2.3-py3-none-any.whl.

File metadata

  • Download URL: richless-0.2.3-py3-none-any.whl
  • Upload date:
  • Size: 8.0 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for richless-0.2.3-py3-none-any.whl
Algorithm Hash digest
SHA256 0560b7ec80d3de1ba731fb869a8e601efe4c8e0f540d28045e740ba65433d68e
MD5 58189d41067482a8475693f35d9d322e
BLAKE2b-256 79e9aec3569483d9dc1887046dc1d3b0fd8a23cbdc9eaa65d8f61545226d55a8

See more details on using hashes here.

Provenance

The following attestation bundles were made for richless-0.2.3-py3-none-any.whl:

Publisher: publish.yml on DavidJBianco/richless

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page