Skip to content

feat(glowm): add interactive pager#16

Merged
denolfe merged 14 commits intomainfrom
feat/glowm-pager
Feb 15, 2026
Merged

feat(glowm): add interactive pager#16
denolfe merged 14 commits intomainfrom
feat/glowm-pager

Conversation

@denolfe
Copy link
Owner

@denolfe denolfe commented Feb 15, 2026

Overview

Adds a less-style interactive pager to glowm for viewing long markdown documents. The pager activates automatically when content exceeds terminal height, with --no-pager flag to disable.

Key Changes

  • Interactive pager with less-compatible keybindings

    • Scroll: j/k, arrows, space/b, d/u, g/G
    • Search: / forward, ? backward with match highlighting
    • Header navigation: n/N to jump between headers
    • Mouse scroll support via SGR protocol
    • Info display with =
  • Line wrapping that preserves ANSI escape codes

    • Splits content into Line objects for viewport display
    • Handles image placeholders and header markers
  • Image handling in pager mode

    • Shows framed box with alt text instead of rendering images
    • Prevents layout issues from variable image heights
  • Terminal resize handling

    • Re-wraps content for new width
    • Preserves relative scroll position and search state

Design Decisions

The pager uses a state machine with PagerState holding lines, scroll position, terminal dimensions, and search state. Rendering writes directly to stdout with ANSI clear/cursor sequences rather than using a canvas abstraction.

Images display as styled placeholder boxes in pager mode because terminal image rendering (Kitty protocol or ANSI blocks) doesn't integrate well with viewport scrolling. The non-pager mode still renders actual images.

Header navigation detects headers via a HEADING_MARKER character injected during markdown rendering, stripped before final output.

Overall Flow

sequenceDiagram
    participant User
    participant CLI
    participant Pager
    participant Render

    User->>CLI: glowm file.md
    CLI->>CLI: Render markdown
    CLI->>CLI: Check content height vs terminal
    alt Content fits
        CLI->>User: Output directly
    else Content exceeds terminal
        CLI->>Pager: runPager(content, images)
        Pager->>Render: Initial render
        loop Input handling
            User->>Pager: Keypress/scroll
            Pager->>Pager: Update state
            Pager->>Render: Re-render viewport
        end
        User->>Pager: q
        Pager->>CLI: Cleanup and exit
    end
Loading

Adds lib/ansi.ts with:
- stripAnsi/visibleLength for ANSI-aware text measurement
- buildPositionMap for mapping visible to ANSI positions
- injectHighlight for search result highlighting
- ANSI escape constants for screen control
Smart default: paginate when TTY and content exceeds terminal height.
Use --no-pager to bypass. Piping always bypasses pager.

less-compatible keys: j/k, space/b, g/G, /, n/N, q
- Smart default: paginate on TTY when content > terminal height
- less-compatible keybindings
- Search with highlighting (/ and ?)
- Image re-rendering on scroll
- Terminal resize handling
- --no-pager flag to bypass
- Add n/N keybindings for next/prev header navigation
- Move search next/prev to Ctrl+N/Ctrl+P
- Add HEADING_MARKER for detecting headers in rendered output
- Add isHeader field to Line type
- Remove search repeat bindings, use / again instead
- Show framed image box with alt text instead of rendering
- Add mouse scroll support
- Fix image placeholder regex to handle ANSI codes
- Skip first header on 'n' when at top of document
@denolfe denolfe merged commit 9940833 into main Feb 15, 2026
2 checks passed
@denolfe denolfe deleted the feat/glowm-pager branch February 15, 2026 04:57
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant