8 Punkte von GN⁺ 2026-03-12 | 5 Kommentare | Auf WhatsApp teilen
  • Wegen der Grenzen des bisherigen Howl-Editors (eingestellte Entwicklung, langsame Suche, keine SSH-Kompatibilität, keine Terminal-Unterstützung) wurde ein neuer TUI-Texteditor selbst entwickelt
  • 13 Editoren wie Helix, VS Code, Vim, Neovim und Emacs wurden ausprobiert, aber keiner erfüllte das gewünschte Bediengefühl (Fingerspitzengefühl)
  • Anfangs wurden nur minimal notwendige, persönliche Funktionen umgesetzt; Performance, Unicode- und Mehrsprachen-Support wurden nachrangig behandelt und schrittweise ausgebaut
  • Im Entwicklungsprozess wurden unter anderem eine eigene Regex-Engine, ein Dateibrowser, TUI-basiertes Rendering und die Integration eines Terminal-Buffers selbst implementiert
  • Für projektweite Suche, Syntax-Highlighting, Caching und die Verteilung von Arbeit über mehrere Threads hinweg wurden zahlreiche Techniken zur Performance-Optimierung eingesetzt
  • Am Ende entstand ein Werkzeug, das perfekt zum eigenen Workflow passt und laut Autor Produktivität und Freude am Programmieren zurückgebracht hat

Grenzen bestehender Editoren und die Suche nach Alternativen

  • Die Probleme des etwa 10 Jahre lang genutzten Howl-Editors waren der Auslöser für die Eigenentwicklung
    • Die Entwicklung war seit Jahren eingestellt; ein eigener Fork wurde gepflegt, doch tiefgreifende Änderungen waren schwierig, da er in MoonScript geschrieben ist
    • Die Dateisuche über das gesamte Projekt war zu langsam und unterbrach den Arbeitsfluss
    • Als GUI-Editor war die Nutzung über SSH für Remote-Arbeit nicht möglich
    • Es gab kein integriertes Terminal, daher war bei externen Befehlen keine Live-Interaktion möglich, und die meisten ANSI-Escape-Codes wurden nicht unterstützt
  • 13 Editoren wurden ausprobiert, darunter Helix, VS Code, Sublime Text, Vim, Zed, Neovim, Emacs, Geany, Micro, Lite XL, Lapce, GNOME Builder und Kakoune
    • Jeder hatte eigene Stärken, erfüllte aber nicht das gewünschte Bediengefühl (Fingerspitzengefühl)
    • Helix wurde am längsten genutzt, verlor aber nach einem Monat seinen Reiz

Frühe Entwicklungsstrategie

  • Zu Beginn wurde der Umfang bewusst minimal gehalten
    • Funktionen für andere Nutzer wurden ausgeschlossen, sämtliche Konfigurationen hartcodiert
    • Performance-Optimierung wurde aufgeschoben und zunächst mit einem String-basierten Buffer gearbeitet
    • Vollständige Unterstützung von Unicode-Graphemen wurde weggelassen; es genügte, wenn das Symbol £ eine einzelne Spalte belegte
    • Syntax-Highlighting unterstützte nur wenige häufig genutzte Sprachen; für den Rest wurde generisches delimiter-basiertes Highlighting verwendet
  • Im zweiten Anlauf wurde zunächst ein einfaches TUI-Framework gebaut, das später größtenteils wieder entfernt und durch einen direkteren, feineren Ansatz ersetzt wurde

Dogfooding in der Praxis

  • Nachdem der Editor den minimalen Funktionsschwellenwert erreicht hatte, um eine einzelne Datei zu öffnen, zu bearbeiten und zu speichern, wurden drei Praktiken eingeführt
    • Statt nano wurde der eigene Editor verwendet und so zwangsweise eingesetzt, etwa zum Bearbeiten von Systemdateien oder für Notizen
    • Immer wenn fehlende Funktionen, Bugs, seltsames Verhalten oder Grenzen auffielen, wurden sie in der README.md des Projekts dokumentiert
    • Probleme, die wirklich störten, wurden sofort behoben
  • Dadurch stieg der Arbeitsaufwand von etwa einer Stunde im Monat auf mehrere Stunden pro Woche
  • Von insgesamt rund 10.000 Zeilen Code wurde fast alles in den letzten sechs Monaten geschrieben

