Skip to content

ekaschalk/notate

Repository files navigation

Notate - Program with Personal Notation

(In-progress, current screenshot, see bottom for current project status)

./img/notate-screencast-2.gif

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.

Selectively APL-ize your code with notate.

Introduction

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     ; Now bar isn't aligned!
     bar)
(∧ foo     ; What we want to see when working...
   bar)
(and foo   ; But now 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.

FAQ

Why?
I’ve found a hobby in confusing over-the-shoulder onlookers. I got a math degree purely to draw pretty symbols all day and wanted to continue the same productivity.

I believe there is a desire for personalized, symbol-based programming. But the downsides have been too substantial, requiring consensus on symbols and contributors to input them.

Scientists should be able to program with the greek alphabet.

Mathematicians should be able to program with notation no different than their pen and paper.

And hipsters should have every emoji at their disposal.

Does Notate support all programming languages?
Mostly.
  • Details: While there is a general approach, I suspect it will be slow. At the moment, a predicate identifying if a visual replacement contributes to indentation must be defined. Currently done for lisps.
How does it work?
By (ab)using particular properties of emacs’s display and modification-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).

    To the point - overlays at the start of each line render the difference of indentation as a single space. Visual replacements are overlays with a ‘display set rather than composition based, like prior work.

Similar work?
Notate is a novel extension of the concept of prettify-symbols, which itself has only a counterpart in vim-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 welcome. For contributing code and raising issues, see CONTRIBUTING.

Goals

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.

Usage

This section is subject to change while under development.

Trying it
Load nt-dev and use nt-dev--switch-to-test-buffer and nt-dev--switch-to-screenshot-buffer to test out Notate. Support for line insertion/deletion is being developed so the buffer must be set up beforehand.
Visual Line Movement
Evil users set evil-respect-visual-line-mode non-nil or line movement behavior will be strange. It is nil by default. For non-evil users, line-move-visual should be non-nil, which it is by default.

Spacemacs users should add in their dotspacemacs/user-config:

(define-key evil-motion-state-map "j" 'evil-next-visual-line)
(define-key evil-motion-state-map "k" 'evil-previous-visual-line)
(define-key evil-visual-state-map "j" 'evil-next-visual-line)
(define-key evil-visual-state-map "k" 'evil-previous-visual-line)
Developing it
Run cask install . then execute tests with cask exec buttercup -L .. Additional developer utilities can be found in nt-dev.

Status

What Works

  • The core idea! Toggling on/off works as expected.
  • (un)rendering a note updates indentation on-the-fly.
  • Deleting around the invisible spaces (masked indent) doesn’t break things.

Whats Being Worked On

  • Buffer modification updates visual indentation.
    • Proof-of-concept implementation working in most cases but won’t scale.
    • Currently implementing an experimental tree-based algorithm. Should scale to arbitrary buffer sizes and numbers of replacements in a buffer.

What Doesn’t Work Yet

  • Whether a visual replacement modifies indent depends on the major-mode.
    • Lisps implemented.
    • Will implement for Python.
    • For other languages, contributors with knowledge of them would help greatly (once this project is sufficiently mature).
  • How far a visual replacement modifies indent depends on the major-mode.
    • Lisps implemented
    • Generalized implemented but not compatabile with buffer modification yet.

About

Program with Personal Notation

Resources

Stars

Watchers

Forks

Releases

No releases published

Packages

No packages published