Releases: Epistates/treemd
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
v0.4.7
[0.4.7] - 2025-12-07
Added
-
Command palette - Press
:to open a fuzzy-searchable command palette (#32)- Type to filter commands with fuzzy matching
- Navigate with
j/kor arrow keys, execute withEnter - Commands include: Save width, Toggle outline, Toggle help, Toggle raw source, Jump to top/bottom, Quit
- Each command has aliases (e.g.,
w/write/savefor save width)
-
Save outline width with confirmation - Press
Sto save current outline width to config with modal confirmation (#32)- Shows confirmation dialog before saving
- Respects power users: manual config values are session-only until explicitly saved
- New users with default config get auto-save behavior
-
Document search with n/N navigation - Full in-document search with match highlighting (#30)
- Press
/in content pane to search within the document - Press
nfor next match,Nfor previous match - Matches highlighted in content view
- Status bar shows match count and current position
- Press
Fixed
-
File creation modal not appearing - Fixed issue where following links to non-existent files would say "file opened" but not show the creation prompt
exit_interactive_mode()andexit_link_follow_mode()were overwriting theConfirmFileCreatemode- Now checks if file creation is pending before resetting mode
-
Double
.mdextension on wikilinks - Fixed wikilinks like[[file.md]]creatingfile.md.md- Now detects if wikilink target already has a markdown extension
- Only adds
.mdif not already present
-
Anchor links in interactive mode - Following anchor links to headings in current file now works correctly (#29)
- Changed from
select_by_text()tojump_to_anchor()for proper anchor handling - Anchor links like
#installationnow jump to correct heading
- Changed from
-
Wikilinks with path separators - Wikilinks containing
/now work correctly (#28)- Removed overly restrictive check that blocked all paths with
/ - Still blocks
..for security (prevents directory traversal) [[docs/guide]]now resolves todocs/guide.md
- Removed overly restrictive check that blocked all paths with
-
Checkbox toggle scroll jump - Toggling checkboxes no longer causes page to jump to top (#31)
- Saves and restores scroll position and element index on file reload
- Interactive mode state preserved after checkbox toggle
-
Config value protection - Outline width cycling no longer overwrites custom config values (#32)
- Tracks whether config has custom outline width at startup
- Power users with custom values: cycling is session-only
- New users with standard values: auto-save for convenience
Technical
-
Command palette system (
src/tui/app.rs)CommandActionenum for available actionsPaletteCommandstruct with fuzzy matching and scoringPALETTE_COMMANDSconstant with all commands and aliases- Filter/navigation/execution methods for palette state
-
Save confirmation modal (
src/tui/ui/popups.rs)render_save_width_confirm()for confirmation dialogrender_command_palette()for command palette UI
-
Config tracking (
src/tui/app.rs)config_has_custom_outline_widthflag to detect power user configs- Standard widths: 20%, 30%, 40% - anything else is custom
Special Thanks
@firecat53 for all the support!
Full Changelog: v0.4.6...v0.4.7
v0.4.6
[0.4.6] - 2025-12-05
Fixed the non-existing file open modal.
The issue was that both exit_interactive_mode() and exit_link_follow_mode() unconditionally set self.mode = AppMode::Normal, which was overwriting the ConfirmFileCreate mode set by load_file() or load_wikilink() when a file doesn't exist.
Full Changelog: v0.4.5...v0.4.6
v0.4.5
[0.4.5] - 2025-12-04
Added
-
Document overview for headerless files - Files without a top-level heading now show a "(Document)" entry in the outline (#25)
- Displays 📄 icon in outline for the document overview
- Shows entire file content including tables and text before the first heading
- Automatically added when there's preamble content or no headings at all
-
Wikilink rendering in content - Wikilinks now render as clickable links in the content pane
[[target]]displays as link with target as text[[target|alias]]displays alias text linking to target- Works in both interactive mode and link follow mode
- Preprocessing converts wikilinks to standard markdown links for consistent parsing
-
Links with spaces in URLs - Links like
[text](path/to/my file.md)now work correctly- CommonMark doesn't support spaces in URLs, but many wikis use them
- Preprocessing converts to angle bracket syntax for compatibility
-
File creation prompts - Following links to non-existent files prompts to create them
- Confirmation dialog with
[y]to create,[n/Esc]to cancel - Creates file with default heading based on filename
- Automatically opens the newly created file
- Works for both relative links and wikilinks
- Confirmation dialog with
-
Page navigation in interactive mode - Scroll content while staying in interactive mode
- Press
uorPgUpto scroll up - Press
dorPgDnto scroll down - Maintains element selection while scrolling
- Press
Fixed
-
Screen artifacts when scrolling - Fixed rendering artifacts caused by tab characters in code blocks (#26)
- Tabs are now converted to 4 spaces in code block syntax highlighting
- Also applies to raw markdown view for consistency
-
Shift+Tab navigation - Fixed Shift+Tab not working for backwards navigation (#18)
- Now uses
KeyCode::BackTabinstead of checking modifiers - Works correctly in both interactive mode and link follow mode
- Now uses
-
Interactive mode scroll preservation - Entering interactive mode no longer jumps to first element
- Now selects the element closest to current scroll position
- Preserves user's view when toggling interactive mode
-
Wikilink anchor support - Wikilinks now support section anchors
[[filename#section]]loads file and jumps to heading[[#section]]jumps to heading in current document
-
Relative file link improvements - Better handling of wiki-style links without extensions
- Files without extension now try
.mdfirst before opening in editor - Improves compatibility with Obsidian and other wiki tools
- Files without extension now try
Changed
-
Interactive mode status bar - Updated to show page navigation hints
- Now displays:
[INTERACTIVE] Tab:Next Shift+Tab:Prev u/d:Page Esc:Exit
- Now displays:
-
Help text updated - Interactive mode section includes new keybindings
- Added
u/dfor page up/down navigation
- Added
Technical
-
Wikilink preprocessing (
src/parser/content.rs)preprocess_wikilinks()converts[[target]]to[target](wikilink:target)before parsingpreprocess_links_with_spaces()wraps URLs containing spaces in angle brackets- Both use compiled regex with
OnceLockfor performance
-
File creation flow (
src/tui/app.rs)AppMode::ConfirmFileCreatefor pending file creation statepending_file_createandpending_file_create_messagefieldsconfirm_file_create()andcancel_file_create()methods
-
Interactive mode improvements (
src/tui/interactive.rs)enter_at_scroll_position()selects element closest to scroll position- Elements sorted by line position after indexing for proper navigation order
- Wikilinks detected via
wikilink:URL prefix from preprocessing
-
Page navigation (
src/tui/app.rs,src/tui/mod.rs)scroll_page_down_interactive()andscroll_page_up_interactive()methods- Keybindings for
u/d/PgUp/PgDnin interactive mode
-
File creation popup (
src/tui/ui/popups.rs)render_file_create_confirm()renders themed confirmation dialog
Acknowledgements
Special thanks to @firecat53 for the tremendous support in QA and UX
Full Changelog: v0.4.4...v0.4.5
v0.4.4
[0.4.4] - 2025-12-04
Added
-
Raw source view toggle - Press
rto toggle between rendered markdown and raw source view (#19)- Shows original markdown with line numbers for debugging rendering issues
[RAW]indicator in title bar and status bar when active- Maintains scroll position when toggling
-
Link search/filter in link navigator - Press
/in link follow mode to filter links by text or URL- Case-insensitive search across link text and targets
- Selection stays within filtered results
- Press
Escto clear filter or exit search mode
-
Links in list items - Interactive mode now extracts and navigates to links within list item content
- Previously only standalone links were indexed; now links embedded in list items are accessible
- Links are indexed per-item with proper highlighting
-
Selection indicator backgrounds - Added background colors to selection indicators for better visibility
selection_indicator_bgtheme field for customizing the background color- Improves contrast in all themes, especially on light backgrounds
Changed
- Status messages auto-dismiss - Temporary status messages now auto-clear after 1 second
- Event loop uses polling with 100ms timeout for responsive UI updates
- No more stale "Rendered view enabled" messages lingering
Technical
- Event polling for piped stdin - Added
poll_event()tottymodule for non-blocking event handling- Supports the same stdin redirection logic as
read_event()for piped input scenarios - Enables timed UI updates without user input
- Supports the same stdin redirection logic as
Acknowledgements
- docs: Minor formatting tweaks README.md by @Zearin in #16
- issues/suggestions: @firecat53 for #17 #18 #19 #20
New Contributors
Full Changelog: v0.4.3...v0.4.4
v0.4.3
[0.4.3] - 2025-12-03
Added
- Themeable UI colors - Replaced hardcoded colors with theme-based colors for better customization
- Added 6 new themeable color fields:
title_bar_fg,scrollbar_fg,selection_indicator_fg,link_fg,link_selected_bg,table_border - All 8 themes now include appropriate colors for these new fields (both RGB and 256-color variants)
- Users can now customize title bar, scrollbars, selection indicators, links, and table borders via config file
- Consistent theming across all UI elements
- Added 6 new themeable color fields:
Fixed
- Search bar overlapping filtered outline results - Search bar no longer overlaps the outline when filtering headings (PR #14)
- Content panes overlapping status bar - Fixed layout issue where content panes could overlap the status bar (PR #13)
Refactored
- Layout builder - Replaced string-based section IDs with
Sectionenum for type-safe layout management
Acknowledgements
- Fix content panes overlapping status bar by @kanatti in #13
- fix: prevent search bar from overlapping filtered outline results by @kanatti in #14
- ux suggestion: Improve the UI color theme @EduardsSk #15
Full Changelog: v0.4.2...v0.4.3