Cursor-Steuerung

  • Die Cursor-Steuerung ist ein besonders schwer umzusetzender Bereich
    • Tastenkombinationen wie ctrl + shift + left wirken für Nutzer selbstverständlich, sind in der Logik aber komplex
  • Ein zentraler Rat ist, höherwertige Eingaben als Kombination primitiver Operationen zu implementieren
    • Beispiel: Backspace auf Wortebene → Cursorbewegung auf Wortebene + Bereichsauswahl + Löschen
  • Für Undo/Redo müssen diese drei Schritte zu einer einzigen Gruppe zusammengefasst werden, damit das Ergebnis intuitiv bleibt
  • Dadurch wurde verständlich, warum modale Editoren solche primitiven Operationen direkt offenlegen

Dateibrowser

  • Der Dateibrowser von Howl war der entscheidende Grund, warum der Wechsel zu anderen Editoren scheiterte
    • Sein sofort aktualisierter Fuzzy-Filter war so gut, dass meist schon 1–2 Tastenanschläge genügten, um die gewünschte Datei zu finden
    • Wenn die Datei nicht existierte, konnte sie inline erstellt werden
    • Bei Eingabe von ~/ wurde automatisch ins Home-Verzeichnis gewechselt
    • Es gab eine Vorschau der zu öffnenden Datei im Hauptbearbeitungsfenster
  • Kritisiert wurde, dass andere Editoren das Öffnen von Dateien über Mausabhängigkeit, GTK-Standarddialoge oder Dateinamensraten lösen
  • Bei der Eigenimplementierung erwiesen sich statt komplexer Verfahren wie Levenshtein distance drei einfache Kriterien als ausreichend
    • Ob ein Pfad mit dem Filterausdruck beginnt
    • Ob er den Filterausdruck enthält
    • Die zuletzt erfolgte Änderungs- bzw. Zugriffszeit
  • Groß-/Kleinschreibung wird ignoriert, bei exakter Übereinstimmung aber leicht höher gewichtet
  • Selbst in Projekten mit Zehntausenden Dateien liegt die gewünschte Datei nach 2 Tastenanschlägen mit etwa 95 % Wahrscheinlichkeit unter den ersten beiden Treffern

Regex-Engine

  • Regex werden an drei Stellen verwendet: projektweite Suche, Syntax-Highlighting und Suchen im Buffer
  • Statt der bestehenden Crate regex-automata wurde eine eigene Implementierung gewählt
    • Es mussten kontextsensitive Edge Cases wie Rusts Raw-String-Syntax behandelt werden
    • Das Projekt diente auch als Übung, einen eigenen Stack aufzubauen und zu verstehen
  • Die erste Implementierung parste die Regex-Syntax mit der Parsing-Crate chumsky und durchlief den AST bei jedem Zeichen, was langsam war
  • Danach folgten schrittweise Optimierungen
    • Single-Pass-Optimierer: Wiederkehrende Gruppen von Zeichen-Matches wurden in einen einzelnen String-Knoten umgewandelt, um exakte String-Suchen auszuführen
    • Extraktion gemeinsamer Präfixe: Zum Beispiel wird in hel[(lo)p] das gemeinsame Präfix hel erkannt und nur dort gematcht → großer Performance-Gewinn bei projektweiter Suche
    • Der AST-Walker wurde als threaded-code-VM auf Basis dynamischer Rust-Aufrufe neu implementiert
    • Die threaded-code-VM wurde in CPS (Continuation-Passing Style) umgeformt, sodass jede VM-Instruktion die nächste per Tail-Call aufruft und Compiler-Optimierungen nutzen kann
    • Langsame dynamische Funktionsaufrufe in Rust wurden ohne vtable-Lookup gekapselt, sodass der Codegen vieler Regex-Instruktionen auf wenige Maschinenbefehle schrumpfte
    • So viele Regex-Instruktionen wie möglich wurden auf Byte-Ebene statt Unicode-Codepoints umgesetzt; dank des UTF-8-Designs funktionieren ASCII-Optimierungen auch bei Multi-Byte-Codepoints
  • Es wurde auch versucht, in Jump-LUT-Ketten zu kompilieren, aber Benchmarks zeigten nur 20–30 % mehr Geschwindigkeit gegenüber threaded code bei deutlich geringerer Flexibilität, daher wurde der Ansatz verworfen
  • Endergebnis: Beim komplexesten Syntax-Highlighting für Rust wird eine automatisch generierte Binding-Datei mit 50.000 Zeilen im kalten Zustand in unter 10 Millisekunden komplett hervorgehoben

