← Blog Home June 30, 2022

Editor Rewrite

I recently finished rewriting the TaskTXT editor. The goal with TaskTXT has always been to make the main editing experience a purely plaintext-based one. That means it behaves like a normal HTML <textarea> tag, nothing magically appears while you are typing, selection always works like you'd expect.

But TaskTXT has features that go beyond. These are carefully built to not get in the way.

1. Highlighting

The header line of a task is a darker color than the comments below it. This helps you focus on the tasks, and helps indicate which lines are being recognized as tasks. This isn't possible with a <textarea> tag. To do it, I overlay a transparent <textarea> on top of a regular div, which can have colors. They need to match up perfectly. This way, it looks like you are editing the colored text, but you are actually typing into an invisible <textarea>. It becomes visible when you highlight the text, and the coloring disappears. The good thing about about coloring text, is that is doesn't change anything about how you type or select text, it doesn't get in the way.

2. Annotations

There are things that appear around the lines of text in TaskTXT such as the timer buttons, timer value readout and the background color that appears in command mode. These are able to be placed accurately thanks to that extra <div>, the same one I use for text coloring. Each line becomes an HTML element, which allows me to place additional content that matches up with a given line.

3. Manipulations

When you press a timer button, or a checkmark button, the text is updated. At first this might seem to go against my rule that TaskTXT should have a purely plaintext experience, but consider that clicking these buttons only can happen while you are not editing. It's perfectly fine to have a button that changes the text for you, but changing the text or predicting what you want as you type is against my rule.

There's a decent amount of code involved in making these three things possible, and the more convoluted it gets, the harder it is to add additional features. I wrote a component I call <MirroredTextarea> which attempts to be act like a normal <textarea> for basic use cases, but can be extended with coloring, annotations and manipulations.

This has enabled me to add further highlighting features, such as changing the color of the guess, timer data. In the future I might add the ability to detect things such as URLs in your text so they become interactive.

Another feature my new system has allowed is for undoable commands. One of the nice things about using plaintext for the main UI of TaskTXT is that you can undo things you've done (typed) without me needing to build an undo feature. The new <MirroredTextarea> makes use of a technique for doing manipulations of the text that is undoable. Now if you click a timer, or a checkmark, you can undo the change. It simply uses the browser's built-in mechanism for undoing a change to text you've typed.