Skip to content

Releases: Epistates/treemd

v0.5.12

07 Jun 13:36

Choose a tag to compare

[0.5.12] - 2026-06-06

Added

  • Toggle mouse capture for text selection - New M shortcut and :toggle mouse capture palette command release the mouse so the terminal's native click-drag selection works for copying arbitrary text; toggle back to restore scroll-wheel navigation. The README also documents the Shift+drag bypass supported by most terminals
  • Toggle heading markers in outline - New outline_heading_markers config option, # keyboard shortcut, and :toggle heading markers palette command to show/hide #/##/### level prefixes in the outline sidebar (default: true) (#57) — thanks to @alisaifee

Fixed

  • Table copy keys did nothing useful - In interactive table mode y/Y/r had been silently rebound to generic copy/raw-source actions during the action-dispatch refactor, so cell, row, and copy-as-markdown copy were inoperative. Restored via dedicated CopyTableCell/CopyTableRow/CopyTableMarkdown actions wired to the existing handlers, with a regression test
  • Inline backticks render as plain text - Inline code in table cells/headers, headings, and blockquotes now renders as styled inline code via format_inline_markdown() instead of literal backticks (#51, #53). Resolves the known issue carried in 0.5.11; requires turbovault-parser 1.5.0
  • Navigation to duplicate headings - Selecting an outline entry whose text appears multiple times always jumped to the first occurrence. HeadingNode/OutlineItem now carry a position index, and all content-extraction, selection-restore, and rendering paths resolve by index. extract_section(text) is preserved for the CLI --section flag, delegating to a new extract_section_at_index() (#56) — thanks to @alisaifee
  • snake_case corruption in subscript rendering - Terms like i_am_a_snake were mangled because _x was always treated as a LaTeX subscript. Subscript conversion now applies to _{x} unconditionally and to bare _x only when not mid-identifier (#58) — thanks to @alisaifee
  • Mermaid image sizing and scrolling - Mermaid diagrams now expand to fit terminal width and scroll correctly (#53)

Changed

  • Trimmed image format dependencies - ratatui-image 10 → 11 (dropped image-defaults) and image now opts into only the needed decoders (png, jpeg, gif, webp, bmp, ico, tiff), substantially shrinking the dependency tree
  • Upgraded parser dependencies - turbovault-parser 1.4.1 → 1.5.0 and turbovault-core 1.4.1 → 1.5.0, plus transitive refreshes
  • Removed outline auto-hide - Dropped the logic that auto-hid the outline when a directory contained few files; outline visibility is now driven solely by user toggle/config
  • Hardened rendering and TTY handling - Tightened audit findings surfaced during PR #53 review across the CLI, table, and TUI rendering paths

TL;DR:

  • fix: inline backtick rendering in tables, headings, blockquotes and mermaid sizing by @esumerfd in #53
  • fix(tui): disambiguate navigation to duplicate headings from outline by @alisaifee in #56
  • fix: prevent snake_case corruption by @alisaifee in #58
  • feat(tui): add toggle for heading markers in outline sidebar by @alisaifee in #57

New Contributors

Full Changelog: v0.5.11...v0.5.12

v0.5.11

28 Apr 12:36

Choose a tag to compare

[0.5.11] - 2026-04-28

Fixed

  • Toggle details no-op after section navigation - In interactive mode, pressing Enter on certain <details> blocks reported "✓ Toggled details" but produced no visible change. InteractiveState::element_states is keyed only by ElementId { block_idx, sub_idx }, so a previous section's Table state at a given block_idx silently blocked a fresh Details from initializing at the same key (the indexer used HashMap::entry().or_insert(), a no-op when present). toggle_details then matched no Details variant and silently failed. Indexer now overwrites stale wrong-variant entries while preserving same-section toggle state. Regression test added.
  • --filter and --level ignored in --tree mode - CLI now honors both flags when rendering the tree output (c3c3fcd)
  • --at-line not wired up; -s mismatched formatted headings - --at-line resolves to the enclosing heading; section selection (-s) now matches headings that contain inline formatting (36c4e60)

Changed

  • Upgraded all dependencies to latest - Refreshed clap_complete 4.6.2 → 4.6.3, mermaid-rs-renderer 0.2.1 → 0.2.2, turbovault-parser 1.4.0 → 1.4.1, turbovault-core 1.4.0 → 1.4.1, open 5.3.3 → 5.3.4, plus transitive refreshes (plist, wasm-bindgen, tokio, libc, js-sys, cc, etc.)

Tests

  • Added end-to-end CLI integration suite covering --tree, --list, --filter, --level, --at-line, and -s (471d9d5)
  • Added coverage for JSON output builder and config loading (ef250da)
  • Added coverage for document tree/search and palette command matching (f185c4b)

Known Issues

  • Inline backticks render as plain text instead of styled inline code in tables, headings, and blockquotes (#51). Fix in flight via #53, pending companion changes in turbovault-parser.

Full Changelog: v0.5.10...v0.5.11

v0.5.9

04 Mar 18:04

Choose a tag to compare

[0.5.9] - 2026-03-04

Added

  • Dynamic help text - Help popup now displays actual configured keybindings instead of hardcoded key strings (#47)

    • User-customized keybindings are reflected in the help menu at render time
    • Structured HelpLine enum replaces raw string-based help entries
  • Noop action for keybinding customization - Users can unbind keys by mapping them to Noop in their config (#46)

    • Noop entries are automatically filtered from the help popup
  • Regression tests for keybinding system - Added tests for user config override, Noop unbinding, clone preservation, and help entry filtering

Fixed

  • Keybinding config merging - User-defined keybindings now correctly override defaults (#46)

    • Previously, defaults were inserted first in the dispatch Vec and matched before user overrides
    • New approach replaces matching default bindings in-place, preserving user precedence
  • Clone for Keybindings discarded user config - clone() always returned default keybindings; now properly clones binding state

  • Wrong action in help for "Exit interactive mode" - Help text used Quit (which exits the app) instead of ExitMode for table navigation exit

  • Duplicate t keybinding - Both ToggleTodoFilter and ToggleThemePicker were bound to t in Normal mode; ToggleTodoFilter moved to T (Shift+t)

  • Phantom S key in status bar - "S or :w to save" referenced an unbound key; updated to ":w to save"

  • Editor in interactive mode - OpenInEditor now jumps to the interactive element's source line instead of the selected heading (#45)

  • File picker missing from help menu - Added file picker entry to help text

  • Potential usize underflow in help text - Key column width calculation now uses saturating_sub

tl;dr:

New Contributors

Full Changelog: v0.5.8...v0.5.9

v0.5.8

02 Mar 03:27

Choose a tag to compare

Full Changelog: v0.5.7...v0.5.8

Full Changelog: v0.5.7...v0.5.8

v0.5.7

27 Feb 01:53

Choose a tag to compare

[0.5.7] - 2026-02-26

Added

  • Home/End key bindings - Navigate to first/last with Home/End keys (#43)

    • Works in Normal, Interactive, Help, and FilePicker modes
    • Also added PageUp/PageDown bindings in Normal mode for consistency
  • Directory and multi-file support - Open file picker with directory argument (#43)

    • treemd . opens file picker in current directory
    • treemd docs/ opens file picker in specified directory
    • Multiple file arguments supported (e.g., treemd *.md)
  • Compact tree style - Gapless box-drawing characters for tree visualization (#43)

    • Now uses ├── instead of ├─ (connected, no gaps)
    • Config option tree_style: "compact" (default) or "spaced"
    • Works in both --tree CLI output and query tree output
  • Todo filter for outline - Filter heading tree to show only headings with open todos (#44)

    • Press t to toggle filtering by open todos (- [ ] or * [ ])
    • Shows only headings that contain open todos (directly or in descendants)
    • Preserves hierarchy: parent headings shown if any child has todos
    • Status message shows count of headings with open todos
  • SOTA Content filtering - Robust YAML frontmatter and LaTeX handling (#43)

    • Unicode Approximation: LaTeX math symbols like \alpha, \sum, \infty are now rendered as readable Unicode (α, , ) instead of being stripped.
    • Superscript/Subscript support: Common exponents and indices (like x^2, n_i) are converted to Unicode (, nᵢ).
    • Environment Preservation: Content inside LaTeX environments (like equation or align) is preserved while stripping the tags.
    • hide_frontmatter option strips ---\n...\n--- blocks at document start.
    • hide_latex option handles math and LaTeX commands robustly without "half measures".
    • Aggressive filtering remains available but the standard mode is now preferred.
  • Smart Responsive Tables - Tables now wrap and collapse intelligently (#43)

    • Cell Wrapping: Long content now wraps into multiple lines within columns, ensuring data remains readable even on narrow terminals.
    • Content-weighted widths: Uses 70% average + 30% max for fairer column distribution.
    • Adaptive padding: Dynamically reduces cell padding (2 → 1 → 0) to save space.
    • Unicode ellipsis: Optimized truncation using for maximum information density.
  • File picker quit - Press q to exit file picker dialog (#43)

Fixed

  • EOF scroll behavior - Content no longer scrolls past the last line (#43)
    • Now uses actual rendered line count (not raw markdown lines) for scroll limits
    • Scroll stops when last line is visible at bottom of viewport
    • Consistent behavior across all scroll methods (j/k, Page Up/Down, Home/End)

Technical

  • Config additions (src/config.rs)

    • Added ContentConfig struct with hide_frontmatter, hide_latex, latex_aggressive fields
    • Added tree_style field to UiConfig (defaults to "compact")
    • Added is_compact_tree() helper method to Config
  • Content filtering utilities (src/tui/ui/util.rs)

    • Added strip_frontmatter() for YAML frontmatter removal
    • Added SOTA strip_latex() with Unicode symbol mapping and environment preservation
    • Added wrap_text() utility for Unicode-aware word wrapping
    • Added filter_content() combining all filters
  • Tree rendering (src/parser/document.rs, src/query/output.rs)

    • Added render_box_tree_styled() method with compact parameter
    • Updated format_tree_value() to support compact mode
  • App state (src/tui/app.rs)

    • Added file_picker_dir field for custom directory support
    • Added should_hide_frontmatter() and should_hide_latex() getters
    • Updated scan_markdown_files() to use custom directory
  • Table rendering (src/tui/ui/table.rs, src/tui/ui/mod.rs)

    • Refactored render_table_row to return Vec<Line> for multi-line wrapping
    • Implemented smart wrapping logic using util::wrap_text
    • Propagated width adjustments through nested content structures
    • Comprehensive test updates for new wrapping behavior

Full Changelog: v0.5.6...v0.5.7

v0.5.6

09 Jan 14:11

Choose a tag to compare

[0.5.6] - 2026-01-09

Added

  • Image configuration - Configure image rendering via [image] section in config
    • Specify preferred renderer: renderer = "kitty" or renderer = "software"
    • Add custom arguments: args = ["--no-animations"]
    • Example config:
      [image]
      renderer = "kitty"
      args = ["--no-animations"]

Full Changelog: v0.5.5...v0.5.6

v0.5.5

03 Jan 01:25

Choose a tag to compare

[0.5.5] - 2026-01-02

Added

  • Inline image rendering - Full image support with Kitty graphics protocol (#40)

    • Images render inline with markdown content using ratatui-image
    • Supports PNG, JPEG, GIF, WebP and other common formats
    • Image modal view - press Enter on an image in interactive mode for full-screen view
    • Press q to close image modal
    • Automatic image caching and lazy loading for performance
    • Works in Kitty, iTerm2, WezTerm, and other terminals with image protocol support
    • Fallback to halfblock Unicode rendering on unsupported terminals
  • GIF animation support - Animated GIFs with playback controls

    • GIFs animate automatically in image modal view
    • Press Space to play/pause animation
    • Press n for next frame, p for previous frame (manual stepping)
    • First frame extraction with proper transparency handling
    • Software rendering mode for flicker-free animation
  • File picker on startup - Interactive file picker when no file is specified

    • Fuzzy search through markdown files in current directory
    • Navigate with j/k or arrow keys
    • Press Enter to open selected file
    • Shows file list with real-time filtering
  • macOS XDG config path support - ~/.config/treemd now supported on macOS (#41)

    • Checks ~/.config/treemd/config.toml first on macOS
    • Falls back to ~/Library/Application Support/treemd/config.toml
    • Enables easier dotfiles management and cross-platform config sharing
  • Alpine Linux support - musl builds for Alpine and other musl-based distributions (#42)

    • Added x86_64-unknown-linux-musl binary to releases
    • Added aarch64-unknown-linux-musl binary to releases
    • Statically-linked binaries work without glibc dependency

Fixed

  • GIF animation flicker - Eliminated flicker by pre-creating protocols and optimizing background clearing
  • Image rendering in normal mode - Images now render correctly outside of interactive mode
  • Inline images in paragraphs - Fixed detection of images within paragraph text
  • Theme preservation - Theme colors maintained correctly during image rendering

Technical

  • New modules

    • src/tui/kitty_animation.rs - GIF animation state machine and frame management
    • src/tui/image_cache.rs - Image caching and lazy loading system
  • Dependencies

    • Added ratatui-image 10 for terminal image rendering
    • Added image 0.25 for image processing
    • Added gif 0.13 for GIF parsing and frame extraction
  • Release workflow

    • Added musl targets (x86_64-unknown-linux-musl, aarch64-unknown-linux-musl) to CI

Full Changelog: v0.5.4...v0.5.5

v0.5.4

16 Dec 18:34

Choose a tag to compare

[0.5.4] - 2025-12-15

Added

  • Navigation save confirmation - Prompts before navigating away with unsaved changes

    • Triggered when pressing backspace to go back in file history
    • Also triggered when following links to other files
    • Dialog options:
      • [y/Enter] Save & Navigate - saves changes then navigates
      • [d] Discard & Navigate - discards changes and proceeds
      • [q] Discard & Quit - discards changes and exits
      • [Esc] Cancel - stays on current file
  • Quit without saving option - Added to save before quit dialog

    • Press [q] to quit immediately without saving changes
    • Press [y/Enter] to save and quit (existing behavior)
    • Press [Esc] to cancel and stay (existing behavior)
  • Editor configuration - Configure external editor via [editor] section in config

    • Specify preferred editor: editor = "nvim" or editor_kind = "NeoVim"
    • Add custom arguments: args = ["--noplugin"]
    • Uses opensesame EditorConfig
    • Example config:
      [editor]
      editor = "nvim"
      args = ["--noplugin"]

Changed

  • opensesame dependency - Updated to use serde feature for config serialization

Full Changelog: v0.5.3...v0.5.4

v0.5.3

13 Dec 21:25

Choose a tag to compare

[0.5.3] - 2025-12-13

Added

  • Styled keybinding hints footer - New context-aware footer bar showing relevant keybindings

    • Styled key badges with theme colors (help_key_bg, help_key_fg, help_desc_fg, footer_bg)
    • Hints update based on current mode (Normal, Interactive, LinkFollow, DocSearch, etc.)
    • Element-specific hints in interactive mode (Checkbox, Table, Link, Details, CodeBlock, Image)
    • Table mode shows cell navigation hints (j/k Row, h/l Col, e Edit, y Copy)
  • Vim-style count prefixes - Repeat motions with numeric prefixes like vim

    • 5j moves down 5 items, 10k moves up 10 items
    • Works in Normal mode (outline/content navigation) and Interactive mode
    • Supports: j/k navigation, h/l table columns, content scrolling
    • 0 without count goes to first item (vim behavior preserved)
    • Link follow mode still uses 1-9 for direct link jumping
  • Collapse/Expand commands - New command palette commands for outline management

    • :collapse / :ca - Collapse all headings with children
    • :expand / :ea - Expand all headings
    • :collapse N - Collapse all headings at level N (e.g., :collapse 2 for h2)
    • :expand N - Expand all headings at level N
    • Status messages show count of affected headings
  • Inline HTML tag rendering - Parse HTML tags in details block summaries

    • <strong>, <b> render as bold
    • <em>, <i> render as italic
    • <code> renders as inline code
    • No longer shows literal <strong> tags in rendered view
  • Nested interactive elements in details blocks - Select elements inside expanded details

    • Tables, links, code blocks, images inside details are now selectable
    • Hierarchical status display: ▸Navigation > Table: 5×3
    • Expansion state persists after exiting interactive mode
  • Safe edit buffer system - Table cell edits are now buffered in memory instead of immediately written to file

    • Changes are applied to in-memory document for immediate display
    • Explicit save required with :w command to write changes to disk
    • Status shows "X unsaved change(s)" after edits
    • Prevents accidental data loss from unforeseen bugs
  • Save command (:w) - New command to save pending edits

    • :w, :write, or :save writes all buffered edits to file atomically
    • Shows confirmation: "Saved X change(s) to filename.md"
  • Undo command (:u and Ctrl+z) - Undo table cell edits before saving

    • :u or :undo in command palette undoes last edit
    • Ctrl+z keybinding in Interactive and InteractiveTable modes
    • Stack-based undo: each edit can be individually reverted
    • Shows remaining unsaved changes count after undo
  • Quit confirmation for unsaved changes - Prompts before quitting with unsaved edits

    • Dialog shows number of unsaved changes
    • Enter/y saves changes and quits
    • Escape cancels and returns to normal mode

Changed

  • Status bar shows context-aware position - Position info based on focused pane

    • Outline focused: [Outline] 3/15 (20%) - heading position
    • Content focused: [Content] Line 42 (35%) - scroll position
    • Cleaner status bar without inline keybinding hints (moved to footer)
  • Esc key behavior in normal mode - Shows helpful hint instead of doing nothing

    • Displays: "Press q to quit • : for commands • ? for help"
    • Guides new users on how to exit or access features

Fixed

  • Table navigation in interactive mode - j/k now moves cells when in table mode

    • Previously j/k moved between elements instead of table rows
    • Esc now exits table mode before exiting interactive mode
  • Table row bounds - Can now navigate to last row in tables

    • Fixed off-by-one error in table_move_down()

Technical

  • Theme footer colors (src/tui/theme.rs)

    • Added help_key_bg, help_key_fg, help_desc_fg, footer_bg to all 16 theme variants
    • Added help_key_style(), help_desc_style(), footer_style() helper methods
    • Updated with_custom_colors() and with_color_mode_custom() for footer fields
  • Config footer colors (src/config.rs)

    • Added footer color fields to CustomThemeConfig for user customization
  • Layout footer section (src/tui/ui/layout.rs)

    • Added Section::Footer to layout system
  • Count prefix system (src/tui/app.rs, src/tui/mod.rs)

    • Added count_prefix: Option<usize> to App state
    • accumulate_count_digit(), take_count(), clear_count(), has_count() methods
    • Event loop accumulates digits before motion commands
  • Collapse/expand methods (src/tui/app.rs)

    • collapse_all(), expand_all(), collapse_level(n), expand_level(n)
    • Added CollapseAll, ExpandAll, CollapseLevel, ExpandLevel to CommandAction
  • HTML parsing utility (src/parser/utils.rs)

    • Added parse_inline_html() function for HTML tag to InlineElement conversion

Full Changelog: v0.5.2...v0.5.3

v0.5.2

12 Dec 18:10

Choose a tag to compare

[0.5.2] - 2025-12-12

Fixed regression from 0.5.1

  • Search navigation after locking in results - Fixed n/N and Tab/Shift+Tab not cycling through matches after pressing Enter to accept search

    • Added missing keybindings in DocSearch mode for match navigation
    • Both outline search (s) and content search (/) now properly support cycling
  • Escape clears search instead of quitting - When search is locked in (after pressing Enter), Escape now clears the search and returns to normal mode instead of exiting the application

  • Re-enter search input with / - After locking in a search, pressing / re-enters input mode to edit the query (keeps existing query)

Added

  • Shift+Tab keybinding in Normal mode for ToggleFocusBack action

Full Changelog: v0.5.0...v0.5.1

Full Changelog: v0.5.1...v0.5.2