CC: Tweaked

CC: Tweaked

42M Downloads

Vague thoughts on improving CraftOS UX

SquidDev opened this issue ยท 5 comments

commented

This isn't really a concrete feature request, but is more some musings on things which would be good to improve to make programming in ComputerCraft a little bit friendlier. I suspect some of what's written here is worth adding to CC, some should be in an external program, and some is an utterly terrible idea!

Definitely would like feedback here, both on sorting out my ideas, and suggesting any other frustrations and UX improvements we could be doing.

Scrolling in the shell

This has been discussed before (#792), where I originally closed it due to concerns about implementation complexity. However, given how useful scrollback is, I do think it's worth revisiting this.

Obviously mbs has had this for years, and while I think there's some bits worth mimicking (the handling it handles full screen programs is very sensible) it's probably worth avoiding copying wholesale. We definitely need a better way of handling errors that occur in full-screen programs (as those get entirely hidden right now).

What's less clear to me is when the shell should scroll, as in when should page up/down and the mouse wheel move the terminal up/down, rather than being forwarded to user programs? mbs intercepts these events when the cursor is blinking (so read is being called) and not in a full screen program (e.g. paint or edit). This works fine, but maybe it's is too hacky for CC itself?

Full filenames in debug information

When CC:T loads a Lua file, it uses the file path as the chunk name, rather than the whole path. This is a bit of a pain for debugging utilities, as you can't map functions back to their original file. We end up doing some very nasty things in our code coverage tooling to work around that.

We've looked at changing this before (#465): the main problem is that for long file names (especially APIs from the ROM) take up far too much space on smaller screens, which makes errors pretty unreadable.

I wonder if the solution here is to patch Cobalt itself: we could make a file's shortsrc just use the last path segment, rather than the last 60 characters.

Tracebacks

There is an existing issue (#231) for this, but I think it's also worth mentioning here. There's been a couple of concerns I have which is why this issue hasn't had much movement:

  • Tracebacks can end up being very long. On turtles, this can mean that the actual error message is pushed off the screen, which is no good! The obvious solution to this is to make the terminal scrollable (see above).

  • Tracebacks can be pretty information dense. Again, on smaller screens, this can make them pretty hard to read, and distract from the actual error. The easiest solution here would be to draw them in a different colour to the actual error (i.e. light grey).

    What I would love to do here is make the error message something you can interact with. For instance, when a program exits we just display the error. However, clicking the error should reveal the first few lines of the traceback (and a "show more" button). You could even have it so that you can expand individual traceback lines to show the actual line of code.

    I think this is probably more towards the end of "this should be a separate project" (or at least should be prototyped externally first). I don't know, maybe a "much better shell" :p.

  • Lua doesn't have the notion of an exception. This means that if a function errors inside a coroutine (such as with the parallel API) or in a coroutine, you have to rethrow the error and throw away all the traceback information. This means whatever we're showing the user could be absolutely useless, which is no good!

    The only solution I can really think of here is to actually define an actual exception type (I'm being fancy, it'd just be a table with a metatable) and provide some utilities for capturing/rethrowing them.

Errors should contain columns

Like with filenames in debug information, this does require modifying Cobalt in a way which diverges from PUC Lua behaviour. I think it's worth doing, as long as we're careful to preserve backwards compatibility (of course!) and make sure our changes could easily be applied to other Lua runtimes.

Runtime errors

While Lua bytecode doesn't track column information, there's no reason we can't still store it in the runtime representation of programs. I don't think we want to surface this in the error message itself (so it'd still just be <filename.lua>:<line>: <error_message>), but we could expose it in debug information - a currentcol to go alongside currentline.

That said, not 100% sure how this should be exposed to users. If we did have our fancy interactive traceback code, we could show the line of code with a red squiggly underneath. Maybe it's worth doing that anyway?

Parser errors

As parser errors are just strings (so are runtime errors, but at least we have the debug API too!), I'm less sure how we expose column information here, though here's some possible options:

  • Put it at the beginning, so errors now start with <filename.lua>:<line>:<col>: is definitely an option, though a little opaque (and maybe breaks programs using Lua patterns on errors, though not sure if we care about that).
  • Add it to the end in the form at column <col>. So, for instance 'then' expected near '=' at column 2.

As an aside, Lua's parser errors stink so much. Maybe we should could a pure-Lua parser which runs in the event of a syntax error and provides better error messages? Again, probably better as a separate project first!

Lua REPL should do syntax highlighting

mbs has had this for years, I've just not got round to adding it to CraftOS as I'm not sure about a good generic API for highlighting in read. The one in mbs/metis is not very user-friendly.

commented

Anyway, I'm still retired. I promise.

commented

It's just a very active retirement.

commented

Errors should contain columns

This is going to be a bit harder than I was expecting, due to how the Lua parser is structured. We should backport Lua 5.2+'s handling of line numbers first1 first, and then look at how to handle columns.

Footnotes

  1. Line numbers of an operation are associated with the rightmost expression. For instance,

    return x
      +
      y
    

    errors with test.lua:3: attempt to perform arithmetic on global 'x' (a nil value), reporting the error on line 3 rather than line 2. โ†ฉ

commented

As mentioned in #1320:

Something that I've given little thought to, but was the first thing on my mind: Would it be possible to, in the case of "attempt to call nil field" like in your example, look at the fields that do exist and try to find what they were looking for? So in this case, it may say something like: "Did you mean receive?".

See also my comments in #1320 (comment).

I think we probably need to do a trawl of the the MCCM and CCF again, and catalogue the common runtime errors people get stuck on - see what's most helpful to provide context on.

commented

mbs intercepts these events when the cursor is blinking (so read is being called) and not in a full screen program (e.g. paint or edit). This works fine, but maybe it's is too hacky for CC itself?

Maybe we should add another terminal api setScrollable, and set it to false when shell starts to execute a program