Tab lists its matches in columns, and says what it can in colour

Tab's listing was six instructions: print the name, print two spaces. It
was the crown of this shell for a while and looks plain next to ls.

Columns cost NOTHING EXTRA. Tab already walks its candidates twice - once
to find the answer, once to show the matches, and tabRunSources exists
because those are the same walk asked two questions. The longest match is
counted on the first, which already visits every one of them, so the
listing needs no walk of its own to know how wide a column should be.
Padding goes before a name rather than after, so a row ends on a name.

Directories are blue and the shell's own commands are green. Both are
free: Tab appends the separator itself, and a built-in is not a file at
all - which is also the only way anybody could know it will run.

A FILE IS NOT COLOURED, and that is a decision. Whether a file will run
is a read of its first block, which is what ls does and what makes ls
cost twice what it otherwise would. Here it would be worse than slow:
candidates are offered from inside a directory walk, and looking a file
up would overwrite the very fields holding the walk's own position. Doing
it safely means holding every candidate name in memory, which is a buffer
the shell would carry whether anybody pressed Tab or not - and ls is one
keystroke away. A Tab press already costs about 200,000 cycles, so the
read was not the objection.

---- And the machine could no longer build itself ----

Found by make test, not by reading. The native assembler ran out of room
for label names on cosmos.asm: 16,758 bytes against 16,384. The index was
1,341 of 1,536 in the same breath.

Which is scratch.asm's own warning happening a second time - "two
ceilings a hundred bytes apart look like one ceiling until the first is
lifted" - so both were raised, out of the seventeen kilobyte page that
file deliberately left unclaimed against exactly this. Names to 26,624
and the index to 2,048, both left about a third clear, with 1,792 bytes
still unclaimed for the same reason.

A name is thirteen bytes on average and an index entry is four, so the
arena will always be the one that speaks first. That is now written down
where the two numbers are.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01E2JrLzFvuFX9fgi1LDRjrW
This commit is contained in:
Anachronaut
2026-09-06 20:18:56 -04:00
co-authored by Claude Opus 5
parent eaeb473176
commit 563bc20a75
9 changed files with 263 additions and 26 deletions
+17
View File
@@ -481,6 +481,23 @@ program; anything after it is a file.
A directory answers with a separator on the end instead of a space, which says what it is and
lets the next part be typed straight away.
**And when there is more than one, they are listed in columns**, sized to the longest of them,
the same way `ls` lays a directory out. The width comes from the screen and the longest name
is counted on the pass that finds the answer - which already visits every match, so the
listing costs no walk of its own to know how wide a column should be.
**Directories are blue and the shell's own commands are green.** Both are known for nothing:
Tab appends the separator itself, and a built-in is not a file at all - which is also why no
amount of reading the disk could have told you it will run.
**A file is not coloured, and that is a decision rather than an omission.** Whether a file
will run is a read of its first block, which is what `ls` does and what makes `ls` cost twice
what it otherwise would. Here it would be worse than slow: candidates are offered from inside
a directory walk, and looking a file up would overwrite the very fields holding the walk's own
position. Doing it safely means holding every candidate name in memory first, which is a
buffer the shell would carry whether anybody pressed Tab or not - and `ls` is one keystroke
away.
**Files are looked for in the three places the shell would look to run one**: where you are,
`/Apps` on the disk you are on, and `/Apps` on drive 0. Offering something the shell would not
find would be finishing a word into a thing that then does not work. A file that is in two of