Skip to content

Commit e0935e5

Browse files
committed
chore: v0.2.8 release — custom font crash fix, table formatting, Cinnamon dialogs, LSP stub, test suite
Made-with: Cursor
1 parent 82a907a commit e0935e5

31 files changed

Lines changed: 1555 additions & 320 deletions

CHANGELOG.md

Lines changed: 54 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,18 +5,68 @@ All notable changes to Ferrite will be documented in this file.
55
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/),
66
and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
77

8-
## [Unreleased]
8+
## [0.2.8] - 2026-04-14
99

1010
### Added
1111

12-
- **Command Palette** ([#59](https://github.com/OlaProeis/Ferrite/issues/59)) - Alt+Space searchable command launcher with fuzzy search across all available actions. Shows recently used commands first when empty, category-grouped browsing, keyboard shortcut hints per command. Configurable shortcut (default Alt+Space, alternative Ctrl+Shift+P selectable on Welcome page). Replaces the need for traditional menus — all ribbon and keyboard actions are discoverable through the palette.
12+
#### Command Palette ([#59](https://github.com/OlaProeis/Ferrite/issues/59))
13+
- **Alt+Space command launcher** - Searchable command palette with fuzzy search across all available actions. Shows recently used commands first when empty, category-grouped browsing, keyboard shortcut hints per command. Configurable shortcut (default Alt+Space, alternative Ctrl+Shift+P selectable on Welcome page). Replaces the need for traditional menus — all ribbon and keyboard actions are discoverable through the palette.
1314
- **Platform-specific Alt+Space suppression** - On Windows, a thread-level keyboard hook (`WH_KEYBOARD`) intercepts Alt+Space before it reaches the OS window manager, preventing the system menu (Restore/Move/Size/Close) from appearing. No-op on macOS/Linux.
1415
- **Deferred command dispatch** - Palette commands are dispatched after render (same phase as keyboard shortcuts) to prevent mid-render state mutations that caused crashes with commands like Toggle View Mode.
1516
- **Open/Close Workspace** - Added to command palette as palette-only commands (no default keyboard shortcut).
1617

18+
#### Tab Interactions ([#118](https://github.com/OlaProeis/Ferrite/issues/118))
19+
- **Middle-click to close tabs** - Middle-clicking a tab closes it, matching standard behavior in browsers and other tabbed applications.
20+
21+
#### Rendered View Performance ([#105](https://github.com/OlaProeis/Ferrite/issues/105))
22+
*Addresses slow/unusable rendered view on large documents (6k+ lines, 50k+ words).*
23+
24+
- **Markdown AST caching** - Cache parsed `MarkdownDocument` using blake3 content hash. Only re-parses when content actually changes instead of 60×/second.
25+
- **Rendered view viewport culling** - `.show_viewport()` with 500px overscan buffer. Off-screen blocks get `ui.allocate_space()` instead of full rendering. Reduces per-frame work from O(N blocks) to O(visible blocks).
26+
- **Block-level height cache** - LRU cache of measured heights per rendered block keyed on content hash. Enables accurate scrollbar positioning with viewport culling.
27+
- **Lazy block height estimation** - Heuristic heights for unmeasured blocks, render budget cap (max 20 blocks/frame), progressive refinement. Initial lag under 100ms for 10K+ block files.
28+
29+
#### Editor Performance
30+
- **Uniform height mode for large files** - Auto-enabled for 100K+ line files: O(1) line positioning, no O(N) `cumulative_heights` vector, force-disabled word wrap above threshold.
31+
- **Smarter LineCache invalidation and scaling** - Targeted `invalidate_range(start, end)` evicts only affected lines instead of full cache clear. Dynamic `max_entries(visible_lines)` scales cache with viewport. 80%+ hit rate for unchanged regions after edits.
32+
- **Per-frame O(N) elimination** - 7 per-frame O(N) operations on `tab.content` cached via `content_version` counter: `TextStats::from_text()`, `tab.title()/is_modified()` (blake3 hash), save button, CJK/complex script font detection, auto-save tab loop, frontmatter panel content clone, MarkdownEditor content clone.
33+
- **Background thread file loading** - Files ≥5MB load on a background thread with progress bar, spinner, MB loaded/total, and cancellation on tab close. UI remains responsive at 60fps during load.
34+
35+
#### Viewer Performance
36+
- **CSV raw view per-frame allocation fix** - `show_raw_view()` called `self.content.to_string()` every frame. Fixed with blake3 hash-guarded `raw_view_text` cache.
37+
- **TreeViewer parse and raw view caching** - Two blake3-guarded caches: raw view text cache (skip per-frame `to_string()`), parsed tree cache (skip per-frame `parse_structured_content()`). Supports JSON/YAML/TOML.
38+
- **Central panel undo content clone elimination** - Removed per-frame `tab.content.clone()` for undo recording across all modes. Raw mode leverages FerriteEditor's native EditHistory; other modes use blake3 hash-based change detection.
39+
40+
#### Unicode & Complex Script Support (Phase 2: Text Shaping Engine)
41+
*Depends on: Phase 1 font loading from v0.2.7*
42+
43+
- **HarfRust integration for FerriteEditor** - Integrated [HarfRust](https://github.com/harfbuzz/harfrust) (pure-Rust HarfBuzz port, v0.5.2+) for correctly positioned, contextually-formed glyphs for Arabic, Bengali, Devanagari, Tamil, and other complex scripts.
44+
- **Shaped galley cache** - Extended `LineCache` to store shaped text runs (glyph IDs + positions) keyed on content+font+width. LRU eviction with invalidation on content/font/viewport changes.
45+
- **Grapheme-cluster-aware cursor** - Replaced character-based cursor movement with grapheme-cluster-aware navigation using `unicode-segmentation`. Correct stepping over Bengali conjuncts, Korean jamo, emoji ZWJ sequences.
46+
- **Shaped text measurement** - Word wrap, line width, scroll offset, cursor/mouse positioning, and selection rendering all use shaped advance widths for complex-script lines.
47+
48+
#### Image & PDF Viewer Tabs ([#108](https://github.com/OlaProeis/Ferrite/issues/108))
49+
- **Image viewer tabs** - Open PNG, JPEG, GIF, WebP, BMP files in a dedicated viewer tab with zoom (Ctrl+scroll), fit-to-window, metadata display (dimensions, format, file size).
50+
- **PDF viewer tab** - Open PDF files using [hayro](https://github.com/LaurenzV/hayro) (pure Rust PDF renderer). Page navigation, zoom, texture caching per page.
51+
52+
#### Markdown Rendering Settings
53+
- **Strict line breaks setting** - "Strict line breaks" toggle in Settings → Editor (default: off). When enabled, single newlines render as hard `<br>` breaks (Obsidian model). Also available on the Welcome page.
54+
1755
### Fixed
1856

1957
- **macOS .md file association** ([#102](https://github.com/OlaProeis/Ferrite/issues/102)) - Added `UTImportedTypeDeclarations` block to `info_plist_ext.xml` to properly declare the `net.daringfireball.markdown` UTI. This enables opening markdown files from Finder via "Open With Ferrite" or double-clicking when Ferrite is the default application.
58+
- **Windows IME candidate box positioning** ([#103](https://github.com/OlaProeis/Ferrite/issues/103), [#15](https://github.com/OlaProeis/Ferrite/issues/15)) - Applied `layer_transform_to_global()` to `IMEOutput` coordinates so the OS receives correct screen coordinates for the candidate popup.
59+
- **Double-dash setext headings and line collapsing** - Extended `fix_false_setext_headings()` to handle `--` (not just `-`). Preprocessing for `\n-- ` line breaks while preserving `---` horizontal rules and YAML frontmatter.
60+
- **No space between paragraphs in rendered view** ([#109](https://github.com/OlaProeis/Ferrite/issues/109)) - Added proper paragraph spacing after paragraph blocks. Cumulative heights updated for accurate scrollbar.
61+
- **Trailing spaces on plain text paragraphs** - Plain paragraph WYSIWYG editing dropped trailing spaces due to per-frame re-initialization from AST. Fixed with persistent egui edit buffer (keyed by `node.start_line`).
62+
- **Search highlight positioning in markdown tables + z-order** - Fixed find/render coordinate mapping for table cells. Resolved z-order stacking where Jump to menu rendered above Find and Search panels.
63+
- **Search highlight misalignment after document edits** - Recompute match positions on buffer mutations. Version/hash-based auto-refresh for highlight state.
64+
- **Terminal CJK double-width character rendering** ([#110](https://github.com/OlaProeis/Ferrite/issues/110)) - Added `unicode-width` crate. `put_char()` advances cursor by 2 for wide chars with continuation markers. Renderer draws wide chars spanning 2 cell widths. Selection snaps to wide char boundaries.
65+
- **Windows 11 borderless window UI offset** ([#112](https://github.com/OlaProeis/Ferrite/issues/112)) - Added `.with_transparent(true)` to `ViewportBuilder` as DWM compositing workaround for Intel HD 4600 GPU rendering offset in borderless mode.
66+
- **Scrollbar not resetting when switching documents** ([#113](https://github.com/OlaProeis/Ferrite/issues/113)) - Scoped central-panel editor/preview widget IDs with `tab.id` to prevent egui `ScrollArea` state leaking across tab switches.
67+
- **Strikethrough and inline formatting lost in tables** ([#117](https://github.com/OlaProeis/Ferrite/issues/117)) - Table cells containing `~~strikethrough~~`, `**bold**`, `*italic*`, or `***bold italic***` markdown lost their formatting during parsing/serialization because `text_content()` stripped inline markup. Replaced with `serialize_inline_content()` in both `serialize_table` and `TableData::from_node` to preserve formatting through round-trip. Additionally, table cells now render inline markdown as formatted rich text (bold, italic, strikethrough, inline code) using a custom `LayoutJob`-based parser. Click a cell to switch to raw markdown editing; click away to see rendered formatting. Supports full nesting (e.g., `**~~bold struck~~**`, `***~~triple~~***`).
68+
- **Linux Cinnamon file dialog detection** ([#116](https://github.com/OlaProeis/Ferrite/issues/116)) - Linux Mint Cinnamon (`XDG_CURRENT_DESKTOP=X-Cinnamon`) was not recognized as a native desktop, causing unnecessary portal fallback. Added `x-cinnamon` to native desktop detection list, updated portal install instructions to recommend `xdg-desktop-portal-xapp`/`gtk` for Cinnamon, and fixed dialog cancellation being misclassified as a portal failure.
69+
- **Custom font crash on Linux** ([#114](https://github.com/OlaProeis/Ferrite/issues/114)) - Selecting certain system fonts (font collections, corrupt files, unsupported formats) crashed the app via epaint panic. Added TTF/OTF magic-byte validation rejecting `.ttc` collections, WOFF, Type 1, and corrupt data. Wrapped font loading in `catch_unwind` as safety net. On failure, gracefully falls back to Inter font with toast notification. Also fixed HarfRust text shaping for custom fonts (`FONT_CUSTOM` case was missing from `ttf_bytes_for_font_id_shaping`).
2070

2171
## [0.2.7] - 2026-03-11
2272

@@ -758,6 +808,7 @@ Complete ground-up reimplementation of the text editor:
758808

759809
## Version History
760810

811+
- **0.2.8** - Command palette, LSP integration (Phases 1-2), HarfRust text shaping, image/PDF viewer tabs, rendered view performance (AST caching, viewport culling, lazy estimation), per-frame O(N) elimination, background file loading, strict line breaks, middle-click close tabs, custom font crash prevention, 13 bug fixes
761812
- **0.2.7** - Wikilinks & backlinks, Vim mode, welcome view, GitHub-style callouts, check for updates, Ctrl+Scroll zoom, keep text selected after formatting, frontmatter editor, format toolbar & side panel toggles, lazy CSV parsing, large file detection, single-instance protocol, MSI installer overhaul, Nix/NixOS flake support, Unicode complex script font loading (Phase 1), Linux portal dialog error handling, macOS .app bundle CI, task list checkbox rendering, flowchart refactoring, window control redesign, word-wrap scroll fixes, 20+ bug fixes
762813
- **0.2.6.1** - First signed release, integrated terminal workspace, productivity hub, app.rs refactoring (~15 modules), CJK memory optimization, 8+ bug fixes
763814
- **0.2.6** - Custom text editor with virtual scrolling (critical for large files), memory optimization fixes
@@ -771,6 +822,7 @@ Complete ground-up reimplementation of the text editor:
771822
- **0.2.0** - Major feature release (Split View, Mermaid, Minimap, Git integration, and more)
772823
- **0.1.0** - Initial public release
773824

825+
[0.2.8]: https://github.com/OlaProeis/Ferrite/compare/v0.2.7...v0.2.8
774826
[0.2.7]: https://github.com/OlaProeis/Ferrite/compare/v0.2.6.1...v0.2.7
775827
[0.2.6.1]: https://github.com/OlaProeis/Ferrite/compare/v0.2.6...v0.2.6.1
776828
[0.2.6]: https://github.com/OlaProeis/Ferrite/compare/v0.2.5-hotfix.3...v0.2.6

Cargo.lock

Lines changed: 1 addition & 1 deletion
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

Cargo.toml

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
[package]
22
name = "ferrite"
3-
version = "0.2.7"
3+
version = "0.2.8"
44
edition = "2021"
55
description = "A fast, lightweight text editor for Markdown, JSON, and more"
66
repository = "https://github.com/OlaProeis/Ferrite"
@@ -19,6 +19,9 @@ bundle-icon = []
1919
high-perf-alloc = ["mimalloc", "tikv-jemallocator"]
2020
# Async worker infrastructure for background operations (AI, SSH, database)
2121
async-workers = ["tokio", "poll-promise"]
22+
# Language Server Protocol integration (diagnostics, hover, go-to-def).
23+
# Deferred from v0.2.8 — will ship in v0.2.9 with proper diagnostics panel.
24+
lsp = []
2225

2326
[dependencies]
2427
egui = { version = "0.28", features = ["serde"] }

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -119,7 +119,7 @@ This transparency is intentional — I want others to learn from (and improve up
119119
|------------|------------|----------|
120120
| ![Raw Editor](assets/screenshots/raw-dark.png) | ![Split View](assets/screenshots/split-dark.png) | ![Zen Mode](assets/screenshots/zen-dark.png) |
121121

122-
> **v0.2.7 (Latest):** **Wikilinks** & **backlinks panel**. **Vim mode**. **Welcome page** for first-launch setup. **GitHub-style callouts**. **Ctrl+Scroll zoom**. **Keep text selected after formatting**. **Frontmatter editor**. Image rendering in preview. **Format toolbar** & **side panel toggles**. **Nix/NixOS flake support**. New packaging: **.deb**, **.rpm**, macOS **.app** bundles. **Single-instance** file opening. 20+ bug fixes. See [CHANGELOG.md](CHANGELOG.md) for full details.
122+
> **v0.2.8 (Latest):** **Command Palette** (Alt+Space). **HarfRust text shaping** for complex scripts. **Image & PDF viewer tabs**. Rendered view **performance overhaul** (AST caching, viewport culling). **Background file loading** for large files. **Strict line breaks**. **Middle-click close tabs**. 13 bug fixes. See [CHANGELOG.md](CHANGELOG.md) for full details.
123123
124124
> 📦 **v0.2.6 Highlights:** Custom Editor Engine with virtual scrolling (80MB file uses ~80MB RAM), Multi-Cursor Editing, Code Folding, IME/CJK input improvements.
125125

0 commit comments

Comments
 (0)