On the design of text editors (2020)
arxiv.org
arxiv.org
Given the potential of modern graphical environments and typography, I’d like to see languages and editors adopt simple spacing improvements like elastic tab stops¹. I don’t want to chose between an aesthetically pleasing layout that draws attention to patterns and anomalies in my code and a layout with completely uniform spacing because anything more carefully aligned is a pain to maintain in later edits and adds noise to diffs. We could shrink blank lines to half-height as well, which would keep the useful visual separation but waste less space.
I’d like to use a (somewhat) wider range of basic symbols than whatever we had in ASCII last century. Even allowing comparison operators like ≤, <, ≠ and = that align consistently would be a useful start.
I’d like simpler syntax highlighting, concentrating on distinguishing major language elements like literals, variables and types, and emphasising problems I probably care about like unclosed strings and misspelt keywords. I’d also like to see colour used more effectively for matching related code like opening/closing pairs or the definition of a value and later references to it.
I’d like to see a sidebar for documentation, not unlike the example for comments in the article, but allowing documentation to be attached at different levels from an individual function or variable up to an entire file or beyond, then having the editor automatically offer all documentation relevant to wherever I am in the code and whatever I’m typing there.
If we were designing a UI for another application, we’d always consider aspects like spacing, symbols and iconography, colour schemes and how to show and navigate related information. It’s strange that we give so little consideration to them in the tools we use ourselves!
(Join me next week for part two of the epic rant, provisionally entitled Why aren’t we all using semantic diff tools yet?)
http://literateprogramming.com/
With a bit of help on tex.stackexchange.com I managed to put together a system which allows editing a .tex file (without the docstrip mandated almost everything is a comment greyness):
https://tex.stackexchange.com/questions/722886/how-to-write-...
What I’m advocating here is a little different, though. While it would certainly be useful to write documentation using more expressive formats than plain text, here I’m arguing for the ability to (a) attach that documentation to specific parts of the code at different scales and then (b) have all relevant information at all scales readily available depending on what I’m currently editing.
One of the reasons I would like to have this ability in my development environment is that I found the literate style to be very helpful for writing informative documentation but relatively unhelpful for finding it again later. By its nature, literate documentation is organised primarily for a linear reading flow, like the story in a book, but most of the time when I’m editing code, that’s not my typical searching behaviour.
Overall, I'd highly recommend it.
https://news.ycombinator.com/item?id=12048693
I continued to work on that project for a while afterwards, but I don’t think my overall views on the pros and cons of the literate style changed much from what I wrote there.
If there’s anything you’re particularly curious about, I’m happy to discuss further (though my professional experience was limited to that one project, so I’m hardly an expert).
I'm generally against metaprogramming and DSLs for that reason, the linter and the debugger don't understand it. Even template languages have the issue, which is a great case for logicless templates.
Seems like LP would be at it's best if your audience is going to read and carefully study your code without a bunch of extra stuff added, as is probably more common in academia, rather than see it indirectly through an IDE.
Visually, font ligatures do just that, and combine your !=, >=, etc. into single elements
It then becomes important to see the difference between ASCII approximations and real Unicode symbols, since this is relevant e.g. when searching for a symbol in your code base or to see at a glance whether usage of Unicode vs. ASCII etc. is consistent.
The only spot I still kinda use such a feature (prettify-symbols-mode specifically) is in LaTeX, where Unicode math is more rare and long equations become nearly unreadable without some kind of rendering in the source code.
So I understand how you could have confusion in your case if you have logical comparators for ≥ and also have strings with "≥" or even variable names, if your language is permissive enough to allow that. But if you search for "≥" it should not return the ">=" disguised as "≥", ...right?
That’s my issue :). Languages like Julia permit both “>=" and "≥" in the source code with the same meaning. But if you use say search-based navigation of your file, how do you know which one to type to get where you want?
Or in Python I’ve seen some people make “alpha” render as α, since it’s a common variable name in physics codes. But “α” itself is a valid Python variable name, and I personally use Greek letters in Python physics code and know others do as well. That can again be confusing, since in Python “alpha” and “α” are not the same variable, so it’s crucial to write it correctly.
For example,
<C-k> -> gives →
<C-k> => gives ⇒
<C-k> d* gives δ (greeks are generally all _letter_*)
<C-k> D* gives Δ
Some of the combinations are a little weird to rememeber, but if you use them regularly then it's easy enough (like greek or arrows).- Like the sibling mentioned, you can use a “compose key” (it’s built in on Linux and can be installed on other platforms). There are other OS-wide options like the TeX input method for Gnome, or TextExpander snippets on Mac.
- In Vim, Ctrl-K in insert mode lets you enter “digraphs”. For instance, Ctrl-K *s will insert a Greek letter “sigma”.
- In Emacs, C-\ will activate an “input method” such as the “TeX” input method that can insert any math or Greek Unicode symbol using LaTeX notation. (I personally like Emacs’ “transient” input method that is activated for one symbol at a time, since it interferes less with coding.)
- In Sublime Text and VSCode there are third-party plugins that insert Unicode symbols via e.g. TeX notation.
- Every Julia editor extension, as well as its REPL, lets you press tab to convert a set of LaTeX-like notations into Unicode symbols in a common way.
- Most editors have support for snippets of some kind, and many have available snippet packs for common math and Greek symbols.
You might also be able to set up your own compose codes in ~/.XCompose, but that didn't work for me. Could be another casualty of Wayland or just some quirk in my setup.
Every text editor that understands Unicode already allows for that. If you want to use ≤ rather than <=, then you need to alter the language, not the editor.
(BTW I'm not a fan of coding ligatures myself, but they seem to be popular.)
I would like to use those same characters, and where applicable with the same sizes and alignments of related characters, everywhere — in my editor, my linters and formatters, my diff tools and version control system UIs, my greybeard CLI text file batch processing incantations, everywhere.
All that really needs is languages that use Unicode characters like ≤, fonts that include all the relevant glyphs, and tools that provide a simple way to enter those characters. But all of these are important, because right now we don’t have simple, standardised ways of doing these things, and so we mostly don’t do them at all.
It’s obviously not a big deal, just a small “quality of life” improvement, but it’s 2024 and I don’t see any good reason why we can’t have nice things. :-)
This is not a hypothetical, btw. One of the most persistent friction points for C++ adoption in Europe was the lack of a ~ (tilde) key, forcing folks to ALT-1-2-6 every time they wanted to implement a destructor...
On Linux I use the sequence Insert, "/", "=", having mapped Insert to act as a Compose key (what other use do you have for it anyway?).
On Windows I use the same sequence, having installed wincompose by Sam Hocevar.
Collapsible images as inline comments can be FAR more effective at embedding relevant information in certain sections of code.
As far as "related coloration" - Jetbrains IDEs let you setup regex around comments that will color them differently which I use in collaborative environments so devs can quickly collate their TODOs, etc.
There's also an extension called Rainbow Braces that helps to highlight opening/closing pairs with different colors.
Like ALGOL?
That's already doable on vim/nvim. BTW, I'm on macOS, and install them via macport. Or perhaps because I already installed some specific fonts....
I don't know what Notepad you use to write your code, but VSCode with font ligatures (for comparison operators) and a linter (aligns the same as elastic tabstops) already does the 80% of what you want. The 20% rest – sidebar for documentation – are not implemented for a reason.
The sidebar to show the documentation is just a presentation detail. What I’d really like as a developer is (a) the ability to attach documentation with a specific scope ranging from small things like a function parameter or variable, though larger things like a function or a set of related functions, up to whole files or packages, and then (b) editors that recognise the scoped documentation and present it contextually.
I’d like all relevant comments to be easily visible when I might want to refer to them. Also, I’d like to know what documentation exists in the first place, which is not always obvious when we rely on things like big banner comments at the top of files/sections or having separate README files scattered through the tree.
I mean, keeping an overview of the documentation open on the side is something I do every day in GNU Emacs, so I'm a bit curious what the reason is why it's not done in Microsoft VS Code.
The reason it doesn't come with the editor is because every language has its own specific documentation format, though I do wish that they could create a consistent set of keyboard shortcuts, search UI, etc for documentation.
It would also be very cool if we could use hyperlinks and backlinks.
Like, you could have a code example that you could reference that shows up when you mouse over a comment in some code or something.
They're unpopular because they're confusing and brittle. How is the relationship between the two maintained when the developer is hard at work, when the text is not just a set piece for pretty presentation? No answer is given, because there is none.
It's a bad idea because it's wasteful of space while achieving very little over a conventional setup.
The text editor or IDE can provide a feature to show(pop up) or hide(collapse) the side comment section when needed while formatting the comments to make them look bold or italic.
This will become a quality of life improvement if the implementation is done right. If not, it will be very confusing as you mentioned. I think writing API documentation can become very easy and since the function and its comment/description align on the same line, generating API documentation will become easy as well.
case closed, guys, we can all go home now.
Straight from my horror cabinet of ideas!
"Multics Emacs: The History, Design and Implementation", Copyright © 1979, 1996 Bernard S. Greenberg
I actually have a link to TFA in the block header in my dots, and it seems a crime that one isn’t there as well.
a little thought about how crt displays work suffices to see why this is the case. if you carefully adjust your deflection coil amplifiers to perfectly align the edge of the text with the physical edge of the display tube, you will almost certainly cut off the edges of the first or last lines or both
marginless displays are a product of flat-panel displays and window systems
i'd like to second the recommendation to look at gravgaard's elastic tabstops idea
_____
† 25 actually i think
Personally, my terminal is "only" 127x31 and a major complaint I have with most user interfaces (including most of the web if you don't take imperfect steps to avoid it) is the font and line height being way too small. The small margin from the cell size leftovers works for me, though it is also uncomfortably wide if used fully for one text area and I set a default width of 78 characters in my editor and make exceptions to that as needed.
Elastic tabstops sounds interesting, although the simple definition presented in the link above seems like there would be cases where adding a line is necessary just to get the desired horizontal indentation. A set of new characters could fix that and allow full document alignment characters as well as consecutive line alignment. I'm not fully convinced that some version of this is a good idea, but maybe it is.
as for elastic tabstops, i want to make three changes. gravgaard proposes a minimum column separation of one space, which i think is a mistake; i want rowspan and colspan; and most radically i want to be able to nest a whole document inside a grid cell with ^k and ^l as delimiters. that would give you fully freeform nested tables
https://sw.kovidgoyal.net/kitty/conf/#opt-kitty.window_paddi...
Nesting documents sounds interesting too. It looks like there are already control characters for "file separator", "group separator", "record separator", and "unit separator" that could be used if they were supported (or "start of text" / "end of text" might be a better fit for nesting, though I'm not sure how any of these were historically used). One issue I have with elastic tabstops is that once you go past "every character can be rendered based on the character and position" there are a large number of potentially interesting features and you would need to find something compelling to decide what features to include or exclude (or else you just have one of many possible document formats, which could be ok for an individual programming language but not as "plain text").
as for plain text, specifically what i want is plain text that can accommodate proportional fonts and different font sizes without losing the ability to do layout. actually specifying things like fonts, font sizes, colors, padding, margins, borders, corner radii, drop shadows, filters, etc., might be done not at all, with some kind of standoff markup (where the markup is in a different file), with embedded escape sequences, or with syntax-highlighting-like rules
^k and ^l, vt and ff, have an advantage over other possible delimiter characters: they are conventionally considered whitespace, making them legal in between tokens in most existing programming languages
with respect to what control characters have historically been used for, i can recommend erica fischer's paper on the history of ascii: https://ia801805.us.archive.org/24/items/enf-ascii/ascii.pdf as well as tom jennings's history of character codes
I have also been starting to think about something a bit similar (but more restricted) on the terminal side, how to adjust terminals to work well with at least proportional fonts (since some languages really need them) and maybe a larger font possibility that uses two lines (I think retaining the fixed size cell as a basic layout feature would be a good idea even if the one cell to one character mapping is removed). Maybe also out of band signaling. Something with much more limitations than the web or GUI (such that the user can configure things once to apply to most everything), although possibly with a full GUI or more complex rendering mode. I hadn't even started to think how it would interact with plain text but I could see some basic positioning/layout stuff being useful in plain text also without causing too much trouble if defined in an easy to render way (as would be best for terminals also). Although the usual issue of how to get there from here would still be a challenge :/.
all languages except chinese, japanese, and korean really need proportional fonts
I know de gustibus non est disputandum, but if you picked up a book in a bookstore and it happened to be printed in Intel One Mono, would you really think, "Oh, what a visual pleasure!" or would you think, "Oh, how unfortunate that 50 years ago they couldn't afford to properly typeset this book and so just xeroxed these typewritten pages!"? I would think the latter.
I've been meaning to try Intel One as my main sans-serif font in the web browser and just changed it (adding it to the top of sans-serif in fontconfig). Looking around a bit I would say the one less than ideal aspect is the word spacing and setting that to -.3ch via stylus to test (unfortunately not a long term solution since it messes up other fonts) makes it look even better (particularly with justified text which gets quite unreasonable with the mono space as the starting point). Maybe I'll try to create a derived "almost mono sans" that just adjusts the space width.
I had a new idea as I woke up today about the layout problem of reconciling a character-cell grid with proportional text, but I don't have it fully understood yet. Basically the idea is that, if you know that a given span of text contains no internal horizontal alignment constraints—for example, a line of a paragraph, or a table-header column title—you can lay it out with internal proportional spacing.
If you run xterm with a proportional font, for example as
xterm -fn '-*-helvetica-*-r-*-*-18-*-*-*-*-*-*-*'
you can get a sort of crude approximation of this behavior; each string it receives from the process in the pty as a single operation gets drawn as a single string and therefore has reasonable horizontal spacing internally, but characters drawn one at a time get placed one by one at their properly horizontally-aligned location. So if you type "ls -al", the six characters show up far apart because they appear one by one; if you then type ^U^Y to erase and redraw them, they appear together as a single string.(I kind of hate Helvetica, but because it's so proportional, it's the font that demonstrates this xterm behavior most clearly.)
xterm is doing this by accident, and so it does things like fail to erase characters that should be erased, use a far-too-wide width for each character column, and not tab to a requested column even when processing actual tab characters (like in ls -Ca output). But you could, I think, improve the behavior substantially with a few small changes.
First, you'd need some kind of explicit indication of which spans contained no internal alignment restrictions, instead of just using the stochastic clue of which characters showed up in a single read() call, which I think is what it's doing.
Second, you could allow each column of the character-cell grid to contract to contain only the characters it needs to contain, rather than giving them fixed locations; using a narrower-than-one-en width for the space character (as your -.3ch kind of does) would probably help with that.
Third, you could probably stretch and squish the actual letterforms themselves—TeX doesn't do this (though it does adjust interletter spacing), and hot lead can't, but medieval scribes did it constantly, and such "microtypography" is coming back into vogue. The place I see it most conspicuously is in the Android Heliboard autocorrection buttons displaying candidate words, though in a fairly crude and rebarbatively exaggerated form.
Fourth, certain glyphs (such as box-drawing characters) definitely have to be stretched to fill out the entire requested space.
I'm not sure this is a good idea, but it might work acceptably.
I look forward to seeing what you come up with!
Nano Emacs – a set of config files to improve the look and feel of Emacs - https://news.ycombinator.com/item?id=33403169 - Oct 2022 (4 comments)
Emacs Notebook - https://news.ycombinator.com/item?id=29932274 - Jan 2022 (1 comment)
GNU Emacs / N Λ N O – Emacs made simple - https://news.ycombinator.com/item?id=29373104 - Nov 2021 (1 comment)
On the other hand, highlighting could help you with semantic. For example rendering in a different color a word that's not been declared/defined before would be greatly valuable. Telling a variable from a type would also be helpful in C-like languages (no, current syntax highlighting schemes don't do this, not even the ones backed by tree-sitter). What about a switch to grey out all local/static definitions and thus emphasize only exported/public ones?
It is not clear if these implicit choices derive from the ignorance of alternatives or if they derive from developers' habits, reproducing what they are used to.
Woah there, easy tiger.The OG literally invented editing text on computers, and since then many novels have been written on keyboards and computers. The "text" editors have fed back into the more basic code editors and we're in a mixed situation between "comfortable to edit code" and "comfortable to edit text".
I'd be interesting to explore more visual programming built into text editors, as an overview of code flow, because right now the best we have is the direct stack trace. In terms of code it would be great to have integrated tools that show a visual representation "map" of the functions usage and data flow.
As for regular prose, it would be interesting to see editors specializing in poems and other use cases. I know some editors specialize in novels by having wiki like features of linking characters to storyline and research work.
I'm not sure how much of those are used by real world authors though, I think they mostly are trying to get closer to the "typing machine" as possible, removing any kind of distraction to get the X words per day in.
I agree, though there is a lot of subtlety in this problem. I tried, with very modest success, to write a tool that would overlay some graphics showing these kinds of information on top of a regular code listing.
The results were rather satisfying when the structure to be illustrated was relatively simple, as it often is in well-written code. However, trying to use those visuals to help analyse and understand less well-written code with complicated, tangled flows felt like looking at spaghetti code in a very literal sense.
Qualitatively it made it obvious when code could benefit from some cleaning up, but that isn’t very useful information unless it also provides useful insight into how to clean the code up, and I never really found a style/format for the visuals that conveyed enough information to provide actionable insights but didn’t become so busy in bad cases that it became was hard to follow.
I know some editors specialize in novels by having wiki like features of linking characters to storyline and research work. I'm not sure how much of those are used by real world authors though…
I’ve only had this discussion with one author recently, but FWIW, they swear by that kind of structured story planning software. I’m not sure how many of the concepts or presentation details in those applications would translate readily to tools for working with code, though.
https://news.ycombinator.com/item?id=41668304
"Bit of a side issue for me: I was working on my Unity game the other day and thought to myself, have IDE's really not progressed all that much in the last 10-20 years?...yada yada"
I don't want to get sidetracked by commenting on it again but I highly agree with the paper, it's time to change things up.