Changelog
May 17, 2026 · View on GitHub
All notable changes to WpfHexEditor are documented here.
Format: Keep a Changelog · Versioning: Semantic Versioning
[0.6.5.95] — 2026-05-17 — ScreenRecorder, ClassDiagram Live Arrows, Scripting Console, Snippets Phase 2, ByteProvider v1.3.0
✨ Added
- ScreenRecorder plugin — full 10-phase capture pipeline: BitBlt + RenderTargetBitmap engine, DPI-aware region selector, CaptureOverlayWindow, F9/Shift+F9 global hotkey registered on overlay HWND; timeline UI (thumbnails, drag-reorder, multi-select), GIF/PNG sequence/FFmpeg export services, playback scrubber, undo/redo, import from file, clipboard paste; themed (all Dock brush tokens), localized in 28 satellite languages;
.whscrsession format; multi-instance document tab support - ClassDiagram — live arrow redraw during node drag — arrows follow nodes in real time while dragging (≤60 relations threshold for smooth 60fps rendering); fixes stale arrows after drop
- Scripting Console panel — dockable Roslyn-based scripting console (Chantier B); async execution, output history, output cap, CTS-safe shutdown;
ScriptingModuleintegration - Snippets Phase 2 — visual in-app snippet editor:
SnippetBodyHighlightBox(RTB highlight),SnippetConflictDetector,SnippetImportExport,SnippetVariablePicker,SnippetsOptionsPage; default snippet pack + user store (UserLanguageSnippetStore) integration - Hex Diff / Patch panel — side-by-side binary diff with concurrent reads, TOCTOU fix, patch export;
HexDiffModule(Chantier A) - Binary Analysis module — 5 panels: navigate, EstimateSize, CSV export;
BinaryAnalysisModule(Chantier C) IdeInputDialog— themed modal input dialog; wired to docking profile directory browse button in options- View menu — 7 new panel entries (ScreenRecorder, Hex Diff, Binary Analysis, Scripting Console, Spell Check, Snippets, Spell Options) wired into View menu via
ViewMenuOrganizer MenuItemDescriptor.HeaderFactory— additiveFunc<string>delegate for live-localizable dynamic menu items without rebuilding the menu tree- Language restart prompt — IDE prompts to restart on language change;
IdeMessageBoxgains custom button support ActivePanelHighlightdefaults to Glow — dock panels now glow-highlight active tab by default- SpellChecker options page — settings + satellite localization (28 langs)
- ByteProvider v1.3.0 — public API tier: DI decorators, AOP intercept, Slice views, Metrics; 90 xUnit tests (
ByteProviderTests,ChangesetTests,DecoratorTests,DiffTests,FactoryTests,InsertDeleteTests,MetricsTests) TerminalHostContextAdapter—ITerminalHostContextimplemented onStandaloneIDEHostContextfor terminal sample
🔧 Fixed
- whfmt.CodeGen v1.1.3 — JSONC
/* */headers in.whfmtfiles now parsed correctly (first-char guard extended) - WpfTerminal decoupled from
IIDEHostContext—RoslynServiceFactoryinjected;Processleak fixed; NuGet standalone contract restored ClassDiagram— staleDiagnosticOutputwiring causingMissingMethodExceptionremoved- Loc:
Assembly.GetSatelliteAssembly— real satellite presence detection replaces glob-based check - Loc: regional sibling fallback —
es-MX → es-ESculture chain resolution; per-manager culture aligned toCommonResourcessatellites;_currentCulturedefaults toen-US - Loc: 36 XAML files —
LocalizedDictionaryinjected +DynamicResource→StaticResourceon loc keys (200 files pass) - Loc:
AsmExplorer_GoToDefinition— missing key added to resx + 28 satellites - MC3089 — misplaced attributes moved back onto
ThemedDialogopening tag inResizeImageDialog - ScreenRecorder: Dispatcher re-entrancy —
DoDragDropdeferred viaBeginInvoketo fix crash on drag - ScreenRecorder: DPI —
ApplyRegionmoved afterShow()for correct physical-DPI resolution; primary screen default; correct DPI for captured bitmaps - Build: 35 CS errors —
VirtualizingPanelinitializer,CodeEditorResourcesaccess, missingusingresolved
📦 Versions in this build
| Component | Version |
|---|---|
WpfHexEditor.App (IDE shell) | 0.6.5.95 ← bumped this release |
WPFHexaEditor (NuGet) | 3.3.1 |
WpfCodeEditor (NuGet) | 0.9.9.0 |
WpfDocking (NuGet) | 0.9.8.0 |
WpfTerminal (NuGet) | 0.9.7.1 |
WpfColorPicker (NuGet) | 2.0.2 |
WpfHexEditor.Core.ByteProvider (NuGet) | 1.3.0 |
WpfHexEditor.Core.BinaryAnalysis (NuGet) | 1.0.1 |
whfmt.FileFormatCatalog (NuGet) | 1.3.2 |
whfmt.Analysis (NuGet) | 1.1.1 |
whfmt.CodeGen (NuGet) | 1.1.3 |
whfmt.Fuzz (NuGet) | 1.1.1 |
whfmt.Validate (NuGet) | 1.0.0 |
WpfHexEditor.SDK | 2.0.0 (frozen) |
[0.6.5.8] — 2026-05-12 — Build-Number Scheme Reset
🔧 Changed
- IDE build number reset —
WpfHexEditor.AppVersion/AssemblyVersion/FileVersionreset from0.6.5.225to0.6.5.8to adopt a new build-number scheme (small monotonic counter inside the0.6.5.*revision slot). No functional change versus0.6.5.225; all features documented under that release remain shipped. - Docs sweep —
ROADMAP.mdLast revisedadvanced to2026-05-12; current-build banner added; this CHANGELOG entry inserted as the new HEAD; published-package READMEs and guides verified against current.csprojversions (no NuGet package re-bumped — only the IDE shell version changed).
📦 Versions in this build
| Component | Version |
|---|---|
WpfHexEditor.App (IDE shell) | 0.6.5.8 ← bumped this release |
WPFHexaEditor (NuGet) | 3.3.1 |
WpfCodeEditor (NuGet) | 0.9.9.0 |
WpfDocking (NuGet) | 0.9.8.0 |
WpfTerminal (NuGet) | 0.9.7.1 |
WpfColorPicker (NuGet) | 2.0.2 |
WpfHexEditor.Core.ByteProvider (NuGet) | 1.1.1 |
WpfHexEditor.Core.BinaryAnalysis (NuGet) | 1.0.1 |
whfmt.FileFormatCatalog (NuGet) | 1.3.2 |
whfmt.Analysis (NuGet) | 1.1.1 |
whfmt.CodeGen (NuGet) | 1.1.2 |
whfmt.Fuzz (NuGet) | 1.1.1 |
whfmt.Validate (NuGet) | 1.0.0 |
WpfHexEditor.SDK | 2.0.0 (frozen) |
[0.6.5.225] — 2026-05-09 — Code Analysis: Scope UX, SplitButton Re-run, Treemap Context Menu, Localization Fixes
✨ Added
- Code Analysis — scope display — toolbar now shows the scope and path of the last run:
Solution: WpfHexEditorControl,Project: WpfHexEditor.App,File: Foo.cs; displayed in italic between buttons and filters when a report is loaded - Code Analysis — SplitButton Re-run — left part re-runs the same scope/path as the last run; dropdown arrow opens a menu with Re-run (same scope), Run Solution, Run Project…, Run File…;
_lastScope/_lastPathpersisted inCodeAnalysisModuleso switching tabs does not reset the scope - Code Analysis — Treemap context menu — right-click on any tile shows a localized context menu: Open File (opens in editor), Copy Path, Copy Metrics (all metrics to clipboard), separator, Run Analysis on File (runs analysis scoped to that file), separator, Filter to This Project (sets the project filter), Highlight Top 10 Hotspots (toggle — dims non-hotspot tiles to highlight the critical ones)
- Code Analysis — 15 new localization keys —
CodeAnalysis_Rerun_SameScope,_RunSolution,_RunProject,_RunFile;CodeAnalysis_Scope_Solution/Project/File;CodeAnalysis_Treemap_OpenFile/CopyPath/CopyMetrics/RunOnFile/FilterProject/HighlightHotspots;CodeAnalysis_Tooltip_Rerun_SameScope/RunSolution; translated in all 28 satellite languages
🔧 Changed
- Code Analysis —
AppLocalizedDictionaryin UserControl.Resources —CodeAnalysisReportPane.xamlnow includes<appSvc:AppLocalizedDictionary/>in its localMergedDictionaries, matching the pattern used byWatchesPanelandAssemblyDetailPane; fixesDataGridTextColumn.Headerand other logical-tree elements that cannot inheritApplication.Resources - Code Analysis —
EnsureReportPaneExistseager init — pane and view-model are pre-built duringInitialize()so layout-restored tabs find real content on the firstBuildContentForItemcall - Code Analysis — diagnostic log removed — temporary
[Code Analysis] Pushing to VMlog removed fromRunAsync(root cause confirmed resolved)
🐛 Fixed
- Code Analysis — empty column headers —
DataGridTextColumn.Header,ComboBoxItem.Content, and button labels were rendering as empty becauseDynamicResource CodeAnalysis_*keys require the dictionary to be in the local UserControl scope; fixed by includingAppLocalizedDictionaryinUserControl.Resources.MergedDictionaries - Code Analysis — Re-run always ran on solution —
_reRunCallbackwas wired toGetSolutionPath()unconditionally; now uses_lastScope/_lastPathso "Run Project" re-runs the project, not the full solution
[0.6.5.110] — 2026-05-05 — DocumentEditor Glyph-Accurate Caret, Ruler Scroll-Tracking, Debug Module Integration
✨ Added
- DocumentEditor: glyph-accurate hit-test — new
GetCharOffsetFromGlyphLinesstatic helper usesPlacedSegment.AdvanceWidthsandInlineVisualLine.CharStart/CharEndfrom the GlyphRun pipeline (same pipeline asDrawVisualLines) to map a screen point to a document character offset; eliminates the class of misalignment caused by the previously usedFormattedTextpath which wraps at different column positions thanGlyphTypeface-backed rendering - DocumentEditor: glyph-accurate caret positioning — new
GetCaretXYFromGlyphLinesstatic helper derives the caret beam X, Y, and height fromPlacedSegment.AdvanceWidths;RefreshCaretVisualandCaretContentXboth use this path when GlyphLines are available;FormattedTextpath retained as fallback for table/image blocks with no GlyphLines - DocumentEditor:
PageCanvasPaddingpublic static accessor —DocumentCanvasRenderer.PageCanvasPaddingexposes the canvas-space top padding constant so dependent controls (vertical ruler, minimap) can compute scroll-relative geometry without internal coupling DebugModule+DebugVisualizerRegistry— Debugger functionality merged fromWpfHexEditor.Plugins.DebuggerintoWpfHexEditor.App/Debugas a first-class core module (DebugModule);IDebugAdapterRegistryandIDebugVisualizerRegistrySDK extension points preserved; debug panels (Locals, Autos, Watch, Call Stack, Threads, Tasks, Registers, Memory, Disassembly) pre-register shells at startup for immediate docking restore- VS-style Call Stack toolbar — search field, navigate backward/forward (←/→), Show All Threads, Show External Code toggles wired in
CallStackPanelViewModel
🔧 Changed
- DocumentEditor: synchronous
RebuildLayoutin all edit paths —InsertTextAtCaret,SplitBlockAtCaret, andDeleteAtCaretnow callRebuildLayout()synchronously (instead of posting atRenderpriority) beforeRefreshCaretVisual; eliminates the one-frame stale layout that caused a visible offset between the typed character and the caret position - DocumentEditor:
SetVerticalOffsetfiresPageGeometryChanged— vertical scroll now notifies allPageGeometryChangedsubscribers (rulers, minimap viewport) in addition to the existingPageChangedevent; ruler was previously not redrawn on scroll - DocumentEditor: ruler graduation anchored to scroll offset —
DrawGraduationsnow receives ; unit-0 of the scale always aligns with the first content line regardless of scroll position; margin zones clip correctly to the visible viewport - DocumentEditor: caret notifications from all mouse paths —
OnMouseDownandOnMouseUp(pending-collapse resolution) now callNotifyCaretBlockChangedIfNeededandNotifyCaretMoved; horizontal ruler indent markers and anyCaretMovedsubscriber now update on paragraph click, not only on keyboard edits DebugModulepanel restore — debug panel shells are pre-built at registration time (not deferred until first dock) so the docking engine can restore their layout positions fromlayout.jsonon startup;EagerContentKeyset for all nine debug panel types
🐛 Fixed
- Caret / insert position mismatch — characters typed at a wrapped line were inserted at the wrong offset because
GetCharOffsetAtPointusedFormattedTextgeometry (different wrap width from GlyphRun); fixed by routing all hit-testing throughGetCharOffsetFromGlyphLines - Vertical ruler not tracking document scroll — ruler was anchored to
VerticalOffset = 0becauseSetVerticalOffsetdid not firePageGeometryChanged; ruler subscription was not triggered on scroll; both issues fixed - Ruler indent markers frozen on paragraph click —
OnMouseDownand edit-path operations did not call caret-moved notifications; horizontal ruler indent markers only updated whenCommitCaretwas reached via keyboard; fixed by adding bothNotify*calls in all caret-setting paths - Document opens dirty —
UndoEngine.MarkSaved()andmodel.IsDirty = falsenow called inBindModelso a freshly opened document does not show the unsaved indicator GetCaretXArgumentOutOfRangeException — guard added when_caretOffsetexceeds the current block's text length after a deletion; caret clamped to[0, textLen]- Minimap viewport rect disproportionate — viewport rectangle in
DocumentMiniMapControlwas computed using pre-zoom metrics; fixed to use the same scaled content height as the renderer AssemblyExplorerblank panel on restore — dual-cache bug whereDockControl._displayContentkept serving a stale placeholder after_contentCachewas cleared; both caches now invalidated together- Module panel restore dual-cache — clearing only
DockControl._contentCacheleft_displayContentserving the stale placeholder on next activation; both caches must be cleared onEagerContentKeymiss
[0.6.5.16] — 2026-05-04 — HexEditor Split View, DocEditor Rulers, Options Localization, Docking Auto-Reset
✨ Added
- HexEditor Split View (#229) —
HexEditorSplitHostwraps twoHexEditorinstances sharing the sameByteProvider; inline split toggle at top of scrollbar; independent scroll, selection, and caret per pane; focus borders in split mode only; status bar hidden on secondary pane;ByteProvider.DataChangedpropagates modify/insert/delete to the peer pane; breadcrumb bar, format detection blocks, undo/redo, and custom background overlays all synced to secondary; standalone-safe (HexEditorSplitHostused inSample.HexEditor);IDocumentEditorundo/redo always delegated to primary pane (sharedUndoEngine); options toggleShowSplitToggleButton; layout persistence - DocEditor Page Rulers — interactive horizontal and vertical rulers tracking zoom level, caret position, and page geometry; drag-to-resize top and bottom page margins;
LayoutTransform-based zoom with snap-to-pixel inGlyphRunRenderer; minimap viewport rect fix (pre-zoom metrics); drag-to-move Word/VS-style selection; staleFormattedTexteviction onMarkBlockDirty - Code/Text Editor Options Localization — 4 new
OptionsResourceskeys (CodeEditor_Tab_Formatting,CodeEditor_HighlightCurrentLine,TextEditor_WordWrap,TextEditor_HighlightCurrentLine) across 29 locales;CodeEditorFormattingPageandTextEditorOptionsPagefully converted to DynamicResource;ErrorPanelOptionsPageadded - Docking Layout Auto-Reset — corrupt or oversized saved layouts detected and discarded on startup instead of crashing; layout persistence save/restore on close/load wired in
MainWindow
🐛 Fixed
- HexEditor
ByteProvider.DataChanged— now propagates all mutation types (modify / insert / delete) to the peer pane in split view; previous implementation only forwarded modification events - DocEditor ruler zoom alignment — ruler horizontal origin computed via
TranslatePointfrom renderer canvas to ruler control; handles margin, padding, and container offsets correctly at all zoom levels
[0.6.5.15] — 2026-05-01 — NuGet Wave, 790+ Formats, 27-Language Localization, WpfDocking 0.9.7
✨ Added
- WPFHexaEditor 3.2.0 — new standalone NuGet package release: Go to offset dialog (
Ctrl+G), unifiedUndoEnginewithCtrl+Z/Y, undo groups and coalescence; drag-selection auto-scroll via window-level mouse capture;ShowColumnHighlight/ShowAsciiColumnHighlightdefaultfalse; BreadcrumbBar Render-priority guard (freeze fix) + phantom empty row fix (XAML/code-behind duplication resolved);ByteProviderextracted toWpfHexEditor.Core.ByteProviderstandalone assembly - WpfCodeEditor 0.9.8.0 — standalone NuGet package release: full guide (
WpfCodeEditor-guide.md) bundled; 57+ language definitions; LSP 3.17 full suite; all satellite assemblies (27 languages) correctly isolated - WpfDocking 0.9.7.0 — horizontal reorder for docked tool-panel tabs (drag left/right within the same edge); tab-switch triple-fire eliminated (layout passes reduced 3→1); StaticResource toolbar labels fix (pre-register output queue prevents first-display race); full localization wired into all Docking strings (27 languages); guide (
WpfDocking-guide.md) bundled - WpfTerminal 0.9.7.0 — standalone NuGet release: LSP host startup stability (burst-init dispatcher calls downgraded to
Backgroundpriority); scroll-bar theming consistent across all docked terminal panels; plugin error routing fixed (forwarded to output panel); guide (WpfTerminal-guide.md) bundled - whfmt.FileFormatCatalog v1.1.0 —
FormatMatcher,FormatFileAnalyzer,CatalogQuery,FormatMetadataExtensions,FormatSummaryBuilderutility layer added;GetAll()/GetCategories()now returnIReadOnlySet<T>backed byFrozenSet<T>;LazyInitializer.EnsureInitializedreplaces manual double-checked lock - WpfHexEditor.Core.ByteProvider 1.1.0 — standalone cross-platform
net8.0NuGet package;IByteProviderabstraction with file, stream, and memory backends; undo-aware byte operations - 790+ .whfmt format definitions — +100 new definitions (Groups C–J complete);
FormatSchemaValidatorwired at load time (schema v2.3 validation on open, violations reported viaFormatLoadFailure) - IDE Localization — 27 languages — 77.9% DynamicResource coverage; all panels, menus, context menus, dialogs, and toolbar buttons translated into 27 languages (ar-SA · cs-CZ · da-DK · de-DE · el-GR · es-419 · es-ES · fi-FI · fr-CA · fr-FR · hi-IN · hu-HU · id-ID · it-IT · ja-JP · ko-KR · nl-NL · pl-PL · pt-BR · pt-PT · ro-RO · ru-RU · sv-SE · th-TH · tr-TR · uk-UA · vi-VN · zh-CN); per-assembly
LocalizedResourceDictionarypattern
🔧 Changed
- NuGet satellite assembly isolation — all 6 packages now use
_BundledProjectDlldirect-path pattern (replaces brokenReferenceCopyLocalPathsapproach forPrivateAssets="all"project references); single_AllSatellitesglob + per-filenameConditionfilter eliminates NU5118 collisions and contamination from unrelated solution projects GeneratePackageOnBuild— set tofalseon all non-release projects to prevent auto-pack during solution builds- NuGet badges count — updated to reflect 7 packages (added ByteProvider)
🐛 Fixed
- Satellite contamination in nupkgs — ResxEditor, Debugger, and other unrelated assembly satellites no longer appear inside WPFHexaEditor, WpfDocking, and other standalone packages
- NU5118 collision — multiple
TfmSpecificPackageFileitems with overlapping culture folders resolved by single-glob + condition pattern - WpfDocking toolbar StaticResource — localized labels now resolve correctly on first display (pre-register output queue)
[0.6.4.75] — 2026-04-15 — Structure Editor, 690+ Formats, whfmt.FileFormatCatalog NuGet
✨ Added
- whfmt.FileFormatCatalog v1.0.0 NuGet — new cross-platform
net8.0NuGet package (dotnet add package whfmt.FileFormatCatalog); extracts the embedded format catalog as a standalone library withEmbeddedFormatCatalogsingleton,DetectFromBytes(ReadOnlySpan<byte>)magic-byte detection,GetByExtension,GetByMimeType,GetByCategory,GetSchemaJson,GetCompatibleEditorIds; zero external dependencies; includes full API guide (whfmt-FileFormatCatalog-guide.md) - WpfHexEditor.Core.Contracts — new
net8.0assembly containingIEmbeddedFormatCatalog,EmbeddedFormatEntry,FormatSignature,FormatCategoryenum (27 categories),SchemaNameenum (5 schemas); breaks WPF dependency from Core.Definitions enabling cross-platform NuGet - Structure Editor (~30%) — new visual
.whfmtbinary template editor: block DataGrid with field types/offsets, drag-drop block reordering,Ctrl+Fsearch, validation pipeline, undo/redo,StructurePopToolbar,BlockTypeBadge,LiveWhfmtBuffer,VariablesTabredesign,TestTabwith live binary preview, variable cross-reference validation, expressionSmartComplete, options page,SimpleBlockInterpreterenhancements,ForensicPatterntolerant converter - WhfmtExplorer browser panels —
WhfmtBrowserPanelandWhfmtCatalogDocumentfor browsing and inspecting all embedded format definitions from within the IDE; category filtering, detail view, format JSON preview - +230 new .whfmt definitions — catalog expanded from ~460 to 690+ format definitions across multiple batch additions (Groups C/D/E +60, Groups F/G/H/I/J +51, +50 additional formats, +30 formats, +14 formats); covers new categories and enriches existing ones
- whfmt schema v2.3 — schema upgraded with
references,forensicPatterns,variablesblocks; all existing definitions aligned to v2.3 - Format Browser/Catalog view menu entries — View menu integration for WhfmtBrowser and WhfmtCatalog panels
InputFiltercontrol — reusable input filter control for hex/decimal/text validationHexStringToColorConverter— value converter for displaying hex color strings as color swatches- WHFMT_LOADING_PIPELINE documentation — internal documentation of the whfmt load pipeline architecture
🔧 Changed
- EmbeddedFormatCatalog refactor — integrated PR #230; resource key prefix updated from
WpfHexEditor.Definitions.FormatDefinitions.toWpfHexEditor.Core.Definitions.FormatDefinitions.;LoadHeaderextended to extractMimeTypesandSignaturesfields;FrozenSet<T>+LazyInitializerfor thread-safe caching - Core.Definitions target framework —
net8.0-windows→net8.0(cross-platform); ProjectRef changed from Editor.Core → Core.Contracts withPrivateAssets=all+ DLL bundling - whfmt schema v2 updates — Data, Database, Disk, Images, Programming, System, Text, Game, Archives categories updated to schema v2 format; references block added across definitions
- WPFHexaEditor NuGet bumps — 3.0.8 → 3.1.0 → 3.1.1 → 3.1.1.1 → 3.1.2 through iterative format detection fixes
- WhfmtBrowserPanel + WhfmtCatalogDocument XAML improvements — layout refinements, theme alignment
🐛 Fixed
- Corrupted whfmt crash guard — corrupted
.whfmtfiles no longer crash the IDE; load failures surfaced viaFormatLoadFailure(OutputLogger red/yellow for IDE, StatusText red for standalone) - Format detection pipeline — thread-safe
GetAll()+ self-healing parsed-formats cache; TIER 1 scored before early-exit; TIER 2 blocked when strong match found; entropy check skipped for Strong/Unique signatures - SignatureStrength converter — global
JsonStringEnumConverterreplaced with targeted[JsonConverter]+ custom converter handling Number/String/unknown gracefully - Invalid JSON escapes — fixed
\xhex escapes in HDF5, NETCDF, NPY whfmt files (invalid in JSON) - Missing required:true — added to 10 .whfmt definitions missing the field
- whfmt schema issues (#229) — addressed issues reported by tecAmoRaller
- TextEditor viewport fix — viewport line-count sync corrected
- Format definition version alignment — all 690+ definitions version-bumped consistently
/* */file headers removed — stripped non-JSON comment headers from all whfmt definitions (JSONC guard fix)
[0.6.4.10] — 2026-04-13 — Column Highlight Defaults + Shared Undo Engine
🔧 Changed
- Column highlight defaults —
ShowColumnHighlightandShowAsciiColumnHighlightinHexEditorDefaultSettingsnow default tofalseto reduce visual noise out-of-the-box
✨ Added
- HexEditor ↔ CodeEditor shared undo engine — unified
UndoEngineacross all editors (IUndoAwareEditorcontract,HexByteUndoEntry,DocumentBufferundo wiring viaByteProvider);Ctrl+Z/Yhistory is now shared across editor types (ADR-UNDO-01 continuation, feat #107)
[0.6.4.9] — 2026-04-13 — BCB Fixes, ByteProvider NuGet, UI Polish & CI
✨ Added
- ByteProvider extraction —
ByteProviderpromoted to a standaloneWpfHexEditor.Core.ByteProviderlibrary and published as a standalone NuGet package;IUndoAwareEditorinterface +HexByteUndoEntryadded;DocumentBufferundo wiring; ByteProvider regression test suite added - GoToPosition dialog — new dialog for jumping directly to a byte offset in the hex view
- NuGet CI pipeline — generic publish workflow covering all 23 packages;
WpfTerminalmade standalone (bundles Core, Core.Events, SDK + satellite assemblies) - LSP semantic highlighting — semantic token colorization wired in Code Editor
🔧 Changed
- Context menu polish — drop shadow + accent band on all context menus; MDL2 icons; Light theme ContextMenu aligned with Dark theme style
- MarkdownEditor WebView2 refactor — HWND resize fix for fullscreen, context menu wiring, find bar wiring; WebView2
WindowsFormsHostsizing corrected
🐛 Fixed
- BCB freeze (Render-priority navigation guard) — BreadcrumbBar (
BCB) was freezing on rapid navigation; fix: Render-priority dispatcher guard prevents mouse re-dispatch loop during visual tree rebuild - BCB visual tree lock — locked BCB visual tree during navigation to prevent a secondary mouse re-dispatch loop causing a freeze
- BCB infinite rebuild loop — resolved double-rebuild per click and phantom empty row caused by XAML/code-behind duplication
- Bookmark chip re-render — stopped re-rendering bookmark chips on every navigation tick; only rebuilds on actual bookmark set changes
- Bookmark chip MouseDown re-dispatch — prevented
MouseDownevent re-dispatch loop from bookmark chips - HexEditor drag-selection auto-scroll — window-level mouse capture now used for both HexEditor and TextEditor; scroll continues while the cursor is outside the control boundary
[0.6.4.8] — 2026-04-08 — Window Menu, Win32 Fullscreen, Docking Overlay Polish
✨ Added
- Window menu — new top-level
_Windowmenu in the IDE shell for managing document windows and layout - Win32 fullscreen — native fullscreen toggle via Win32 API; hides title bar and chrome for distraction-free editing
🔧 Changed
- Docking overlay — VS-like overlay border with active-tab gap for dock and document panels; placement-aware tab styles for document host
- Docking overlay gap — refined active-tab gap logic and placement-aware styles to match Visual Studio drop-target feedback
🐛 Fixed
- Minimap scroll — scroll position in
MinimapControlnow tracks viewport changes correctly - Plugin panel loading overlay — suppressed the loading overlay after the first initialization; no longer flashes on subsequent panel activations
- ClassDiagram layout loop — removed
ArrangeOverride100 k extent that caused an infinite WPF layout loop
[0.6.4.6] — 2026-04-06 — Lazy Plugins, Tab Groups, Document Structure, Roslyn Inline Hints
✨ Added — Lazy / Standby Plugin Loading (ADR-LAZY-01)
- 5 plugins now lazy-loaded: Archive Explorer, Assembly Explorer, File Comparison, Custom Parser Template, Document Loaders — stay
Dormantuntil first invoked, reducing startup time and memory footprint - Manifest-driven stubs — dormant plugins declare
menuContributionsinmanifest.json; the host registers placeholder menu items and SDK commands so plugins are fully discoverable in menus and Command Palette before they load - Single-click activation — clicking a stub activates the plugin in the background, then executes its View
ICommanddirectly (no second click required) - Activation toast —
PluginActivatingToastServiceshows a brief non-blocking notification while the plugin loads CommandInvokedEvent+PluginActivatingEvent— two new IDE events for command-triggered and activation lifecycle hooks- Panel state persistence — at shutdown, open lazy plugin panels are saved to
AppSettings.LazyPluginsToRestore; at next startup they are eagerly re-activated inside theSuspendRebuildblock so the dock layout restores their panels correctly - Plugin Monitor — standby plugins shown with purple "Standby" badge;
SuspendPluginAsyncsupport WpfHexEditor.SDK.targets—PluginActivationOnStartup,PluginActivationExtensions,PluginActivationCommands,PluginMenuContributionsJsonMSBuild properties generateactivation+menuContributionsblocks automatically on every build
✨ Added — Tab Groups (ADR-TABGROUP-01)
ITabGroupServiceSDK contract — split active document tab horizontally or vertically, move tabs between groups, close groupsTabGroupServiceimplementation in the IDE shell- 16
TG_*theme tokens × 18 Colors.xaml themes —TG_ActiveTabBrush,TG_InactiveTabBrush,TG_SplitterBrush,TG_BadgeBrush… - Keyboard shortcuts — split horizontal (
Ctrl+Alt+→), split vertical (Ctrl+Alt+↓), move to next group, close group - Tab group badges — document count badge on group headers
- Drag visual —
IsDocumentDragflag enables distinct drag-between-groups visual feedback - Options page —
TabGroupsOptionsPagewith tab group behavior settings - 77 integration tests across
DockEngineTabGroupTests+TabGroupSettingsTests
✨ Added — Document Structure Panel (ADR-DOCSTRUCT-01)
WpfHexEditor.Plugins.DocumentStructure— new plugin providing a VS-style outline panel that shows the structural skeleton of the active document- 8 providers: LSP (
LspDocumentStructureProvider), Source Outline, JSON, XML, Markdown, INI, Binary Format, Folding Regions — auto-selected byDocumentStructureProviderResolver DocumentStructureViewModel— full INPC, background refresh, debounce, expand/collapse all, filterStructureListCommand+StructureNavigateCommand— terminal commands for scripted navigation- 18
DS_*theme tokens × 18 Colors.xaml —DS_HeaderBrush,DS_KindBrush,DS_HoverBrush… DocumentStructureRefreshRequestedEvent— IDE event for requesting a provider refreshIDocumentStructureProviderSDK extension point — plugins can register custom providers
✨ Added — Roslyn Semantic Inline Hints Upgrade (ADR-ROSLYN-INLINEHINTS-01)
IReferenceCountProviderSDK contract — decouples reference counting from the Roslyn implementation; exposed viaIDEHostContextRoslynReferenceCountProvider— Roslyn-backed implementation usingFindReferencesAsync; gracefully degrades to regex fallback when Roslyn workspace is unavailableIsRoslyntuple flag onInlineHintsService— hints tagged as Roslyn-backed render with a subtle "R" indicator_hintTooltip— hover tooltip on inline hints shows full semantic context (type, members count, file locations)- whfmt-driven
CanProvide— each language.whfmtdeclaresideMetadata.inlineHints.enabledto opt in/out
✨ Added — Code Editor: Ctrl+Click Links & Emails (ADR-CTRL-LINK-01)
ClickableLinksEnabledDP — toggleable via options; Ctrl+Click URLs open in default browserClickableEmailsEnabledDP — toggleable separately; Ctrl+Click email addresses open default mail clientLinkHitZone+IsEmail— hit-test model distinguishes URLs from email addresses for separate toggle controls_emailRegex— compiled static regex for email detection- TextEditor —
ScanLinksInText+RefreshLinkAdornerbackported from CodeEditor
🔧 Changed
- whfmt schema —
whfmt.schema.jsonupdated withideMetadatablock (inlineHints.enabled,inlineHints.provider,diffMode);DiffModeDetectorreadsideMetadata.diffMode; 33 language files updated - View menu classification —
ViewMenuClassifiercascade: user override → explicitCategory→ Group mapping → keyword heuristics;"Core IDE"category places items at root View level (below Solution Explorer) - Options pages —
OptionsPageHelpershared utility extracted (Core + App); 19 options pages refactored to use it - Docking themes — new color tokens added to Dark/Light docking themes
- Assembly Explorer — menu contribution
categorycorrected to"Core IDE"so it appears in the main View menu section, not a submenu
🐛 Fixed
- WPF Binding errors 4 & 5 — suppressed across 6 docking theme files (ADR-WPF-BIND-01)
- JSON parse noise —
FormatDetectionServiceno longer logs spurious JSON deserialization warnings - DocumentStructure —
Background=DockBackgroundBrush,ComboBox=DockComboBoxStyleexplicit, buttonsDock=Left, deferred initialization, Options page guard - Lazy plugin activation — stubs required two clicks to open panel; fixed by executing the plugin's registered WPF
ICommanddirectly viaUIRegistry.GetFirstViewCommandForPlugin()afterActivateDormantPluginAsync - Assembly Explorer bin manifest —
menuContributionsandactivation.commandsoverwritten on rebuild; fixed by moving all activation metadata intoWpfHexEditor.SDK.targetsMSBuild properties
[0.6.4.3] — 2026-04-02 — AI Assistant Plugin + Roslyn Integration
✨ Added — AI Assistant Plugin (WpfHexEditor.Plugins.AIAssistant)
- Multi-provider AI chat — 5 built-in providers: Anthropic (SSE + tool_use + thinking), OpenAI (function_calling), Google Gemini (1M context), Ollama (local), Claude Code CLI (stdio JSON)
- 25 MCP IDE tools —
McpServerManagerorchestrates stdio + in-process servers: Whfmt (4), HexBuffer (4), Solution (5), Build (5), Debugger (7) - Streaming chat UI —
AIAssistantPanelwith tab strip, chat bubbles, streaming dots animation, model pill, accent Send button - Inline apply —
ApplyCodeCommandextracts fenced code blocks →IDiffServicepreview before apply - @mentions —
@file/@selection/@errors/@solution/@hexresolved viaContextInjector+ IDE services - Command palette —
AICommandPalette(Ctrl+Shift+A), 5 quick actions + user prompt presets - Connection manager —
AIConnectionServicewith 6-state health check (5 min),ConnectionManagerPopupfor per-provider API key config - Model switcher —
ModelSwitcherPopupgrouped by provider, context tokens display, thinking toggle - Inline chat —
InlineChatPopup(Ctrl+I) Copilot-style floating popup - Account & usage —
AccountUsagePopupwith per-provider token/cost tracking (UsageTracker) - Terminal commands —
/ai-ask,/ai-explain,/ai-fix,/ai-new-tab - Context menu —
AISolutionExplorerContributor(explain/review/document file) - Conversation persistence — JSON in
%AppData%/WpfHexEditor/AIAssistant/conversations/ - 6 built-in presets — Explain, Tests, Review, Docs, Refactor, Binary Format
- Titlebar icon —
AITitleBarContributorwith sparkle glyph, status tooltip - 17
CA_*theme tokens × 18 Colors.xaml - Auto-fallback — when no API key configured, auto-selects Claude Code CLI if installed
✨ Added — Roslyn Integration (WpfHexEditor.Core.Roslyn)
- In-process Roslyn —
RoslynLanguageClientreplaces OmniSharp for C#/VB.NET analysis - Non-blocking load with LSP status bar integration
🔧 Changed
- Plugin renamed —
ClaudeAssistant→AIAssistantacross all namespaces, classes, strings, and command IDs to reflect multi-provider support - AppData migration — auto-migrates
%AppData%/WpfHexEditor/Claude/→AIAssistant/on first run - SDK —
ITitleBarContributorinterface,IUIRegistry.RegisterTitleBarItem/UnregisterTitleBarItem,UIElementKind.TitleBar - SDK —
GetCommandPaletteAnchor()for DPI-aware plugin popup positioning
🐛 Fixed
- Model switcher popup positioning and DPI awareness
- Code Editor whitespace rendering mode persistence
- Column rulers persistence across sessions
- Code Editor collapsed fold label misalignment with tab characters
- LSP status bar now follows active document (non-blocking Roslyn load)
[0.6.4.2] — 2026-03-30 — Options Reorganization + Code Editor Settings Wiring
✨ Added — Code Editor Settings
BracketPairColorizationsetting inAppSettings.CodeEditorDefaultSettings(defaulttrue) — persisted and applied viaEditorSettingsServicetoCodeEditor.BracketPairColorizationEnabledColorSwatchPreviewsetting (defaulttrue) — applied toCodeEditor.ColorSwatchPreviewEnabledFormatOnSavesetting (defaultfalse) — applied toCodeEditor.FormatOnSave(public property exposed from_formatOnSavefield)- All three settings wired in
CodeEditorOptionsPage(App)Load()/Flush()with dedicated checkboxes in the "Features" section
🔧 Changed — Options Tree Reorganization
- Code Editor options page moved from
"Editor"category →"Code Editor"category; page named"Features" - Language Servers options page moved from
"Editor"→"Code Editor" - Static registry entry
"Code Editor", "General"renamed →"Code Editor", "Appearance & Colors"inOptionsPageRegistry.cs OpenSettingsAt("Editor", "Language Servers")updated toOpenSettingsAt("Code Editor", "Language Servers")inMainWindow.PluginSystem.cs
[0.6.3.8] — 2026-03-29 — HexEditor Undo/Redo Overkill Upgrade
Block-level undo/redo for the HexEditor, fixing paste-byte-by-byte, broken batch, cut split, plus coalescence for hex digit typing and a VS-style history dropdown.
🐛 Fixed
- Paste (overwrite mode) was byte-by-byte — pressing Ctrl+Z after pasting N bytes would only undo 1 byte. Root cause:
HexEditorViewModel.Paste()calledModifyByte()in a loop, each call recording its ownRecordModify()entry. Now wrapped inBeginUndoTransaction/CommitUndoTransaction→ single undo step. UndoRedoManager.EndBatch()was broken — accumulated operations in_batchOperationsthen pushed them individually anyway. The comment said "they'll be undone/redone together" butUndo()only popped one entry at a time. Fixed withUndoGroupcomposite —EndBatch()now creates one grouped entry.- Cut = 2 separate undo steps — cut (copy + delete) was not wrapped in any transaction. Ctrl+Z after cut would only restore the selection highlight, not the bytes. Now wrapped in a named transaction.
✨ Added — UndoRedoManager (ADR-UNDO-01)
UndoGroup(internal sealed class) — composite entry wrappingList<UndoOperation>with a description string; enables multi-op atomic undo- Stack type changed from
Stack<UndoOperation>→Stack<object>(accepts bothUndoOperationandUndoGroup) BeginBatch(string description)— description parameter added (was parameterless)EndBatch()— now creates a singleUndoGrouppushed as one entry instead of N individual opsRollbackBatch()— new: discard batch without pushing (for exception paths)PeekUndoDescription()/PeekRedoDescription()→ human-readable string for dynamic tooltip / menu headerGetUndoDescriptions(int)/GetRedoDescriptions(int)→ ordered list for history dropdown- Coalescence — consecutive single-byte
Modifyops at adjacent positions within 500 ms are merged into a single ranged op (keeps history clean during hex digit typing) PopUndo()/PopRedo()now returnobject(callers updated accordingly)
✨ Added — ByteProvider Transaction API
BeginUndoTransaction(string description)— delegates to_undoRedoManager.BeginBatch()CommitUndoTransaction()— delegates to_undoRedoManager.EndBatch()RollbackUndoTransaction()— delegates to_undoRedoManager.RollbackBatch()PeekUndoDescription()/PeekRedoDescription()— pass-through for tooltip dataGetUndoDescriptions(int)/GetRedoDescriptions(int)— pass-through for history listUndo()/Redo()handleUndoGroup— iterate ops in reverse order (undo) or forward (redo); extractedApplyUndoOperation()/ApplyRedoOperation()helpers
✨ Added — HexEditorViewModel Descriptions
UndoDescription,RedoDescription,UndoHistory,RedoHistoryproperties (notified inUndo()/Redo())Paste()insert mode:InsertBytesalready records one op, now wrapped for description labelDeleteSelection(): wrapped inBeginUndoTransaction("Delete N bytes")
✨ Added — UndoHistoryPopup (new control)
Controls/UndoHistoryPopup.cs— VS-style popup listing undo/redo step descriptions- Hover highlights all steps up to the hovered row; click invokes
StepsRequested(int steps)for multi-level undo/redo - Uses
ET_PopupBackground/SE_HoverBrushtheme tokens; no new tokens required
✨ Added — Dynamic Undo/Redo Descriptions in Shell
IDocumentEditor— addedstring UndoDescription { get => "Undo"; }andRedoDescription { get => "Redo"; }default interface members (no breaking change to existing implementations)HexEditor.EditOperations— exposesUndoDescription,RedoDescription,GetUndoDescriptions(),GetRedoDescriptions()MainWindow.xamltoolbar Undo/Redo buttons:ToolTipnow bound toActiveDocumentEditor.UndoDescription/RedoDescriptionwithFallbackValue- Edit menu
_Undo/_RedoHeadernow dynamically bound to descriptions (e.g. "Paste 50 bytes")
[0.6.3.7] — 2026-03-25 — Debugger UI, Workspace System, Sticky Scroll, Find All References & Performance
This release delivers a fully wired VS-style debugger UI, a .whidews workspace system, sticky scroll with line numbers, Find All References (Shift+F12), auto-close brackets/quotes, F#/VB.NET language support, a redesigned New File Dialog, Compare Files overkill upgrade (Phases A–H), DiffHub document viewer redesign, end-of-block hover hints, build progress bar, Quick File Open (Ctrl+P), InlineHints background pre-warming, 3 phases of architectural refactoring, and a critical performance fix that eliminates a 100% CPU / 567 MB infinite render loop introduced by the sticky scroll implementation.
✨ Added — Integrated Debugger UI (ADR-DBG-02 + ADR-DBG-BP-01)
- Debug menu (
_Debug) inMainWindow.xaml— Start/Stop/Restart Debugging, Step Over/Into/Out, Toggle Breakpoint, Delete All Breakpoints, Show Debug Panels, Attach to Process - Debug toolbar pod —
DebugToolBarWrapPanel in main toolbar; Continue/Pause/Stop + Step Over/Into/Out buttons;Visibility=Collapsedby default, shown onDebugSessionStartedEvent, hidden onDebugSessionEndedEvent - Execution line highlight —
DB_ExecutionLineBackgroundBrush(semi-transparent yellow) drawn inOnRenderafter current-line highlight;_executionLineOneBasedfield;DB_ExecutionLineBrush(opaque) for the gutter arrow - Gutter hover ghost —
BreakpointGutterControltracks_hoverLineonMouseMove/MouseLeave; draws outline circle (BpDisabledPen) on hovered lines with no active breakpoint - Gutter overlap fix —
BreakpointGutterControlatx=0;GutterControl(fold) moved tox=BreakpointGutterControl.GutterWidth(16 px) inArrangeOverride - Debug status bar —
DbgStatusItem+DbgStatusText(yellow#FFDD00); shows"Paused at file:line"on pause, hidden on resume/end BreakpointInfoPopup(new) — right-click gutter → VS-style popup: location, editable conditionTextBox, Enable/Disable toggle, Delete, Save;IBreakpointSourceextended withGetBreakpoint/SetCondition/SetEnabled/DeletereturningBreakpointInforecord- Non-executable line validation —
LanguageDefinition.BreakpointRulesrecord (NonExecutablePatterns: IReadOnlyList<string>) compiled toList<Regex>inCodeEditor.RebuildBreakpointValidation()on language change; left-click on non-executable line shows 1.5 s tooltip "Cannot place breakpoint on this line" IDebuggerServiceextended —UpdateBreakpointAsync(filePath, line, condition, isEnabled)+DeleteBreakpointAsync(filePath, line)implemented inDebuggerServiceImpl.csbreakpointRulesblock added to CSharp, JavaScript, TypeScript, Python.whfmtfilesDB_*tokens already in all 18Colors.xamlfiles via prior session;_debugStartedSubwired to_subscriptions
✨ Added — Workspace System .whidews (ADR-WS-01)
WpfHexEditor.Core.Workspaces—WorkspaceManager,WorkspaceSerializer(ZIP + JSON: manifest / layout / solution / openfiles / settings),WorkspaceModelsrecords (WorkspaceCapture,WorkspaceState,OpenFileEntry, …)IWorkspaceServiceSDK contract +WorkspaceOpenedServiceEventArgs;IDEHostContext.Workspace(nullable);WorkspaceServiceImplbridgesIWorkspaceManager→IWorkspaceServicewith Dispatcher marshallingMainWindow.Workspace.cspartial class —InitializeWorkspaceSystem(), 5 async handlers (New/Open/Save/SaveAs/Close),CaptureWorkspaceState()(SnapshotEditorConfigs()+DockLayoutSerializer.Serialize),ApplyWorkspaceStateAsync()(theme/layout/solution/files),UpdateWorkspaceStatusBar()- File menu Workspace submenu — 5 items; status bar
WorkspaceStatusItem+WorkspaceStatusText WorkspaceSettings— 5 prefs:PromptSaveOnClose,RestoreSolution,RestoreFiles,RestoreTheme,RecentWorkspacePath;WorkspaceOptionsPage(Category=Environment)- 5 Workspace command IDs in
CommandIds.cs; registered inMainWindow.Commands.cs
✨ Added — New File Dialog Redesign (ADR-NFD-01)
- 860×540 3-panel dialog — sidebar (categories), center (template grid/list), description panel
- 23 templates across 5 categories — General / C# .NET / Script / Data / Web;
DotNetFileTemplates.cs(7),WebFileTemplates.cs(4),ScriptFileTemplates.cs(3),DataFileTemplates.cs(3) - Grid/list view toggle, search, sort, category filter;
IFileTemplategainedCategory+IconGlyphvia default interface members (no breaking change)
✨ Added — Compare Files Overkill Upgrade (ADR-DIFF-01)
WpfHexEditor.Core.Diff—DiffEngine,MyersDiffAlgorithm,BinaryDiffAlgorithm,SemanticDiffAlgorithm,DiffModeDetector,GitDiffService,DiffExportServiceGitRefPickerPopup— floating branch/commit picker;CompareFileLaunchServiceorchestrator- 4 new
CommandIds—CompareWithActiveEditor/Clipboard/Head/ReopenLast;DockTabControl.ExtraMenuItemsFactory+DockControl.TabExtraMenuItemsFactoryextensibility hooks SolutionExplorerCompareContributor— always shows Compare with Active/Another File; conditionally shows Compare with HEAD/Branch/Commit when.gitdetected (cached repo root)ComparisonOptionsPage(IOptionsPage, Category=Editor)DiffHubPanel(6-row XAML: toolbar/inputs/ratio-bar/search/tabs/status) +DiffHubViewModel(INPC,DiffEngine, filter+search, history up to 20 entries)- 14
DF_*tokens × 18Colors.xamlfiles
✨ Added — DiffHub Document Viewer Redesign (ADR-DIFF-02)
DiffViewerDocument(new) — opens as a full document tab (4-row layout: toolbar/inputs/sync-scroll side-by-side/overview ruler)DiffViewerViewModel— INPC, parallelLeftRows/RightRows, word-level segments,Alt+Up/DownnavigationDiffHubPanelsimplified to compact launcher (file inputs + history only); 8 newDF_*tokens v2 × 18 themes- Tab dedup:
_openViewers Dictionary<string, DiffViewerDocument>keyed by"diff://{left}|{right}"
✨ Added — End-of-Block Hover Hint (ADR-EBH-01)
EndBlockHintPopup(new) — hover over},#endregion,</Tag>→ VS-style popup showing the matching opening line(s); grace timer 200 ms;ET_*tokens; syntax-colored header viaISyntaxHighlighter.Highlight(); meta row with pills (region name, nesting depth)ShowEndOfBlockHint+EndOfBlockHintDelayMsDPs inCodeEditor; hover timer (default 600 ms);HandleEndBlockHintHover,FindRegionEndingAt,OnEndBlockHintNavigate→NavigateToLineLanguageDefinition.EndOfBlockHintSettingsrecord +EndOfBlockHintDto;endOfBlockHintblock added to 18.whfmtfilesAppSettings.EndOfBlockHintEnabled/EndOfBlockHintDelayMs;ApplyOptions()wired; 18ET_*tokens × 18 themes
✨ Added — Build Progress Bar (ADR-BUILD-SB-01)
<ProgressBar>inBuildStatusItem(MainWindow.xaml) — 80 px wide, 6 px tall,Visibility=Collapsedby defaultBuildStatusBarAdapter—_updatecallback extended toAction<string,string,bool,int>(progressPercent: 0–100 = show, -1 = hide);OnProgresspassese.ProgressPercentMainWindow.Build.cs—UpdateBuildStatusBarextended; setsBuildProgressBar.Value+Visibilityon eachBuildProgressUpdatedEvent
✨ Added — Find All References / InlineHints (#157)
WorkspaceFileCache— static thread-safe singleton (ReaderWriterLockSlim);GetPathsForExtensions()/GetLines(); caps: 5 000 files, 2 MB/file;WorkspaceChangedevent; subscribesSolutionManager.SolutionChangedInlineHintsService—ComputeHintsData()background worker; regex-based reference counting across solution;ReferenceHintrecordInlineHintslayer —CE_InlineHint*tokens; clickable "N références" above each declaration; click opensFindReferencesPanelReferencesPopup→FindReferencesPanel— dockable VS2022-style panel;ReferenceGrouptree; title bar with refresh/close; scope filterComboBox; searchTextBox;F8/Shift+F8navigation;Shift+F12keybindingInlineHintsVisibleKindsbitmask (InlineHintsSymbolKindsenum, 12 kinds);CodeEditorInlineHintsPageoptions page
✨ Added — Auto-close Brackets & Quotes (#163)
AutoClosingBrackets,AutoClosingQuotes,SkipOverClosingChar,WrapSelectionInPairs— 4 new options inCodeEditorOptions; wired inApplyOptions()- Auto-insert matching
)]}"'on type; skip-over existing closing char; wrap selection in pair when opening char typed with selection active - Options section added to
CodeEditorOptionsPage
✨ Added — Quick File Open (#179)
Ctrl+Pbinding →CommandPaletteService.OpenWithPrefix("#")(file search mode)CommandPaletteOptionsPagesection for#mode settings
✨ Added — F# / VB.NET Language Support
FSharp.whfmt+VBNet.whfmt— full syntax definitions with folding, highlighting, breakpoint rulesLspServerRegistry—fsautocompleteentry (F#) + OmniSharpvbentry (VB.NET)DocumentManager.ResolveLanguageId()+CodeEditor.LSP.cslanguage ID maps updated for"fsharp"/"vb"IlSpyTypeDecompiler._decompLangMap— VB.NET decompilation support- F# / VB.NET project templates —
FSharpConsoleApp,FSharpClassLib,VbNetConsoleAppregistered in template registry
✨ Added — Sticky Scroll (#160)
StickyScrollHeader(newFrameworkElement) — renders N scope signature lines pinned at the top;StickyScrollEntryrecord;ScopeClickedevent →NavigateToLine; theme tokensCE_StickyScrollBackground/Foreground/Border× 18 themesFindScopeChainAt(int firstLine)— O(N) insertion-sorted scan (replaces O(N log N) LINQ.OrderBy()); bounded to_stickyScrollMaxLinesUpdateStickyScrollHeader()— syntax-highlighted entries viaISyntaxHighlighter.Highlight(); wired inOnRender(scroll-gated) andArrangeOverride- Line numbers in gutter —
Update()pre-builds right-aligned line numberFormattedTextusing editor'sLineNumberForeground+_lineNumberTypeface; matches editor gutter style exactly - 6 options in
CodeEditorOptions:StickyScrollEnabled,StickyScrollMaxLines,StickyScrollSyntaxHighlight,StickyScrollClickToNavigate,StickyScrollOpacity,StickyScrollMinScopeLines ApplyStickyScrollSettings()public API onCodeEditor; wired inMainWindow.ApplyEditorSettings()
✨ Added — InlineHints Background Pre-warming
WorkspaceFileCache.Invalidate()refactored — clears caches instantly (microseconds), then_ = Task.Run(RebuildAndWarmAsync)RebuildAndWarmAsync()— Phase A:BuildSolutionPaths()off UI thread; Phase B: fireWorkspaceChanged; Phase C: pre-warm line cache (yield every 20 files)- Eliminates IDE freeze on solution open that previously blocked the UI thread with
File.Exists()× 5 000
✨ Added — Assembly Explorer Fix (ADR-AE-01)
BuildDecompiledCodeEditor()now createsCodeEditorSplitHostinstead ofTextEditor; mapsEditorLanguageNamedisplay names → LanguageRegistry IDs ("C#"→"csharp","VB.NET"→"vb"); sets language viahost.SetLanguage(lang), markshost.IsReadOnly = trueProjectReferencetoWpfHexEditor.Editor.CodeEditoradded toAssemblyExplorer(compile-only; resolved via ALC at runtime)
✨ Added — Unit Testing Panel — Context-Sensitive Detail Panel (ADR-UT-12)
UnitTestingViewModel.SelectedNode (object?)replaces directSelectedResultassignment; syncsSelectedResult = value as TestResultRowfor backward compatTestProjectNode+TestClassNode—TotalDurationMs/TotalDurationTextcomputed properties;AddResults()accumulates on both- Detail pane —
ContentControl Content="{Binding SelectedNode}"with 3 implicitDataTemplates (project / class / test result), each with a Run action button
✨ Added — Architectural Refactoring Phases 1–3 (ADR-REF-01)
- Phase 1 —
RelayCommandconsolidation (~29 files → SDK canonical);ExecuteBuildOperationAsynchelper;CompositeDisposablefor event subscriptions;ShowOrDockPanelhelper - Phase 2 —
BreakpointPersistenceManagerextracted fromDebuggerServiceImpl;ExternalShellProcessManagerextracted fromShellSessionViewModel(shell process lifecycle + stdio piping);RichTextBoxFindServiceextracted fromTerminalPanel.xaml.cs - Phase 3 —
CodeEditor.cs(10 007 lines) split into 5 partial class files:Core/Rendering/Input/Document/LSP
⚡ Performance — Sticky Scroll Render Loop + 5 Optimizations (ADR-IH-PERF-02)
- FIX 1+2 — CRITICAL: Infinite render loop eliminated —
|| _stickyScrollHeader?.RequiredHeight == 0condition inOnRenderwas always true outside any scope →InvalidateArrange()every frame → 100% CPU + 567 MB memory pressure; replaced with_lastStickyFirstLineguard soUpdateStickyScrollHeader()runs only when viewport scrolls;InvalidateArrange()gated on_stickyScrollLastEntryCountchange - FIX 3 — HIGH:
FindScopeChainAt()— O(N log N) LINQ.OrderBy()per scroll frame → O(N) single-pass insertion into bounded list - FIX 4 — HIGH:
StickyScrollHeaderallocation-freeOnRender—TryFindResource,new Pen(),new SolidColorBrush(),new FormattedText()moved fromOnRenderintoUpdate()(called only on scroll); static frozen fallback brushes/pens;OnRendercalls onlyDrawTexton pre-built objects - FIX 5 — MEDIUM:
WorkspaceFileCachebatch yields —await Task.Yield()per file (5 000 continuations) → yield every 20 files (~250 continuations) - FIX 6 — MEDIUM:
FindReferencesPaneldebounce — 200 msDispatcherTimeron searchTextBox.TextChanged; scopeComboBox.SelectionChangedremains instant
🐛 Fixed
- TextEditor scrollbar never appearing —
TextViewporthadVerticalAlignment="Stretch"insideScrollViewerinnerGrid→ viewport always filled ScrollViewer height → scroll extent never exceeded viewport → scrollbar never showed; fix:VerticalAlignment="Top" - Sticky scroll infinite render loop — see Performance section above
[0.6.3.6] — 2026-03-23 — LSP Engine, Command Palette, Diagnostic Tools & Major IDE Expansion
This release is the largest since v0.6.0, delivering a production-grade LSP client engine, a VS Code-style Command Palette with 9 search modes, a Diagnostic Tools plugin, a fully dockable Search Panel, a centralized Command System, IDE-wide EventBus full coverage, Document Model Phase 1, incremental builds with dirty tracking, Class Diagram 10-phase overkill, XAML Designer Phase 3, Markdown Editor IDE integration, Code Editor multi-caret + word wrap + data-driven folding, DI infrastructure, and dozens of theme/stability fixes across all 18 themes.
✨ Added — LSP Client Engine (ADR-DI-01 + ADR-LSP-01 + ADR-LSP-02)
AppServiceCollection—Microsoft.Extensions.DependencyInjection-backed service provider wired inMainWindow;MainWindowServiceArgsrecord;BuildServiceAdapters()extracted;_serviceProviderdisposed inShutdownPluginSystemAsyncLspClientImpl— full JSON-RPC LSP client over stdio; server lifecycle (initialize/shutdown/exit);ServerCapabilitiesparse (null/bool/JsonObjectvariants for all capability flags); capability-gated dispatch for all 10 providersLspDocumentSync—DidOpen/DidChange/DidCloseper open document;FromUri()static helper (file:///→ local path)- Completion —
SmartCompletePopupwired to LSP (SetLspClient()); asyncShowSuggestions();MapLspItem()/LspKindToGlyph(); LSP-first with local fallback - Hover quick-info —
HoverQuickInfoService(already done in prior release) - Signature help —
SignatureHelpPopup(Popup,PlacementMode.Absolute); triggered on'('inCodeEditor.OnTextInput; capability-gated - Code actions —
LspCodeActionProvider(textDocument/codeAction);LspCodeActionPopup(promise-based Popup + ListBox,CE_*tokens);Ctrl+.inCodeEditor; context menu "Quick Fix…" - Rename symbol —
LspRenameProvider(textDocument/rename);LspRenamePopup(TextBox, pre-filled + SelectAll);F2inCodeEditor; context menu "Rename Symbol";ApplyWorkspaceEdit()bottom-up via buffer LspEditParser— shared static helpers:ParseWorkspaceEditsupports bothchangesanddocumentChangesformats- Breadcrumb bar —
LspBreadcrumbBar22px row inCodeEditorSplitHost; debounced 200 msCaretMoved;BC_*tokens;CodeEditorSplitHostimplementsILspAwareEditor - LSP status bar —
LspStatusBarAdapter(WpfHexEditor.App.Servicesnamespace); subscribesServerStateChanged; displays server state per language - Workspace symbols —
WorkspaceSymbolsPopup(mirrorsCommandPaletteWindow);ListBoxItem.IsSelectedProperty; opened viaCtrl+T - Inlay hints —
LspInlayHintsLayer(Layers/ folder); 500 ms debounce;CE_InlayHint*tokens - Code lens —
LspCodeLensLayer(Layers/ folder); 800 ms debounce;CE_CodeLens*tokens - Semantic tokens —
LspSemanticTokensLayer(Layers/ folder); 1 s debounce;SE_*overlay rectangles ILspAwareEditor— opt-in:SetLspClient(ILspClient?)+SetDocumentManager(IDocumentManager);LspDocumentBridgeServiceresolves viaFindDocumentByBuffer→ callsSetLspClient+SetDocumentManageron doc open; clears on unregisterLspServersOptionsPage— code-behind UserControl with DataGrid, Add/Remove/Browse; registered as"Language Server Protocol" > "Servers"- 30 new theme tokens —
SC_*/BC_*/LSP_*/CE_*/SE_*/PE_*/PD_*/MKT_*× 18 themes via PowerShell
✨ Added — Command System + Command Palette (ADR-CMD-01 + ADR-CP-01/02/03)
WpfHexEditor.Commandsproject —CommandDefinitionrecord;ICommandRegistry/CommandRegistry(thread-safe);IKeyBindingService/KeyBindingService;CommandIds(~45 constants); decoupled fromAppSettingsviaOverridesChangedcallback patternMainWindow.Commands.cs— registers all ~45 built-in commands; wiresOverridesChanged→ persist toAppSettings.KeyBindingOverrides+ save;LoadKeyBindingOverrides()on startupKeyboardShortcutsPage— code-behind DataGrid + search + inline edit + reset; registered viaOptionsPageRegistry.RegisterDynamic- Title bar launcher —
TitleBarSearchButton(380px wide,WindowChrome.IsHitTestVisibleInChrome);TitleBarSearchLabelshows solution name (SemiBold) or<Wpf:HexEditor Studio />(Italic);TB_Search*tokens × 18 themes CommandPaletteWindow— code-behind only, VS Code-style non-modal overlay; 9 search modes:>commands,@symbols (LSP),:go-to-line,#files (solution),%content grep,?help, Tab cycle;Ctrl+Shift+PshortcutCommandPaletteService— 3-tier fuzzy scoring (prefix 1000 / substring 500 / subsequence 100);FrequencyBoost(+300 / +150 / +50 by recency);ContextBoost(+200);BuildEmptyQueryResultsshows recents firstCommandPaletteSettings— 14 properties:WindowWidth/ShowIconGlyphs/ShowCategoryHeaders/ShowGestureHints/DescriptionMode/HighlightMatchChars/MaxResults/SearchDebounceMs/DefaultMode/ShowRecentCommands/RecentCommandsCount/FrequencyBoostEnabled/ContextBoostEnabled/CommandHistory;MaxGrepResults/MaxGrepFileSizeBytesfor%grep modeCommandPaletteOptionsPage— 5-section options page (Appearance/Description/Search/Recents/Modes) with Reset; registered under"Command Palette" > "Général"- ADR-CP-03 file search + content grep —
#mode: solution file index with fuzzy path matching;%mode: async file-content grep withMaxGrepFileSizeBytesguard, progress indicator, cancellable CP_*+KSP_*tokens — 12 + 6 tokens × 18 themes
✨ Added — Diagnostic Tools Plugin (ADR-DT-01 + ADR-DT-02)
WpfHexEditor.Plugins.DiagnosticTools— priority 45; subscribesProcessLaunchedEvent/ProcessExitedEventonIIDEEventBusProcessMonitor— 500 ms CPU% + memory polling viaPerformanceCounter+ GC APIsEventCounterReader— EventPipeSystem.Runtimeprovider (GC, threadpool, exceptions) viaMicrosoft.Diagnostics.NETCore.ClientDiagnosticsSession— per-process session coordinating monitor + event readerHeapSnapshotService—DiagnosticsClient.WriteDump(DumpType.WithHeap)→%TEMP%\WpfHexEditor\<pid>_<timestamp>.gcdumpDiagnosticToolsPanel.xaml— 4 tabs: Summary / Events / CPU / MemoryCpuGraphControl/MemoryGraphControl—DrawingVisual, 120-point ring-buffer, auto-scale Y,LineTowithisSmoothJoin- 8
DT_*tokens × 18 themes;Microsoft.Diagnostics.NETCore.Client 0.2.510501+Microsoft.Diagnostics.Tracing.TraceEvent 3.1.7NuGet refs
✨ Added — Document Model Phase 1 (ADR-DOC-01 + ADR-DOC-02)
IDocumentBuffer/DocumentBuffer— thread-safe shared in-memory content buffer;DocumentBufferChangedEventArgs;Dispatcher-marshalledChangedeventIBufferAwareEditor— opt-in:AttachBuffer(IDocumentBuffer)+DetachBuffer(); implemented byCodeEditor,TextEditor,MarkdownEditorHost,CodeEditorSplitHost,XamlDesignerSplitHostDocumentModel.Buffer—IDocumentBuffer? Buffer { get; internal set; }on all open documentsDocumentManager—GetBuffer()/GetBufferForFile();_buffersdict (keyed by filepath,OrdinalIgnoreCase);ResolveLanguageId()map (10 entries); buffer create/attach inAttachEditor(); release/detach inUnregister()LspBufferBridge— subscribesIDocumentBuffer.Changed→ILspClient.DidChangewith 300 msDispatcherTimerdebounce; sendsDidOpenon construct andDidCloseon DisposeLspDocumentBridgeService— coordinates bridges; oneILspClientper language ID (lazy init); wired inMainWindow.PluginSystem.cs; disposed inShutdownPluginSystemAsyncFindDocumentByBuffer(IDocumentBuffer)— O(n) scan added toIDocumentManager+DocumentManager
✨ Added — IDE EventBus Full Coverage (ADR-EB-01 + ADR-EB-02)
- 39 typed events —
RegisterWellKnownEvents()expanded 10 → 36 → 39 types;FileClosedEvent/WorkspaceChangedEvent/TerminalCommandExecutedEvent/CodeEditorCommandExecutedEventfully published CodeEditorCursorMovedEvent—EditorEventAdaptersubscribesCodeEditor.CaretMoved(1-based line/col)CodeEditorFoldingChangedEvent— subscribesFoldingEngine.RegionsChanged(CollapsedCount)CodeEditorSelectionChangedEvent— uses_codeEditor.SelectedText(max 4096 chars)BuildProgressUpdatedEvent—BuildSystem.RunBuildAsync()fires after each project (ProgressPercent)ParseCompletedEvent—IncrementalParser.ParseCompletedevent +ParseCompletedEventArgs;EventBusIntegration.TrackParser()/UntrackParser()for LSP pipeline coordinationProcessLaunchedEvent/ProcessExitedEvent—StartupProjectRunnermonitors stdout/stderr and publishes; consumed byDiagnosticToolsplugin- Solution Explorer + generic editor adapters (ADR-EB-02) — 3 additional publisher adapters
✨ Added — Incremental Build (ADR-BUILD-03 + ADR-BUILD-CE-01)
IIncrementalBuildTracker/IncrementalBuildTracker— FSW per project dir;BuildFileWatcher;BuildSystem.BuildDirtyAsync()builds only dirty projects + transitive dependentsCtrl+Alt+F7— incremental build shortcut- Solution Explorer dirty dot — orange
●indicator viaIsBuildDirtyonProjectNodeVm+DataTrigger - Gutter diagnostics —
CE_GutterError/CE_GutterWarningtokens × 18 themes;RenderValidationGlyph()usesTryFindResource;CodeScrollMarkerPanel.UpdateDiagnosticMarkers()error/warning ticks on scrollbar - Multi-caret —
_caretManagerwired;Ctrl+Alt+Clickadds secondary caret;Ctrl+D=SelectNextOccurrence(); secondary carets rendered at 60% opacity CodeEditorSplitHostimplementsIDiagnosticSource(forwarding)EditorEventAdapter— instantiated per code-editor tab inMainWindow.xaml.cs, disposed on close
✨ Added — Search Panel (Dockable, VS-Style)
ISearchable/ISearchPanel— contracts inEditor.CoreRegexSearchEngine+SearchMode.Regex/HexRegex+SearchCapabilities[Flags] enumIByteSearchSourceinWpfHexEditor.Core.Search.Services;ITextSearchSourceinEditor.CoreSearchPanelViewModel— async search dispatch; result collection; navigation; export commands; routes toByteSearchService/TextSearchService/RegexSearchEngineby modeSearchPanel.xaml— 4-row VS-style layout (toolbar / inputs / virtualized ListView / status); implementsISearchPanelHexEditor.SearchableIntegration.cs(partial class) — explicitISearchable+IByteSearchSourceCodeEditorSplitHost+TblEditorimplementISearchable+ITextSearchSourceCtrl+Shift+F— replaces oldAdvancedSearchCommand; opens dockableSearchPanel- 14
SP_*tokens × 18 themes
✨ Added — Class Diagram Overkill (ADR-CD-OVK-01)
- 10-phase overhaul — DSL v2 (generics, packages, notes, stereotypes,
GenericTypeParser); Layout v2 (Force-Directed Fruchterman-Reingold + Hierarchical Sugiyama + Swimlane,Ctrl+Shift+Acycle); Canvas v2 (MultiSelectAdorner,InPlaceEditAdorner,DiagramClipboardService,DiagramAlignmentService); Orthogonal + Bézier arrow routing (A* on 10px grid); Roslyn incremental analysis cache; 6 panel VMs upgraded; Export v2 (PlantUML, XMI 2.1, Interactive SVG); Minimap + Grid overlay; Performance (DiagramSpatialIndexO(1), 3-LODVirtualDiagramCanvas); Plugin live sync (1 s rate limit,DiagramFilterService,NavigateToSourceService) - 46 new
CD_*tokens × 18 themes
✨ Added — XAML Designer Phase 3 (ADR-XD-03)
- Phase 10 completion —
ConstraintAdorner/ConstraintService/ResponsiveBreakpointBar;GradientEditorAdorner;BindingPathPickerPopup;ResourceReferenceService.ApplyResourceReference;PerformanceOverlayAdorner/DesignCanvasStats(Ctrl+Shift+F9) - 40 new
XD_*tokens × 18 themes - 9 panels migrated to
WpfHexEditor.Plugins.XamlDesigner(ADR-XD-02); 4 domain types promoted to Models/
✨ Added — Markdown Editor Full IDE Integration
MD.whfmtroutes.mdto markdown-editor; lazymermaid.js(detectsHasMermaidDiagram); adaptive debounce 300 / 800 / 1500 ms; off-thread word count + reading time- Image paste —
Ctrl+V→ writes toassets/as PNG or base64 inline - Insert / Format toolbar pods;
MarkdownOutlinePanel(H1–H6 tree, 400 ms debounce, off-thread) - Context menus —
MdContextMenu.xamlwithMD_ContextMenuStyletokens; VIEW+ACTIONS groups on preview; FORMAT+INSERT groups on source editor
✨ Added — Code Editor Improvements
- Word wrap —
IsWordWrapEnabledtoggle; prefix-sum wrap map (_wrapHeights[]/_wrapOffsets[]);RenderTextContentWrapped/RenderSelectionWrappedpaths; H-scrollbar auto-hides - Multi-caret —
Ctrl+Alt+Clickadds caret;Ctrl+D=SelectNextOccurrence(); secondary carets at 60% opacity - Data-driven folding —
FoldingRulesrecord; 4 strategies:PatternFoldingStrategy/NamedRegionFoldingStrategy/TagFoldingStrategy/HeadingFoldingStrategy;LanguageFoldingStrategyBuilder; 4.whfmtformats migrated; XAML/XML multi-line tag folding; XMLC comment block folding - Scope guide lines fix —
ComputeScopeGuideX()usesstartLine(opening tag indent) instead ofstartLine+1 - Horizontal caret auto-scroll —
EnsureCaretHorizontallyVisiblehooked toCaretStatusin TextEditor;EnsureCursorColumnVisiblemoved before virtual-scroll guard in CodeEditor
✨ Added — Docking Engine Improvements
WpfHexEditor.Docking.Wpfextracted (ADR-055) — split fromWpfHexEditor.Shell; contains all WPF docking controls + themes;Shellis now theme-XAML-only; pack URIs updated cross-assembly- Auto-Hide grouped behavior — pin hides the entire group; one
AutoHideGroupIdper group; flyout shows inline tab strip for multi-item groups; context menu (Show/Float/Close) withGroupFloatRequested/GroupCloseRequested;ShowForItemcancels both axis animations before assignment;BeginAnimation(...,null)releases hold on resize - Theme persistence (ADR-052) —
ApplyTheme()now persistsActiveThemeName+ saves + sets_lastAppliedTheme;LoadDefaultLayoutFromResource()reads embeddeddefaultLayout.json;OnResetLayout()restores from resource - Docking Sprint 3 — incremental visual tree (M2.1):
ItemAddedToGroup/ItemRemovedFromGroupevents,_tabControlCache,AddTab/RemoveTab; WeakEvent subscriptions (M2.4): 8 weak-reference lambdas inAttachEngine(); undo/redo layout (M3.3):LayoutSnapshotCommand.Redo()uses_afterSnapshot,Ctrl+Shift+Z/Y
✨ Added — Plugin Sandbox Signing (ADR-SB-01)
ValidateSignature()— checksIsSigned/ file exists / ≥8 bytes;[SECURITY]prefix on hash mismatch for signed plugins;SIGNED/unsignedlog per plugin
🐛 Fixed
- UI freeze on hex/decompile tab open — eliminated synchronous work on UI thread during tab activation; async pipeline enforced throughout
LspServersOptionsPagetheme — mergedDialogStyles.xamllocally;SetResourceReferencefor DataGrid/Row styles; page now follows active themeCommandPaletteOptionsPagetheme — mergedDialogStyles.xamllocally;MakeSectionHeader/MakeInfoTextuseSetResourceReference("CP_SecondaryTextBrush"); TextBox / Button / RadioButton / CheckBox now theme-awareAutoHideBarNaN crash —ShowForItemcancels both axis animations + explicitFrom=0;hideAnim.Completedguarded withif (_isOpen) return- Auto-hide bar buttons —
UpdateItemsnow creates one button per item (not per group) - XAML Designer non-renderable root —
DesignCanvas.PeekRootTagName()+s_nonRenderableRootsset; early exit forResourceDictionary/Style/DataTemplateetc.;XamlRenderErrorKind.NonRenderableRootauto switches to CodeOnly + blue info banner;ElementSupportsTagAttribute("Color")fix (Color struct excluded fromTaginjection) - Solution Explorer search — 4 modes (FileName / Name+Content / ContentOnly / Regex);
ControlTemplate.Triggers DataTriggerforIsSearchVisible(Style.Triggers broken for TreeViewItem); 2-char minimum +_searchActiveflag - XAML fold guide X position —
ComputeScopeGuideX()usesstartLine(tag's own indent, notstartLine+1) .whlang→.whfmtJSONC —JsonCommentHandling.Skip+AllowTrailingCommasat both parse sites;PatternFoldingStrategystrips line comments before brace matching; 454.whfmtheaders converted to/* */block comments- Class Diagram context menu —
PlacementTarget = thisbeforeIsOpen = trueto prevent off-screen rendering - Class Diagram DSL body extraction —
openBrace = source.IndexOf('{', typeMatch.Groups[5].Index + typeMatch.Groups[5].Length)avoids consuming class{in regex terminal CommandPaletteWindowhover theme — explicitTransparentdefault bg +IsMouseOvertrigger usingCP_HoverBrush;CP_HoverBrushtoken × 18 themes
[0.6.3.2] — 2026-03-22 — Docking, Format Catalog & XAML Designer Fixes
🐛 Fixed — Docking System
- Incremental visual tree (M2.1) —
DockEnginefiresItemAddedToGroup/ItemRemovedFromGroupevents;DockTabControlgainsAddTab/RemoveTab;DockControlskips fullRebuildVisualTreeon incremental tab changes;DocumentTabHost.ClearEmptyPlaceholder()removes Start tab before first document - WeakEvent subscriptions (M2.4) —
DockControl.AttachEngine()now uses lambdas capturingWeakReference<DockControl>for all 8 engine events;DetachEngine()unsubscribes and nulls them — breaks the strong reference fromDockEnginetoDockControl - Undo/redo layout (M3.3) —
IDockCommand.Redo()default interface method;LayoutSnapshotCommand.Redo()restores_afterSnapshotto avoid staleDockItemrefs;DockControlgainsCommandStack+ExecuteUndoable()helper; Float/AutoHide/Dock/AutoHideAll/RestoreAll commands now undoable;Ctrl+Shift+Z/Ctrl+Shift+Ybound to Undo/RedoLayout - Undock drag-follows-cursor —
DockDragManager.BeginFloatingDragaccepts pre-capturedcursorDipfromBeginDrag/BeginGroupDragto avoid staleMouse.GetPositionafter HWND creation - Float dimensions preserved on undock —
ApplySizeToFloatDimensionscaptures only the compact axis perLastDockSide(Width for Left/Right, Height for Top/Bottom) so undocked panels keep their docked size - NaN DoubleAnimation crash in AutoHide —
ShowForItemnow cancels both axis animations before any Width/Height assignment;hideAnim.Completedguarded withif (_isOpen) return _layoutWasRestoredFromFilenot set on default layout —LoadDefaultLayoutFromResource()now sets the flag so plugin panels absent fromdefaultLayout.jsonare correctly deferred on first launch
🐛 Fixed — Format Catalog & Code Editor (.whfmt JSONC)
- JSONC comment handling in
EmbeddedFormatCatalog— addedJsonDocumentOptions { CommentHandling = JsonCommentHandling.Skip, AllowTrailingCommas = true }to bothLoadHeader()andGetSyntaxDefinitionJson()parse sites; formats with/* */headers now load correctly - All 454
.whfmtheaders converted —//line-comment headers replaced with/* */block comments across all format definitions; UTF-8 BOM stripped;CSharp.whfmtmissing opening{restored PatternFoldingStrategycomment-awareness — brace patterns (\{/\}) are now matched against the line text with the comment portion stripped via_lineCommentPrefix; prevents spurious fold regions from{/}inside JSONC comment linesLanguageFoldingStrategyBuilder— forwardslineCommentPrefixtoPatternFoldingStrategyconstructorCodeEditor— passesnewLang?.LineCommentPrefixtoLanguageFoldingStrategyBuilder.Build()
🐛 Fixed — XAML Designer
- Persistent canvas border rectangle — removed
SetResourceReference(BorderBrushProperty, "XD_CanvasBorderBrush")andBorderThickness = new Thickness(1)fromDesignCanvasconstructor; these were added during visual polish and caused a permanent 1px border rectangle visible at all times even with no file loaded
[0.6.3] — 2026-03-22 — Class Diagram Plugin Fixes
🐛 Fixed — Class Diagram Plugin Menu & Solution Explorer
- Class Diagram menu registration — plugin menu items (Class Outline, Class Properties, Diagram Toolbox, Relationships, Diagram History, Diagram Search) now register under
ParentPath = "View"instead of"View/Panels"; theMenuAdapteronly resolves top-level menu names so the items now correctly appear in the main View menu grouped underGroup = "ClassDiagram" - Double separator in Solution Explorer context menus —
ClassDiagramContextMenuContributorwas prepending aSeparator()before each contributed item in addition to the staticPluginMenuSeparator, resulting in two consecutive separator lines before "View Class Diagram" / "Generate Class Diagram for Project" / "Generate Class Diagram for Solution"; removed the redundant contributor separators PluginMenuSeparatorarchitecture — refactoredSolutionExplorerPanel.RebuildPluginMenuItems()soPluginMenuSeparatoracts as a permanent invisible position marker (alwaysCollapsed); a self-cleaning taggedSeparatoris now injected dynamically as the first plugin item, guaranteeing exactly one visual separator before the plugin zone regardless of node type (File / Project / Solution) or plugin count
[0.6.0] — 2026-03-18 — Visual XAML Designer, Shared Undo Engine & Rect Selection
✨ Added — Visual XAML Designer: Bidirectional Sync & Full IDE Integration
- Bidirectional canvas↔code selection sync (~95% fidelity) — selecting an element on the design canvas highlights its XAML tag in the code editor; cursor moves in the code editor highlight the corresponding canvas element; position/size changes propagate both ways in real time
#regioncolorization — XAML code editor renders#region/#endregionmarkers with dedicated brush tokens; collapsed regions show an inline{…}badge without affecting the gutter triangle- Error card overlay — when XAML is malformed, the designer surface displays an inline error card with the message and line reference instead of a blank canvas; card dismisses as soon as the error is resolved
- Rotation handle — element resize overlay now includes a rotation arc handle above the selection frame; dragging rotates the element and patches the
RenderTransformXAML attribute in real time - Parent selection via
Escape— pressingEscapeon a selected element walks up to its parent container (VS-like hierarchical selection); repeated presses bubble to the root - 4 split layouts —
HorizontalDesignRight(default),HorizontalDesignLeft,VerticalDesignBottom,VerticalDesignTop; toggled via inline toolbar dropdown button orCtrl+Shift+L; persisted asxd.layoutinEditorConfigDto.Extra; status bar 5th item reflects active layout - Overkill overhaul (phases A–F) — F4 property inspector improvements, refined multi-select handles, panel UX polishing, ZoomPanCanvas
TransformGroupcorrection, advanced element alignment guides
✨ Added — Shared Undo/Redo Engine (UndoEngine)
UndoEngine(WpfHexEditor.Editor.Core.Undo) — replaces both editors' custom undo stacks;List<IUndoEntry>with split pointer, max 500 entries; each entry implementsUndo()/Redo()for clean replay- Coalescing —
IUndoEntry.TryMergecombines consecutive same-type edits within a 500 ms window (e.g.,Insert+InsertinCodeEditorUndoEntry) to prevent micro-entry flooding on fast typing - Transactions —
BeginTransaction()/CommitTransaction()groups multiple entries into aCompositeUndoEntry; all nested operations replay atomically as a single undo step - Save-point tracking —
MarkSaved()/IsAtSavePointdrivesIsDirtydirectly;StateChangedevent propagates the dirty flag to the IDE title bar without polling Ctrl+Shift+Zredo — added to both CodeEditor and TextEditor key bindings (previously onlyCtrl+Ywas available)- Dynamic context menu headers — Undo and Redo items display the pending operation count: "Undo (3)" / "Redo (1)"
IDocumentEditorextended withUndoCount/RedoCountdefault interface members (DIMs) for status bar consumption; oldUndoRedoStackclass and file removed
✨ Added — Rectangular Selection + Drag-and-Drop (CodeEditor + TextEditor)
- Alt+Click rectangular selection — starts a column-aligned block selection in both editors; rendered as a single merged rectangle (no visible row seams at join lines)
- Text drag-to-move — click-and-drag a non-rectangular selection to relocate it inline; recorded as a single compound undo entry equivalent to cut + paste
- Rectangular block drag-to-move — dragging a rectangular selection moves the entire block to the target column position; columns outside the block are preserved unchanged
IUndoEntrymigration —TextEdit(TextEditor) converted toIUndoEntryto participate in the sharedUndoEngine; no external API change
✨ Added — NuGet Solution Manager
NuGetSolutionManagerDocument+NuGetSolutionManagerViewModel— solution-level NuGet panel aggregating all packages across all VS projects in the workspace; opened via right-click on the solution node → "Manage NuGet Packages for Solution…"- 4 tabs — Browse (online
nuget.org/v3search), Installed (current packages per project), Consolidate (cross-project version mismatches), Updates (available upgrades) - Content ID
doc-nuget-solution-{name}— content router matches this prefix before single-projectdoc-nuget-entries to avoid routing collisions;_nugetSolutionManagerMapprevents duplicate documents
✨ Added — Inline Hints: Per-Language Gates + 29 New Language Definitions
- Per-language Inline Hints — Inline Hints hints and Ctrl+Click navigation are now gated per-language via the
.whlangdefinition; languages that do not declare symbol-resolution support no longer fire spurious LSP requests on hover - 29 new
.whlangdefinitions — extended the embedded language set; total embedded language definitions now exceeds 55, covering most common text, markup, config, and code file types
🔧 Refactored — Shell Rename (WpfHexEditor.Docking.Wpf → WpfHexEditor.Shell)
- Assembly, namespace root (
WpfHexEditor.Shell.*), and Pack URI prefix updated across the entire solution using Core = WpfHexEditor.Docking.Core;alias added to 4 files that reference both namespaces; 0 build errors after rename
🔧 Fixed
- ZoomPanCanvas
RenderTransform— corrected to use a singleTransformGroupcombiningScaleTransform+TranslateTransform; zoom and pan no longer produce coordinate-system drift under rapid interaction - Zoom-pan content anchoring — transforms now applied to the inner content element rather than the
ZoomPanCanvasframe itself; zoom origin stays correctly anchored to the mouse cursor position - Ctrl+Click navigation — restored definition navigation when the
Languagedependency property is not explicitly set onCodeEditorSplitHost.OpenAsync; previously fell through without navigating - Toolbar layout pod — removed duplicate layout pod from the main IDE toolbar; the pod is now exclusive to the XAML Designer toolbar strip
[0.5.8] — 2026-03-17 — Ctrl+Click Navigation, Search Highlight Fix & Inline Hints Improvements
✨ Added — Code Editor: Ctrl+Click Go-to-Definition
- Cross-file declaration scan (step 3b) — when LSP has no result, the editor now scans all workspace files sharing the same extension via
WorkspaceFileCache.GetPathsForExtensions; found declarations fireReferenceNavigationRequestedto navigate directly to the correct file and line without LSP - Multi-location
ReferencesPopup— when LSP returns more than one definition location,HandleDefinitionLocationsAsyncbuildsReferenceGroup/ReferenceItemstructs and opensReferencesPopupinstead of silently taking the first result MetadataUripassthrough —GoToExternalDefinitionEventArgsnow carries the raw OmniSharp metadata URI (omnisharp-metadata:?assembly=X&type=Y&...) extracted from the LSP response;HandleExternalDefinitionAsyncpasses it through the event- External symbol decompilation (
MainWindow.xaml.cs) —OnGoToExternalDefinitionRequestednow fully implements the decompilation pipeline:ParseMetadataUriextractsassembly=andtype=from the metadata URI query stringFindAssemblyPathresolves the DLL via 3-tier fallback: loadedAppDomainassemblies → .NET runtime directory → NuGet package cache (%USERPROFILE%\.nuget\packages)AssemblyAnalysisEngine.AnalyzeAsync+CSharpSkeletonEmitter.EmitTypeproduce a C# skeleton- Opens a read-only TextEditor tab (
decompiled:{assembly}:{type}) — deduplication guard prevents duplicate tabs on repeated Ctrl+Click GoToLinenavigates the decompiled source to the symbol's declaration line
WpfHexEditor.Core.AssemblyAnalysisadded to App project references — enables the decompilation pipeline inMainWindow.xaml.cs
🔧 Fixed — Code Editor: Search Highlight Misalignment
RenderFindResultsX position — replaced rawcolumn * _charWidthwith_glyphRenderer.ComputeVisualX(lineText, column)so tab characters (rendered as expanded spaces) are accounted for correctly; highlight boxes now align exactly with the matched text regardless of tab indentationRenderFindResultsY position — replaced raw_lineHeightarithmetic with_lineYLookup.TryGetValue(line, out double ry)to respect per-line Y offsets introduced by Inline Hints hint rows; highlights in Inline Hints-decorated files no longer drift vertically
🔧 Fixed — Compilation Errors
_lastFindQuerymissing (×8) — field was accidentally removed with the old find-bar block; restoredprivate string? _lastFindQuery;in the#region Fields - Find/Replacesection ofCodeEditor.csDockDirectionnot found (×10) —MainWindow.Build.csreferencedDockDirection.Bottomwithout the requiredusing WpfHexEditor.Docking.Core;; using directive added
[0.5.2] — 2026-03-16 — Code Editor Navigation Bar, Assembly Explorer Expansion & Build Refactoring
✨ Added — Code Editor: VS-Like Navigation Bar
- Navigation bar — VS-style dual-combo toolbar at the top of the Code Editor: left combo lists all types (class/interface/struct/enum/delegate), right combo lists all members (methods, properties, fields, events, constructors, indexers)
- CaretMoved event —
ICodeEditor.CaretMovedraised on every line/column change; nav-bar combos auto-select the matching type and member as the caret moves - Auto-scroll — clicking a combo item scrolls the editor to the corresponding declaration line
- Segoe MDL2 Assets icons — each member kind uses a Segoe MDL2 glyph matching the IDE Solution Explorer palette (method
\uE8A0, property\uE74C, field\uE894, event\uE7C3, constructor/indexer\uE8D5) _camelCasename support — member name parser strips leading underscores before matching, so_fieldis correctly classified as a private field node in the nav-bar
✨ Added — Themes: Code Editor Selection Token
CE_SelectionInactivebrush token added to all 8 built-in themes — used by the Code Editor to distinguish inactive (unfocused window) text selections from active ones
✨ Added — Options: MouseWheelSpeed
MouseWheelSpeedDP / enum selector — new Hex Editor Display option (System,Slow,Normal,Fast,VeryFast); defaults toSystem(matches OS wheel delta); controls smooth-scroll velocity in the Code Editor and HexEditor
✨ Added — Assembly Explorer: Major Expansion
- ILSpy decompiler backend —
IlSpyDecompilerBackendwraps the ILSpy engine;DecompilerServiceselects betweenSkeletonDecompilerBackend(BCL-only) and ILSpy backend viaDecompilerOptions.UseIlSpy - VB.NET decompilation language —
VbNetDecompilationLanguageadded to the decompiler language registry; surface in the detail pane language selector - Decompile cache —
DecompileCacheprevents redundant decompilation of unchanged assemblies; keyed by(filePath, tokenHandle, language) - Assembly Diff panel —
AssemblyDiffPanel+AssemblyDiffViewModel: compare two loaded assemblies side-by-side; highlights added/removed/changed members with color coding - Assembly Search panel —
AssemblySearchPanel+AssemblySearchViewModel: full-text search across all loaded assembly members with type/kind filter and instant results list - Source View panel —
SourceViewModel+ read-only source tab inAssemblyDetailPane - CFG Canvas —
CfgCanvascustom control +CfgViewModel: control-flow graph rendering for a selected method (nodes = basic blocks, edges = jumps/branches); opens in a dedicated tab - XRef View —
XRefViewModel: shows all cross-references to a selected member (callers/implementors); listed in the detail pane XRef tab - Assembly Workspace entry —
AssemblyWorkspaceEntryserialization; loaded assemblies are persisted in the workspace and restored on next session open - Options page —
AssemblyExplorerOptions+AssemblyExplorerOptionsPage.xaml: decompiler backend selector (Skeleton/ILSpy), VB.NET toggle, cache size, pinning behavior - Decompiler contracts —
IDecompilerBackend+DecompilerOptionsextracted to allow swappable backends without changing the plugin API
✨ Added — NuGet Support in Project System
- NuGet V3 client —
NuGetV3Client+INuGetClient: queriesnuget.org/v3for package search, version listing, and dependency resolution - NuGet DTOs —
NuGetDtosmodels for API responses CsprojPackageWriter— writes<PackageReference>entries to.csprojfiles programmaticallyNuGetPackageViewModel— display model for the NuGet package browser panel
✨ Added — Workspace Templates
WpfHexEditor.WorkspaceTemplatesproject —TemplateManager,ProjectScaffolder,IProjectTemplate; 3 built-in JSON templates (blank,sdk-plugin,text-analysis)- Initializers —
SmartCompleteInitializer,LanguageInitializer,OptionsInitializer,PluginInitializer; each wires one aspect of a new workspace on scaffold NewProjectDialog— XAML dialog +NewProjectDialogViewModelfor creating projects from templates
🔧 Fixed / Refactored — Build System
MSBuildAdapter— surface engine errors from the MSBuild evaluation step; async fire-and-forget replaced with properawait; copy MSBuild Locator DLL to plugin output directory during buildBuildSystem/IBuildAdapterrefactored — clean separation between adapter contract and engine;MSBuildLogger.csandNuGetRestoreStep.csremoved (responsibilities folded into adapter and core engine)BuildOutputAdapter/OutputServiceImpl— build output now correctly classified (info/warn/error/success) before routing to the Build channel
🔧 Fixed — Code Editor Scrolling & UX
- Smooth scrolling — disabled by default; opt-in via options; prevents unintended inertia during precision editing
- Mouse-click offset — corrected hit-test calculation when pixel-based smooth scroll is active (caret no longer lands one line off)
- Gutter update guard — gutter repaint skipped when editor content hasn't changed, reducing flicker during rapid scrolling
- Scrollbar cursor —
Arrowcursor explicitly set on scrollbar tracks to override the inheritedIBeamfrom the editor host - Split toggle — split-view toggle button moved clear of the vertical scrollbar track
[0.5.1] — 2026-03-16 — Source Outline Patch
🔧 Fixed
- Solution Explorer: source type nodes auto-expanded on first lazy load —
SourceTypeNodeVminheritedIsExpanded = truefrom the base class default, causing class/struct/interface nodes to appear fully expanded (all members visible) the moment a.csor.xamlfile node was expanded for the first time. Type nodes are now explicitly initialized withIsExpanded = falseinApplyOutlineToNode; the user must intentionally expand a type node to reveal its members.
[0.5.0] — 2026-03-16 — Code Editor, Source Outline, Build Output, Assembly Explorer & VS Solution Loader
✨ Added — Solution Explorer: Source Outline Navigation
SourceOutlineEngine(WpfHexEditor.Core.SourceAnalysis) — BCL-only regex-based parser that extracts types and members with 1-based line numbers from.csand.xamlfiles; results are cached per file pathISourceOutlineService— contract for source outline providers; injected intoSolutionExplorerViewModelSourceTypeModel/SourceMemberModel/SourceOutlineModel— immutable models for parsed types and membersSolutionExplorerNodeVm— lazy expansion viaTreeViewItem.ExpandedEvent;LoadingNodeplaceholder shown while parsing; outline nodes exposeLineNumberfor direct navigationSolutionExplorerViewModel—OutlineServicewired; async expand handler callsSourceOutlineEngineon background threadSolutionExplorerPanel.xaml.cs—TreeViewItem.Expandedhandler triggers on-demand source parse; prevents double-expansion- Source outline is activated automatically for
.csand.xamlnodes in the Solution Explorer tree
✨ Added — Assembly Explorer Improvements (v0.2.1)
- Collapse All — toolbar button + context menu item collapses the entire assembly tree to root nodes
- Close All Assemblies — toolbar button (
ToolbarRightPanel, always visible) + context menu item (red#EF4444) clears all loaded assemblies in one action;CloseAllCommandwired inAssemblyExplorerViewModel - Decompile to C# → Code Editor tab —
OnDecompilenow setsViewModel.SelectedNodebefore executingOpenInEditorCommand; ensures right-click context menu decompilation always opens the correct node in a Code Editor tab - C# Syntax Highlighting in decompiled output — decompiled C# skeleton rendered with full token-level syntax coloring in the Code Editor tab (keywords, types, strings, comments, numbers, operators)
- Extract to Project workflow —
AssemblyCodeExtractServiceextracts decompiled C# from any type/method/assembly node and places it in a chosen project;ProjectPickerDialoglets the user select the target project; wired viaExtractToProjectAsyncinAssemblyExplorerPanel
✨ Added — Build Output Routing (#103 partial)
OutputServiceImpl.Write("Build", …)— fixed: now routes toOutputLogger.BuildInfo/BuildWarn/BuildError/BuildSuccess(was silently routing to the General channel)OutputLogger.FocusChannel(string source)— new static method; switches the Output panel to the specified tab on the UI thread viaDispatcher.InvokeAsyncOutputPanel.SetActiveSource(string source)— newinternalmethod; iteratesSourceComboBox.Itemsto match and programmatically select the correct channel- Auto-focus Build tab —
MainWindow.Build.cscallsOutputLogger.FocusChannel(SourceBuild)in all build runners (RunBuildSolutionAsync,RunRebuildSolutionAsync,RunCleanSolutionAsync,RunBuildProjectByIdAsync,RunRebuildProjectByIdAsync) before awaiting the build - Empty-solution guard — if no solution or projects are loaded,
RunBuildSolutionAsynclogs a gold warning "No solution or projects loaded — nothing to build." and returns immediately instead of silently succeeding
✨ Added — VS Solution Loader: Project Templates
DotNetProjectTemplate— abstract base withName,Description,DefaultProjectName,SupportedLanguages,GenerateFiles()ConsoleAppTemplate— .NET 8 console application scaffoldClassLibraryTemplate— .NET 8 class library scaffoldWpfAppTemplate— WPF application scaffold (net8.0-windows)AspNetApiTemplate— ASP.NET Core Web API scaffold- Templates are discovered via
VsSolutionLoaderPluginand used by "New Project" dialogs
✨ Added — Code Editor Enhancements (#84 partial)
- Full
.whlangsyntax coloring — all 26 embedded language definitions now produce token-level colored output (keyword, type, string, comment, number, operator, url, preprocessor, attribute, identifier) - Live brush resolution —
ResolveBrushForKind()usesTryFindResourcedirectly on the editor control instead of the WPF DP system; eliminates "brush not found" fallback to transparent on theme switches - Foreground base pass — entire document gets the theme foreground color before token colorization to prevent uncolored regions from rendering transparent
- Hover-only URL underline — hyperlinks in code are underlined only on
MouseEnter; tooltip shows the full URL; click opens in browser - URL baseline fix — underline drawn closer to text baseline for visual consistency with VS Code
CodeEditorSplitHostimprovements — split host properly propagates theme changes to both panesCodeDocumentmodel cleanup — simplified document state; reduced unnecessary allocationsCodeEditorFactoryregistration aligned with updated factory contracts
✨ Added — LSP Infrastructure
RefactoringEngine(WpfHexEditor.LSP) — central registry forIRefactoringimplementations;Register(IRefactoring)+GetAvailable(RefactoringContext)for contextual filtering; resolvesCS0246compile error inCommandIntegration
✨ Added — Docking Engine: Tab Overflow
TabOverflowButton— improved overflow button for docked tab groups; correct positioning, theme-aware context menuTabOverflowPanel— manages collapsed tab groups; updated hit-testing and layout logicDockControl/DockTabControl— wired tab overflow to new panel;DockTabEventWirerupdated to relay overflow events
🔧 Fixed
- Assembly Explorer: Decompile context menu — right-click "Decompile to C#" had no effect;
SelectedNodewas not set beforeOpenInEditorCommandexecuted (eb536cc6) - Assembly Explorer: AssemblyDiffPanel crash —
XamlParseException: 'ContextMenu' cannot have a logical or visual parentatInitializeComponent(); root cause: Button with TextBlock child +<Button.ContextMenu>property element causes parent conflict in WPF XAML; fixed by converting Button content toContent=""attribute form - Code Editor: syntax highlight transparent on load —
ResolveBrushForKindreferenced DP-system brushes that weren't in scope at paint time; now usesTryFindResourceon the control element (ff19b091) - Build system: output not visible — all build output was routed to the General channel with
[Build]prefix; now correctly routes to the dedicated Build channel (d335b505) - Build toolbar/menu: disabled after solution open — build commands stayed grayed out after opening a
.sln; fixed by refreshing command states onSolutionLoadedEvent(d8fe1882) - File access: FileShare.None causing lock conflicts — analysis services opened files exclusively; replaced with
FileShare.ReadWritethroughout + external change detection (b3090989) - Changeset tracking: performance regression —
.whchgtracking was O(n²) on large files; optimized and disabled by default (f140c544) - Startup: System.Text.Json 10 transitive dependency — MSBuild packages pulled in JSON 10 which conflicted with WPF serialization; pinned to 8.x in affected projects (
1027f192) - Grammar Explorer: embedded grammar discovery — deferred panel docking and reliable discovery of grammars bundled as embedded resources (
a7196376) - SolutionLoader: VS/WH/MSBuild build order — plugins not included in App build order; added project references (
7a7b318d) - PluginDev: duplicate DevPluginHandle + missing using — removed duplicate type, added
System.IOimport (eb656c35) - Compilation errors: PluginProjectTemplate, CodeEditorOptionsPage, Initializers — various CS errors fixed (
131cd20b)
⚡ Changed
- SolutionLoader: dynamic file-dialog filter —
ISolutionLoaderplugins now declare their supported file extensions; the Open Solution dialog filter is built dynamically from all registered loaders (ba9279b2) - External solution routing via
ISolutionLoader—.slnfiles are routed to the correct loader plugin instead of being hard-coded inMainWindow - IProjectTemplate: extended contract with
DefaultProjectName,SupportedLanguages,GenerateFiles()
What's Next
Full roadmap → ROADMAP.md
| Priority | Feature | Issue |
|---|---|---|
| 🔥 High | LSP Engine — go-to-definition, find-references, incremental symbol parsing | #85 |
| 🔥 High | SmartComplete — autocomplete, signature help, quick-info | #86 |
| 🔥 High | Assembly Explorer — ILSpy full decompilation, hex sync, metadata token navigation | #106 |
| 🔥 High | MSBuild — error list navigation with file/line jump, incremental builds | #103 |
| 🔥 High | Synalysis Grammar Support — .grammar file parser + 10 embedded grammars | #177 |
| ⚡ Next | Git Integration — commit/push/pull/branch, inline gutter diff | #91 |
| ⚡ Next | Plugin Marketplace — online registry, signed packages, auto-update | #41–43 |
| ⚡ Next | Integrated Debugger — breakpoints, watch, call stack | #44 |
| ⚡ Next | Service Container / DI — unified IDE service registry | #36 |
| 📋 Planned | Command Palette (Ctrl+Shift+P) — fuzzy search across all IDE commands | #133 |
| 📋 Planned | IDE Localization Engine — full i18n, EN/FR initial | #100 |
| 📋 Planned | Installable Package — MSI / MSIX / WinGet | #109 |
[0.4.0] — 2026-03-16 — Plugin Architecture v2: EventBus, Lazy Loading, Capability Registry, Extension Points & Dependency Graph
✨ Added — WpfHexEditor.Events (new project)
WpfHexEditor.Events— newnet8.0leaf project (no WPF dependency); referenced by SDK, PluginHost, and AppIDEEventBase— abstract record base for all IDE events:EventId,Source,Timestamp,CorrelationIdIDEEventContext— per-publish context:PublisherPluginId,IsFromSandbox,CancellationTokenIIDEEventBus— typed pub/sub interface with sync and async publish; context-aware subscribe overloads;IEventRegistry EventRegistrydiagnostics accessorIDEEventBus— implementation:ReaderWriterLockSlim, weak-reference handler entries, lazy purge on publish, rolling event log (last 100 entries),GetLog()/ClearLog()for diagnosticsIEventRegistry/EventRegistry— subscriber count tracking per event type;GetAllEntries()for options page
10 built-in IDE event types (WpfHexEditor.Events.IDEEvents):
FileOpenedEvent—FilePath,FileExtension,FileSizeFileClosedEvent—FilePathWorkspaceChangedEvent—WorkspacePath,PreviousWorkspacePathPluginLoadedEvent—PluginId,PluginName,IsolationModePluginUnloadedEvent—PluginIdEditorSelectionChangedEvent—Offset,Length,SelectedBytesDocumentSavedEvent—FilePathTerminalCommandExecutedEvent—Command,ShellTypeBuildStartedEvent,BuildSucceededEvent,BuildFailedEvent
✨ Added — Feature 1: Lazy Loading (#77)
PluginActivationConfig(SDK) — manifest sub-model:FileExtensions,Commands,OnStartup; plugins withonStartup: falseremain dormant until activatedPluginState.Dormant(SDK) — new state betweenUnloadedandLoading; dormant plugins are discovered but not loadedPluginManifest.Activation(SDK) — optionalPluginActivationConfig?property; backward compatible (null = eager load)PluginActivationService(PluginHost) — watchesFileOpenedEventonIDEEventBus; triggersLoadPluginAsyncfor dormant plugins matching file extension or command triggers; prevents double-activation viaHashSet<string>WpfPluginHost—LoadAllAsyncpartitions plugins into startup vs dormant;RegisterDormantPlugin(); wires_activationService- Plugin Manager UI —
IsDormant,ActivationTriggerLabel,LoadNowCommandonPluginListItemViewModel; dormant badge (purple) + lazy info card with "Load Now" button inPluginManagerControl.xaml
✨ Added — Feature 2: ALC Isolation Diagnostics
PluginAssemblyConflictInfo(SDK) —record(AssemblyName, HostVersion, RequestedVersion, DetectedAt)PluginLoadContext(PluginHost) —LoadedAssemblieslist,DependencyConflictDetectedevent,CreateWeakReference(); host version always wins on conflictPluginEntry—LoadContextWeakRef(WeakReference<PluginLoadContext>),AssemblyConflictslist,LoadedAssemblyCount- Plugin Manager UI — ALC metrics card (InProcess only): assembly count + conflict count; expandable conflicts list;
ZeroToGreenNonZeroToOrangeconverter
✨ Added — Feature 3: Capability Registry
PluginFeature(SDK) —static classwithconst stringwell-known feature names:HexViewOverlay,BinaryAnalyzer,PEParser,DisassemblyProvider,DecompilerProvider,FormatDetector,StructureTemplate,ScriptEngine,TerminalExtensionIPluginCapabilityRegistry(SDK) —FindPluginsWithFeature(),PluginHasFeature(),GetFeaturesForPlugin(),GetAllRegisteredFeatures()PluginCapabilityRegistry(PluginHost) — live queries overWpfPluginHost._entries; no cachingPluginCapabilityRegistryAdapter(PluginHost) — lazy wrapper resolving circular dependency;.SetInner()called after host constructionPluginManifest.Features(SDK) —List<string>feature declarations; e.g."features": ["HexViewOverlay", "BinaryAnalyzer"]IIDEHostContext.CapabilityRegistry(SDK) — exposes capability registry to all plugins- Plugin Manager UI — feature chip strip (
WrapPanelof pillBorderelements) in plugin detail pane
✨ Added — Feature 4: IDE EventBus Integration
IIDEHostContext.IDEEvents(SDK) — exposesIIDEEventBusto plugins; sandbox plugins receive events via IPC bridgeSandboxPluginProxy—WireIDEEventBridgeToSandbox(): subscribes toFileOpenedEvent+EditorSelectionChangedEventonIDEEventBusand forwards to sandbox process via named-pipeIDEEventNotificationmessagesSandboxedPluginRunner—HandleIDEEventNotification(): deserializes event payload, resolves concrete type fromWpfHexEditor.Eventsassembly, publishes toSandboxLocalEventBusvia reflectionIDEEventBusOptionsPage.xaml(PluginHost) — new Options page underPlugin System > Event Bus: rolling event log (last 100), subscriber count table per event type, "Clear log" button; full theme complianceWpfPluginHost— publishesPluginLoadedEvent/PluginUnloadedEventon every load/unloadMainWindow.PluginSystem.cs(App) — constructsIDEEventBus, registers 10 well-known events in registry, wiresFileOpened→FileOpenedEvent,SelectionChanged→EditorSelectionChangedEvent
✨ Added — Feature 5: Extension Points
- Extension point contracts (SDK,
WpfHexEditor.SDK.ExtensionPoints):IFileAnalyzerExtension—Task<FileAnalysisResult> AnalyzeAsync(string filePath, CancellationToken ct)+FileAnalysisResultrecordIHexViewOverlayExtension—IEnumerable<HexOverlayRegion> GetOverlays(byte[] data, long offset, long length)+HexOverlayRegionrecordIBinaryParserExtension—ParsedStructure? TryParse(Stream data, string fileExtension)+ParsedStructurerecordIDecompilerExtension—Task<string> DecompileAsync(byte[] data, CancellationToken ct)IExtensionWithContext— optional init interface;Initialize(IIDEHostContext context)called by host after instantiation
ExtensionPointCatalog(SDK) — staticIReadOnlyDictionary<string, Type>mapping well-known point names to contract typesIExtensionRegistry(SDK) —GetExtensions<T>(),Register<T>(),UnregisterAll(pluginId),GetAllEntries()ExtensionRegistry(PluginHost) — thread-safe impl (ReaderWriterLockSlim); snapshot onGetExtensions<T>()prevents mutation during iterationPluginManifest.Extensions(SDK) —Dictionary<string, string>mapping extension point name → fully-qualified class name in plugin assemblyWpfPluginHost—RegisterExtensionContributions()afterInitializeAsync;ExtensionRegistry.UnregisterAll()duringUnloadPluginAsyncIIDEHostContext.ExtensionRegistry(SDK) — exposes extension registry to all plugins- Plugin Manager UI — extensions chip strip in plugin detail pane;
Extensions/HasExtensionsonPluginListItemViewModel MainWindow.PluginSystem.cs— wires file-open handler to callGetExtensions<IFileAnalyzerExtension>()and routes results to Output Panel
✨ Added — Feature 6: Plugin Dependency Graph
PluginDependencySpec(SDK) — parsed versioned constraint:PluginId+PluginVersionConstraint;Parse("BinaryAnalysisCore >=1.0")— backward compatible with plain IDsPluginVersionConstraint(SDK) — single-class parser; operators>=,>,<=,<,=,^;bool Satisfies(Version candidate); no NuGet dependencyPluginDependencyGraph(PluginHost) — adjacency-list graph with forward + reverse edges;Build(),GetLoadOrder(),GetDependents(),GetCascadedUnloadOrder(),GetCascadedReloadOrder(),Validate();DependencyValidationErrorrecord withDependencyErrorKind(Missing | VersionMismatch | Circular)WpfPluginHost— replaces inlineTopologicalSort()with_dependencyGraph.GetLoadOrder();CascadingUnloadAsync()andCascadingReloadAsync(); plugins with unmet dependencies markedIncompatibleand skipped at startupPluginManifest.Dependencies— existingList<string>now supports versioned syntax:"BinaryAnalysisCore >=1.0"; plain IDs still work (any version)- Plugin Manager UI —
DependsOnchip list (green=satisfied, red=missing),DependedOnBylist,HasUnresolvedDeps; Cascade Unload / Cascade Reload buttons; dependency section in right pane
🔧 Changed
- All 10 plugin
.csprojfiles —<PluginIsolationMode>changed fromSandbox→Auto;Autois now the correct default (host decides InProcess vs Sandbox based on trust level and capability declarations) StandaloneIDEHostContext(Sample.Terminal) — implements 3 newIIDEHostContextmembers (IDEEvents,CapabilityRegistry,ExtensionRegistry) with null-object stubsExtensionRegistry— promoted frominternaltopublic(required byAppproject)IDEEventBusOptionsPage— uses concreteIDEEventBustype (diagnostics methods not on interface)
[0.3.0] — 2026-03-15 — Plugin System Phase 5-12, Sandbox & IDE Enhancements
✨ Added — Plugin Sandbox (Phases 9–12)
- HWND Embedding — out-of-process plugin UI surfaces embedded directly into the IDE docking system via Win32 HWND parenting; plugins run fully isolated but appear native
- IPC Menu/Toolbar Bridge — sandbox plugins register menus, toolbar items, and options pages in the host IDE via named-pipe IPC;
SandboxPluginProxydispatches menu clicks back to plugin process - IPC HexEditor Event Bridge (Phase 12) —
SelectionChanged,FileOpened,FormatDetected, andViewportScrolledevents forwarded from host to sandbox plugins;ParsedFieldspanel refresh now works from sandbox context SandboxJobObject— Windows Job Object wrapper constraining sandbox process CPU and memory usage; enforces per-plugin resource budgets with configurable limits- Auto Isolation Mode / Decision Engine —
PluginMigrationPolicyevaluates plugin trust level, crash history, and resource usage to automatically selectInProcessvsSandboxisolation; no manual configuration required PluginMigrationMonitor— tracks plugin migrations between isolation modes; exposes upgrade/downgrade history, trigger reasons, and stability metrics; observable from Plugin Manager
✨ Added — Plugin Options UI
UI/Options/— dedicated options sub-panel within Plugin Manager for per-plugin sandbox configuration, migration policy overrides, and resource budget thresholdsAssemblyExplorerOptionsPage.xaml— updated options page with sandbox-compatible bindingsDataInspectorOptionsPage.xaml— updated options page with sandbox-compatible bindings
✨ Added — Plugin Manager Improvements
PluginListItemViewModel— extended withIsolationMode,MigrationStatus,SandboxHealth,LastMigrationReason; badge indicators for auto-isolation decisionsPluginManagerControl.xaml— isolation mode column, migration history button, sandbox health indicator in list; options sub-panel per pluginPluginManagerViewModel— wires migration monitor; exposesMigrationHistoryCommand; auto-refreshes on isolation mode change
✨ Added — Themes
- All 8 theme
Colors.xamlfiles updated — new brush tokens for sandbox health badges, isolation mode indicators, and plugin options UI
🧪 Added — Tests
PluginMigrationMonitor_Tests— unit tests covering migration trigger logic, history accumulation, and observer notificationPluginMigrationPolicy_Tests— unit tests covering decision engine: trust thresholds, crash-rate fallback, manual override precedence
✨ Added — Plugin System (5 new projects)
WpfHexEditor.SDK — public plugin contract layer
IWpfHexEditorPlugin/IWpfHexEditorPluginV2— plugin lifecycle (Init / Activate / Deactivate / Dispose)IIDEHostContext— full IDE access gateway for pluginsIUIRegistry— panel registration, Show / Hide / Toggle / Focus APIIDockingAdapter— ShowDockablePanel / HideDockablePanel / ToggleDockablePanel / FocusDockablePanel- Service contracts:
IHexEditorService,ICodeEditorService,IOutputService,IErrorPanelService,ISolutionExplorerService,IParsedFieldService IPluginWithOptions— optional interface; plugins exposing it get an auto-registered Options page under "Plugins"IFocusContextService,IPluginEventBus,IPluginState,IPluginDiagnostics,IPermissionService,IMarketplaceService,IThemeServicePluginManifestwithResolvedDirectory(runtime-only,JsonIgnore)
WpfHexEditor.PluginHost — runtime host infrastructure
WpfPluginHost— discovery (%AppData%\WpfHexEditor\Plugins\+bin\Plugins\), load, unload, enable/disablePluginEntry— internal mutation API:SetState,SetInstance,SetInitDuration,SetLoadedAt,SetFaultException,Unload()(clears collectibleAssemblyLoadContext)PluginCrashHandler—HandleCrash+ asyncHandleCrashAsync()overloadPluginWatchdog—WrapAsync()returnsTask<TimeSpan>(elapsed time)PluginOptionsRegistry— thread-safe runtime registry of plugin options pages keyed by plugin IDPluginLoadContext— collectibleAssemblyLoadContextfor hot-unloadPluginManifestValidator,PluginDiagnosticsCollector,PluginScheduler,PluginEventBus,PluginStateSerializerPermissionService—PermissionChangedEventArgsvia object-initializer (PluginId, Permission, IsGranted)UIRegistry— delegates Show/Hide/Toggle/Focus toIDockingAdapterPluginManagerControl.xaml— enable/disable/uninstall actions, live status,PluginListItemViewModel(LoadedAt, AssemblyPath, OptionsPageFactory)SandboxPluginProxy— out-of-process proxy over named-pipeIpcChannel
WpfHexEditor.PluginSandbox — isolated host process (stub, net8.0-windows)
- Console host entry point; named-pipe IPC with main IDE process
WpfHexEditor.Core.Terminal — command engine (31 built-in commands)
- Category Core:
clear,echo,exit,help,history,version - Category File System:
copy-file,delete-file,list-files,open-file,open-folder - Category Editor:
close-file,read-hex,save-file,save-as,search,select-file,write-hex - Category Project / Solution:
close-project,close-solution,open-project,open-solution,reload-solution - Category Panels:
append-panel,clear-panel,close-panel,focus-panel,open-panel,toggle-panel - Category Plugins:
plugin-list,run-plugin - Category Diagnostics:
send-error,send-output,show-errors,show-logs,status HxScriptEngine— executes.hxscriptfiles;CommandHistorywith persistence
WpfHexEditor.Terminal — WPF dockable terminal panel
TerminalPanel.xaml— VS-style dockable panel, prompt input, colored outputTerminalPanelViewModel— implements bothITerminalContextandITerminalOutput;TerminalOutputLinewith severity-to-brush converter
7 First-party plugin packages (Sources/Plugins/)
WpfHexEditor.Plugins.DataInspector— wraps DataInspectorPanel; implementsIPluginWithOptions(DataInspectorOptionsPage: display format, endianness, auto-refresh interval)WpfHexEditor.Plugins.StructureOverlay— wraps StructureOverlayPanelWpfHexEditor.Plugins.FileStatistics— wraps FileStatisticsPanelWpfHexEditor.Plugins.PatternAnalysis— wraps PatternAnalysisPanelWpfHexEditor.Plugins.FileComparison— wraps FileComparisonPanelWpfHexEditor.Plugins.ArchiveStructure— wraps ArchiveStructurePanelWpfHexEditor.Plugins.CustomParserTemplate— wraps CustomParserTemplatePanel
Packaging tools (Sources/Tools/)
WpfHexEditor.PackagingTool—whxpackCLI,ManifestFinalizer(SHA-256),PackageBuilder→.whxplugin(ZIP)WpfHexEditor.PluginInstaller— WPF installer dialog,PluginPackageExtractor,--silentmode,PluginInstallException
✨ Added — App Integration (Plugin System)
MainWindow.PluginSystem.cs—InitializePluginSystemAsync,ShutdownPluginSystemAsync,UpdatePluginFocusContextOnOpenTerminal()— createsTerminalPanel+TerminalPanelViewModel, docks as"panel-terminal"OnOpenPluginManager()— docksPluginManagerControlas"plugin-manager"- Tools menu — Plugin Manager + Terminal entries; toolbar separators with
DataTrigger-controlled visibility - Dynamic Options registration — each plugin implementing
IPluginWithOptionsgetsOptionsPageRegistry.RegisterDynamic()on load;UnregisterDynamic()on disable/unload
✨ Added — Options Module
HexEditorBehaviorPage.xaml(.cs)— new Options page: data interpretation, scroll markers, advanced behaviorHexEditorStatusBarPage.xaml(.cs)— new Options page: status bar element visibility togglesPluginSystemOptionsPage.xaml(.cs)— plugin loading settings, sandbox mode, auto-update policyOptionsPageRegistry.RegisterDynamic(category, pageName, factory)/UnregisterDynamic(pageId)— runtime plugin options page registrationAppSettings— expanded withSolutionExplorerSettings,CodeEditorDefaultSettings,TextEditorDefaultSettings, plugin system settings (~30 new properties)
✨ Added — Service Layer
DockingAdapter—ShowDockablePanel,HideDockablePanel,ToggleDockablePanel,FocusDockablePanel(usesDockItemState.Hiddencheck)ErrorPanelServiceImpl—PostDiagnosticnow acceptsDiagnosticSeverityenum (was string); maps SDK→Core severity; usesAddSourceSolutionExplorerServiceImpl—OpenFileHandlerdelegate avoids circular App↔SDK referenceHexEditorServiceImpl—ReadBytes,GetSelectedBytes,SearchHex,SearchText,GoToOffset
✨ Added — Docking Improvements
AutoHideBar—SnapshotReadyevent (fires after open animation + Render priority) andDismissingevent (before close animation)DockControl— wiresSnapshotReady/Dismissing;MinCaptureSizeguard inCaptureAutoHideSnapshotTabHoverPreview— title-only fallback card for never-activated tabs; hides popup on selected tab; title fromDockItem.TagAutoHideBarHoverPreview— button-relative placement replacesPlacementMode.Mouse(Win32 layered window bug)DockTabControl— float threshold check moved before reorder-dispatch; vertical drag cancels reorder and floats insteadDockDragManager— guard forDocumentTabHost.Node == null
✨ Added — Solution Explorer Improvements
- Expand-state persistence — captures/restores
IsExpandedper node acrossRebuild()in same session - Drag & drop from Windows Explorer —
DataFormats.FileDrophandled; files added to project without dialog - Delete from disk —
ItemDeleteFromDiskRequestedevent; moves to Recycle Bin with confirmation
✨ Added — HexEditor Enhancements
HexEditor.StatusBarContributor—RaiseHexStatusChanged()fired onByteGrouping,OffSetStringVisual,DefaultCopyToClipboardModeproperty changes- net48 compatibility —
(CopyPasteMode[])Enum.GetValues(typeof(CopyPasteMode))(genericEnum.GetValues<T>()not available in net48)
✨ Added — Format-Aware Editor Selection
EmbeddedFormatCatalog— parsespreferredEditoranddetection.isTextFormatfrom.whfmtJSONEmbeddedFormatEntryrecord —string? PreferredEditorandbool IsTextFormatEditorRegistry.FindFactory(string filePath, string? preferredId)— preferred-first, fallback first-match- 427
.whfmtformat definitions annotated with"preferredEditor"key MainWindow.GetPreferredEditorId()— consultsEmbeddedFormatCatalog(PreferredEditor → IsTextFormat → null)
✨ Added — Image Viewer
IImageTransform+ImageTransformPipeline— composable transform architecture- Transforms:
RotateImageTransform,FlipImageTransform,CropImageTransform,ResizeImageTransform,ScaleImageTransform ResizeImageDialog.xaml(.cs)— width/height input with aspect ratio lockImageContextMenu.xaml— right-click context menu (copy, save, zoom, transform actions)ImageViewer.xaml(.cs)— major enhancement: zoom/pan, transform toolbar, context menu, theme complianceDockEngine/FloatingWindow— minor additions for ImageViewer floating window sizing
✨ Added — Plugin Monitoring Panel (Phases 1–5 complete)
PluginMonitoringViewModel— observesPluginEntrycollection, polls CPU% and memory MB at 1 s interval viaPerformanceCounter/ GC; rolling 60-point chart history; per-plugin CPU estimation (processCpu × avgMs / sumAvgMs)PluginMonitoringPanel.xaml(.cs)— VS-style dockable panel; globalCanvas+Polylinecharts + per-pluginSparklineControlcolumns in DataGrid; detail pane with 4-tabTabControl(Overview / CPU+RAM / Permissions / Settings); alert badge in toolbar; export dropdown (CSV / JSON / event log / copy table); drag-drop.whxplugininstallSparklineControl— newFrameworkElement-based mini chart (no external lib); renders CPU and RAM rolling sparklines directly viaOnRender; bound toPluginMiniChartViewModel(60-point history)PluginPermissionRowViewModel— interactive permissions editor: togglesIsGranted→ callsPermissionService.Grant/Revokeimmediately; risk badge (High/Medium/Low); declared vs granted columnsPluginAlertEngine— debounced per-plugin threshold evaluation (CPU%, MemMB, ExecTimeMs); 60 s cooldown per plugin per metric; raisesAlertTriggeredevent consumed by toolbar badgePluginDiagnosticsExporter— exports metrics to CSV, full diagnostics to JSON, crash summary to plain text; no external NuGet; triggered via toolbar export commandsWpfPluginHost— expanded load/unload/enable/disable lifecycle; diagnostic hooks; hot-unload via collectibleAssemblyLoadContextPluginManagerViewModel— full VM with Enable/Disable/Uninstall/Reload commands, filter/search,SelectionChangedwiring to monitoring panel; drag-drop.whxplugininstall viaPluginManagerControlPluginManagerControl— DataGrid with status column, toolbar actions, details pane with sparkline charts; drag-drop install dropzone overlay;PluginListItemViewModelextended withLiveCpuPercent,LiveMemoryMb,DiagnosticsSummary, sparkline history- Plugin
.csprojfiles — SDK manifest metadata (PluginId,PluginVersion,PluginEntryPoint, …) for auto-generatedmanifest.jsonat build time
✨ Added — Options
PluginSystemOptionsPage— complete settings page: monitoring enabled/interval, sandbox mode, auto-update, trusted publisher; bound toAppSettings.PluginSystemSettingsAppSettings.PluginSystemSettings—MonitoringEnabled,MonitoringIntervalMs,MaxHistoryPoints, sandbox policy
✨ Added — Terminal Panel Overhaul
TerminalModeenum —Interactive/Script/ReadOnlymodes with visual indicatorTerminalExportService— export full session to.txt/.logfile with timestamp headerITerminalService(SDK) — new service contract exposingExecute,Clear,ExportSession,HistoryLines; consumed by plugins viaIIDEHostContext.TerminalServiceTerminalServiceImpl— App-side implementation wiringTerminalPanelViewModelto the SDK contract; registered inIDEHostContextITerminalOutput.WriteTable()— helper for tabular output (header + rows) with column alignmentTerminalCommandRegistry— new built-in commands:export-log,set-mode,terminal-infoTerminalPanelViewModel— TerminalMode state machine; per-mode prompt styling;ExportSession()delegation toTerminalExportService; improved async command dispatch;ITerminalContext/ITerminalOutputmerged into single VMTerminalPanel.xaml— mode indicator badge; export toolbar button; resize-handle polish; full keyboard history (↑/↓) wired toCommandHistoryIIDEHostContext.TerminalService— plugins can now read/write terminal programmaticallyPluginCapabilities.Terminal— new capability flag; plugins declare terminal access requirement in manifestIDEHostContext/PluginHost.IDEHostContext— exposesITerminalService;PluginPermission.Terminalentry
✨ Added — PropertiesPanel Auto-Refresh
HexEditor.PropertyProvider—DependencyPropertyDescriptor.AddValueChangedonSelectionStartProperty/SelectionStopProperty; bypasses anti-recursion guard that silently droppedSelectionChangedduring keyboard navigation- 400 ms one-shot
DispatcherTimerdebounce —PropertiesChangedfires only after cursor is idle; eliminates synchronousFileStream+ entropy calls on every keypress BuildDocumentGroup()—EditModebound asenum(not.ToString()); ComboBoxSelectedItemnow matchesAllowedValuescorrectly (was always empty)
🔧 Changed
PluginEntrypromoted frominternaltopublic- Section separators normalized from Unicode box-drawing (
──) to ASCII (--) across 134 files MainWindow.xaml— Tools menu: Plugin Monitoring entry added;PluginMonitoringPaneldock item registeredSolutionExplorerPanel— toolbar layout polish; drag-drop from Windows Explorer refined- Plugin
.csprojSDK manifest metadata (PluginId,PluginVersion,PluginEntryPoint, …) updated and bumped across all 7 first-party plugin packages MainWindow—SetActiveEditornow called only on hex editor tab activation; non-hex tabs (Code, JSON, TBL…) no longer reset the active editor reference, keeping panels connectedPluginManagerControl— tab hover / selected theming aligned with all 8 global themes;RelayCommandwired to enable/disable/uninstall toolbar actions; list item foreground driven byDockMenuForegroundBrush
✨ Added — Output Service
OutputPanel.GetRecentLinesFromSource(source, count)— returns the last N lines from a specific source channel as plain stringsOutputPanel.ActiveSource— exposes the currently selected source channel nameOutputLogger.GetRecentLines(count)— reads recent lines from the active source; thread-safe viaDispatcher.InvokeOutputServiceImpl.GetRecentLines()— fully wired (was aTODOstub returning empty list)
✨ Added — Format Definitions
- Source code format definitions (
Programming/SourceCode/) —.whfmtfiles for Shell, Bash, PowerShell, Batch, and related scripting formats; extends the 427-entry embedded format catalog
🐛 Fixed
PermissionService—PermissionChangedEventArgsobject-initializer form; missingSystem.IOusingPluginManifestValidator— constructor signature andresult.IsValid(was!result.HasErrors)SolutionExplorerPanel— CS0136 variable scope collision inOnTreeDragOverHexEditor.Events.cs — EnsurePositionVisibleDOWN scroll: replaced centering formula (lineNumber - visibleLines/2) withLastVisibleBytePosition-based edge trigger; scroll now advances exactly 1 line per arrow-down keypress at viewport bottom;VerticalScroll.Valuesynced in all scroll pathsImageViewer—FileShare.ReadWrite(wasRead) allows concurrent access when HexEditor has the same file open; eliminatesIOExceptionon dual openMainWindow— panels (ParsedFields, DataInspector, Properties…) now auto-refresh on file open; panel refresh dispatched non-blocking viaDispatcher.InvokeAsync(DispatcherPriority.Background)PluginMonitoringPanel/TerminalPanel— panels showed placeholder on layout restore;BuildContentForItemnow routesTerminalPanelContentIdandPluginMonitorContentIdto their factories;DataContextwired via deferredDispatcher.InvokeAsyncafterInitializePluginSystemAsyncWelcomePanel—## What's Nextroadmap section was silently dropped by the changelog parser (regex required## [Label]brackets); special-cased before regex; rendered as distinct purple roadmap block, never counted againstMaxVersionsDisplayed- VisualStudio theme —
PM_*brush keys corrected to match VS2022 palette; theme file was referencing wrong color tokens BinaryAnalysisPanelremoved from solution (replaced by ParsedFields plugin); dangling project reference cleaned up
🐛 Fixed — DataInspector — ActiveView Scope + SDK Viewport API (2026-03-08) — Issue #171
- DataInspector not reactive to viewport scroll — Added
ActiveViewas a thirdDataScopevalue. The panel subscribes toIHexEditorService.ViewportScrolledwhen active, with a_viewportRefreshPendingcoalescing flag to prevent Dispatcher flooding during fast scroll._wholeFileChartLoadedflag prevents full-file reload on everySelectionChanged. (Fixes #171) - SDK — viewport API —
IHexEditorServicenow exposeslong FirstVisibleByteOffset,long LastVisibleByteOffset, andevent EventHandler ViewportScrolled.HexEditorServiceImplsubscribes toHexEditor.VerticalScrollBarChangedand forwards it viaViewportScrolled. - Chart position configurable — Toolbar combo (Left / Right / Top / Bottom) persisted in
DataInspectorOptions.RebuildLayout(ChartPosition)dynamically reconfiguresMainAreaGridrow/column definitions andGridattached properties onChartContainer,ChartSplitter, andListContainer. - Files:
IHexEditorService.cs,HexEditorServiceImpl.cs,DataInspectorPanel.xaml(.cs),DataInspectorOptions.cs,DataInspectorOptionsPage.xaml(.cs),DataInspectorPlugin.cs
🐛 Fixed — Status Bar (2026-03-08) — Issues #168 #169 #172 #173 #174
- File Size missing from IDE status bar —
HexEditor.StatusBarContributornow exposes a_sbFileSizeitem (first position, read-only) reportingVirtualLengthviaFormatFileSize(). Refreshed on every file operation / selection change / mode change viaRaiseHexStatusChanged(). (Fixes #169, #172) - Stale status bar values on tab switch — Added
void RefreshStatusBarItems()toIStatusBarContributor. All editors implement it (HexEditor→RefreshStatusBarItemValues(),TblEditor,CodeEditor,ImageViewer,EmptyStatusBarContributorno-op).OnActiveDocumentChangednow calls it unconditionally.RefreshText.Textcleared when a non-hex editor becomes active. (Fixes #173) - Split-pane focus does not update status bar —
StoreContent()subscribes toUIElement.IsKeyboardFocusWithinChangedfor all non-panel content. On focus-enter,SyncStatusBarToFocusedEditor(contentId)performs a lightweight sync (updatesActiveDocumentEditor,ActiveStatusBarContributor, callsRefreshStatusBarItems()+SyncActiveDocument()). Skips if the same contributor/editor is already active. (Fixes #168, #174) - Files:
IStatusBarContributor.cs,HexEditor.StatusBarContributor.cs,MainWindow.xaml.cs,TblEditor.xaml.cs,CodeEditor.cs,ImageViewer.xaml.cs - Commit:
05c19630
🐛 Fixed — Docking (2026-03-08) — Issue #170
- Outer/root-level dock support —
DockEngine.DockAtRoot(item, direction)wrapsLayout.RootNodeentirely viaWrapWithSplit(), creating true full-width/height panels outside all side panels (like VS outer dock targets).DockEdgeOverlayWindowrewritten with dual indicator sets: outer (36 px, at window edge → root-level) and inner (28 px, at document host → existing behaviour).HitTestEx()returns(Direction, IsOuter).DockDragManageruses_isOuterEdgeDropflag andComputeInnerBoundsInCenterHost()to routeOnFloatingMouseUptoDockAtRoot()when outer. (Fixes #170) - Drop preview mismatch — Inner hits now snap preview to
DocumentTabHostbounds; outer hits snap toCenterHostbounds, matching the actual panel width created. - Files:
DockEngine.cs,DockEdgeOverlayWindow.cs,DockDragManager.cs
🐛 Fixed — Reset Layout / DockingAdapter (2026-03-08)
- Open documents lost after Reset Layout —
OnResetLayoutnow snapshots opendoc-*DockItems before callingSetupDefaultLayout()and re-docks them after._contentCache.Clear()removed from the reset path to preserve editor instances. - Plugin menus broken after Reset / Load Layout —
DockingAdapterfields (_engine,_layout) made non-readonly;_allKnownPanelsdict tracks every registered panel. NewRebindLayout(engine, layout)updates refs and re-defers panels absent from the new layout.ApplyLayout()calls_dockingAdapter?.RebindLayout(...)after every layout change. - Files:
DockingAdapter.cs,MainWindow.PluginSystem.cs,MainWindow.xaml.cs
✨ Added — Document Lifecycle Service (2026-03-08)
DocumentModel— observable per-tab state:Title,IsDirty,CanUndo,CanRedo,IsBusy,IsReadOnly,IsActive. WiresIDocumentEditorevents → properties viaAttachEditor/DetachEditor.IDocumentManager/DocumentManager— central document registry:Register,Unregister,AttachEditor,SetActive,GetDirty; typed events:DocumentRegistered,DocumentUnregistered,ActiveDocumentChanged,DocumentDirtyChanged,DocumentTitleChanged.MainWindow.DocumentModel.cs—InitDocumentManager(),RegisterDocumentFromItem(),UnregisterDocument(),SyncActiveDocument(); routesDocumentTitleChanged→DockItem.Title;DocumentDirtyChanged→CommandManager.InvalidateRequerySuggested().CollectAllDirtyItemsnow queries_documentManager.GetDirty()(O(n) over models) instead of walking the layout tree.- Files:
DocumentModel.cs,IDocumentManager.cs,DocumentManager.cs,MainWindow.DocumentModel.cs,MainWindow.xaml.cs
🐛 Fixed — Plugin Monitor: metrics always 0 for event-driven plugins (2026-03-08) — Issue #176
- Root cause —
Diagnostics.Record(nonZeroTime)was only called during Init / Shutdown / Reload. The periodic 5 s sampling tick passedTimeSpan.Zero.AverageExecutionTimeexplicitly filters zero-duration samples, so all plugins hadavgMs = 0after startup except Archive Structure (4.2 ms init). After the previous weight-formula fix, plugins withavgMs = 0receivedweight = 0— correct math, wrong observable result: actively working plugins (e.g. Data Inspector analysing a 2 MB file) displayed 0% CPU / 0 MB RAM. TimedHexEditorService(new) — Proxy/Decorator overIHexEditorService. Intercepts the add accessors of all 5 events (SelectionChanged,ViewportScrolled,FileOpened,FormatDetected,ActiveEditorChanged). Times each plugin's handler invocation viaStopwatchand records the elapsed time toPluginDiagnosticsCollector. After a few selection changes the plugin accumulates non-zeroavgMsand receives a proportional CPU/RAM share in the Plugin Monitor.PluginScopedContext(new) — LightweightIIDEHostContextDecorator created once per plugin. SubstitutesHexEditorwith the timed proxy; all other 10 services delegate to the shared base context.WpfPluginHost.LoadPluginAsync— now createsTimedHexEditorService+PluginScopedContextper plugin and passespluginContexttoInitializeAsyncinstead of the shared_hostContext.PluginAlertEngine— AddedStartupGracePeriod(30 s). Alerts suppressed whileUptime < 30s, eliminating false "CPU 100% exceeds threshold 50%" alerts fired for every plugin during batch init.- Files:
TimedHexEditorService.cs(new),PluginScopedContext.cs(new),WpfPluginHost.cs,PluginAlertEngine.cs - Commit:
5c75f60c
🐛 Fixed — Plugin Monitor (2026-03-08) ⚠️ Partial — #175 still open
- Sparklines not updating —
PluginMonitorRow.MiniChartis now a proper observable property (backing field +OnPropertyChanged()). Row pre-assignsMiniChartbeforeRows.Add()to avoid null-binding on initial render. - CPU reading reflects idle process CPU, not startup spike —
WpfPluginHostadded_lastSampledCpuPercentfield updated exclusively inOnSamplingTick;PluginMonitoringViewModel.Refresh()reads_host.LastSampledCpuPercentinstead of per-plugin ring-buffer first sample (which captured the ~100% startup spike). - Initial events not shown —
_dispatcherstored in VM constructor;AddEvent()guards mutations with_dispatcher.CheckAccess();SynthesizeInitialLoadEvents()called at construction to replay already-loaded plugin events. - Weight fallback incorrectly distributes metrics — Partial fix applied in
50f800ca: non-loaded plugins → weight = 0;sumExecMs > 0 && avgMs = 0→ weight = 0;sumExecMs = 0→ equal share. Issue #175 remains open — further investigation needed for metric attribution accuracy under real multi-plugin load. - Files:
PluginMonitoringViewModel.cs,WpfPluginHost.cs
[0.3.0 cont.] — 2026-03 — IDE & Project System
✨ Added — Project System
- Solution & Project management (
.whsln/.whprojformats) withSolutionManagersingleton - Virtual & physical folders in Solution Explorer —
PhysicalFolderNodeVm,PhysicalFileNodeVm - Show All Files mode — scans disk recursively and shows untracked files at 45% opacity
- Format versioning pipeline —
IFormatMigrator+MigrationPipeline(current version: 2) - V1→V2 format migration — in-memory only, file never modified automatically
- Atomic upgrade —
UpgradeFormatAsynccreates.v{N}.bakbackups before writing - Read-only format mode —
ISolution.IsReadOnlyFormatblocks saves on unupgraded files - File templates — Binary, TBL, JSON, Text with
FileTemplateRegistry IEditorPersistableinterface — bookmarks, scroll, caret, encoding restored per fileIItemLink— typed links between project items (e.g..bin↔.tbl)
✨ Added — IDE Panels
- Error Panel (
IErrorPanel) — VS-style diagnostics panel with severity filtering and navigation IDiagnosticSourceinterface — any editor can push diagnostics to the Error Panel- JsonEditor diagnostics — real-time JSON validation errors forwarded to Error Panel
- TblEditor diagnostics — validation errors forwarded to Error Panel
ERR_*theme keys — Error Panel colors in all 8 themes
✨ Added — Search
- QuickSearchBar — inline Ctrl+F overlay (VSCode-style), no dialog popup
- Ctrl+Shift+F → opens full AdvancedSearchDialog (5 search modes)
- "⋯" button in QuickSearchBar — closes bar and opens AdvancedSearchDialog
✨ Added — IDE
- WelcomePanel — VS Start Page-style welcome document shown on IDE launch (
doc-welcomeContentId)- Quick Actions: New File, Open File, Open Project / Solution, Options
- Recent Files & Recent Projects filtered to physically existing paths only (deleted entries hidden)
- Live changelog fetched from GitHub (
raw.githubusercontent.com) — loading state + offline fallback - Resources section: GitHub Repository + Report an Issue buttons (opens default browser)
- App
Logo.icodisplayed in header - Full theme compliance via existing
DockBackgroundBrush/DockTabActiveBrush/DockMenuForegroundBrushkeys - Fix:
Loaded -= OnLoadedprevents dialog-loop caused by Click-handler accumulation on docking re-attach
✨ Added — Themes & UI
PanelCommon.xaml— shared panel toolbar styles (30px VS-style toolbar, Segoe MDL2 icon buttons)Panel_*theme keys —ToolbarBrush,ToolbarBorderBrush,ToolbarButtonHoverBrush, etc. in all 8 themes- ParsedFieldsPanel refactored to VS-style toolbar (draggable title bar removed)
PFP_*theme keys — ParsedFieldsPanel colors in all 8 themes
✨ Added — Docking
- Tab colorization — per-tab custom color with
TabSettingsDialog - Left / right tab strip placement — configurable per dock group
TabSettingsDialog— color picker + placement selector
✨ Added — HexEditor API
LoadTBL(string)public API — load a TBL file programmatically- Auto-apply project TBL — when a
.binis opened and its project has a linked.tbl, it is applied automatically TblEditorRequestedevent — opens TBL Editor without circular reference (Core→TblEditor)
🔧 Changed
SolutionExplorermoved toWpfHexEditor.Panels.IDE(wasWpfHexEditor.WindowPanels)ParsedFieldsPanel—TitleBarDragStartedevent removed; docking system handles floating- App status bar — HexEditor internal status bar hidden (
ShowStatusBar = false); App owns the status bar
[2.7.0] — 2026-02 — IDE Application & Editor Plugin System
✨ Added — WpfHexEditor.App
- Full IDE application with VS-style docking (
WpfHexEditor.Docking.Wpf) IDocumentEditorplugin contract — Undo, Redo, Copy, Cut, Paste, Save, IsDirty, IsReadOnlyEditorRegistry— plugin registration at startup (EditorRegistry.Instance.Register(...))- Content factory with cache —
Dictionary<string, UIElement>keyed byContentId ActiveDocumentEditorINPC property — drives Edit menu bindingsActiveHexEditorINPC property — drives status bar DataContext- VS2022-style status bar — left: editor status messages · center: EditMode + BytePerLine · right: panel count
- Auto-sync via
DockHost.ActiveItemChanged→ connects/disconnects ParsedFieldsPanel per active tab
✨ Added — Editors
- TBL Editor (
WpfHexEditor.Editor.TblEditor) — standaloneTblEditorControl, implementsIDocumentEditor- Virtualized DataGrid, inline Ctrl+F search overlay, status bar
TblExportService.ExportToTblFile()for save/export
- JSON Editor (
WpfHexEditor.Editor.JsonEditor) — implementsIDocumentEditor+IDiagnosticSource- Real-time validation,
PerformValidation(),EnableValidationtoggle
- Real-time validation,
- Text Editor (
WpfHexEditor.Editor.TextEditor) — implementsIDocumentEditor+IEditorPersistable- Caret/scroll persistence (1-based in DTO, 0-based in VM)
✨ Added — Panels
- ParsedFieldsPanel singleton — auto-connects to active HexEditor via
IParsedFieldsPanelinterface - DataInspectorPanel — 40+ byte type interpretations at caret
- SolutionExplorerPanel — hierarchical VM tree,
ISolutionExplorerPanel - PropertiesPanel — context-aware F4 panel via
IPropertyProvider/IPropertiesPanel
✨ Added — HexEditor IDocumentEditor
HexEditorimplementsIDocumentEditorviaHexEditor.DocumentEditor.csRaiseHexStatusChanged()— firesStatusMessageafter load, edit mode change, bytes-per-line changeIDiagnosticSourceimplementation — exposesHexEditor.DiagnosticSource.csIEditorPersistableimplementation — bookmarks, scroll, caret, encoding, edit mode
🔧 Changed — Docking Engine
CreateTabControl— allDockGroupNodepanels always get title bar +TabStripPlacement = Dock.BottomFloatGroup()—GroupFloatedevent fires beforeLayoutChanged(prevents duplicate windows)FindWindowForItem— checks both active item and non-active group itemsRestoreFloatingWindows()— called byRebuildVisualTree()for persisted float positionsFloatLeft / FloatTop / LastDockSideserialized inDockItemDto
[2.6.0] — 2026-02-22 — V1 Legacy Removal & Multi-Byte Fixes
🚨 Breaking — V1 Legacy Removed
Complete removal of Legacy V1 code after 12-month deprecation period:
HexEditorLegacy.xaml/.cs(6,521 LOC)ByteProviderLegacy.cs(1,890 LOC)- 6 legacy sample projects (5,079 LOC)
- V1 rendering classes:
BaseByte,HexByte,StringByte,FastTextLine(2,051 LOC) - V1 search dialogs:
FindWindow,FindReplaceWindow
Total removed: 17,093 lines of code (-30% codebase)
CompatibilityLayer (725 LOC) is kept for API backward compatibility — zero migration required.
🐛 Fixed — Multi-Byte Mode (ByteSize 16/32)
- Click positioning in Bit16/32 modes for both hex and ASCII panels
- Keyboard navigation left/right in multi-byte modes
- Unified hit testing via single
HitTestByteWithAreamethod (click, mouseover, drag, auto-scroll) - ASCII mouseover alignment in multi-byte modes
GetDisplayCharacter— returns all bytes in multi-byte groups (e.g."MZ"instead of"M")GetCharacterDisplayWidth— FormattedText measurement for pixel-perfect alignment- ByteOrder setting respected in ASCII panel (HiLo/LoHi)
- TBL hex key building in multi-byte mode uses
Values[]array
✨ Added
RestoreOriginalByte(long)— restore a single modified byte to its original valueRestoreOriginalBytes(long[])/RestoreOriginalBytes(IEnumerable<long>)— batch restoreRestoreOriginalBytesInRange(long, long)— restore a contiguous rangeRestoreAllModifications()— clear all modifications at once- Full Undo/Redo integration for restore operations
- Category localization
CategoryKeyboardMouseadded to all 19 language files
[2.5.0] — 2026-02-14 — Critical Bug Fixes & V2 Architecture
🐛 Fixed — Critical
Issue #145 — Insert Mode Hex Input ✅
- Typing consecutive hex chars in Insert Mode now works:
FFFFFFFF→FF FF FF FF(wasF0 F0 F0 F0) - Root cause:
PositionMapper.PhysicalToVirtual()returned wrong position for inserted bytes - Files:
PositionMapper.cs,ByteReader.cs,ByteProvider.cs
Save Data Loss Bug ✅
- Catastrophic data loss (MB → KB file corruption) fully resolved
- Same PositionMapper bug caused
ByteReaderto read wrong bytes during save - Fast save path added for modification-only edits (10-100x faster)
🚀 Performance
- 10-100x faster save — debug logging overhead removed from all production paths
- Fast save path — modification-only edits bypass full virtual read
🏗️ Architecture
- MVVM + 16 specialized services
- Extracted 2,500+ lines of business logic into services
- 80+ unit tests (xUnit, .NET 8.0-windows)
[2.2.0] — 2026-01 — Search Performance & Service Architecture
🚀 Performance
- LRU Search Cache — 10-100x faster repeated searches, O(1) lookup, auto-invalidation at all 11 modification points
- Parallel Multi-Core Search — 2-4x faster for files > 100MB, automatic threshold
- SIMD Vectorization (net5.0+) — AVX2/SSE2, 4-8x faster single-byte search, processes 32 bytes/cycle
- Span<T> + ArrayPool — 2-5x faster, 90% less memory allocation
- Profile-Guided Optimization (.NET 8.0+) — 10-30% CPU boost, 30-50% faster startup
🏗️ Architecture — Service Layer (10 Services)
ClipboardService · FindReplaceService · UndoRedoService · SelectionService · HighlightService · ByteModificationService · BookmarkService · TblService · PositionService · CustomBackgroundService
🧪 Testing
- 80+ unit tests:
SelectionServiceTests(35),FindReplaceServiceTests(35),HighlightServiceTests(10+)
[2.1.0] — 2025 — V2 Rendering Engine
✨ Added
HexEditorV2control with customDrawingContextrendering- MVVM architecture with
HexEditorViewModel - True Insert Mode with virtual position mapping
- Custom background blocks for byte range highlighting
- BarChart visualization mode
🚀 Performance
- Rendering: 99% faster vs V1 (DrawingContext vs ItemsControl)
- Memory: 80-90% reduction
[2.0.0] — 2024 — Multi-Targeting & Async
✨ Added
- .NET 8.0-windows support
- Multi-targeting: .NET Framework 4.8 + .NET 8.0-windows
- Async file operations with progress and cancellation
- C# 12 / 13 language features
[1.x] — 2023 and earlier
Legacy V1 monolithic architecture. See GitHub Releases for historical notes.
V1 NuGet package (WPFHexaEditor) remains available for existing users but is no longer maintained. See Migration Guide.
Legend
| Icon | Meaning |
|---|---|
| 🚀 | Performance improvement |
| 🐛 | Bug fix |
| ✨ | New feature |
| 🔧 | Internal change / refactor |
| 🏗️ | Architecture change |
| 🧪 | Testing |
| 🚨 | Breaking change |