blog > Jeanine: a 2d text editor proof of concept (09 Aug 2023)

Jeanine: a 2d text editor proof of concept

It's about time I make this project public and write something about it, just for the sake of having the idea and this implementation out in the open, so maybe others can be inspired.


Check out related work

Index #


The initial idea #

I think this idea struck me at 2019/2020, probably while looking at the graph representation of disassembled code in IDA (The Interactive Disassembler).

IDA with graph view of a piece of disassembled code

One of the main thoughts I had was that I wanted to shove functions to the side. People always say you have to split up code and functions should be short, but then you have a lot of functions that may only get used only once cluttering your file. So it seemed like a nice idea to be able to move those functions to the side and only have "entry" functions in the main view of a source file.

Another possible benefit I thought was to better visualize code flow, depending on how much the code is split into different blocks. Though this may be more applicable for assembly code like shown in IDA than typical high-level language code.

Some history:


The functionality so far (lots of images here) #

(most of following bullet points can be expanded for images and/or more info)

(this is a list of <detail> elements, your browser should support clicking it to expand/collapse)

It is very bare bones and doesn't have things like warnings when closing while modifications haven't been saved yet, but it is in a usable state for me. It's been a long time since I've done decent work on this project, and I don't expect to do so very soon. I want to, but there's a lot of other things I want to do, too.


Missing things that would be nice to have #

Just a few things form the top of my head. I don't plan to make this an editor with a lot of functionality, it works in what it's supposed to do and I find it works well for me for my use cases so far (which is basically only C so far).


How block configuration is stored #

The configuration of the blocks/panels is stored in the source file, as C-style block comments.

Have a look at these source files (and their git history) to get a good idea of what the impact is: (and maybe download Jeanine and open the files in it!)

Spec copied from readme-jeanine-comments.txt:
Jeanine comments
Jeanine comments specify how to layout the source text. They start with a
jeanine: prefix, followed by the directive character and a colon (like p:),
followed by properties (like i:1;), optionally followed by a colon and
another directive with properties and so on. There may only be maximum one
jeanine comment on a single line.

Currently, both directives and property names are a single character in length.
Property values can be of any length, but they cannot include a semicolon.

Currently C-style block comments are always used.

If a value is a floating point number, it must include a decimal point.


jeanine:                          standard jeanine comment prefix
  p:                        "panel" directive
    i:1;p:0;a:b;x:0;y:30;   properties and their values

jeanine:                      standard jeanine comment prefix
  s:                    "secondary link" directive
    a:b;i:2;            properties and their values
	    :           directive separator
	     s:         "secondary link" directive
	       a:b;i:3; properties and their values

| Panel directive (p)
| -------------------
| These define a "panel", which is a section of text. Everything from the start
| of a panel directive until the next panel directive (or EOF) will be put in
| the same panel. Panel directives should be placed on a dedicated source line.
| The start of the source implicitely defines the root panel, which has an id
| of 0. The root panel is the only panel that has no parent.
| | Properties
| | ----------
| | - a: the anchor which specifies how this panel is attached to its parent:
| |      - b: bottom (bottom of parent linked to top of child)
| |      - t: top (top of parent linked to top of child)
| |      - r: right (requires a right link location directive; see below)
| | - i: the id of this panel
| | - p: the id of the parent of this panel
| | - x: the x-offset where this panel is located, relatively to the standard
| |      location as determined by the anchor. If this is a float value,
| |      it is a multiple of the font width, otherwise it's in pixels.
| | - y: the y-offset where this panel is located, relatively to the standard
| |      location as determined by the anchor. If this is a float value,
| |      it is a multiple of the font height, otherwise it's in pixels.

| Right link directive (r)
| ------------------------
| These define the location where panels with a 'right' anchor are linked.
| Since a right link is linked at a specific line, it needs an additional
| jeanine directive to know at which line it is linked (unlike top and bottom
| links, which are always at panel boundaries).
| Using a property in the panel directory to store the line number where the
| link is located would be less suitable, since it will possibly be incorrect
| after making edits in the source while not in jeanine/2d mode. Putting a
| jeanine comment at the end of the line that is linked, will survive those
| edits.
| | Properties
| | ----------
| | - i: the id of the child panel that is linked from here

