Releases: Epistates/treemd
v0.5.9
[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
HelpLineenum replaces raw string-based help entries
-
Noopaction for keybinding customization - Users can unbind keys by mapping them toNoopin their config (#46)Noopentries are automatically filtered from the help popup
-
Regression tests for keybinding system - Added tests for user config override,
Noopunbinding, 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
Vecand matched before user overrides - New approach replaces matching default bindings in-place, preserving user precedence
- Previously, defaults were inserted first in the dispatch
-
CloneforKeybindingsdiscarded 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 ofExitModefor table navigation exit -
Duplicate
tkeybinding - BothToggleTodoFilterandToggleThemePickerwere bound totin Normal mode;ToggleTodoFiltermoved toT(Shift+t) -
Phantom
Skey in status bar - "S or :w to save" referenced an unbound key; updated to ":w to save" -
Editor in interactive mode -
OpenInEditornow 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
usizeunderflow in help text - Key column width calculation now usessaturating_sub
tl;dr:
- Fix keybindings config merging by @enzalito in #46
- Update help_text to display actual keybinds by @enzalito in #47
New Contributors
Full Changelog: v0.5.8...v0.5.9
v0.5.8
Full Changelog: v0.5.7...v0.5.8
Full Changelog: v0.5.7...v0.5.8
v0.5.7
[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 directorytreemd 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
--treeCLI output and query tree output
- Now uses
-
Todo filter for outline - Filter heading tree to show only headings with open todos (#44)
- Press
tto 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
- Press
-
SOTA Content filtering - Robust YAML frontmatter and LaTeX handling (#43)
- Unicode Approximation: LaTeX math symbols like
\alpha,\sum,\inftyare 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 (x²,nᵢ). - Environment Preservation: Content inside LaTeX environments (like
equationoralign) is preserved while stripping the tags. hide_frontmatteroption strips---\n...\n---blocks at document start.hide_latexoption handles math and LaTeX commands robustly without "half measures".- Aggressive filtering remains available but the standard mode is now preferred.
- Unicode Approximation: LaTeX math symbols like
-
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
qto 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
ContentConfigstruct withhide_frontmatter,hide_latex,latex_aggressivefields - Added
tree_stylefield toUiConfig(defaults to "compact") - Added
is_compact_tree()helper method to Config
- Added
-
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
- Added
-
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
- Added
-
App state (
src/tui/app.rs)- Added
file_picker_dirfield for custom directory support - Added
should_hide_frontmatter()andshould_hide_latex()getters - Updated
scan_markdown_files()to use custom directory
- Added
-
Table rendering (
src/tui/ui/table.rs,src/tui/ui/mod.rs)- Refactored
render_table_rowto returnVec<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
- Refactored
Full Changelog: v0.5.6...v0.5.7
v0.5.6
[0.5.6] - 2026-01-09
Added
- Image configuration - Configure image rendering via
[image]section in config- Specify preferred renderer:
renderer = "kitty"orrenderer = "software" - Add custom arguments:
args = ["--no-animations"] - Example config:
[image] renderer = "kitty" args = ["--no-animations"]
- Specify preferred renderer:
Full Changelog: v0.5.5...v0.5.6
v0.5.5
[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
qto 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
Spaceto play/pause animation - Press
nfor next frame,pfor 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/kor arrow keys - Press
Enterto open selected file - Shows file list with real-time filtering
-
macOS XDG config path support -
~/.config/treemdnow supported on macOS (#41)- Checks
~/.config/treemd/config.tomlfirst on macOS - Falls back to
~/Library/Application Support/treemd/config.toml - Enables easier dotfiles management and cross-platform config sharing
- Checks
-
Alpine Linux support - musl builds for Alpine and other musl-based distributions (#42)
- Added
x86_64-unknown-linux-muslbinary to releases - Added
aarch64-unknown-linux-muslbinary to releases - Statically-linked binaries work without glibc dependency
- Added
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 managementsrc/tui/image_cache.rs- Image caching and lazy loading system
-
Dependencies
- Added
ratatui-image 10for terminal image rendering - Added
image 0.25for image processing - Added
gif 0.13for GIF parsing and frame extraction
- Added
-
Release workflow
- Added musl targets (
x86_64-unknown-linux-musl,aarch64-unknown-linux-musl) to CI
- Added musl targets (
Full Changelog: v0.5.4...v0.5.5
v0.5.4
[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)
- Press
-
Editor configuration - Configure external editor via
[editor]section in config- Specify preferred editor:
editor = "nvim"oreditor_kind = "NeoVim" - Add custom arguments:
args = ["--noplugin"] - Uses opensesame EditorConfig
- Example config:
[editor] editor = "nvim" args = ["--noplugin"]
- Specify preferred editor:
Changed
- opensesame dependency - Updated to use serde feature for config serialization
Full Changelog: v0.5.3...v0.5.4
v0.5.3
[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)
- Styled key badges with theme colors (
-
Vim-style count prefixes - Repeat motions with numeric prefixes like vim
5jmoves down 5 items,10kmoves up 10 items- Works in Normal mode (outline/content navigation) and Interactive mode
- Supports: j/k navigation, h/l table columns, content scrolling
0without count goes to first item (vim behavior preserved)- Link follow mode still uses
1-9for 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 2for 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
:wcommand 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:savewrites all buffered edits to file atomically- Shows confirmation: "Saved X change(s) to filename.md"
-
Undo command (
:uandCtrl+z) - Undo table cell edits before saving:uor:undoin command palette undoes last editCtrl+zkeybinding 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/ysaves changes and quitsEscapecancels 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)
- Outline focused:
-
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()
- Fixed off-by-one error in
Technical
-
Theme footer colors (
src/tui/theme.rs)- Added
help_key_bg,help_key_fg,help_desc_fg,footer_bgto all 16 theme variants - Added
help_key_style(),help_desc_style(),footer_style()helper methods - Updated
with_custom_colors()andwith_color_mode_custom()for footer fields
- Added
-
Config footer colors (
src/config.rs)- Added footer color fields to
CustomThemeConfigfor user customization
- Added footer color fields to
-
Layout footer section (
src/tui/ui/layout.rs)- Added
Section::Footerto layout system
- Added
-
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
- Added
-
Collapse/expand methods (
src/tui/app.rs)collapse_all(),expand_all(),collapse_level(n),expand_level(n)- Added
CollapseAll,ExpandAll,CollapseLevel,ExpandLeveltoCommandAction
-
HTML parsing utility (
src/parser/utils.rs)- Added
parse_inline_html()function for HTML tag to InlineElement conversion
- Added
Full Changelog: v0.5.2...v0.5.3
v0.5.2
[0.5.2] - 2025-12-12
Fixed regression from 0.5.1
-
Search navigation after locking in results - Fixed
n/NandTab/Shift+Tabnot 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+Tabkeybinding in Normal mode forToggleFocusBackaction
Full Changelog: v0.5.0...v0.5.1
Full Changelog: v0.5.1...v0.5.2
v0.5.1
[0.5.1] - 2025-12-12
Fixed
-
Search navigation after locking in results - Fixed
n/NandTab/Shift+Tabnot 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+Tabkeybinding in Normal mode forToggleFocusBackaction
Full Changelog: v0.5.0...v0.5.1
v0.5.0
[0.5.0] - 2025-12-11
Added
-
Customizable keybindings system - Full keybinding customization via config file
- Configure any key for any action using intuitive TOML syntax
- Multi-key sequences supported (e.g.,
"g g" = "First") - 12 distinct modes: Normal, Help, ThemePicker, Interactive, InteractiveTable, LinkFollow, LinkSearch, Search, DocSearch, CommandPalette, ConfirmDialog, CellEdit
- 70+ bindable actions covering all application functionality
- Uses keybinds-rs for robust key parsing
- Built-in defaults following vim conventions
- Example configuration:
[keybindings.Normal] "j" = "Next" "k" = "Previous" "Ctrl+c" = "Quit" "g g" = "First" # Multi-key sequences! [keybindings.Interactive] "Escape" = "ExitInteractiveMode"
-
Unified search system - Consistent search experience across outline and content
- Press
sto search/filter the outline tree - Press
/to search document content - Press
Tabto toggle between outline and content search (preserving query) - Both modes highlight matches with themeable colors
n/Nnavigate matches in both modes after pressing Enter- Visual search bar with cursor and clear mode indicator
- Press
-
Open links from search - Follow links directly from document search results
- When search matches a link, press Enter to follow it
- Works with anchor links, file links, wikilinks, and external URLs
-
Open editor at location - Jump to specific line when editing
- Press
eto open current file at the selected heading's line number - Uses opensesame for cross-editor line support
- Works with VS Code, vim, neovim, emacs, and most editors
- Press
-
Themeable search highlighting - Customize search match colors in config
search_match_bg/search_match_fgfor matchessearch_current_bg/search_current_fgfor focused match- Works consistently in both outline and content views
Changed
- Parser rewrite using turbovault - Switched to turbovault-parser for markdown parsing
- More robust handling of complex nested structures
- Better performance on large documents
- Improved code block detection in list items
- Proper handling of inline formatting in all contexts
Fixed
-
Checkbox toggle with inline markdown - Fixed toggling checkboxes when task items contain inline formatting (PR #38 by @viniciussoares)
- Checkboxes with bold, italic, code, or links now toggle correctly
- Uses regex-based markdown stripping instead of brittle character parsing
- Example:
- [x] **Important** tasknow works properly
-
Query engine missing code blocks in list items - Code blocks nested inside numbered/bulleted list items are now correctly extracted for queries
- Queries like
.codeand.code[pattern]now find code blocks inside list items - Also extracts images and tables nested within list items
- Recursively extracts from blockquotes and details blocks as well
- Queries like
-
Nested code blocks in lists - Code blocks inside list items now render correctly
- Fixed indentation detection for nested blocks
- Proper syntax highlighting maintained
-
Interactive element parsing - Fixed element detection after parser rewrite
- All interactive elements (checkboxes, tables, code blocks, links) correctly indexed
-
Wikilink resolution - Fixed wikilinks with path separators
[[docs/guide]]now correctly resolves todocs/guide.md
-
Search mode stability - Fixed various search mode issues
- Backspace, Escape, Enter all work correctly in search modes
- Ctrl+U clears search query
- Search state properly preserved when toggling between modes
Technical
-
Keybindings module (
src/keybindings/)action.rs- 70+ actions with descriptive names and categoriesdefaults.rs- Built-in vim-style defaults for all modesmod.rs-Keybindingsstruct wrapping keybinds-rs with mode dispatch- Actions serializable for config file persistence
-
Parser refactoring (
src/parser/)- Migrated from pulldown-cmark to turbovault-parser 1.2.3
- Simplified content.rs from ~1000 lines to focused wrapper
- Better link extraction with improved anchor handling
-
Search infrastructure (
src/tui/)outline_search_activeanddoc_search_activefor input state trackingtoggle_search_mode()for seamless Tab switching- Shared highlighting utilities in
ui/util.rs
-
Recursive block extraction (
src/query/eval.rs)- Added
extract_nested_blocks()helper function extract_blocks()now descends into List, Blockquote, and Details blocks
- Added
Dependencies
- Added
keybinds = "0.2"with crossterm and serde features - Added
strum = "0.27"for action enum iteration - Added
opensesame = "0.1"for editor line positioning - Updated
turbovault-parser = "1.2.3"(replaces direct pulldown-cmark usage)
PRs
- Fix checkbox toggle failing when task items contain inline markdown formatting by @viniciussoares in #38
- Feature/keybindings v2 by @nicholasjpaterno in #35
- Release/v0.5.0 by @nicholasjpaterno in #36
New Contributors
- @viniciussoares made their first contribution in #38
- @nicholasjpaterno made their first contribution in #35
Full Changelog: v0.4.7...v0.5.0