Syntax-Highlighting-Cache

  • Anfangs wurde bei jeder Änderung die gesamte Datei neu hervorgehoben, was bei großen Dateien zu Performance-Problemen führte
  • Implementiert wurde ein On-Demand-Cache für Token-Highlighting
    • Tokens werden in Chunks ähnlicher Größe hervorgehoben
    • Wenn Änderungen (damage) im Buffer auftreten, werden nur Chunks, die sich mit dieser Position überschneiden oder danach liegen, invalidiert
  • Selbst im pessimistischsten Fall (Bearbeitung in der Mitte einer großen Datei) bleibt der Highlighting-Zustand vor dem Schaden erhalten; unterhalb des sichtbaren Bereichs ist keine Verarbeitung nötig, weil dort keine Highlighting-Informationen angefordert werden
  • Durch den demand-driven Ansatz funktioniert das auch korrekt mit mehreren Panels, die verschiedene Teile desselben Buffers anzeigen

Projektweite Suche

  • Der Suchprozess besteht aus vier Schritten
    • Vom aktuellen Verzeichnis aus wird rückwärts nach einem .git/-Verzeichnis gesucht, um den Projekt-Root zu bestimmen
    • Alle Verzeichnisse unterhalb des Projekt-Roots werden rekursiv durchlaufen und das Suchmuster mit Dateiinhalten abgeglichen
    • Für jedes positive Match wird ein Dateisnippet extrahiert und zur Ergebnisvorschau Syntax-Highlighting angewendet
    • Ergebnisse werden anhand der Navigationsdistanz vom aktuellen Pfad sortiert; nähere Dateien erhalten eine höhere Priorität
  • Es gibt standardmäßige Filterregeln, um etwa Build-Verzeichnisse zu vermeiden
  • Die Verarbeitung ist multithreaded, mit grundlegender Work-Stealing-Verteilung zwischen Threads
    • In einer speziellen Struktur, in der alle Threads zugleich Produzenten und Konsumenten sind, musste das Problem der Termination Detection gelöst werden
    • Wartende Threads erhöhen einen atomaren Zähler; erreicht dieser die Zahl der Worker und ist die Aufgabenwarteschlange leer, wird global beendet
  • Dank Regex-Optimierungen und moderner SSD-Geschwindigkeit ist eine einfache Mustersuche selbst in großen Codebasen wie Veloren nahezu sofort abgeschlossen
  • Im Flamegraph ist der Prozess größtenteils IO-bound
  • Große Codebasen im Editor mit Gedankengeschwindigkeit durchsuchen zu können, trägt stark zur Produktivität bei

Terminal-Emulator-Buffer

  • In einem panelbasierten Editor ist es sehr praktisch, ein Panel als Terminalfenster zu verwenden
  • Ein eigener ANSI-Parser war geplant, doch die Unterstützung moderner Terminalfunktionen wie OSC52 und der Kitty Keyboard Protocol Extensions ist sehr umfangreich
  • Deshalb wird die Crate alacritty_terminal genutzt, um den Escape-Sequence-Parser und die Terminal-Zustandsverwaltung des Alacritty-Terminalemulators wiederzuverwenden
  • Dadurch lassen sich Kernfunktionen von screen/tmux ersetzen und sogar reichhaltigere Escape-Sequence-Unterstützung bereitstellen

Rendering-Optimierung

  • Trotz TUI bleibt Bandbreite bei Remote-Verbindungen auf Mobilgeräten wichtig
  • Double Buffering: Es werden zwei interne Kopien des Terminalbildschirms vorgehalten
    • Beim Neuzeichnen wird mit dem vorherigen Frame verglichen und nur für geänderte Zellen ANSI-Escape-Sequenzen ausgegeben
    • Auch Sequenzen für Cursorbewegungen oder Stilwechsel werden nur bei tatsächlichem Bedarf ausgegeben
  • In den meisten Terminalemulatoren (außer Ghostty) ist es schneller, eine große Datei im Terminal-Panel des Editors mit cat auszugeben und danach den Editor zu schließen, als direkt im Host-Terminal cat auszuführen
    • Der Grund ist, dass alacritty_terminal die Kosten der stdout-Byteverarbeitung gegenüber dem Host-Terminal abfängt