| Secondary link directive (s)
| ----------------------------
| While panels are already linked by means of properties in the panel directive,
| secondary links can also be made so it is possible to have multiple links to
| the same panel. The difference between primary and secondary links is that
| a primary link defines the location of the child. A panel must always have a
| primary link (except for the root panel). Secondary links are outgoing,
| meaning they are placed at the parent's position and link to a child.
| Secondary links with a top or bottom anchor can be placed in a jeanine comment
| anywhere within the panel's region, but are usually put at the end. They must
| be in a jeanine comment that has its own dedicated line. That comment may then
| not contain any directives that don't require a dedicated line (like a
| secondary link with a right anchor).
| Secondary links with a right anchor must be placed at the end of the line
| where the link should be.
| | Properties
| | ----------
| | - i: the id of the panel that is linked here
| | - a: anchor:
| |      - b: bottom (bottom of parent linked to top of child)
| |      - t: top (top of parent linked to top of child)
| |      - r: right (this line at the parent to top of child)

| Legacy right link directive (l)
| -------------------------------
| These were in use when jeanine comments weren't fully specced out yet. They
| are deprecated and won't newly appear any more, but might still be interpreted
| for backward compatibility reasons. The 'l' initially stood for 'link'. This
| directive is the functional equivalent of 1..n right link directives (r).
| This directive doesn't have properties, but rather a comma separated list of
| ids that denote the child ids. (This inconsistency is the reason that it is
| deprecated)
| | Syntax
| | ------
| | /*jeanine:l:2,1*/
| |   jeanine:        standard jeanine comment prefix
| |           l:      "link" directive
| |             2,1   child panel ids that are right-linked here (2 and 1)


Observations (the good and the bad) #

So far I've only really used this editor on two C projects; basdon and nfsu2-re.

lots of vertical blocks stacked


Related work #

Code Bubbles #

Very similar concept, though you start with a blank canvas and can add bubbles from your source code, which is automatically split for you. It does this by relying on the Eclipse IDE which is running in the background, which makes it that the bubbles are made reliably based on the structure of the code. This also means that it has actual IDE functionality like syntax highlighting, autocomplete, outline etc.

This project seems to still get new commits on GitHub.


Patchworks and Code Ribbon #

Patchworks seems like a standalone editor that shows files in a grid-like fashion. I can't seem to find a download for that, but Code Ribbon is a reimplementation, based on Atom.

The second iteration of the Patchworks editor

From the same author as Code Bubbles.


On the design of text editors #

Not an actual implementation, but a paper discussing text editor design and the visual clutter of IDEs. It has a section that describes how comments could be placed in a margin, next to code, which reminds me of how I wanted to "move stuff to the side".

This paper also influenced the visuals of Jeanine a tidbit, it made me add margins inside the code blocks and around the code block headers, though very subtle.

I can agree with its description of how modern IDEs have a lot of visual clutter and only a small amount of space for displaying actual code. I usually try to hide a lot of things in IDEs (even tabs) so I can focus on the code. Ideally I'd only have a menu bar, and the main screen split between an area that I can switch between fileexplorer/outputconsole/other and an area for code.


Natto #

"Write JavaScript on a 2D canvas"

I haven't played around with this yet, so no comments.


@koujaku's whiteboard coding idea #

Looks very cool and similar but way more functional! Though I'm not sure if it actually allows you to edit the contents.

See also this reply:

#GameMaker embraced this concept in their implementation of the "workspace"



Territory is a code graph browser. You can think of it as your editor's "Go To Definition" function with superpowers. See the entire control flow at a glance and never lose context.

Judging by the video on its homepage it's similar to Code Bubble where clicking on a call to a function opens its definition in a new bubble. Currently in development and invite-only. Looks like it's only a read-only browser.


VSCodeBlocks #

Does not put code in blocks, but provides an extra view with movable blocks that can serve as a high-level overview and documentation for your code, pretty cool!