Skip to content

About

Drei-Panel-Desktop-App (WPF/.NET 10) zum Erkunden, Durchsuchen und Bearbeiten großer Markdown-Bestände: Volltext-Suche (SQLite FTS5), WebView2-Vorschau, Markdown-Editor mit Tag-Verwaltung, WikiLink-Graph, Tag-Cloud und eingebaute Selbstaktualisierung

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Repository files navigation

MdExplorer

CI License: MIT .NET 10

Ein Ordner voller Markdown-Notizen wird ab einer gewissen Größe unübersichtlich: Man weiß noch, dass etwas notiert wurde, aber nicht mehr, wo — und schon gar nicht, welche Notiz mit welcher zusammenhängt. MdExplorer indexiert solche Bestände und macht sie erkundbar: Volltextsuche über alles, Schlagwörter projektweit pflegbar, die Verweise zwischen den Notizen als Graph und eine Vorschau, in der sich jede Datei direkt bearbeiten lässt.

Alles läuft lokal. Kein Konto, kein Server, keine Cloud: Der Suchindex liegt in einer SQLite-Datenbank im Anwendungsordner, die Notizen bleiben, wo sie sind, und ohne Internetverbindung funktioniert die Anwendung vollständig.

Windows-Desktop-Anwendung, gebaut mit WPF auf .NET 10, Drei-Panel-Oberfläche mit Datei-Browser, Suche und HTML-Vorschau auf Basis von WebView2. MIT-Lizenz.

Oberfläche

Volltextsuche mit Trefferstellen und Vorschau:

Suche über den gesamten Bestand

Alle Dateien mit Kennzeichnung, Zeitraum-Filter und Änderungsdatum:

Liste aller Dateien

Verweise zwischen den Notizen als Graph:

Graph der Verweise

Kennzeichnungen umbenennen, zusammenführen oder löschen:

Verwaltung der Kennzeichnungen

Voraussetzungen

Zum Benutzen: Windows und die WebView2-Runtime, die auf aktuellen Windows-Installationen bereits vorhanden ist. Sonst nichts — SQLite bringt die Anwendung über das Paket Microsoft.Data.Sqlite selbst mit.

Zum Bauen: zusätzlich das .NET 10 SDK.

Installation

Fertige Fassungen liegen auf der Releases-Seite: ein Windows-Installer samt SHA-256-Prüfsumme und ein Archiv zum Entpacken. Das Archiv läuft aus jedem beliebigen Ordner, ohne Installation.

Der Installer ist nicht signiert — Windows zeigt beim ersten Start deshalb eine Warnung, die sich über „Weitere Informationen" übergehen lässt.

Die Fassung trägt noch eine Null vor dem Punkt, und das ist eine Aussage: Die Anwendung tut, was sie soll, und ist täglich im Einsatz, aber Einstellungen, Datenbankformat und Bedienung sind nicht eingefroren. Eine spätere Fassung darf Dinge anders machen.

Aus dem Quelltext bauen

git clone https://github.com/ReneSchustek/mdExplorer.git MdExplorer
cd MdExplorer
dotnet restore MdExplorer.slnx

Entwicklung

dotnet build MdExplorer.slnx -c Release
dotnet test  MdExplorer.slnx
dotnet run   --project MdExplorer.App

Statische Analyse

Produktivprojekte ziehen StyleCop.Analyzers und SonarAnalyzer.CSharp zentral über Directory.Build.props ein; Tests bleiben ausgenommen. Der Build läuft mit TreatWarningsAsErrors=true — jede StyleCop- oder Sonar-Meldung bricht den Build. Regelwerk: stylecop.json und der StyleCop/Sonar-Abschnitt in .editorconfig.

dotnet build MdExplorer.slnx -warnaserror

liefert bei sauberem Stand 0 Warnungen / 0 Fehler.

Vollständige Anleitung: docs/HANDBUCH.md.

Projektstruktur

Produktivcode liegt unter src/, die Tests spiegeln ihn unter tests/.

