Skip to content

Releases: SophanaSok/marquee-markdown

v0.11.1

Choose a tag to compare

@github-actions github-actions released this 03 Sep 16:28

Nothing in the reader changed. The project has a website, and the places
that name a homepage now point at it; crates.io only reads that field at
publish time, so it takes a release to move the link.

Changed

  • The project's homepage is now https://marquee-markdown.com/. The
    crate, the Homebrew formula, the Scoop manifest and the nix derivation all
    pointed at the GitHub repository, which stays as repository. The crate
    also gains a documentation link to the same site, which crates.io shows
    beside Homepage and Repository. The AUR packages keep url on GitHub
    because their source arrays are built from it.

v0.11.0

Choose a tag to compare

@github-actions github-actions released this 02 Sep 22:25

HTML in a README stops being a second-class document. A <table> and a
<ul> now walk to the same block their markdown spelling produces, so the
column solver and the list emitter draw them without ever learning there was
a second source of cells or items — spans, sections, captions and alignment
on one side; markers, indent, ordered numbering and nesting on the other.
What happened before was all-or-nothing: one <table> anywhere, or one
<ul> inside a <details>, sent its whole block to the page as raw tags.

Both come with the tag-omission rules the markup they meet actually has.
<tr><td>a<td>b is two cells and <li>a<li>b is two items, rather than
each one nested inside the one before it; and a table or a list split by a
blank line — which ends the HTML block, and is the form GitHub requires for
markdown to render inside — is gathered back into one.

Three fixes to markdown tables fell out of the table work: a header with no
rows under it drew a doubled bottom edge, a cell containing a line break
claimed the width of all its lines at once, and card layout centred each
value behind its label. Links inside a framed cell are now interned, so ]
walks a contributor grid.

A minor rather than a patch because it renders markup 0.10.0 declined.
cargo semver-checks against v0.10.0 reports nothing: the stable half of the
library API, render and theme, is untouched.

891 tests and a doctest, up from 853.

Added

  • HTML <ul>, <ol> and <li> are rendered as a list, not as tags. A
    list in a README walks to the same block a markdown list produces, so the
    markers, the indent, the ordered numbering and a list nested in an item all
    apply to it unchanged — the list emitter was not touched, and nothing
    downstream can tell which source the items came from.

    An item holds blocks, so everything the HTML reader can make reaches an item
    too: a heading, a paragraph, a quote, a table, another list. <ol start> is
    honoured. </li> written and left out are both understood — <li>a<li>b is
    two items, not one item holding the other, which is the list's half of the
    tag-omission rule tables already had. A list split by a blank line — which
    ends the HTML block, so its items arrive loose — is gathered back into one,
    and a stray paragraph inside a list joins the item above it rather than
    disappearing.

    This is also what stops one <ul> from taking a whole <details> block to
    the page as markup, which is what it did before.

    Limits, deliberate: a list inside a table cell keeps one item per line but
    loses its markers, because a cell holds inline content and a marker
    synthesized there would land in the plain mirror as searchable text. The
    same rule costs a list split by a blank line its numbering, because the
    <ol> that said so is in an earlier block. type, reversed and value
    are not read; the block tree has no way to say them. And <dl>/<dt>/<dd>
    is still declined to literal markup: there is no term-and-definition shape
    in the block tree and no way to indent without a marker, so a bulleted <dl>
    would be a guess rendered as if it were known.

  • HTML <table> is rendered as a table, not as tags. A <table> in a
    README walks to the same block a markdown pipe table produces, so the
    column solver, the box drawing, the shaded header band and the narrow-width
    label: value cards all apply to it unchanged — solve_widths was not
    touched, and nothing downstream can tell which source the cells came from.

    What it understands is what READMEs actually contain: <thead>/<tbody>/
    <tfoot> (the footer renders last wherever it was written), a leading row
    of <th> as the header when <thead> was left out, align on a cell, row
    or table, colspan and rowspan, <caption> as a strong paragraph above
    the table, a <br> inside a cell, and <td>/<tr> written without their
    closing tags. A <center> or <div align> around the table lends it their
    alignment, and a table split by a blank line — which ends the HTML block, so
    its rows arrive loose — is gathered back into one.

    Three fixes fell out of it and apply to markdown tables too: a header with
    no rows under it drew a doubled bottom edge, a cell containing a line break
    claimed the width of all its lines at once, and card layout centred each
    value behind its label instead of setting it flush.

    Links inside a framed cell are now interned, so ] walks a contributor
    grid; before this they were on the page but not reachable.

    Limits, deliberate: a table inside a table is declined to literal markup,
    because a cell holds inline content and nesting could only flatten the
    inner one into a run-on sentence. A cell holding an element with no emitter
    <pre>, <input>, <dl> — still sends the whole block to literal
    markup, because the scan that declines runs over the block rather than the
    cell. style="text-align:…" is not read; only the align attribute is.
    Per-cell alignment is not representable, so a column takes the header
    cell's alignment or the first body cell that states one. And search matches
    a table line by line, so a phrase that wraps inside a cell is not found
    across the wrap.