Fazit: Baut eure eigenen Werkzeuge

  • Der selbst gebaute Editor ist zu einem Werkzeug geworden, das perfekt zum eigenen Workflow passt
  • Der Autor widerspricht der verbreiteten Annahme, eigene Editoren oder Tools zu bauen sei sinnloses Leiden
  • Vier Vorteile werden genannt
    • Perfekte Anpassung: Das Werkzeug tut genau das, was man will – nicht mehr und nicht weniger
    • Lernen vielfältiger Technologien: Tiefes Verständnis für Regex, ANSI, Pseudoterminals (pty), TUI-Design, Details von UTF-8 und andere breit nützliche Techniken
    • Langfristige Produktivitätssteigerung: Das eigene Werkzeug wird vollständig verstanden und auf den persönlichen Workflow zugeschnitten, wodurch Reibung mit dem Tool sinkt
    • Reine Freude: Das Lösen in sich geschlossener Probleme und das direkte Erleben des Ergebnisses an den Fingerspitzen entfachte die Liebe zum Programmieren neu; zum ersten Mal seit Jahren wurde beim Coden wieder breit gelächelt und allein gelacht
  • Es muss kein Texteditor sein: Empfohlen wird, eigene Werkzeuge zu bauen, schwierige Teile nicht an statistische Blackboxes wie KI auszulagern und die Herausforderung selbst zu genießen

5 Kommentare

 
xguru 2026-03-12

Eigentlich ist an diesem Beitrag vor allem ein Wort am erstaunlichsten.

Fingerspitzengefühl

Finger + Spitzen + Gefühl

Dass es im Deutschen tatsächlich ein Wort gibt, das das Bediengefühl in den Fingerspitzen ausdrückt, ist wirklich … ach …

 
carnoxen 2026-03-12

Finger war also auch Deutsch. Ich dachte, es wäre Englisch ...

 
mhcoma 2026-03-13

Da es zur gleichen Wortfamilie gehört, teilt es viel Grundwortschatz.

 
yangeok 2026-03-12

