Een onofficiële gids voor markdown-ts-mode in Emacs 31

Introductie

Emacs 31 is uitgebracht en brengt veel nieuwe functies met zich mee. Een van deze toevoegingen is de markdown-ts-mode. In Emacs versie 31 wordt deze modus gemarkeerd als "experimenteel". Maar wat betekent dat precies? Moet je het gebruiken? Is het al klaar voor gebruik, of is het slechts een eerste schets?

Deze post dient als een korte gids om deze modus up-and-running te krijgen en helpt je de antwoorden op deze vragen te vinden.

Wat is de huidige status van de functies?

Omdat dit een experimentele modus is, moet je er expliciet voor kiezen om deze te gebruiken. Dit betekent dat waarschijnlijk nog niet alles vlekkeloos werkt en dat er meer tests en feedback nodig zijn.

Laat je echter niet misleiden door de term "experimenteel". Dit betekent niet dat de modus onvolledig is qua functies. Integendeel, het is een zeer functierijke modus. De modus ondersteunt al de volledige CommonMark-specificatie, evenals het grootste deel van GitHub Flavored Markdown (GFM). Daarnaast biedt het extra's zoals codeblokken voor modi die geen tree-sitter gebruiken (zoals Elisp), hulpprogramma's voor inhoudsopgaven en interfaces met externe converters zoals Pandoc en GFM.

Voordat je er diep in duikt, heb je hulp nodig om de modus te activeren. Tree-sitter kan lastig zijn, zeker als dit je eerste ervaring ermee is. Daarom volgt hier een korte installatiegids.

Installatie: Waar is de modus en moet ik deze installeren?

"Experimenteel" betekent dat Emacs de modus niet standaard inschakelt. Je kunt dus niet simpelweg een .md-bestand openen of M-x markdown-ts-mode aanroepen; je moet de bibliotheek eerst laden.

Er zijn meerdere manieren om dit te doen. Voor wie use-package gebruikt, is dit de aanbevolen initiële configuratie:

