Commit Graph

76 Commits

Author SHA1 Message Date
Kartik K. Agaram 375c7fe0db bugfix: handle a missing save dir
Scenario:
  * run a whole new app (no save dir yet) as a .love file
  * open the driver, make an edit

Before this commit, I was seeing errors due to the save dir not
existing. Let's depend on love.filesystem as needed. Another "good seam"
IMO (https://lobste.rs/s/idi1wt/open_source_vs_ux).
2023-11-17 12:32:43 -08:00
Kartik K. Agaram a428068d3e fix initialization errors using driver.love
Changes inside on.initialize are minefields. Until now, if you made a
mistake when modifying on.initialize, you could end up in a situation
where the app would fail irrecoverably on the next startup. You'd have
to go dig up a text editor to fix it.

After this commit, errors in on.initialize wait for commands from
driver.love just like any other error.

Recovering from errors during initialization is a little different than
normal. I don't know how much of initialization completed successfully,
so I redo all of it.

I think this should be safe; the sorts of things we want to do on
startup tend to be idempotent just like the sorts of things we do within
an event loop with our existing error handling.

Things are still not ideal. Initialization by definition happens only
when the app starts up. When you make changes to it, you won't find out
about errors until you restart the app[1], which can be much later and a
big context switch. But at least you'll be able to fix it in the usual
way. Slightly more seamless[2].

One glitch to note: at least on Linux, an app with an initialization
error feels "sticky". I can't seem to switch focus away from it using
Alt-tab. Hitting F4 on the driver also jarringly brings the client app
back in focus when there was an initialization error. But the mouse does
work consistently. This feels similar to the issues I find when an app
goes unresponsive sometimes. The window manager really wants me to
respond to the dialog that it's unresponsive.

Still, feels like an improvement.

[1] I really need to provide that driver command to restart the app! But
there's no room in the menus! I really need a first-class command
palette like pensieve.love has!

[2] https://lobste.rs/s/idi1wt/open_source_vs_ux
2023-11-17 11:55:57 -08:00
Kartik K. Agaram ef5e7e0556 don't hide errors when driver.love connects
The intent of hiding errors is to see if a code change I made improved
things. But many commands from the driver don't involve a code change.
It seems more useful to leave the error up in those situations.
2023-11-16 23:12:14 -08:00
Kartik K. Agaram 90dc7ce6dc run all tests on startup 2023-11-16 22:10:03 -08:00
Kartik K. Agaram cda85faf3b remove cruft handler 2023-11-13 09:44:59 -08:00
Kartik K. Agaram 279c42966b Merge text0
I've tested both syntax error and run-time error flows.
2023-11-10 10:15:35 -08:00
Kartik K. Agaram 66ef316503 strip numeric prefix from callstack filenames 2023-11-10 07:06:37 -08:00
Kartik K. Agaram b38f172ceb remove a no-op regex munging on callstacks
It seems to have been introduced in commit 46889593da back in Jan, and I
was using it to summarize multiple failing tests. However, it's not used
in that scenario anymore (and anyway it seems wasteful to compute the
stack for each failing test and then throw it all away).
2023-11-09 21:16:13 -08:00
Kartik K. Agaram f6ee78f824 bugfix 2023-11-09 18:03:29 -08:00
Kartik K. Agaram cd5ab62971 provide a filename for clearer error callstacks 2023-11-09 17:53:30 -08:00
Kartik K. Agaram 9b4e1ce3e1 start saving edits right in the source dir
This is much easier to explain, and it also avoids errors like
forgetting to delete the save dir after editing sources in source dir.

One drawback: there's a little more risk of accidental data loss, either
because of bugs here or programmer mistakes. To mitigate this risk, put
your apps in a git repo and periodically `git commit`.
2023-09-09 10:47:22 -07:00
Kartik K. Agaram 993b5d6ca3 simplify check for '0000' 2023-09-09 10:17:38 -07:00
Kartik K. Agaram c7e26e656b ignore long (block) comments when selecting buffer name
I asked on the lua-l mailing list, and this seems like the cleanest
approach.
2023-07-25 15:36:11 -07:00
Kartik K. Agaram f23ed15fd9 avoid some unnecessary allocations
To find the first word we currently strip _all_ Lua comments. This is
really wasteful for large definitions. At least avoid all these
allocations if the first word is not a comment.
2023-07-24 00:44:34 -07:00
Kartik K. Agaram 5cac6d8584 handle messages that are all comment 2023-07-24 00:40:34 -07:00
Kartik K. Agaram d16eba699f don't tolerate Lua comments when parsing commands
We only care about Lua comments when the message doesn't start with a
command.
2023-07-24 00:28:24 -07:00
Kartik K. Agaram 6679c6e545 ignore comments when selecting buffer name 2023-07-23 22:32:36 -07:00
Kartik K. Agaram 3fdd0d339c slightly easier to understand
A comment is now in a better place.

Inlining an unnecessary function boundary removes ambiguity between the
similar names load_all and load_files_so_far. It also shrinks call
stacks on error.
2023-06-19 10:14:42 -07:00
Kartik K. Agaram d486f94a4b bail early on errors
Returning errors can feel warm and fuzzy, but it does no good if the
caller doesn't actually check the return value.

Scenario:
  define a new function B
  call it when initializing global variable A
  everything works fine
  restart

Before this commit you get a weird error because we silently stopped
loading, and now lots of functions are missing.

After this commit you get a better error message.
2023-06-19 09:56:24 -07:00
Kartik K. Agaram 2f933e383d delete a dead variable 2023-06-19 09:46:25 -07:00
Kartik K. Agaram 05a9b0c168 send a response when deleting a definition
There's a protocol invariant to preserve here: If a live command sends a
response in any situation, it needs to send a response in all
situations. Otherwise the driver can't decide whether to wait or not.
2023-04-30 22:58:31 -07:00
Kartik K. Agaram bda9ceccf6 refuse to delete frozen definitions 2023-04-30 22:04:01 -07:00
Kartik K. Agaram 01be5ccd9d combine 2 levels of indent 2023-04-30 22:02:57 -07:00
Kartik K. Agaram acc2fea361 bugfix: deleting definitions
scenario: delete a definition, restart
Before this commit, the deleted definition would return.
2023-04-30 22:02:29 -07:00
Kartik K. Agaram f41a1fc69d bugfix: recover from error on new command
Second issue introduced in commit a2451aa26. It's worth checking error
recovery in the simpler test, even though it's technically caught in the
next one. A little redundancy seems good here.
2023-04-22 18:05:16 -07:00
Kartik K. Agaram b4a9f7f7f1 bugfix: only include files with numeric _prefixes_
A Lua gotcha: gmatch doesn't support '^'. I don't know why I was doing
that weird single-iteration loop anyway.
2023-04-20 23:42:44 -07:00
Kartik K. Agaram a2451aa26e attempt at better error recovery
- I often find that opening up driver.love and sending any message gets
  my app unwedged. Retrying should be easy. Just press a key.
- There's really no reason for the app to become unresponsive while
  waiting for code changes.

This approach tries to address both. Press any key to retry, or show the
error right on the window while I whip out driver.love. You can also
copy the message to the clipboard by hitting 'c'.

Drawbacks of this approach:
  - nobody's going to read the message. I myself didn't notice the
    default support for copying the error message for _months_.
  - more complexity for anyone reading the code to parse. More stuff
    that can go wrong. Any errors within the handler will crash the app
    hard. (Though now there's less code in the handler, so maybe this is
    an improvement on that score.)

The best plan is still to not rely on this too much. Don't ship bugs.
2023-04-20 00:30:25 -07:00
Kartik K. Agaram 991eb3c660 remove a local 2023-04-19 08:34:18 -07:00
Kartik K. Agaram d929b1c1d7 missing definition 2023-04-17 21:10:17 -07:00
Kartik K. Agaram 912ca601ab new file-system format for freewheeling apps
1. No more version history, now we have just the contents of the current
   version.

2. Editing a definition no longer changes the order in which definitions
   load.

This should make repos easier to browse, and more amenable to modify.
You don't need driver.love anymore. And a stable order eliminates some
gotchas. For example:

  using driver.love, define `Foo = 3` in a definition
  define `Bar = Foo + 1`
  edit and redefine `Foo = 4`

Before this commit, you'd get an error when you restart the app.
Definitions used to be loaded in version order, and editing a definition
would move it to the end of the load order, potentially after
definitions using it. I mostly avoided this by keeping top-level
definitions independent. It's fine to refer to any definition inside a
function body, we only need to be careful with initializers for global
variables which run immediately while loading.

After this commit you can still end up in a weird state if you modify a
definition that other later definitions use. In the above example, you
will now see Foo = 4 and Bar = 4. But when you restart, Foo = 4 and Bar
= 5. But that's no more confusing than Emacs's C-x C-e. It's still
a good idea to keep top-level definitions order-independent. It's just
confusing in a similar way to existing tools if you fail to do so. And
your tools won't tend to break as badly.

Why did I ever do my weird version history thing? I think it's my deep
aversion to risking losing any data entered. (Even though the app
currently will seem to lose data in those situations. You'd need to
leave your tools to find the data.) Now I rely on driver.love's undo to
avoid data loss, but once you shut it down you're stuck with what you
have on disk. Or in git.

I also wasn't aware for a long time of any primitives for deleting
files. This might have colored my choices a lot.
2023-04-16 11:16:47 -07:00
Kartik K. Agaram e57ffabf4b make preprocessing more obvious 2023-04-16 11:16:47 -07:00
Kartik K. Agaram b0bcea8f95 some more cleanup after the undo 2023-04-16 11:16:23 -07:00
Kartik K. Agaram 209c380852 undo previous commit 2023-04-15 17:29:55 -07:00
Kartik K. Agaram 02cdf25c1d abortive experiment: keep definitions independent
Functions can refer to each other, but global variable initializers
shouldn't.

But this doesn't work. That comment keeps growing to capture more corner
cases.

Step back. What am I trying to achieve?

I'm not trying to create a better abstraction for programming with. I'm
trying to use an existing abstraction (LÖVE) without needing additional
tools.

I'm not supporting end-user programming, only end-programmer
programming. What happens in a regular LÖVE program if you use a global
before it's defined? You get an error, and you're on the hook to fix it.
But it's obvious what's going on because a file has an obvious sequence
of definitions. But what if you have multiple files? It's easy to lose
track of order and we mostly don't care.

The important property existing dev environments care about: merely
editing a definition doesn't _change_ the order of top-level
definitions. Let's just provide this guarantee.

We'll no longer load definitions in order of their version. Just load
definitions in the order they were created. Editing a definition doesn't
change this order. Deleting and recreating a definition puts it at the
end.
2023-04-15 17:24:11 -07:00
Kartik K. Agaram 6274322412 reorg 2023-04-15 10:14:42 -07:00
Kartik K. Agaram b6cb27ddf2 clarify a comment 2023-04-15 10:12:32 -07:00
Kartik K. Agaram 275b707546 rename 2023-04-09 22:31:12 -07:00
Kartik K. Agaram c1b86211cb prevent overriding foundational definitions 2023-04-09 22:29:44 -07:00
Kartik K. Agaram 572d7fcb94 audit all calls to live.eval
Ignoring errors should be extremely rare and well-considered.
2023-04-09 10:40:11 -07:00
Kartik K. Agaram 8096955025 abstraction: roll forward/back 2023-04-09 10:24:23 -07:00
Kartik K. Agaram f387c40d95 restart on a remote command from the driver
This should be useful for ensuring that apps work the same after
restart.
2023-04-07 18:18:43 -07:00
Kartik K. Agaram 951cbe6d0b I'm blind 2023-02-04 21:19:05 -08:00
Kartik K. Agaram e96fa2cce7 support including a default_map
The first time you connect to an app with driver.love, it'll request and
obtain any available default_map to show you. That should make for a
better initial experience. Past that point you're free to move
definitions around, and the default map will stop getting in your way.
2023-01-25 18:09:47 -08:00
Kartik K. Agaram 7168ed5372 consistently save/restore state when running tests
It's not obvious, but this is a refactoring. There should be no behavior
changes.
2023-01-23 20:29:59 -08:00
Kartik K. Agaram 20a586dc1f undo font changes when running tests
This seems to be making test runs less flaky in downstream forks.
2023-01-23 20:17:09 -08:00
Kartik K. Agaram 2f1ec093ba rename 2023-01-23 20:12:23 -08:00
Kartik K. Agaram 26652810f9 send Test_failures _before_ restoring globals
A bugfix, but slightly mind-bending.
2023-01-23 09:16:31 -08:00
Kartik K. Agaram 00ec1dd39e restore globals after running tests
Is it possible this will work?

If so, the programmer's responsibility is to ensure App.initialize_globals()
has no side-effects besides initializing global bindings.
2023-01-23 00:01:15 -08:00
Kartik K. Agaram 461ac9d18b stop cranking CPU on error 2023-01-22 21:53:58 -08:00
Kartik K. Agaram e3ced06b82 return failing tests with every code change 2023-01-22 16:39:54 -08:00