-
Notifications
You must be signed in to change notification settings - Fork 767
Description
RFC: Widget messages
The current user widgets system supports exactly one kind of user widget - a widget panel, that is a piece of UI which can appear as a top-level panel next to the tactic state, messages, etc, in the infoview. Since we already have all the infrastructure for dynamic code loading in the infoview set up, there is no reason to limit ourselves to panels. Here I would like to propose widget messages. Implementation-wise, these would need one new constructor of MessageData, MessageData.ofWidget (msg : WidgetMsg). I have not implemented this, but I am happy to do it if there is interest/approval. Widget messages are primarily motivated by the use-cases they would enable:
Example 1: "Try this"
We can write a generic "Try this" UI component resulting in tryThis : Syntax → Syntax → WidgetMsg where tryThis stxRef newStx is the data of a "Try this" display that replaces stxRef with newStx upon a click. We would then include it in messages output by tactic code using something like m!"<some tactic output>{.tryThis stxRef newStx}".
Example 2: Contextual traces in failure messages
It is currently not always easy to view extra detail associated with a failure message. For instance, suppose the system prints a failed to synthesize instance SomeClass α message. In cases where it is not obvious why the synthesis failed (e.g. when debugging typeclass hierarchies), we can debug it by setting trace.Meta.synthInstance true. However we must either do so on the entire enclosing command which produces lots of irrelevant output, or extract a self-contained trace.Meta.synthInstance true in #synth SomeClass α which may be non-trivial if α depends on local context. And in any case we have to type the option in every time! It would be convenient if the failure message directly included a [Trace] button below it which would show this output when clicked. This could be achieved straightforwardly with a widget message. The idea extends to other failures, e.g. trace.Meta.isDefEq traces for expected .. but got ... Note that this is not supposed to collect traces eagerly as these can use up substantial memory. Rather, the data of a [Trace] button is just the inputs to the failed computation, and clicking it would rerun the computation with tracing enabled.
Pitfalls and alternatives
- We already have specialized data associated with message, for example
MessageData.ofExpr e. This is a bit more thanMessageData.ofWidget (displayTheExpr e)because it contains more data than just "display this". For example, we can inspect it to check if a message containssorryexpressions. An alternative along these lines would be to addMessageData.ofTryThis,MessageData.ofTraceOnClicketc. The problem with this approach is that it's not user-extensible. - We need to maintain compatibility with text-based environments and ones without the JS-based infoview, so
WidgetMsgshould likely include atoTextfield, even if just to emit a placeholder in the case of inherently graphical messages.