# lesser

A lesser pager, even less than [less]. Implemented in Rust.

It aims to be a drop-in replacement for `less` in everyday use — git, man,
systemd-journald — without the long tail of features almost nobody touches.
It is a clean-room reimplementation derived from the `less(1)` man page and
observed runtime behavior; no `less` source was read.

## Install

From source:

```
cargo install lesser
```

## Use

Just like `less`:

```
git diff --color=always | lesser -R
man ls | lesser
ls -la | lesser
lesser src/main.rs
```

`lesser` reads the `LESS` and `SYSTEMD_LESS` environment variables and
accepts their bundled-flag form (`LESS=FRX`, `SYSTEMD_LESS=FRSXMK`). Flags
that aren't implemented yet are silently ignored, never errored — set it
as `$PAGER` and expect things to work.

`LESS=FRX` (git's default) is the canary configuration this is built for.

## Keys

Navigation:

| Key                | Action               |
|--------------------|----------------------|
| `q`                | quit                 |
| `space`, `PgDn`    | page down            |
| `b`, `PgUp`        | page up              |
| `j`, `↓`, `Enter`  | next visual row      |
| `k`, `↑`           | previous visual row  |
| `g`, `Home`        | first row            |
| `G`, `End`         | last row             |

Search:

| Key             | Action                                       |
|-----------------|----------------------------------------------|
| `/`             | start search; matches highlight as you type  |
| `Enter`         | commit pattern and jump to first match       |
| `Esc`, `ctrl-c` | cancel                                       |
| `Backspace`     | erase char (empty input + Backspace exits)   |
| `n`             | next match (wraps around)                    |

Display:

| Key | Action                |
|-----|-----------------------|
| `S` | toggle chop / wrap    |

## Flags

| Flag | Behavior                                                           |
|------|--------------------------------------------------------------------|
| `-R` | pass ANSI color escapes through                                    |
| `-F` | quit if the input fits one screen                                  |
| `-X` | skip alternate screen (output stays in scrollback on exit)         |
| `-S` | start in chop mode (default is wrap; toggle with `S` at runtime)   |
| `-K` | quit on `ctrl-c` (accepted; not yet wired in)                      |

## What works

- Stdin and file input
- `-R` ANSI passthrough — colored `git diff` renders correctly, with
  per-line SGR reset to prevent color bleed
- `-F` quit-if-one-screen — `git log -1` doesn't pop a pager for two lines
- `-X` no-init — output stays in scrollback after exit
- Wrap (default) and chop modes, with runtime `S` toggle
- Smooth visual scrolling: a wrapped line advances one visual row at a
  time, not one logical line
- Resize handling: `SIGWINCH` rebuilds the visual layout while preserving
  the user's logical-line position
- Regex search with live highlighting as you type, wrap-around, `n` for
  next match
- `LESS` / `SYSTEMD_LESS` env-var bundles parsed; unknown flags ignored
- Unicode display widths (CJK characters take two columns and chop/wrap
  correctly)

## What doesn't (yet)

- `-K` (quit on ctrl-c) is accepted but not wired in
- Backspace-overstrike decoding for older `man` output (`_\bx` underline,
  `x\bx` bold) is not implemented
- Without `-R`, ANSI escapes pass through as-is rather than being shown
  literally as `^[[31m` (less's default)
- No marks, tags, `!` shell escape, `+cmd`
- No multi-file navigation (`:n` / `:p`)
- No `LESSOPEN` preprocessors
- No hex mode
- No reverse search `?`, no `<num>g` jump-to-line

These map to the roadmap and explicit non-goals in [PLAN.md].

## Targets

Linux and macOS, primarily. Should work on other Unix-likes; not actively
tested. Windows is best-effort and currently untested.

## License

MIT or Apache-2.0, at your convenience.

[less]: https://github.com/gwsw/less
[PLAN.md]: PLAN.md