v0.10.0

Choose a tag to compare

@github-actions github-actions released this 02 Sep 15:49

A hardening release. The two changes a reader can meet are refusals: -w
stops at 1000 columns, because every rendered line is padded to the content
width and -w 65535 turned a 33 KB document into 48 MB of spaces; and only
http:, https:, mailto: and local paths reach the system opener, because
a link's scheme picks which program runs and a document does not get to pick
programs. Around them, CLICOLOR_FORCE keeps color in a pipe, a file in the
wrong encoding renders instead of erroring, and every release archive and
package now carries the man pages and completions.

Added

  • CLICOLOR_FORCE=1 (or FORCE_COLOR=1) forces color into a pipe, so
    marquee-markdown doc.md | less -R keeps its color, and TERM=dumb now
    gets plain text — no color, no OSC 8 hyperlinks, no centering — which is
    what an editor's embedded shell is asking for. NO_COLOR still wins over
    everything; it is the reader's own hand on the switch.

Changed

  • -w is capped at 1000 columns, and -w 0 ("do not wrap") renders at
    that cap rather than at 16,383 columns. Every rendered line is padded to
    exactly the content width, so the width bounds the output size directly:
    -w 65535 turned a 33 KB document into 48 MB of mostly spaces. The flag
    refuses larger values; a config file's width is clamped.
  • Only http:, https:, and mailto: links, and local paths, are handed
    to the system opener.
    A link with any other scheme — file:, a protocol
    handler some application registered — is refused with a message: a scheme
    picks which program runs, and a document does not get to pick programs,
    however deliberate the keypress that followed it.
  • The Debian and RPM packages ship man pages and shell completions for
    both binaries, in the paths the distributions document, and every release
    archive now carries them too — including the cross-compiled macOS build and
    the Windows zip, which used to go without. The .deb gains a real extended
    description in place of the raw README and drops its duplicate LICENSE
    (the generated copyright file already carries it); the RPM marks the
    README as documentation.
  • The crate description keeps to the strictest packaging rules any channel
    applies
    — under 80 characters, no leading article — because it is also
    the Debian synopsis, the RPM summary, the Homebrew desc, and the Scoop
    description. It was 98 characters with a leading "A ", which lintian
    rejects outright. A test now holds all four spellings together.
  • The release workflow's token is read-only except where the release is
    published
    , third-party actions included; the checkout action is on the
    same major as CI's, and the changelog-notes heredoc uses a random delimiter
    so no changelog line can truncate it.

Fixed

  • A local file in the wrong encoding renders instead of erroring. A
    Latin-1 document was refused with "stream did not contain valid UTF-8"
    while the same bytes fetched from a URL rendered fine; both now render with
    replacement characters. Actual binary data — an image opened by mistake —
    gets "is not a text file" rather than either a decoder error or a screenful
    of mojibake, from a file, a URL, or standard input alike.
  • EDITOR, VISUAL, and PAGER settings may quote a path with spaces.
    EDITOR='"C:\Program Files\Editor\edit.exe" -w' used to try to run a
    program called C:\Program.
  • A document with no links no longer pays a full metadata scan every
    frame.
    The link collector's memo tested its entries for emptiness to
    decide whether it had run, and a link-free document is also empty, so it
    re-collected once per keystroke.
  • A remote document of exactly 8 MiB is accepted. It used to be rejected
    as "larger than 8 MiB", which it is not.
  • Two READMEs whose names differ only in case pick the same file every
    run.
    The choice fell to whichever name the directory listing happened to
    yield first; byte order now breaks the tie the priority list cannot.
  • Overlapping terminal pauses can no longer reopen the gate early. The
    handshake that stands the terminal reader down tracked "paused" as a flag,
    so the first of two overlapping pauses to end would have resumed input
    under the second. Unreachable with today's callers, but that was a fact
    about the callers, not a guarantee; it is a count now.

