Fonts im Emacs
Ich mag Bitmap-Fonts, was wahrscheinlich daran liegt, dass ich mit ihnen aufgewachsen bin. Mit pixeligen Buchstaben in einem 8×8-Raster habe ich angefangen und auch heute noch arbeite ich damit im xterm, emacs (na ja, siehe unten) oder gar im Eclipse unter Windows (Dina).
Emacs + Ubuntu + fixed = Probleme
Ubuntu mag keine Bitmap-Fonts. Erstmal sind die generell abgeschaltet
(siehe /etc/fonts/conf.d/70-no-bitmaps.conf
) und wenn man das
umgeht, gibt es immer noch Probleme unter Emacs mit efont-fixed
als Font:
- Unter Ubuntu 16.04 LTS hatte ich den komischen Effekt, dass
manche fettgedruckten typografischen Anführungszeichen oder Umlaute
plötzlich zwei Zeichen breit waren. Das sah dämlich aus und machte
das Layout kaputt. Außerdem werden solche Zeilen ein oder zwei
Pixel höher, was mich total irritiert.
Debian stable zeigt den Fehler immer noch so, es scheint damit an der Emacs-Version zu liegen, betriffen ist jeweils ein 24er. - Unter Ubuntu 18.04 LTS werden sämtliche fettgedruckten Zeichen nur noch als Kästen angezeigt. Das ist ein Emacs 25.
Das kann an irgendwelchen meiner Einstellungen liegen – da es aber auf drei Rechnern auftritt, muss ich die wohl gut synchron halten… Oder es ist wirklich irgendwie kaputt.
OpenType Fonts
Um den Problemen unter Emacs zu entgehen, habe ich schon länger damit
herumexperimentiert, einen anderen Font zu benutzen. Das geht relativ
trivial mit folgender Zeile in der ~/.emacs
:
- (set-face-attribute 'default nil :font "Source Code Pro 10")
Danach läuft der Emacs mit Source Code Pro in 10 Pixel Größe – kein Bitmap-Font, sondern ein OpenType-Font mit Anti-Aliasing und allen Schmakazien. Das sieht für meine Augen erstmal ungewohnt aus, aber dafür kann ich wenigstens wieder alles lesen.
Begehrlichkeiten
Da ich inzwischen nicht nur in normal und fett denke, sondern gute
Fonts mit vielen Schriftstärken mag und Source Code Pro jede Menge
Auswahl bietet, musste ich das auch mal ausprobieren. Wenn man dem
Fontnamen noch ein Light
spendiert, bekommt man eine dünnere
Schrift, die ich auf schwarzem Hintergrund richtig schön finde:
- (set-face-attribute 'default nil :font "Source Code Pro Light 10")
Allerdings ist fetter Text nicht dünner geworden: bold bleibt bold
und der Unterschied zwischen light und bold ist mir optisch zu
groß. Also bin ich erstmal bei der Fassung ohne Light
geblieben.
Lisp zur Rettung
Da ich in anderer Mission gerade an meinen Emacs-Einstellungen herumdoktore und inzwischen etwas Lisp kann, kam mir folgende Idee:
- Schrift auf
Source Code Pro
umstellen wie oben beschrieben (ohneLight
). - Alle Schrifteinstellungen im Emacs durchgehen (die sogenannten
faces) und
:weight normal
durch:weight light
ersetzen. (das ist jetzt der Stand, wo fett zu fett ist). - Nochmal alle Faces durchgehen und
:weight bold
durch:weight semi-bold
ersetzen.
Einfach, logisch und funktioniert sogar!
Dies ist der Codeschnippsel dazu:
- (defun my:change-face-weight (face old new)
- "Conditionally change font weight in a FACE.
- If FACE has :weight OLD it will be changed to :weight NEW."
- (when (eq (face-attribute face :weight) old)
- (set-face-attribute face nil :weight new)))
- (defun my:change-all-face-weight (old new)
- "Conditionally change font weights in all faces.
- All faces with a :weight OLD will be changed to :weight NEW."
- (mapc (function (lambda (face) (my:change-face-weight face old new))) (face-list)))
- (set-face-attribute 'default nil :font "Source Code Pro 10")
- (my:change-all-face-weight 'normal 'light)
- (my:change-all-face-weight 'bold 'semi-bold))
Das ganze ist dann noch eingepackt in eine Erkennung, ob Emacs
grafisch oder auf der Konsole läuft (da braucht man den Font nicht zu
verstellen) und ob ich auf dem Laptop bin (da wird mir light zu
dünn, also lasse ich das). Details dazu in meiner ~/.emacs
, welche
sich hier in der aktuellen Version und hier im Zustand zur Drucklegung
des Artikels befindet.
Das sieht schön aus, aber ich glaube, im Dauerbetrieb ist mir die Schrift doch zu mager. Werde ich im Auge behalten. Aber eigentlich will ich richtige Bitmaps, so wie im Xterm!
Mehr geht immer
Was mir auf jeden Fall bereits aufgefallen ist: Wenn die
Hintergrundfarbe nicht schwarz ist, dann ist light definitiv zu
dünn. Das sollte sich mit einem einfachen if
erledigen lassen,
aber: Denkste!
Ein Face hat ein (oder gar mehrere) Basis-Faces, von denen es seine
Attribute erbt. Am Face selbst werden aber nur die Änderungen
gegenüber dem Parent gespeichert. Wenn ich nun ein Face auf :weight
bold
setzte, dessen Parent auch auf :weight bold
steht, so
wird das bold
gar nicht abgespeichert (sondern stattdessen
unspecified
, was ein vererbtes Attribut markiert). Wenn dann später
der Parent geändert wird, schlägt das auf das Child durch, auch wenn
ich da vorher explizit etwas anderes gesetzt hatte (das wurde ja aber
nicht abgespeichert).
Da ich nur über (face-list)
iteriere, kommen die Faces in
irgendeiner Reihenfolge, bei der auch mal Parents hinter den Childs
stehen und es funktioniert einfach nicht. Ich müsste die
(face-list)
in irgendeine Baumstruktur umwandeln und dann von oben
nach unten durchgehen. Daran habe ich mir bisher leider vergeblich
die Finger gebrochen (ich merke schon wieder ganz stark, dass ich
untypisierte Sprachen nicht mag). Ich überlege schon, die
Schriftstärken für alle Faces händisch per Emacs Customization zu
editieren und dann als eigenes Theme abzuspeichern…
Oder ich nehme einfach wieder Bitmap-Fonts. Das muss doch möglich sein! Ich bleibe da am Ball.
Mitch’s Manga Blog am : Fonts im Emacs: gelöst!