(use-package markdown-ts-mode
  :ensure nil
  :mode ("\\.md\\'" "\\.mdx\\'" "\\.markdown\\'")
  :config
  (require 'markdown-ts-mode-x))

Als je use-package niet gebruikt, kun je dit doen:

(autoload 'markdown-ts-mode "markdown-ts-mode" nil t)
(dolist (re '("\\.md\\'" "\\.mdx\\'" "\\.markdown\\'"))
  (add-to-list 'auto-mode-alist (cons re 'markdown-ts-mode)))
(with-eval-after-load 'markdown-ts-mode
  (require 'markdown-ts-mode-x))

Nu zijn zowel de modus als de x-bibliotheek (met handige extra's) geladen, en kun je Markdown-bestanden openen.

Testen zonder configuratie aan te passen

Wil je experimenteren zonder je eigen configuratie te wijzigen?

  1. Sla de bovenstaande code op in een bestand, bijvoorbeeld testing.el.
  2. Start Emacs met: emacs -Q --load 'testing.el'.

BELANGRIJK: Je hoeft dit pakket niet te downloaden via een package manager. De (inmiddels verouderde en gearchiveerde) MELPA-repository weigert installaties op Emacs versie 31 en biedt zeer beperkte functies. Als je die versie gebruikt, gebruik je niet de nieuwe ingebouwde markdown-ts-mode.

Het eerste Markdown-bestand openen

Als je voor het eerst een tree-sitter-gebaseerde modus gebruikt, is het belangrijk om te weten dat tree-sitter fantastisch en snel is, maar dat het een eigen set taken en debugging-vaardigheden vereist.

Wanneer je een .md-bestand opent, kan het zijn dat Emacs vraagt om een grammatica te installeren. Dit gebeurt als Emacs geen grammatica voor Markdown vindt in je systeem (standaard in ~/.emacs.d/tree-sitter/). Emacs zal aanbieden deze te downloaden en compileren vanuit een repository die is gedefinieerd in de broncode van markdown-ts-mode. Bevestig dit met y. Let op: Markdown gebruikt twee grammatica's: een hoofdgrammatica en een voor inline-parsing. Installeer beide.

Probleemoplossing bij installatie

Mocht het niet werken, controleer dan het volgende:

  • Is Emacs gecompileerd met de tree-sitter flag? Controleer dit met M-: (featurep 'treesit) RET. Het moet t teruggeven.
  • Heb je de benodigde tools voor het compileren van grammatica's, zoals make en gcc?
  • Heb je het tree-sitter-cli pakket van je distributie geïnstalleerd? Controleer dit met tree-sitter --version.

Grammatica's en Fontificatie

Een bijzonder kenmerk van markdown-ts-mode is dat het niet alleen met Markdown werkt, maar met alle beschikbare -ts-modes.

Veel Markdown-bestanden hebben een header in TOML- of YAML-formaat. Om deze correct te kleuren (fontificeren), heeft Emacs een grammatica voor dat specifieke formaat nodig. Als een deel van je tekst niet correct gekleurd wordt, mis je waarschijnlijk een grammatica.

Je kunt een grammatica handmatig installeren via: M-x treesit-install-language-grammar RET yaml

Mocht Emacs geen suggestie doen voor de repository, dan kun je de broncode van de betreffende modus (bijv. yaml-ts-mode.el) raadplegen om de juiste URL en commit te vinden, of deze handmatig invoeren.

Een opmerking over grammatica's

Een -ts-mode is slechts zo goed als de tree-sitter-grammatica die erachter zit. Dit betekent dat we afhankelijk zijn van externe grammatica's die worden gedeeld door verschillende editors. De auteurs van de modi proberen altijd de meest stabiele versie (commit) aan te bevelen. Voor markdown-ts-mode wordt gebruikgemaakt van de grammatica's van tree-sitter-markdown, omdat deze de meest complete en breed geaccepteerde zijn.

Overzicht van functies in markdown-ts-mode

De modus beschikt over een easy-menu voor snelle ontdekking van functionaliteiten. Je kunt dit menu openen door op "Markdown" in de mode-line te klikken, via de menubalk (indien ingeschakeld), of via Ctrl + rechtermuisklik in de buffer.

Bewerken

Hier is een overzicht van de belangrijkste sneltoetsen en functies:

Nadruk (Emphasis)

Je kunt markers handmatig typen, of de modus gebruiken via C-c C-x C-f (markdown-ts-emphasize):

  • b: vetgedrukt (bold)
  • B: vetgedrukt met underscores (bold)
  • i: cursief (italic)
  • I: cursief met underscores (italic)
  • a: vet + cursief (both)
  • s: doorhalen (gone)
  • c: inline code (code)
  • SPC: nadruk op het huidige punt verwijderen

Tip: C-c C-x RET (markdown-ts-toggle-hide-markup) verbergt de markers, waardoor de tekst direct als vet of cursief wordt weergegeven (vergelijkbaar met Org-mode).

Koppen (Headings)

Typ # tot ######. Ook Setext-koppen (=== en ---) worden herkend.

  • M-<left>: promote (laag verhogen)
  • M-<right>: demote (laag verlagen)
  • M-<up> / M-<down>: verplaats een hele sectie (inclusief inhoud en kinderen)
  • TAB: zichtbaarheid van de kop wisselen (outline folding)
  • S-TAB: zichtbaarheid van alle koppen wisselen

Lijsten en Checkboxes

Typ -, +, * of 1..

  • M-RET: nieuw lijstitem invoegen
  • RET: markdown-ts-newline zet de lijst automatisch voort
  • M-<left> / M-<right>: item promoten of demoten
  • C-c C-r: genummerde lijst opnieuw nummeren
  • C-c C-c: checkbox wisselen ([ ] $\leftrightarrow$ [x])

Blokken

Gebruik C-c C-, (markdown-ts-insert-structure) gevolgd door één toets:

  • ` ``: fenced code block (vraagt om de taal)
  • ~: tilde fenced code block
  • q: block quote
  • d: divider (thematische breuk)
  • t: tabel

Codeblokken

Dit is een van de sterkste functies. Een codeblok met een opgegeven taal wordt gekleurd door de specifieke modus van die taal.

Wanneer je de cursor in een blok plaatst, schakelt Emacs over naar markdown-ts-code-block-in-context-mode. Binnen dit blok:

  • TAB en RET werken volgens de indentatie-regels van de betreffende taal.
  • M-q vult de tekst in volgens de regels van die taal.
  • M-. springt naar de definitie via xref.
  • Navigeer tussen blokken met C-c C-v n (volgende) en C-c C-v p (vorige).

Tabellen

Voeg een tabel in met C-c C-, t of M-x markdown-ts-table-insert-table. Je bevindt je dan in markdown-ts-in-table-mode:

  • TAB / S-TAB: volgende/vorige cel (formatteert ook de tabel)
  • RET / S-RET: volgende/vorige rij
  • M-RET: rij invoegen eronder
  • M-<up> / M-<down>: rij verplaatsen
  • M-<left> / M-<right>: kolom verplaatsen
  • M-S-<up>: rij invoegen erboven / M-S-<down>: rij verwijderen
  • M-S-<right>: kolom links invoegen / M-S-<left>: kolom verwijderen
  • C-c C-c: hele tabel uitlijnen
  • C-c C-t a: kolomuitlijning instellen (links, midden, rechts)
  • C-c C-t t: tabel transponeren

Links en Afbeeldingen

  • Fragment-links (bijv. [intro](#intro)) zijn klikbaar en springen naar de betreffende kop.
  • Afbeeldingen worden inline gerenderd. Schakel dit met C-c C-x C-v (markdown-ts-toggle-inline-images).

Navigatie

  • C-c C-n / C-c C-p: volgende/vorige kop
  • C-c C-u: terug naar bovenliggende kop
  • C-c C-f / C-c C-b: volgende/vorige kop op hetzelfde niveau
  • M-x imenu: spring naar een kop of benoemd codeblok via completion
  • M-x markdown-ts-view-mode: een leesmodus (read-only) met eenvoudige navigatie (n, p, u, f, b, TAB).

Extra's (markdown-ts-mode-x.el)

Inhoudsopgave (TOC)

Een inhoudsopgave wordt afgebakend door HTML-comments: <!-- markdown-ts-toc: --> en <!-- markdown-ts-toc-end: -->.

  • M-x markdown-ts-toc-insert-template: voegt de markers in.
  • M-x markdown-ts-toc-generate: genereert de inhoudsopgave.
  • M-x markdown-ts-toc-update-before-save-mode: update de TOC automatisch bij het opslaan.

Exporteren

Met M-x markdown-ts-convert kun je de buffer converteren naar andere formaten:

  • PDF via Pandoc.
  • HTML via Pandoc, cmark, cmark-gfm, markdown of markdown.pl.

Met een prefix-argument wordt het resultaat direct getoond (standaard via eww).

Integratie met Eglot en Eldoc

Je kunt Eglot configureren om documentatie (vaak in Markdown) te renderen met markdown-ts-view-mode:

(setopt eglot-documentation-renderer #'markdown-ts-view-mode)

Aanpassingen en Hulp

Je kunt de modus aanpassen via M-x customize-group RET markdown-ts RET. Hier kun je instellingen wijzigen voor:

  • Weergave: verbergen van markup, bullets, checkboxes, afbeeldingen.
  • Codeblokken: standaardmodi en context-mode.
  • Tabellen: auto-align en kolombreedte.
  • Faces: kleuren aanpassen per Markdown-element.

Hoe kun je helpen?

De beste manier om te helpen is door de modus te gebruiken. Rapporteer bugs direct via Emacs met M-x report-emacs-bug RET, bij voorkeur met een klein voorbeeld dat het probleem reproduceert.

Technische beperkingen en eigenaardigheden

Grammatica's als externe assets

Grammatica's zijn niet specifiek voor Emacs geschreven, maar worden gedeeld door diverse editors. Een fix in de grammatica kan daarom tijd kosten. Als een bug voortkomt uit de manier waarop de grammatica parseert, wordt dit vaak in de modus zelf opgevangen.

Indirecte buffers

Tree-sitter en indirecte buffers werken momenteel niet goed samen. Parsers worden niet gedeeld met indirecte buffers, en font-lock wordt daar niet ondersteund. Dit is een beperking van Emacs zelf, niet van markdown-ts-mode.

Conclusie: Is het klaar voor gebruik?

Betekent "experimenteel" dat de modus slechts een schets is? Nee. Het betekent dat de modus nog evolueert en dat de API of het gedrag nog kan veranderen.

Moet je het gebruiken? Ja! Als je comfortabel bent met het label "experimenteel", probeer het dan uit. Hoe meer mensen het gebruiken, hoe sneller we bugs kunnen vinden en oplossen. Of het in de volgende Emacs-release definitief uit de experimentele fase gaat, hangt af van de feedback en de laatste puntjes op de i.