luke.b//blog

I am genuinely feeling like a small amount of progress is better than stabbing around in the dark trying to fix issues I don’t fully understand.

Taking things back to base principles is time consuming but also very satisfying and much easier to validate than a trial-an-error approach, which I’m all to familiar with.

I’m also using this as an opportunity to practice writing good tests, because ultimately I’m starting to believe that good tests are the savior of sane software development.

I made a small amount of progress on rewriting the “buffer” component of my terminal, which is a prerequisite of rewriting the “scroll margins” component, which is a prerequisite of hopefully fixing some bugs.

I tell myself it will all be worth it in the end.

There seems to come a point in most software projects where a bug appears that reveals a large amount of technical debt, which previously was harmless.

It turns out there’s a bug in the terminal that I’m writing that suggests I’ve been doing it all wrong from the beginning.

It also turns out that implementing scrolling - any kind of scrolling - is one of the hardest problems in computer science that remains unsolved… by me… in this one project.

Anyway. Rewriting this part of my terminal will be tricky because it isn’t separated out from the rest of the terminal in a nice way.

One option is to separate it out, write tests for that specific part including tests that will fail unless a certain bug is fixed.

This seems to be quite an effective method: “iterative TDD”.

Every time I go to buy an urbit identity, I end up spending a long time looking at all the cool icons and weird names and I get decision paralysis trying to figure out which one I want to use.

I came back to this scrolling issue twice now, and ultimately I’ve realised that the code which updated the “Scrolling Margins” of the terminal buffer is flawed in that it doesn’t just scroll the lines of the buffer that are within the margins, but it also reduces the size of the buffer to the size of the viewport, without preserving the location of everything that was in the viewport before.

To solve this I think need to make sure that the entire buffer is preserved, but the lines within the scroll margins are scrolled.

The issue is that the scroll margins are relative to the viewport, but the buffer isn’t necessarily the size of the viewport. I think this could be the design flaw that makes my implementation so complicated, but it has certain advantages.

Scrolling the content is such a crucial part of a terminal to get right it seems. A lot of interactions depend on it going smoothly.

I think I want to take the TDD an reintroduce the scroll margins as an individual component.

For now I’ve figured out how to fix the bug though, so I’ll continue.

For once it looks like my tests have picked up on a regression, which is good :)

For now I need to rest though!

I’ve been trying to fix a bug with with nomad all morning so I ’m going to take a break.

Essentially it fails to deal with the terminal changing in size such that there are fewer rows on display than there are in the internal buffer.

Before the resize, the cursor is positioned by the running program in the buffer and the program might assume that during a terminal resize, the cursor will stay in the same position. I’m pretty sure bash assumes this, for example, because it doesn’t send any cursor position updates when the program is sent the new size of the terminal.

But after a resize, the program might send a \n, which will incorrectly insert text at the row index that is now beyond the now smaller buffer.

I’ve made some progress this week at enabling text selection in nomad, but I’ve realised that clipboard access is actually a bit tricky.

Each platform has slightly different requirements when it comes to supporting the clipboard. It’s possible to run different programs depending on the platform in order to copy/paste something from/to the clipboard:

macOS

# copy text
echo 'hello' | pbcopy

# paste text
pbpaste

Linux

# copy text
echo 'hello' | xclip

# paste text
xclip -o

I can’t be bothered right to do this bit now, but at least I’ve made a small amount of progress.

I am so tired from work. ugh.

Didn’t get as far as I wanted on the text selection feature for nomad. I did fix a bug with mouse tracking control sequences not being parsed correctly, and I also started work on detecting mouse press/release sequences.

Next I will have to make the subterminal aware of where it is relative to the host terminal so that it can calculate the offset position.

It’s possible that the program running in a subterminal will expect to receive mouse control sequences. This is normally controlled with a flag that enables this behaviour, so I might have to make the subterminal aware of this flag and make sure that text selection can only be done if the program being run is not interested in mouse tracking (e.g. bash doesn’t care about mouse clicks, so it won’t set this particular flag).

I’m going to take a quick break from my Urbit antics to start writing a feature into nomad that will allow text selection and support for copying text to the clipboard.

It’s something I really miss when I’m using nomad because it’s really frustrating not to be able to quickly copy some output to slack or to use in another command.

First up - text selection. This will require parsing of control sequences that indicate mouse interaction, which is already used in nomad for scrolling individual terminals.

page 7 of 27 after before