trying to fix

This commit is contained in:
Chris Cochrun 2022-01-03 12:41:35 -06:00
parent fa407dfeb6
commit e013d7569e
22945 changed files with 447936 additions and 0 deletions

View file

@ -0,0 +1,100 @@
<p>In a recent entry on <a href="https://protesilaos.com/codelog/2020-07-17-emacs-mixed-fonts-org/">configuring mixed
fonts</a>,
I outlined how to specify your typefaces of choice by configuring the
<code>default</code>, <code>variable-pitch</code>, and <code>fixed-pitch</code> faces. This would allow
you to benefit from variegated typography, such as having paragraph text
rendered in a proportionately spaced font, while inline code is
displayed as monospaced.</p>
<p>The overall approach of controlling the three basic faces is fine, but
the code I shared had the unintended consequence of breaking the
built-in <code>text-scale-adjust</code> command (by default bound to <code>C-x C-+</code>,
<code>C-x C--</code>, <code>C-x C-0</code>). Here I issue a corrective to the technique that
was used before.</p>
<h2>The code that breaks text-scale-adjust</h2>
<p>This is the gist of what I was using for several months:</p>
<pre><code class="language-elisp">(set-face-attribute 'default nil :font "Hack-16")
(set-face-attribute 'fixed-pitch nil :font "Hack-16")
(set-face-attribute 'variable-pitch nil :font "FiraGO-16")
</code></pre>
<p>A variant of the above can be expressed as follows:</p>
<pre><code class="language-elisp">(set-face-attribute 'default nil :family "Hack" :height 160)
(set-face-attribute 'fixed-pitch nil :family "Hack" :height 160)
(set-face-attribute 'variable-pitch nil :family "FiraGO" :height 160)
</code></pre>
<p>If you set fonts this way and try to use <code>text-scale-adjust</code> in a buffer
with mixed fonts, you will notice that only the main text, affected by
the <code>default</code> face, gets scaled. The rest retain their height—not good.</p>
<p>This is because of a hard-wired assumption in the <code>text-scale-adjust</code>
command to only target the <code>default</code> face: <code>variable-pitch</code> and
<code>fixed-pitch</code> remain in tact, thus breaking our expectations.</p>
<p>The problem consists in the fact that we are specifying an absolute size
for each font family. Whereas we should be benefiting from relative
sizes that all have a single point of reference, which is easy to do.</p>
<h2>The recommended way to set font heights with faces</h2>
<p>Let us re-purpose the sample code from the previous section, in order to
get the behaviour we expect out of <code>text-scale-adjust</code>.</p>
<pre><code class="language-elisp">(set-face-attribute 'default nil :font "Hack-16")
(set-face-attribute 'fixed-pitch nil :family "Hack" :height 1.0)
(set-face-attribute 'variable-pitch nil :family "FiraGO" :height 1.0)
</code></pre>
<p>A alternative to the above is this:</p>
<pre><code class="language-elisp">(set-face-attribute 'default nil :family "Hack" :height 160)
(set-face-attribute 'fixed-pitch nil :family "Hack")
(set-face-attribute 'variable-pitch nil :family "FiraGO")
</code></pre>
<p>Notice that we set an absolute point size only for the <code>default</code> face.
While we instruct Emacs to interpret the height of <code>fixed-pitch</code> and
<code>variable-pitch</code> as relative to that constant. Therein lies the
difference between integer and floating point values for the <code>:height</code>
attribute (remember to consult <code>C-h f set-face-attribute</code>).</p>
<p>Strictly speaking, the <code>:height 1.0</code> is not necessary, unless you are
overriding a prior state. It is what applies when the specification is
omitted. Rendering it explicit here helps us spot the subtleties in
notation and be clear about what is at play.</p>
<h2>Details are tricky</h2>
<p>I was using the old technique for several months, adjusting fonts
through a bespoke function of mine that altered their absolute sizes.
What inspired me to investigate and eventually address this issue is a
particular statement in the doc string of <code>set-face-attribute</code>:</p>
<blockquote>
<p>Note that for the default face, you must specify an absolute height
(since there is nothing for it to be relative to).</p>
</blockquote>
<p>Which implied that if the <code>default</code> was a constant, all other faces
could simply have a relative height. This is because of the peculiar
nature of that face to serve as the foundation upon which all others are
established. As such, a <code>:height</code> with a floating point is a multiple
of the <code>default</code> font size. Simple and effective!</p>
<p>I am now happily using <code>text-scale-adjust</code> in tandem with the tools I
mentioned in my recent video about <a href="https://protesilaos.com/codelog/2020-07-16-emacs-focused-editing/">“Focused editing” for
Emacs</a>.</p>
<p>This information is also documented in the <a href="https://protesilaos.com/emacs/modus-themes/">official manual of the Modus
themes</a> because they are designed
to cope well with mixed font scenaria, such as when the user decides to
enable the built-in <code>variable-pitch-mode</code>.</p>