It’s an interesting idea to use colours for more information in a text editor.
A lot of the suggestions here are things VS Code has been incrementally adding as visual guides over time though. For example the way VS Code highlights other instances of the same symbol (variable/function name) under the cursor goes a long way to address the specific Import, Argument, Type, and Exception cases listed in the article.
Combined with heat maps for test coverage and git commit recency in the gutter, I am skeptical that switching out syntax highlighting on demand (I.e keyboard shortcuts I’m assuming) would be ergonomic and viable.
That said, I love that there’s thinking in this space on how to improve the visual comprehension of code. There still are plenty of crutches I use, such as expanding the selection along the syntax tree (^??? on Mac) just to trace all the parenthesis and braces in JS/TS – I don’t find the rainbow braces very useful at all.
IntelliJ IDEs have great support for customization of this - for example, I highlight functions, properties, and extension function calls differently in Kotlin.
The example with the circles is a little misleading. The first task is find the circle, whereas the second task is find the red object, since this is the circle.
That said, I totally agree with the notion that the color channel can be used in different ways during different tasks. For example, when reviewing a book, highlighting is a useful way to utilize the color channel. But what percent of the time do we spend re-reading text versus reading it the first time?
I actually created a startup around and idea I had that makes better use of color during the first reading. [1]
My approach improves visual tracking and attention by using subtle color gradients that wrap from the end of one line to the beginning of the next.
You’re right that on the website I use the ‘bright’ color scheme, to make it as obvious as possible what’s happening. The color options within the tools are more subtle (darker red, in particular).
I get the opposite effect. The shifting colors slow me down because I'm expecting them to have some special significance. Once I force myself to ignore the colors, I can read at almost normal speed again (although it takes extra concentration). I wouldn't want to read a whole page like this.
Have you ever read a lot of small-font wide-margin text and had momentary trouble with seamlessly traversing focus from the end of one line to the start of the correct next line?
I have, and suspect a lot of people have. Very minor issue, but the fact it happens suggests there is some small cognitive load that could be alleviated in general.
I do suspect that the optimal type of visual affordance may vary from person to person.
Is this supposed to help focus and get deeper understanding of long texts? Because it’s slowing me way down, changing my extremely fast reading mode that often looks forward a bit for improved context, to a more word-by-word style of reading.
Yeah, it's not for skimming — more for 'close reading'. It's definitely not for people who speed-read/skim by moving vertically down the page. But it can speed up close reading (where you're reading every word), and it also turns out to be helpful for certain learning disabilities (dyslexia, ADHD, etc).
The person you're replying to is not describing skimming, they're describing reading instead of "sounding it out".
Your technique seems able to help people who likely learned to read with a ruler hiding upcoming lines, or with a finger pointing at the word they say aloud, and people who read with subvocalization.
Such readers generally process text at not much higher rates than speech, and often prefer audio books or YouTube which add visuals or emotion since reading holds no particular advantage.
Other readers take in chunks of meaning, mapping from word form sequences to concepts without going through phonics. It's not skimming. (It's possible it's the same pathway but subconscious instead of aware of the tracking and subvocalization.) These readers can still play back the individual words, with the same recall accuracy as the word by word or sound by sound readers. For these folks, audio books and YouTube are an excruciatingly slow way to transfer information.
These faster readers are "close reading", not skimming. They are reading every word, but mapping word shapes into phrases at a time (perhaps similar to how LLMs can correctly answer completely typo-garbled questions).
The difference between these methods of reading is at least 4x and often 10x or more speed with the same or better concept learning and recall.
Your method is clearly (pun intended) able to assist those who would 'need' the ruler or fingertip to go sound by sound or word by word, with crossing end of line to start of next. (Likely similar reasons some folks read web pages successively highlighting lines with their mouse; your approach would likely help them too.)
But as you're seeing in these comments, it generally brings sequence absorbers to a crashing slowdown.
Only speaking for myself: I love reading, always loved reading. I read a lot, and I read every day. It’s one of my most important things in life. I’m guessing doing something that much just comes with improvements.
> Your technique seems able to help people who likely learned to read with a ruler hiding upcoming lines, or with a finger pointing at the word they say aloud, and people who read with subvocalization.
> Such readers generally process text at not much higher rates than speech, and often prefer audio books or YouTube which add visuals or emotion since reading holds no particular advantage.
I'm somewhere in between these - I subvocalize, but at about 2-3 times the speed of speech, and I hate audiobooks/etc. My eyes jump several words at once and I read them individually with my peripheral vision - so the while their example isn't really slowing me down much, it is distracting.
I find the example website almost as distracting as a Hollywood ransom note made out of random newspaper clippings. But it's even worse with the continuous variation, as some phrases seem to call out as if the color were emphasis like italics, bold, or underline.
It's got me wondering if zebra-striping background shades as in spreadsheets would be a better compromise. To help some readers with their eyeball "carriage return" without disrupting those of us who visually parse larger blocks of text.
>The example with the circles is a little misleading. The first task is find the circle, whereas the second task is find the red object, since this is the circle.
I think you completely missed the point of the square/circle example. The red circle is just a circle with syntax highlighting. The task is still to find the circle, but you are supposed to know in advance that the syntax highlight color for "a circle" is red.
The first circle is shown without syntax highlighting, the second circle is shown with syntax highlighting. "Square" and "circle" is the syntax, red is the highlighting. The point of the first example is to show how much easier it is to spot the circle when it takes advantage of syntax highlighting.
It's a very good example of why syntax highlighting helps with these kinds of tasks. The squares could be blue, black, yellow or white and it would still be easier to spot the circle because it's highlighted in red.
It doesn't even matter what color the circle was highlighted with, so long as it's different than the syntax highlighting of the squares.
My mind keeps trying to associate meaning with why some words are highlighted and others are not.
Since there is no particular reason, my mind came up with an alternation in recital: redder words are spoken more loudly, and blue words are spoken with a higher pitch.
definitely forces you to slow down and try to read the words (and end up feeling annoyed it didn't highlight importance as you'd usually expect), but i kept getting 2000s / 2010s word art and powerpoint effects vibes from the gradients.
Yup, I like this point. Oils / YSH is kind of a mash-up between shell and Python:
1. shell-like commands - ls *.py
2. python-like expressions - 42 + a[i] + f(x, y)
So it would be nice to highlight them differently to help people learn the language. It's not always obvious where commands are valid and where expressions are.
I think it's not a good idea to cram it all into colors. Many of these things are already possible in modern editors. Through hover, squiggly lines, faded out lines, marking at the left / right of the lines or other hints. If you do it all with colors, you are introducing different modes. And modes should be avoided if possible UX. https://www.nngroup.com/articles/modes/
I don't get that conclusion from the article. The summary is that modes are useful for exposing a large number of features using a limited number of input controls, but that care should be taken to make each mode visually distinctive, and to not use them when mode input errors could have disastrous consequences.
I get some of the criticism, but those are minor concerns to decide to avoid them altogether. Modal UIs can make users much more productive, and input more intuitive, after an initial adjustment period.
Consider the Normal/command mode in Vim. With just a few keystrokes you can operate on text in a fraction of time and effort than in Insert/editing mode. Not only that, but commands are combined using intuitive mnemonics (`cw`, `di(`, etc.), which makes them easy to remember and discover.
Whenever I go back to an editor that uses key chords for commands, I gain a larger appreciation for modal UIs.
I didn't claim that Vim was easy to learn, it certainly has a learning curve. But once you go through `vimtutor` and keep some cheatsheets handy during the adjustment, the actual command composition becomes rather intuitive and discoverable.
This is much more user friendly than remembering a list of Ctrl+Alt+<something> key combinations found in non-modal UIs.
If the ASCII text format had included the color byte next to every letter-byte, we might have had manually colored programming languages (i.e. it would be a kind of code comment). Imagine, coding guidelines that include coloration requirements...
(I usually use this observation from the other side, as a reductio ad absurdum about coding guidelines that could as well be implemented as editor settings.)
I don't show as colorblind on any of the tests, but on some monitors I can't distinguish this shade of green (https://htmlcolorcodes.com/colors/nyanza/) - or any paler green - from white. I worked at a place which used an alternating white/green background pattern to distinguish data rows (because company branding was a darker similar shade of green). Moreover the coding culture there was to favor manually created (not programmatic) data grids if the information was static, so it was manually colored. I was always getting asked, "why did you break the color pattern?" and my response would be, "what pattern?"
The funny thing is we were supposed to be making Ada compliant websites. But I guess it didn't prevent using the website, just an aesthetic choice. Or "can't see one specific shade of green" isn't a disability.
For what it's worth I also have never been entirely convinced "navy blue" is different from "black" and that the existence of navy blue as a distinct color isn't some elaborate joke being played on me. Someone gave me a pack of dress socks of all different shades of grey, black, and navy blue as a Christmas gift, and they meant well but do not know the apprehension they caused.
I prefer my navy blue stuff to be a slightly lighter shade than sometimes used. For a really dark navy, I’d need to have a known black reference, and a lot of light, to determine the color.
And that light green just looks tan to me (kind of like the background here on HN), or like a normal monitor with the blue light blocking turned on.
Doesn't Emacs have syntax highlighting for all of these cases? It even has a tree-sitter integration which highlights even more accurately than good-ol-regexes.
Something i wanna try at some point, is to make all faces in a file equal to the background, except for comments, so as to read only the comments of a file. Or read only comments and function definitions. Or only function definitions and variables.
That might not be difficult to do it yourself. Modus themes for example have code mappings, with a different coloration for code literals. In that file [1] for example, bg-main has the hex value of #000000, total black. If you want some part of the code to disappear, make it the same value. You could make builtins or constants #000000, and they will not be visible in the source file.
You can create different themes, like a comment theme, in which every part of the code is invisible (i.e. hex value black) except for the part you want visible, comments in that case. Then when you want everything visible again, you toggle the loaded theme.
I don't know if i will create such themes myself, my github account is on github/pramatias. I may upload something in the future, or may not.
With comments, it depends on the case. When reviewing code, or on an architectural refactoring with no new code being inserted, comments being more visible is certainly desirable. In a normal setting of writing code, comments should fade out.
You can have the best of both worlds, by switching themes with appropriate coloration whenever you like. In emacs there are a ton of themes, each with it's own emphasis on coloration, but you can also make your own easily, or tune an existing one. I have commented already on how to tune one, using modus themes, on the same thread.
> In a normal setting of writing code, comments should fade out.
Not convinced by 'should' because it seems like it would make it easier to not notice a comment that needs updating and humans in general (myself definitely included) are bad enough at that already.
(Note that that doesn't mean I'm arguing that it's a -wrong- choice, just yet another trade-off to be considered)
I had lexical highlighting in javascript for a while, but IIRC I stopped using it because the plugin didn't play well with JSX.
To be honest it wasn't that big of a deal. Definitely not a game changer. Although I like that people are at least considering these things. Most people I showed the lexical highlighter to couldn't imagine not having syntax highlighting (which is silly, you get used to it quickly).
I like Vim highlighting method. It's does its job but prevents you from stepping into a rabbit hole.
Argument/field/etc highlighting already leaked into popular IDEs and gosh I hate it when it's a non-tunable default. Feels like reading through a christmas tree. And I can never tell which shade of cyan is which anyway, unless it's textually obvious.
This is not that great idea. Both too little and too much information is bad.
I've already experienced it in practice in NetBeans 6+ where there was so much information (not just colors but various types of underlines etc.) that the code just looked like a rainbow and was hard to focus. I had to disable half of the features to be able to work again.
(Interestingly there were more issues with the newer NetBeans versions that I decided at one point, screw it and downgraded to NetBeans 5.5 and it was the best decision for my productivity in Java, I use it to this day).
Highlight variables across function calls and produce hues of that colour as the variable is consumed by computation into other variables.
Colour functions by how big their test coverage is using flamegraph metadata.
My IDE already tells me through colours (lighter hues) and squigglies if a function is transitively unused (when not exported), or a variable is declared but not consumed.
Nowadays, things like Treesitter can provide comprehensive semantic syntax for many languages, along with surprisingly elegant ways to run custom queries that might let you do some of the things listed here, with a consistent interface across multiple languages.
I used to cycle through various VIM highlighting modes for this reason, but I never stopped to think through what I was doing. I just did it. I recall one scheme lit up all the integers so I could see all the magic numbers in my code. This is a great idea. Looking forward to seeing it in VScode.
I was excited for this because the premise made a lot of sense, but I think the examples demonstrate why we don't already do this in the ways listed. (Stick around because I'll list examples where we already do this in far more useful ways that people with poor tooling don't seem to know about)
Nesting parens and/or braces - Breaking things into functions and clear indentation within those functions is already a much clearer information channel. Color is nice and all, but it's no substitute for communicating abstractions and invariants. If nothing else, code should still be clear even to people using different tools or with color blindness.
Many of the suggestions, such as "Highlight all functions with try blocks" and "All functions more than 100 lines long", point to code quality problems due to leaky abstraction. If it matters to a function's caller whether it has 99 or 101 lines, or whether it can internally handle errors, something is desperately wrong. If you want to discourage such functions, we have linters for conditions like that, it shouldn't be a distraction to people maintaining the callers of such functions.
An example I almost agree with is "All functions that transitively call functions that make an http call", though I would generalize that to any network IO. Conventionally, in Rust such functions should now be async functions, and in Go they should take a `Context` for cancellation, both of which are visible at the call site, so idiomatic code is already clear in these ways. Again, it's a way we make things clear and explicit in the code itself, not just the highlight. (It's one of the reasons people blasted Scala's implicit arguments design; the saving wasn't worth the loss of clarity, highlighted or not)
"All lines last edited by a particular member of the team" - IDEs already have git blame views that provide much more information such as the commit comment and date. Either way these often fall down in practice; if you so much as change the indent level, it's your line now as far as the tooling is concerned.
Now for examples where we actually do this already and deserve to be credited:
JetBrains Rust Rover highlights unsafe functions very distinctly. unsafe{} blocks are allowed to call safe or unsafe functions, and this just shows you which of them are unsafe. That's a lot more useful than "All functions more than 100 lines long". I don't care how long it is, I do care if it could be the reason my project becomes the next vulnerability news cycle.
Unlike Rust and Java, Go doesn't have a way to limit a binding to at-most-once initialization, so "All variable identifiers we assign to twice" might actually be useful though in many cases it would just be ugly for no reason. For now though, JetBrains GoLand highlights shadowed variables, including in cases where they avoid bugs more than they cause them, but at least the right intention was there; whether a variable is shadowed is visually unclear in Go because := reuses an existing binding or makes a new one depending on the scope (unlike Rust's `let` which always makes a new binding even in the same scope), so the highlighting does provide information that's easy to miss otherwise. Where I disagree most is that the puke-green color makes it look like you're supposed to avoid it. Of course GoLand also highlights reused bindings specially too, with a neat underline that doesn't make it look like a problem to avoid.
I could go on but this is already a very long comment. I hope this is enough to demonstrate that many of the examples don't make a lot of sense because there are already better highlights or other tooling available, and tools already do use semantic highlighting for a few useful things without reducing the value of syntax highlighting. This is a well-understood idea in modern tools, it's just used more sparingly than suggested here.
I like the "unsafe function" idea. More generally, it would be great if you could somehow show an "unsafe chance" metric, which would show lines that can cause multithreading issues. That is, rather than relying on the unsafe{} blocks, you would use some sort of Valgrind or similar output to generate a heuristic that measures the chances of shared data collisions or the like.
This is kind of similar to the way Wolfram Mathematica highlights code. If everything is fine, everything is mostly black. Color is used while editing to highlight the "Head" and brackets of the expression being changed. It is also used to bring attention to missing/excessive parameters or invalid option names.
Love it. I want to color the lines based on their chance for causing errors. It would have to be a heuristic based on various metrics, like the number of historical changes to a line, code complexity, and test/coverage hits.
Why not have an editor, in which you can switch between various colorings? Like switching to friend-foe colors on the minimap in a strategy game and switching to normal player colors again. Just that one can switch between syntax highlighting and something else.
A lot of the suggestions here are things VS Code has been incrementally adding as visual guides over time though. For example the way VS Code highlights other instances of the same symbol (variable/function name) under the cursor goes a long way to address the specific Import, Argument, Type, and Exception cases listed in the article.
Combined with heat maps for test coverage and git commit recency in the gutter, I am skeptical that switching out syntax highlighting on demand (I.e keyboard shortcuts I’m assuming) would be ergonomic and viable.
That said, I love that there’s thinking in this space on how to improve the visual comprehension of code. There still are plenty of crutches I use, such as expanding the selection along the syntax tree (^??? on Mac) just to trace all the parenthesis and braces in JS/TS – I don’t find the rainbow braces very useful at all.
reply