Documentation

  • SECURITY.md no longer claims remote documents are HTTPS-only (plain
    http:// is fetched as given) or that raw HTML is always shown literally
    (the default mode renders a recognized subset as styled text); it now also
    records the link-scheme allowlist. docs/ROADMAP.md records the absence of
    BiDi reordering as a known gap. AGENTS.md names syntect's actual feature
    set.

v0.9.0

Choose a tag to compare

@github-actions github-actions released this 02 Sep 03:49

--style system stops being a snapshot. It asked the terminal what colors it
was using once, before the screen was taken, and then painted in those colors
for the rest of the session — so changing your terminal's colorscheme, or the
desktop theme behind it, left the page in colors the terminal had stopped
using. It now follows.

Added

  • --style system follows the terminal while you read. Change the
    colorscheme and the page is repainted in the new palette with no keystroke.
    Four things can prompt it and the common case needs none of them set up:
    regaining focus (portable, and where a theme change is nearly always noticed,
    because a theme is nearly always changed from another window), the new R
    key, a path named in [theme] watch, and SIGUSR1.

  • R, bound in the document, browser and contents panes, re-reads the
    terminal's colors — or re-reads a theme file, so a palette being written is
    visible without restarting the reader.

  • [theme] watch, a list of paths whose change means the terminal may have
    been retinted. For a desktop that swaps a theme underneath a window that
    never loses focus, which is the one case regaining focus cannot see. A
    leading ~ expands. No desktop's directory layout is compiled in; on Omarchy
    the path is ~/.local/state/omarchy/current/theme.

  • SIGUSR1 re-reads the terminal's colors. The one trigger with no race in
    it: a desktop's theme hook runs after the terminals have been retinted, so
    the answer is already the new palette. packaging/omarchy/ ships the hook.

  • scripts/recolor-check.py, a pty check for what a unit test cannot
    reach: that a retint is followed, that a burst of triggers costs one
    question, that a signal is a trigger, that a terminal which never answers is
    never asked twice — and that none of the replies leak into the key stream and
    get parsed as bindings.

Changed

  • The terminal may now be asked about its colors while the reader is
    running.
    src/util/osc.rs said this must never happen, and that is no
    longer true: app::recolor takes the same gate::pause handshake that
    hands an editor the terminal, so every reader has provably left its read
    before a question goes out, and discard_pending_input runs before the gate
    reopens so a late reply is not parsed as a handful of keys.

  • Following stops when you choose a palette by hand. T and accepting in
    the theme picker both mean this one rather than keep following; choosing
    system in the picker starts it again.

  • mmd config prints the [theme] section even when nothing is set, so
    the setting is discoverable rather than only documented.

Performance

Regaining focus happens far more often than a theme changes, so the cost of
noticing nothing had to be near zero:

  • A terminal that answered nothing when first asked is never asked again, so
    screen, a dumb terminal and every Windows console pay nothing at all rather
    than a 100 ms timeout per trigger.
  • A trigger asks for the background alone — two escape sequences rather than
    nineteen — and only a background that actually moved pays for the full
    sixteen-slot read. An unanswered probe buys nothing and is not followed up.
  • Triggers arriving together are collapsed into one question, which matters
    because one theme switch usually arrives twice: as a watched path and as a
    regained focus.

Breaking

  • app::external::Request has gained a variant and is now #[non_exhaustive],
    so a downstream match over it needs a wildcard arm. It is part of the
    internal half of the API, which this file has always said may change before
    1.0; the enum is marked so that the next variant is not another break.

v0.8.0

Choose a tag to compare

@github-actions github-actions released this 01 Sep 23:50

The reader tells you how to use it. A hint line above the status bar names the
handful of keys worth knowing, rendered from the keymap in force rather than
written out, so it cannot advertise a key you rebound.

Added

  • A hint line above the status bar, naming the handful of keys worth
    knowing — j/k scroll · / search · t contents · ? help · q quit · s theme · H hints. Rendered from the live keymap, like the key reference, so it never
    advertises a key that has been rebound, and it follows the pane in force: the
    contents pane offers folding, a prompt offers the way out of it, the theme
    picker says that moving previews.

    On by default. The keys are the part of a full-screen reader that nothing
    else announces, and a reader who does not already know ? has no way in;
    against that, the line costs one row of document on every screen. So it is
    the reader's row to spend either way: H hides it for the session — the key
    is advertised on the line itself, so nobody has to go looking for it — and
    hints = false under [ui], or MARQUEE_UI_HINTS=0, hides it for good.
    Nothing writes to the configuration file behind a keystroke.

    It degrades by dropping hints from the end rather than wrapping, and a
    terminal too narrow for even the first one spends the row on the document
    instead — measured against what the keymap actually produces, so a reader
    who rebound j to ctrl+alt+n moves the threshold with them. The reader
    still works down to 1x1.

  • toggle-hints, bound to H in the document, browser and contents modes,
    and [ui] hints alongside [ui] contents.

  • Panes::hints() and Panes::height(). The hint row is derived from the gap
    between the document and the status bar rather than stored — the rows below
    the document are contiguous, so there is no second place for the two to
    disagree, and the public shape of Panes is unchanged. height() is the
    whole terminal, for the callers that were adding two of the three rows up
    and coming out one short.

Changed

  • The status bar no longer ends in ? help while the hint line is offering
    it.
    The bar pointed at the key reference because nothing else did; two of
    them a row apart read as a stutter. It asks rather than assumes — the hint
    line has to be on screen and wide enough to have kept that chip, which it
    is not below about 44 columns, so a narrow terminal still gets told once.

v0.7.1

Choose a tag to compare

@github-actions github-actions released this 01 Sep 22:23

Nothing in the reader changed. This is a test that could fail on a busy
machine and a packaging manifest that had never been run, both found by
building the nix derivation for the first time.

Fixed

  • Three watch tests no longer assert on their own setup. Creating the
    document is a write like any other, and arming the watch immediately
    afterwards does not reliably exclude it — the close can be reported once the
    watch is up. The negative test counted that as the failure it was looking
    for; worse, the two positive tests could pass on it, reporting a working
    watch without one. They now drain until the watcher goes quiet before
    asserting.

    It takes contention to see: 3 rounds in 20 of the suite inside the nix
    sandbox, 1 in 40 locally with four suites at once, and never on an idle
    machine — which is why three CI platforms called it green. concerns was
    never at fault, and no reader behaviour changes: the cost was always one
    redundant re-read of a document just opened, the bargain the sibling case
    already accepts on macOS.

  • installManPage in the nix derivation was handed a named pipe. Process
    substitution is /dev/fd/63 — no name, no section suffix, and the hook
    declines to guess, so the install phase failed. The completions were
    unaffected because --cmd already names those.

  • packaging/nix/README.md documented a command that could not work.
    default.nix takes lib and rustPlatform as arguments, so it needs
    callPackage, and a pinned nixpkgs rather than <nixpkgs>, which is a
    search-path error on an install with no channels.

Changed

  • The nix derivation carries real hashes, and AGENTS.md records what a
    pty with no size looks like when the reader meets it: alternate screen
    entered, nothing painted, clean exit 0 — the size query working, not a
    broken binary.

v0.7.0

Choose a tag to compare

@github-actions github-actions released this 01 Sep 20:57

Added

  • Eight ports of established colorschemes ship with the reader:
    catppuccin-latte, catppuccin-mocha, dracula, gruvbox-dark, nord,
    solarized-dark, solarized-light and tokyo-night. --style <name>
    selects one, themes lists them, and the picker previews them like any
    other.

    They are TOML files in themes/, embedded with include_str! and parsed by
    the same loader a user theme goes through — the rule that a shipped theme
    must not be a privileged code path, now that there is more than one kind of
    shipped theme. A file of the same name in the user's theme directory still
    wins, so retuning one is a copy and an edit rather than a fork.

    Only Solarized has an exact counterpart among the seven syntax themes the
    highlighter carries; the rest are paired by eye. docs/THEMES.md has the
    schema, the seven names, and what a theme PR needs.

  • <details> and <summary> are rendered instead of being printed as
    tags.
    The block becomes a quote titled by its summary, always open: a
    terminal page has no click, and hiding the body would lose content the
    author shipped.

    A blank line inside <details> ends the HTML block — CommonMark's rule, and
    the form GitHub requires for markdown to render inside — so the open tag and
    the body arrive separately and the body is not ours to wrap. In that case
    the summary stands alone as a strong paragraph rather than as a gutter bar
    around nothing, and the body follows as itself.

  • Manifests for the AUR and nixpkgs, in packaging/aur/ and
    packaging/nix/. Two AUR packages, one building from source and one
    unpacking the release archive; a nixpkgs-style derivation written in the
    shape pkgs/by-name wants. Neither is published yet, and
    packaging/README.md says what each still needs.

  • docs/demo.tape, a VHS script for the README's animated demo. It
    records the moving parts only — the contents pane tracking the scroll,
    folding, search narrowing as you type, the theme picker previewing. Not
    gated in CI: a GIF is a lossy re-encode, so a byte-comparison would be
    flaky rather than protective.

Changed

  • $E = mc^2$ reads as a code span rather than as a formula wearing its
    dollar signs.
    ENABLE_MATH had never been in the parser's option set,
    while the handler for the events it produces had been sitting there since
    the beginning — so every $ in a document reached the page literally,
    through code that could not run. TeX is not typeset; there is no glyph
    budget for that in a cell grid, and code styling marks the span as notation
    without pretending otherwise.

  • themes measures its own name column rather than padding to a fixed
    twelve, which the first bundled palette overran.

Fixed

  • An overlay panel no longer leaves an unpainted cell beside it when its
    edge cuts a double-width glyph in half.
    The panel paints over the glyph's
    first cell; the second is one column outside it and belongs to nobody, so it
    stayed as the terminal left it — a one-cell hole showing the shell's
    background, hard against the border.

    Latent since the overlays were written, and reachable only when a panel's
    width put its edge on a wide glyph. Shipping a few themes made the theme
    picker wide enough to land on one, which is how it was found: by
    tests/frame.rs, which is the only mechanical guard the painted page has.
    ui::clear_panel now measures the edge before clearing — clearing is what
    destroys the evidence — and repaints the orphan.

Internal

  • Theme::from_toml parses a theme from text already in hand;
    Theme::from_file is now a thin wrapper over it, so there is still one
    parser.
  • render::highlight::has_syntax_theme reports whether the highlighter knows
    a syntax theme by name, which the bundled palettes are checked against.
  • tests/docs.rs gained
    every_pinned_package_manifest_points_at_a_real_release, extending the
    Homebrew staleness guard to the AUR PKGBUILDs and the nix derivation.
  • Two keyseq tests navigated the theme picker by counting j presses from
    slate to system, which only worked while exactly three themes shipped.
    They use G now, since system is the last row by construction. A picker
    wheel test asserted 3.min(len - 1) and passed for the wrong reason: the
    clamp hid the fact that the picker opens on the theme in force, not at the
    top.

v0.6.1

Choose a tag to compare

@github-actions github-actions released this 26 Aug 20:49

Changed

  • Resizing a document full of code is no longer dominated by re-highlighting
    it.
    Syntax highlighting depends on the text, the language and the theme,
    and a resize changes none of them — but it was being done from inside the
    layout emitter, so every width change re-ran syntect over every fenced block
    in the document and threw the result away.

    It was not a small part of the bill. A document of 120 rust fences laid
    out in 199 ms, against 6 ms for the same text with the language taken off:
    about 97% of a re-layout was highlighting, paid again for every step of a
    drag. Six hundred fences took a full second, each time.

    Highlighting is now kept for as long as the parse it belongs to, which is
    exactly how long it stays valid:

    document before after
    this README 8.6 ms 2.0 ms
    120 rust fences 198.8 ms 8.9 ms
    600 rust fences 999.3 ms 49.8 ms
    600 fences, no language 32.4 ms 32.0 ms

    The last row is the control: nothing to highlight, so nothing to save.

    Switching themes does pay again, once, because the theme is one of the three
    things highlighting depends on — the syntax theme it names, the surface
    colour forced onto every span, and the fill used where there is no language.
    A one-shot render keeps nothing, since it lays the document out once and a
    memo could only cost it memory; its peak stays where it was. A reader
    holding a 300 KB code-heavy document pays about 10 MB for this, and about
    0.1 MB for a document the size of this README.

Fixed

  • A document can no longer take the terminal down with it. Nesting deeply
    enough — about 3,000 levels of > - , or 8,000 nested <div>s — overflowed
    the stack while the document was being laid out: layout walks the block tree
    by recursion, so the depth of the call chain was the depth of the document,
    and the document chose it.

    That is the worst way this program can fail. A stack overflow aborts, and
    an abort does not unwind, so neither the RAII terminal guard nor the panic
    hook that exists for exactly this ever ran. The reader died with the
    alternate screen still up, the cursor still hidden and mouse reporting still
    on — a terminal that needed reset before it could be used again. Nor did
    the document have to be your own: https:// and github:// are ordinary
    sources.

    Nesting is now capped at 256 levels, in the markdown tree and the HTML one
    alike. Past the cap a container is not represented and its children are
    spliced into its parent, so the text still renders — at the capped indent
    rather than a deeper one — instead of being truncated or refused. The cap is
    far above anything a terminal can show: each level of quote or list costs two
    cells of lead, so 80 columns is full of decoration by about level 40, and
    from there the content is already pinned to the one cell the lead leaves it.

  • A resize that stops no longer leaves the last frame mangled. Pane
    geometry is recomputed before every draw, which is why the resize event
    itself does nothing — but the recompute asked Terminal::get_frame for the
    area, and ratatui only updates that inside draw. So it was always reading
    the size of the previous frame: the resize event woke the loop, the loop
    laid the document out for the width the terminal used to be, and drew it
    into the width it now is. Ratatui clips widgets to the buffer, so nothing
    overflowed — it just came out wrong, with the contents pane still divided
    where it had been and headings cut off mid-word.

    Dragging a window edge hid this, because each new event redrew from the
    freshly-learned size. A resize that stops — the ordinary case — had
    nothing following it, so the mangled frame stayed up until a key was
    pressed. The terminal is now asked its size before the geometry is decided,
    the same call the loop already makes after handing the screen to an editor,
    and for the same reason.

v0.6.0

Choose a tag to compare

@github-actions github-actions released this 26 Aug 19:00

--style system: a palette built from the colors your terminal is already
using. Nothing resolves differently than it did — the only change to auto,
the default, is that its documentation now describes it accurately.

Added

  • --style system builds the whole palette out of the terminal's own
    colors rather than shipping one. The page and the text are taken verbatim
    from OSC 10 and OSC 11; cards, borders and the muted tone step off them;
    headings, links and the five callout hues come from the OSC 4 ANSI slots.
    Every color that ends up as text is held to a WCAG contrast floor against
    the page and walked toward the foreground until it clears — which is what
    keeps a light scheme's yellow from becoming an unreadable heading, and what
    makes this survive a colorscheme that reports every slot as black.

    It is listed by themes, selectable in the s picker, and saved to the
    configuration file like any other. Anything that will not answer falls back
    to a shipped palette rather than refusing to start: screen, which swallows
    the question, and tmux, which answers the device query and nothing else.
    Only a terminal that answers nothing at all pays the 100 ms timeout; where
    the device query comes back — tmux included — the fallback is immediate.

  • terminal-query, in [general], and MARQUEE_TERMINAL_QUERY. Default
    on; off stops the terminal being asked anything, for a terminal that prints
    the question instead of answering it.

Changed

  • --style auto is now documented as what it is: an alias for slate. It
    has carried a promise to follow the terminal's background since the
    beginning and has never kept it — the seam was there from the start and both
    callers passed "unknown", so it has always answered the dark palette. The
    behavior is untouched, deliberately: it was the default, and the first
    release to start keeping that promise would move every reader on a light
    terminal from slate to paper without being asked. The documentation now
    matches the code instead of the other way round, and --style system is
    where following the terminal lives.

  • The default style is now slate rather than auto, which is the same
    theme by another name — mmd config says style = "slate" where it used to
    say style = "auto". Naming the palette states the default instead of
    deferring it to whatever auto happens to mean, so changing what a reader
    who never chose a theme sees now takes changing the default, deliberately,
    rather than falling out of a change to auto. auto remains a name
    --style and [general] style accept.

    Nothing resolves differently. -s auto is byte-for-byte -s slate, with a
    terminal sitting there answering or without one.

  • The reader takes the mouse wheel by default, where it used to wait to be
    asked with -m. Not a preference: a terminal whose alternate scroll mode is
    on — which is the default in most of them — answers a wheel that nobody
    claimed by manufacturing arrow keys, multiplied by whatever scroll factor it
    was configured with. They arrive as ordinary keystrokes, indistinguishable
    from a hand on j, so a stray touchpad brush would yank the document away
    from someone reading it with the keyboard, and only while the pointer
    happened to be over the window. Claiming the wheel is what stops the terminal
    doing that, and it makes a tick the same three lines everywhere instead of a
    number the terminal picked.

    The cost is that selecting text with the mouse needs shift held while the
    reader is open, which is the trade less --mouse makes. --no-mouse and
    mouse = false hand the wheel back; -m is still accepted, still means the
    same thing, and still overrides a configuration file that turned it off.

  • The wheel moves the pane the movement keys would move, rather than the
    document whatever has focus. Tab into the contents pane and the wheel moves
    the outline; open the key reference and it moves the reference; in the file
    browser it moves the list. It resolves to the same Action a key does, so
    the two cannot drift apart, and a pane that grows movement keys gets the
    wheel with them. A sideways tick still only pans a document — h and l
    fold the outline, which is not something to do to somebody by accident.

Fixed

  • Pointer movement redrew the reader, for nothing. Asking a terminal to
    report the mouse asked it, through crossterm, for any-event tracking as well
    as the wheel — a report per cell the pointer crossed, each one a wakeup, a
    re-layout and a whole frame drawn and diffed away, for as long as a hand
    rested on the mouse. Nothing here has ever read a mouse column. The reader
    now asks for the wheel and nothing else, and drops the rest on arrival in
    case it was asked anyway.

  • Mouse tracking left on by another program is now turned off on the way
    in.
    An editor opened with e and then killed leaves it on for good, and
    the reader it comes back to had no way to know: it would report every pointer
    movement into a program with no use for a mouse at all.

  • A README key table ran past its own end on Windows. The doc-drift scan
    split on a blank line, which a CRLF checkout does not contain, so every
    table continued to the end of the file and fed the chord parser whatever
    backticks it met. Nothing after the key tables had a backticked cell in its
    first column until now, which is why it had never shown.

Notes

The question and its answer travel the same stream as keystrokes, and reading
is destructive. So the exchange happens once, before the screen is taken and
before the thread that owns standard input exists; on /dev/tty rather than
either standard stream; declined outright if anything is already queued; and
ended by a device-attributes sentinel rather than by the clock. Only system
asks at all.

Windows falls back for now: the replies arrive there through the console input
API rather than as bytes on a device, which is a different mechanism rather
than a variation on this one.

registry::resolve takes what the terminal answered in place of its old
Option<bool>, and registry::Origin has gained a variant and become
#[non_exhaustive]. Both are in the stable half of the API, which is what
makes this 0.6.0 rather than 0.5.2.

v0.5.1

Choose a tag to compare

@github-actions github-actions released this 21 Aug 15:45

Packaging and test-suite fixes. Nothing a reader will notice: of the three
changes here, two are to files excluded from the published crate, and the
third is internal.

Fixed

  • The Homebrew formula had no url and no sha256. Not stale — absent,
    since it was written, through four releases. brew install had nothing but
    --HEAD to fetch, and the version its own test block asserts against did
    not exist. It now points at the tag's source tarball, which is what the
    formula builds from; the checksums.txt on a release describes the prebuilt
    archives it never downloads.
  • The configuration tests read whoever was running them.
    Config::load(.., None, ..) stubbed the environment but not the filesystem,
    so locate reached for the real default path and "nothing configured" meant
    "nothing configured, unless this machine has a file". Three tests asserting
    the defaults were asserting the machine had no configuration. They passed for
    as long as they did because hardly anyone had one — and then the theme picker
    started writing it, so trying the headline feature of 0.5.0 turned the suite
    red for reasons unconnected to anything the contributor touched. locate is
    handed the location now, which is what the module header always claimed.

Changed

  • tests/docs.rs checks the Homebrew formula, and the smoke job checks that a
    configuration file in the usual place is read — the one line no unit test can
    see, since it reaches through dirs. Both were confirmed by breaking them.