Projekt Inhalt
src/MdExplorer.App WPF-Frontend (MVVM, WebView2-Preview, Settings-Dialog)
src/MdExplorer.Core Abstraktionen, Pfade, IFileSystem, Settings-Modell
src/MdExplorer.Data EF Core / SQLite, Repositories, Migrations
src/MdExplorer.Indexer Datei-Scan, FileSystemWatcher, Hash-Pipeline
src/MdExplorer.Parser Markdig-basierter Parser mit WikiLink-Erweiterung
src/MdExplorer.Search FTS5-Suche über SQLite
src/MdExplorer.Graph WikiLink-Graph (Snapshot + Canvas-Renderer)
src/MdExplorer.TagCloud Tag-Cloud-UserControl + Hintergrund-Refresh
src/MdExplorer.Update Prüfung auf neue Fassungen und deren Installation
tests/*.Tests xUnit-Tests pro Modul
installer/ Inno-Setup-Skript für das Installationsprogramm
tools/ Build- und Sicherheits-Tooling (gitleaks, Secret-Scan)
docs/ Architektur- und Settings-Dokumentation

Eine ausführliche Schichten- und Abhängigkeitsübersicht steht in docs/ARCHITECTURE.md.

Konfiguration

Anwendungsdaten

Datei Pfad Inhalt
settings.json %LOCALAPPDATA%\MdExplorer\settings.json Index-Roots, Ausschluss-Muster, Darstellung, Verhalten
ui-layout.json %LOCALAPPDATA%\MdExplorer\ui-layout.json Spaltenbreiten des Hauptfensters
app.db %LOCALAPPDATA%\MdExplorer\app.db SQLite-Datenbank (FTS5-Suchindex, Tags)
logs\ %LOCALAPPDATA%\MdExplorer\logs\ tägliche Log-Dateien
settings-history\ %LOCALAPPDATA%\MdExplorer\settings-history\ pro Save ein JSON-Snapshot (Retention 30)
settings-audit.log %LOCALAPPDATA%\MdExplorer\settings-audit.log JSON-Lines mit Wann/Snapshot/Diff je Save

Settings-Dialog

Datei → Einstellungen… oder Tastenkürzel Strg+, öffnet einen modalen Dialog mit drei Tabs:

  • Indexierung — Index-Wurzeln, Glob-Ausschluss-Muster (mit !-Negation), Auto-Hashtag-Extraktion
  • Darstellung — Theme (System/Hell/Dunkel), Preview-Schriftgröße, Treffer pro Seite
  • Verhalten — Such-Debounce, Indexer-Resync-Intervall, Update-Prüfung beim Start, Bilder aus dem Netz in der Vorschau

Speichern erfolgt atomar (.tmp + File.Move). Detailliertes Schema und Beispiele: docs/SETTINGS.md.

Die Wahl unter Darstellung gilt für die gesamte Anwendung, auch für die Dokument-Vorschau: Wer „Dunkel" wählt, während Windows hell steht, bekommt eine durchgehend dunkle Oberfläche. Der Wechsel wirkt sofort, ohne Neustart.

Folder-Tree und Indexierung pausieren

Im Tab „Ordner" zeigt das Folder-Tree die konfigurierten Index-Wurzeln. Rechtsklick auf einen Ordner öffnet ein Kontextmenü:

  • Indexierung pausieren — fügt den Ordner zu Indexing.UiExcludedFolders in der settings.json hinzu. Der Ordner und seine Inhalte werden ab dem nächsten Indexer-Lauf übersprungen; im Tree bleibt der Knoten ausgegraut sichtbar (Pause-Icon).
  • Indexierung wieder aufnehmen — entfernt den Pfad aus der Liste. Der nächste Indexer-Lauf nimmt die Dateien wieder auf.

Die Pause-Liste persistiert beim Neustart und wirkt additiv zu den Glob-ExclusionPatterns und .mdignore-Dateien.

Bedienung

Hauptfenster

Drei-Panel-Layout mit optionaler Tag-Cloud rechts:

  1. Links — Tab „Ordner" (Baum) oder „Alle Dateien" (flache Liste)
  2. Mitte — Suchpanel mit Treffer-Liste
  3. Rechts — Dokument-Panel (Lese-/Bearbeiten-Modus)
  4. Optional ganz rechts — Tag-Cloud (ein-/ausblendbar)

Tastatur-Shortcuts

Shortcut Aktion
Strg+F Suchfeld fokussieren
Esc Sucheingabe leeren
Strg+, Einstellungen öffnen
Strg+E Dokument-Panel zwischen Lesen und Bearbeiten umschalten
Strg+S Aktuelle Markdown-Datei speichern (nur im Bearbeiten-Modus)
F1 Handbuch-Fenster öffnen

Suche

Das Suchpanel in der mittleren Spalte sucht beim Tippen — nach einem konfigurierbaren Debounce feuert die FTS5-Volltextsuche automatisch; ein expliziter Such-Button ist nicht nötig. Mehrere Wörter werden mit „UND" verknüpft, "…" sucht Phrasen, wort* als Präfix; die Filter tag:, -tag: und path: schränken auf Metadaten bzw. Pfad-Fragmente ein. Über die Dropdowns lassen sich Modus (FTS5 / Regex) und Ähnlichkeit (None / Stemmed / NearStem / NearStemSynonyms) umschalten.

Das Kontrollkästchen „Nur aktueller Ordner" steuert den Such-Scope: ohne Haken (Default) wird global über alle Index-Wurzeln gesucht; mit Haken werden die Treffer auf den im Ordnerbaum gewählten Pfad und dessen Unterordner beschränkt. Die Wurzel selbst zu wählen hebt die Einschränkung wieder auf. Umschalten löst die Suche sofort neu aus.

Bleibt die Trefferliste leer, benennt sie den Grund: „Noch nichts gesucht" vor der ersten Eingabe, „Nichts gefunden" bei einer Anfrage ohne Treffer und „Die Suche ist gescheitert", wenn die Abfrage selbst fehlgeschlagen ist. Die drei Lagen sehen gleich aus und brauchen verschiedene Antworten.

Alle Dateien — Suchfeld, Filter und Sprungleiste

Der Tab „Alle Dateien" filtert beim Tippen über Titel, Pfad und Kennzeichnungen; Escape leert das Feld. Über die Umschalter „Alle", „Heute", „7 Tage" und „30 Tage" lässt sich nach der letzten Änderung einschränken. Ein Klick auf den Pfad eines Eintrags schränkt auf dessen Ordner ein, ein Klick auf eine Kennzeichnung auf diese; mehrere Einschränkungen wirken zusammen. Jede aktive Einschränkung steht als Merkzettel über der Liste und ist dort einzeln abnehmbar.

Nach Titel oder Pfad sortiert erscheint ab 50 sichtbaren Einträgen die Sprungleiste A B C … Z #. Sie rollt zur jeweiligen Gruppe, ohne zu filtern; Buchstaben ohne Einträge bleiben stehen und sind abgeblendet. Die Liste ist nach denselben Buchstaben sichtbar gruppiert. Nach Datum sortiert entfallen Gruppen und Leiste.

Zusammenhänge am Dokument

Unter dem geöffneten Dokument steht, was daran hängt: auf welche Dokumente es verweist, welche auf es verweisen, in welchem Ordner es liegt und welche Kennzeichnungen es trägt. Jeder Eintrag führt weiter — ein verwandtes Dokument wird geöffnet, Ordner und Kennzeichnung führen in die Suche mit der passenden Einschränkung.

Im selben Bereich lässt sich die Datei umbenennen, verschieben und löschen, ohne den Zusammenhang zu verlassen. Vor dem Löschen und vor einer Umbenennung, die Verweise bricht, nennt die Rückfrage die Folgen: wie viele Dokumente danach ins Leere zeigen. Ein Verschieben lässt die Verweise unberührt, weil ein WikiLink auf den Dateinamen zeigt und nicht auf den Pfad — dort wird deshalb nicht gefragt.

Markdown-Editor

Im rechten Panel lässt sich jede .md-Datei direkt bearbeiten. Die Mode-Umschaltung erfolgt über den Toolbar-Button „Bearbeiten" oder Strg+E. Im Edit-Modus zeigt eine Monospace-TextBox den Rohtext; die Tag-Leiste oben aktualisiert sich live nach 300 ms Debounce. Tags lassen sich manuell hinzufügen, entfernen oder umbenennen — neue Tags werden in einem verwalteten Kommentar-Block <!-- mdexplorer-tags: #a #b --> am Dateiende gepflegt. Strg+S speichert atomar (Temp-Datei + File.Move); das ursprüngliche Zeilenende (CRLF/LF) bleibt erhalten. Externe Änderungen während einer Edit-Session werden vor dem Schreiben erkannt und blockieren das Speichern bis zur manuellen Auflösung.

Schreibschutz (Default): Jede frisch geladene Datei ist gegen versehentliches Editieren gesperrt — Tippen, Tag-Hinzufügen, Tag- Entfernen und Strg+S bleiben wirkungslos. Der Button „🔒 Entsperren" in der Editor-Toolbar gibt die Datei zum Bearbeiten frei; „🔓 Sperren" schließt sie wieder ab.

Direct-Load: Klickt der Nutzer auf eine .md-Datei, die der Indexer noch nicht erfasst hat (Erstkonfiguration, sehr große Roots), lädt der Editor sie direkt vom Dateisystem statt den Klick zu ignorieren. Die Preview rendert sofort; Speichern bleibt gesperrt, bis der Indexer-Lauf die Datei erfasst hat.

Tag-Cloud

Ansicht → Tag-Cloud blendet das rechte Panel ein. Es zeigt die häufigsten Tags mit logarithmisch skalierter Schriftgröße. Klick setzt das Suchfeld auf tag:<slug> und triggert eine Suche; Strg ergänzt additiv, Alt exkludiert (-tag:<slug>). Sortierreihenfolge (Häufigkeit / Alphabetisch / Zuletzt verwendet) und Long-Tail-Modus lassen sich in der Panel-Kopfzeile umschalten.

Tag-Verwaltung

Ansicht → Tag-Verwaltung… öffnet einen modalen Dialog, der alle Tags mit Anzahl betroffener Dateien auflistet. Pro Auswahl:

  • Umbenennen — alle Vorkommen #alt werden zu #neu (Body + YAML-Frontmatter tags-Listen).
  • Zusammenführen — der Quell-Tag verschwindet; sein Vorkommen wird durch den Ziel-Tag ersetzt. Duplikate im Frontmatter entfernt der Dialog automatisch.
  • Löschen — sämtliche Vorkommen werden aus Body und Frontmatter entfernt.

Vor jeder Operation zeigt ein Bestätigungsdialog die Anzahl betroffener Dateien und die ersten zehn Pfade. Dateien werden atomar geschrieben; der FileSystemWatcher triggert anschließend automatisch den Re-Index.

Indexer-Fortschritt während des ersten Scans

Auf großen Wurzeln (mehrere Tausend .md-Dateien) committed der Indexer den Initial-Scan in Batches: nach jeweils Indexer.InitialScanBatchSize Dateien (Default 100) erfolgt ein Zwischen-SaveChanges. Der „Alle Dateien"-Tab und der Folder-Tree aktualisieren sich nach jedem Batch automatisch — der Tab bleibt nicht mehr leer, bis der gesamte Scan durch ist.

Betriebs-Status (Health-LED)

Links in der Statusleiste sitzt eine LED, die den aggregierten Betriebs-Status zeigt: grün = normal, gelb = Warnungen im jüngsten Log-Fenster, rot = Fehler oder Critical-Einträge. Der ToolTip zeigt den Grund (Anzahl + letzte Meldung). Klick auf die LED öffnet direkt den Live-Log-Viewer.

Gibt es Dateien, die nicht verarbeitet werden können, nennt der ToolTip zusätzlich deren Anzahl („3 Dateien nicht verarbeitbar.") und die LED steht mindestens auf Gelb — auch dann, wenn im Log-Fenster längst nichts mehr dazu steht.

Dateien, die nicht verarbeitet werden können

Manche Markdown-Dateien lassen sich nicht auswerten, etwa weil sie zu tief verschachtelt sind oder ihr Frontmatter kaputt ist. Eine solche Datei wird einmal mit vollem Fehlerbericht ins Protokoll geschrieben und danach in Ruhe gelassen — sie bekommt einen Vermerk mit ihrem Inhalt und der Fassung des Auswerters. Erst wenn sich die Datei ändert oder eine neue Programmfassung läuft, wird es erneut versucht; klappt es dann, verschwindet der Vermerk von selbst. Alle übrigen Dateien werden davon nicht berührt.

Live-Log-Viewer

Ansicht → Logs… öffnet ein eigenes Fenster mit den letzten Log-Einträgen aus dem In-Memory-Ringpuffer (Kapazität 2000). Die Toolbar bietet einen Minimum-Level-Filter (Alle bis Kritisch) und eine Substring-Suche über Nachricht und Quelle. Der „Exportieren…"-Button schreibt die aktuell sichtbaren Einträge als UTF-8-Datei. Der Sink läuft parallel zu File- und Debug-Sink — die Rotation der logs\-Dateien bleibt davon unberührt.

Settings-Audit-Trail

Jede Settings-Änderung erzeugt automatisch zwei Spuren:

  • ein vollständiger JSON-Snapshot unter settings-history\settings.<UTC>.json (Retention 30, älteste werden verworfen)
  • eine JSON-Lines-Zeile in settings-audit.log mit timestamp, snapshot und einem strukturellen changes-Diff (Pfad inkl. Array-Index, alte und neue Werte als JSON-Literal).

Identische Speichervorgänge (gleicher Stand) erzeugen weder Snapshot noch Audit-Eintrag.

WikiLink-Graph

Ansicht → Graph… öffnet ein eigenes Fenster mit dem WikiLink-Graphen des aktuellen Bestands. Knoten sind Markdown-Dateien, Kanten sind [[WikiLink]]-Referenzen aus dem Parser. Der Graph rendert in einer eingebetteten WebView2-Instanz; HTML, JavaScript und CSS sind als Embedded Resources im App-Modul abgelegt — keine externen CDNs, keine Netzwerkverbindung notwendig. Die Content-Security-Policy erzwingt default-src 'none' mit Nonce-basierter Skript-Whitelist.

Update-Hinweis

Beim Start prüft die Anwendung einmal täglich, ob auf GitHub eine neuere Version veröffentlicht wurde (öffentliche Releases-API, ohne Anmeldung). Ist eine neuere Version verfügbar, erscheint oben im Hauptfenster eine dezente, schließbare Hinweisleiste mit Link auf die Release-Seite — es wird nichts automatisch heruntergeladen oder installiert. Die Prüfung lässt sich unter Datei → Einstellungen… → Verhalten mit „Beim Start nach Updates suchen" abschalten; ohne Netzverbindung verhält sich die Anwendung unverändert.

Lizenz

Veröffentlicht unter der MIT-Lizenz — © 2026 Rene Schustek.

About

Drei-Panel-Desktop-App (WPF/.NET 10) zum Erkunden, Durchsuchen und Bearbeiten großer Markdown-Bestände: Volltext-Suche (SQLite FTS5), WebView2-Vorschau, Markdown-Editor mit Tag-Verwaltung, WikiLink-Graph, Tag-Cloud und eingebaute Selbstaktualisierung

Topics

Resources

Stars

0 stars

Watchers

0 watching

Forks

Releases

Packages

Used by

Contributors

Languages