lesster – a less-like interactive text pager library for Nim.
Exports the public API for embedding the pager in other Nim programs:
- viewText – display an in-memory sequence of lines.
- viewFile – display a file path, or "-" to read from stdin.
Keybindings
| Key | Action |
|---|---|
| ↑ / | ↓ Scroll one line up / down |
| PgUp | /PgDn Scroll one page up / down |
| Space | Scroll one page down |
| g | Jump to the top |
| G | Jump to the bottom |
| / | Enter case-insensitive regex search mode |
| n | Next search match |
| N | Previous search match |
| m | Toggle minimal Markdown rendering on / off |
| s | Toggle word-wrap on / off |
| Tab | Cycle through colour themes |
| q | Quit |
Types
Theme = object titleBg*: iw.BackgroundColor ## Title bar background titleFg*: iw.ForegroundColor ## Title bar foreground bodyBg*: iw.BackgroundColor ## Content area background bodyFg*: iw.ForegroundColor ## Content area foreground statusBg*: iw.BackgroundColor ## Status bar background (normal mode) statusFg*: iw.ForegroundColor ## Status bar foreground (normal mode) searchBg*: iw.BackgroundColor ## Search prompt bar background searchFg*: iw.ForegroundColor ## Search prompt bar foreground matchBg*: iw.BackgroundColor ## Search-match line highlight background matchFg*: iw.ForegroundColor ## Search-match line highlight foreground mdHeaderBg*: iw.BackgroundColor ## Markdown header background (same as body background). mdHeaderFg*: iw.ForegroundColor ## Markdown header foreground (bright/accent color). mdCodeBg*: iw.BackgroundColor ## Markdown code-block background (contrasts with body background). mdCodeFg*: iw.ForegroundColor ## Markdown code-block foreground. mdEmphasisBg*: iw.BackgroundColor ## Markdown emphasis background (same as body background). mdEmphasisFg*: iw.ForegroundColor ## Markdown emphasis foreground (same accent as header).
- Colour configuration for every visual element drawn on screen. Set bodyBg / bodyFg to bgNone / fgWhite to let the terminal's own theme shine through (the "terminal" preset).
Lets
ThemesTable = toTable([("terminal", Theme(titleBg: bgNone, titleFg: fgWhite, bodyBg: bgNone, bodyFg: fgWhite, statusBg: bgNone, statusFg: fgWhite, searchBg: bgNone, searchFg: fgYellow, matchBg: bgNone, matchFg: fgYellow, mdHeaderBg: bgNone, mdHeaderFg: fgYellow, mdCodeBg: bgBlack, mdCodeFg: fgWhite, mdEmphasisBg: bgNone, mdEmphasisFg: fgYellow)), ( "default", Theme(titleBg: bgBlue, titleFg: fgWhite, bodyBg: bgBlack, bodyFg: fgWhite, statusBg: bgCyan, statusFg: fgBlack, searchBg: bgYellow, searchFg: fgBlack, matchBg: bgYellow, matchFg: fgBlack, mdHeaderBg: bgBlack, mdHeaderFg: fgCyan, mdCodeBg: bgBlue, mdCodeFg: fgWhite, mdEmphasisBg: bgBlack, mdEmphasisFg: fgCyan)), ("dark", Theme(titleBg: bgBlack, titleFg: fgCyan, bodyBg: bgBlack, bodyFg: fgWhite, statusBg: bgBlue, statusFg: fgWhite, searchBg: bgGreen, searchFg: fgBlack, matchBg: bgGreen, matchFg: fgBlack, mdHeaderBg: bgBlack, mdHeaderFg: fgCyan, mdCodeBg: bgBlue, mdCodeFg: fgWhite, mdEmphasisBg: bgBlack, mdEmphasisFg: fgCyan)), ("light", Theme( titleBg: bgWhite, titleFg: fgBlue, bodyBg: bgWhite, bodyFg: fgBlack, statusBg: bgBlue, statusFg: fgWhite, searchBg: bgYellow, searchFg: fgBlack, matchBg: bgYellow, matchFg: fgBlack, mdHeaderBg: bgWhite, mdHeaderFg: fgBlue, mdCodeBg: bgCyan, mdCodeFg: fgBlack, mdEmphasisBg: bgWhite, mdEmphasisFg: fgBlue)), ("matrix", Theme( titleBg: bgBlack, titleFg: fgGreen, bodyBg: bgBlack, bodyFg: fgGreen, statusBg: bgGreen, statusFg: fgBlack, searchBg: bgGreen, searchFg: fgBlack, matchBg: bgGreen, matchFg: fgBlack, mdHeaderBg: bgBlack, mdHeaderFg: fgGreen, mdCodeBg: bgBlue, mdCodeFg: fgWhite, mdEmphasisBg: bgBlack, mdEmphasisFg: fgGreen)), ("mono", Theme( titleBg: bgWhite, titleFg: fgBlack, bodyBg: bgBlack, bodyFg: fgWhite, statusBg: bgWhite, statusFg: fgBlack, searchBg: bgWhite, searchFg: fgBlack, matchBg: bgWhite, matchFg: fgBlack, mdHeaderBg: bgBlack, mdHeaderFg: fgWhite, mdCodeBg: bgBlue, mdCodeFg: fgWhite, mdEmphasisBg: bgBlack, mdEmphasisFg: fgWhite))])
Consts
ThemeNames = ["default", "dark", "light", "matrix", "mono", "terminal"]
- Ordered list used when cycling themes with Tab.
Procs
proc getMounted[T](node: T; ctx: var Context[State]): T
proc renderRoot(node: nw.Node; ctx: var Context[State]) {. ...raises: [Exception, KeyError], tags: [RootEffect], forbids: [].}
proc viewFile(path: string; title: string = ""; themeName: string = "default"; markdownMode: bool = false) {. ...raises: [IOError, KeyError, IllwaveError, Exception], tags: [ReadIOEffect, RootEffect, ReadEnvEffect, WriteIOEffect, TimeEffect], forbids: [].}
-
Launch the interactive pager for a file path, or "-" for stdin.
When reading from stdin, fd 0 is reconnected to /dev/tty after all data has been buffered so that keyboard input still works.
proc viewText(lines: seq[string]; title: string = "lesster"; themeName: string = "default"; markdownMode: bool = false) {. ...raises: [KeyError, IllwaveError, IOError, Exception], tags: [RootEffect, ReadEnvEffect, WriteIOEffect, TimeEffect], forbids: [].}
-
Launch the interactive pager with an in-memory sequence of text lines.
title is displayed centred in the title bar. themeName must be one of the keys in ThemesTable ("default", "dark", "light", "matrix", "mono", "terminal"); unknown names fall back to "default".
Methods
method mount(node: nw.Node; ctx: var Context[State]) {.base, locks: "unknown", ...raises: [], tags: [], forbids: [].}
method render(node: nw.Box; ctx: var Context[State]) {....raises: [Exception], tags: [RootEffect], forbids: [].}
method render(node: nw.Node; ctx: var Context[State]) {.base, locks: "unknown", ...raises: [], tags: [], forbids: [].}
method render(node: nw.Scroll; ctx: var Context[State]) {. ...raises: [Exception, KeyError], tags: [RootEffect], forbids: [].}
method render(node: nw.Text; ctx: var Context[State]) {. ...raises: [ValueError, Exception, KeyError], tags: [RootEffect], forbids: [].}
method unmount(node: nw.Node; ctx: var Context[State]) {.base, locks: "unknown", ...raises: [], tags: [], forbids: [].}