Deutsch, bei dem unendlich viele Wortkombinationen möglich sind, haha.

 
GN⁺ 2026-03-12
Hacker-News-Kommentare
  • Hat durchgehend Spaß gemacht zu lesen. Ich empfehle inzwischen auch Freunden, ihren eigenen Texteditor zu bauen
    Ich benutze meinen Editor „Left“ nun seit fast 10 Jahren. Am Anfang war er nicht perfekt, aber ich habe Left weiterentwickelt, indem ich Left mit Left bearbeitet habe. Die Freude, morgens ein Werkzeug zu öffnen, das ich mit eigenen Händen gebaut habe, belohnt mich 20-fach für die investierte Zeit

    • Ich benutze auch seit über 10 Jahren einen persönlichen Editor. Den Tag mit einem Werkzeug zu verbringen, das genau zu mir passt, fühlt sich wirklich angenehm an
    • Ich benutze meinen Editor „aoeui“ jetzt seit 19 Jahren. Das war eine der Entscheidungen mit dem größten Einfluss auf meine Produktivitätssteigerung
    • Mich würde interessieren, welche Funktionen am wichtigsten waren. Ich würde auch gern wissen, ob er so entworfen wurde, dass er mehrere Workflows unterstützt
  • Es gibt den Spruch: „Im Leben sollte man einmal ein Haus bauen, einen Baum pflanzen und einen Editor schreiben.“ Ich habe mit dem Letzten angefangen
    Das ist eine Zeile aus Vip, einem Vi-artigen Editor auf Basis von PicoLisp

  • Ich habe auch von Grund auf einen eigenen Texteditor gebaut. Weil er viele Funktionen hat, habe ich externe Tools wie LSP, tree-sitter und fzf aktiv genutzt.
    Er wurde im suckless-Stil so entworfen, dass man ihn einfach durch direkte Code-Änderungen anpassen kann.
    In den ersten Wochen war er voller Bugs, aber mit jeder Korrektur wurde er stabiler. Mein Projekt hat kann man sich ansehen

    • Genau. Es ist ein großartiges Gefühl, wenn sich frühere Änderungen und Verbesserungen irgendwann zu einer künftigen Beschleunigung der Produktivität aufsummieren
  • Kann jemand vielleicht eine Textbearbeitungsbibliothek empfehlen?
    Eine GUI ist Pflicht, also muss man am Ende auch Font-Renderer und Grafik-Kontext direkt behandeln.
    Für eine reine Konsole ist das für mich nicht nutzbar, und wenn man nur die GUI baut, fehlt die Editierfunktionalität, also brauche ich beides.
    Überraschenderweise ist es schwer, eine reine API-Bibliothek zu finden, die diese Anforderungen erfüllt.
    Meistens ist es entweder ein fertiger Editor oder gleich ein riesiges Framework.
    Eigentlich hätte ich einfach gern nur eine grundlegende Editier-Engine, die große Textdateien schnell verarbeiten kann

    • Ich war überrascht, wie leistungsfähig Terminal-Emulatoren inzwischen sind. Clipboard, Maus-Events, Fokus-Tracking, Benachrichtigungen und fast alles andere sind möglich.
      Mit Tools wie trolley kann man das sogar wie eine native UI auf ghostty-Basis verpacken
    • Mehrere schlanke GUI-Editoren basieren auf Scintilla. Es unterstützt GTK, Windows und Mac. Allerdings ist es funktionsreich und könnte für die Nutzung als einfache API schon zu viel sein
    • Es gibt auch stb_textedit.h, aber ich würde es nicht empfehlen. Bei UTF-8-Verarbeitung, Erkennung von Wortgrenzen und anderem gibt es viele Einschränkungen.
      Stattdessen ist die Kombination aus SDL und SDL_ttf eine ziemlich gute Wahl. SDL3_ttf verbessert auch die String-Verarbeitung
    • Das hängt von der Plattform ab, aber wenn GUI-Rendering nicht das Ziel ist, könnte raylib eine gute Alternative sein
  • Ich habe den „kilo“-Editor von antirez noch einmal nachimplementiert.
    Der Originalcode und das Tutorial sind sehr gut gemacht, daher war das ein hervorragendes Projekt, um Terminalmodus und die Grundlagen der Sprache C zu lernen

  • Ich habe Erinnerungen daran, in den 90ern selbst einen Editor für COBOL- und ASM-Dateien gebaut zu haben.
    Er hatte Syntax-Highlighting, schnelles Buffering und sogar einen Bildschirmschoner.
    Er lief auf einem Pentium 120 und war meiner Erinnerung nach tausendmal schneller als das heutige VSCode

    • Ich habe auch einen Editor in VB6 gebaut. Auf der Marketing-Seite von 2002 standen Funktionen wie „unbegrenzte Templates, Farbdruck, Regex-Suchen/Ersetzen, Code-Vervollständigung“.
      Damals schrieb man alle HTML-Tags in Großbuchstaben
    • Es tut weh, VSCode auf einem alten Laptop zu starten, weil es so langsam ist. Ich komme aus der vim-Generation, aber ich habe das Gefühl, dass man das heutigen Leuten nur schwer empfehlen kann
    • Zur Erinnerung: Auch Borland Turbo Pascal und Turbo C konnten mehrere Dateien gleichzeitig öffnen
  • Hier ist der Editor zte, den der Autor dieses Artikels gebaut hat

  • Der Satz „Widerstehe der Versuchung, die schwierigen Teile in eine Statistik-Box zu schieben“ ist mir wirklich im Gedächtnis geblieben

  • Ich benutze auch meinen eigenen Editor. Andere Leute interessiert das kaum, aber der Wert, den ich aus einem selbstgebauten Werkzeug ziehe, ist groß

    • Ich benutze auch einen Editor, den ich in meiner eigenen Programmiersprache geschrieben habe. Zum Glück musste ich nicht auch noch mein Betriebssystem selbst bauen
    • Ich habe einen bestehenden Editor angepasst und auf meinen Geschmack zugeschnitten. Er kann Bilder laden und Skripting, und HTML-Tags werden mit passenden Farben markiert.
      Es gibt auch eine einfache „Browser“-Funktion, mit der man per F5 Links öffnen kann
    • Du hast keinen Link dagelassen :(
    • Ich benutze auch meinen eigenen Editor. Jedes Mal, wenn Freunde auf meinen Bildschirm schauen und fragen „Was ist das denn?“, bin ich ein bisschen stolz
  • Josh Barretto ist das Genie, das den Super Mario 64 GBA Port gemacht hat. Seinen Editor würde ich gern ausprobieren