(In-progress, current screenshot, see bottom for current project status)
Notate your programs with indentation-correcting visual replacements of symbols with other symbols.
Ligature’s generalization, known to Emacs as prettified-symbols
, causes
alignment and indentation issues, preventing one from rendering for
as ∀
and
int
as ℤ
in their code.
With notate, selectively APL-ize your code.
Ligatures render consecutive graphemes, or characters, as a single glyph.
Fonts with programming ligatures, like Fira Code, design their ligature glyphs to have the same width as their constituent characters. The glyphs for >= and -> take up two spaces.
Matching sizes of operators and their replacements is not possible in general.
For example, render and
as ∧
:
(and foo ; The actual text
bar)
(∧ foo ; What we see when working - bar isn't aligned!
bar)
(∧ foo ; What we want to see when working...
bar)
(and foo ; But now the true indentation is incorrect!
bar)
There are many examples: render beta
as β
, in
as ∈
, compose
as ∘
,
the “nameless” package, and so on.
Notate visually-only replaces strings with other strings, masking indentation.
Our working indentation is visually modified so that in the example above, we see example 3 while the true text is example 1. When we search for “and” it will jump to “∧”. When your coworker walks over, hiding your abominable operators is as simple as a toggle.
- Why?
- I’ve found a hobby in confusing over-the-shoulder onlookers. I believe in the value of notation, as a graduate in math (go gators). The aesthetic of my programs are important to me.
- Does Notate support all programming languages?
- Yes-ish.
- Details: notate is major-mode agnostic except for a fn to calculate the
range of an indentation mask. This too can be made major-mode agnostic,
however, a general implementation will be slower, more complex and
potentially brittle. See
nt-bounds.el
.
- Details: notate is major-mode agnostic except for a fn to calculate the
range of an indentation mask. This too can be made major-mode agnostic,
however, a general implementation will be slower, more complex and
potentially brittle. See
- How does it work?
- By (ab)using particular properties of emacs’s
display
andmodification-hooks
text properties.- Details: My approach has received ‘praise’ from Emac’s maintainer in the
past: “Using display properties and overlay strings to “fix” what the
display engine does is fundamentally wrong, and is not what these features
were designed for.”
notate attempts to so egregiously abuse Emac’s display engine that a skilled user cannot help themselves but to correct me (by extending Emac’s C display engine with indentation metrics smarter than fixed-width columns).
I’m joking - this project would complement and ideally inform an extension of Emac’s indentation engine and native ligature support. And in time, I will try my hand at it myself.
- Details: My approach has received ‘praise’ from Emac’s maintainer in the
past: “Using display properties and overlay strings to “fix” what the
display engine does is fundamentally wrong, and is not what these features
were designed for.”
- Similar work?
- Notate is a novel extension of the concept of
prettify-symbols
, which itself has only a counterpart invim-conceal
. Notate is self-contained and cannot leverage prior work around the concept of prettifying. - Contributing?
- Would be greatly appreciated! Non-coding materials like images, screencasts, and other examples are useful and exciting. For contributing code and raising issues, see CONTRIBUTING.
Graphemes, characters, ligatures, and glyphs can be confusing when used technically. I understand the least precise definition of ligatures to be: render consecutive characters as a specific character.
Emac’s built-in prettified-symbols-mode
implements the natural generalization
of this definition: render symbols as other symbols. This prior work cannot be
used due to technical details surrounding choice of text properties. The term
pretty-symbols
is unique to Emacs, not widely known, and in my opinion, not
serious enough for the possibilities it opens.
I want:
- Discourse to move from “prettifying” to “notating” programming buffers.
- Emac’s C display engine to eventually benefit from the challenges, performance considerations, and ideas presented in this work.
- More imaginative notation, supported languages, and awareness of the possibilities Emacs offers and encourages.
- The core idea!
- Toggling on/off works perfectly.
- Deleting any part of a note updates indent on-the-fly correctly.
- Deleting any part of a mask deletes mask’s region.
- That is, deleting near the beginning of a masked line behaves the same as if the line wasn’t masked at all.
- Newline insertion.
- Handling non-cooperative users (insert unbalanced/sexp-completing text) might be quite difficult to handle in a way that isn’t just resetting the entire region’s notes.
- Buffer modification that adds or removes lines.
- Line up-down movement needs left/right offset equal to masked/unmasked indent.
- Boundary functions need fleshing out.
- Only concerned with lisp-like boundaries atm.
- Special indent rules not handled yet.
- Expectation is for contributors with deeper knowledge of various languages to contribute here.
- Either height or width is normalized, not both.
- Compare the two progress-2 images in ./img. See the
nt-normalize-height?
variable for commentary. - Possibly something just have to deal with. Solving at lisp-level will make things quite a bit more complicated and obfuscated.
- Compare the two progress-2 images in ./img. See the