Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

OSC 133: Support semantic prompt regions #5932

Open
jparise opened this issue Feb 22, 2025 · 4 comments
Open

OSC 133: Support semantic prompt regions #5932

jparise opened this issue Feb 22, 2025 · 4 comments
Assignees
Labels
vt Control sequence related

Comments

@jparise
Copy link
Collaborator

jparise commented Feb 22, 2025

Our support for semantic prompts (OSC 133) is currently row-based. It should be region-based, allowing semantic prompts to span multiple rows and allowing a row to contain multiple semantic prompts.

Row-based support is too limiting and has led to problems like #3003, where we needed to change the way we emit prompt markers to work around the implicit "last prompt marker on a row wins" behavior of the current implementation.

Region-based support would also let us reliably support more advanced prompt behavior, such as styling different prompt regions, collapsing prompts and their output, and implementing more advanced selections and click-based movements. Here are some examples from DomTerm:

Prompt region styling

Image

Command output collapsing

Image

Prompt-aware selection

Image

Notes

  • Wezterm has a SemanticZone type that is created by semantic prompt markers. This could be a nice generalization to adopt.
  • We only support a minimal subset of the OSC 133 commands. We should support most/all of those commands and their behaviors.
  • Similar to how we manage hyperlinks, we should optimize for sparse page-based prompt storage.
  • We could add an Inspector mode to visualize semantic prompt regions.
  • Support OSC 133's cl (click-move) option #1966 exists to specifically track the click-based movement part of the specification. This would be a nice-to-have, but it's not important as the other fundamentals described here.
@jparise jparise added shell-integration vt Control sequence related labels Feb 22, 2025
@mitchellh
Copy link
Contributor

I think we should separate the shell integration side of this from the core side. I believe the actionable part of this issue is to enhance the core to understand semantic prompt regions, is that correct?

@jparise
Copy link
Collaborator Author

jparise commented Feb 22, 2025

I think we should separate the shell integration side of this from the core side. I believe the actionable part of this issue is to enhance the core to understand semantic prompt regions, is that correct?

They'll need to coordinate (i.e. we may need to adjust the sequences sent by our integration scripts). But there's otherwise nothing additional we should need to do on the shell integration side. It would be fine to remove the shell-integration label.

@mitchellh
Copy link
Contributor

Agreed. In this case, I think we should focus on the core support first which will certainly require some ingenuity.

@jparise
Copy link
Collaborator Author

jparise commented Mar 19, 2025

I've been exploring some approaches, and I think there are three ways to go:

Cell-based

  • Add a (2-bit) field to every Cell that stores its semantic type: output, input, or prompt (output is the zero value)
  • Maintain a Row-level flag as a fast way to check if the row contains any non-output (i.e. prompt) cells, similar to how we optimize the hyperlink checks
  • OSC 133 commands set the cursor's semantic type for the current and future cells
  • Additional OSC 133 marker data (such as a command's exit code) would need to be stored somewhere (not in the Cell)

This approach favors the read path. It's easy to check a cell's type, and ranges/zones can be derived through cell-wise iteration.

Two are two more complex aspects to this approach:

  1. Maintaining the Row-level flag across some screen operations like reflows. In those cases where the affected rows previously had the prompt flag set, we need to revisit all of their cells to check if the resulting rows still contain prompt cells. It's not too much work and is easy to verify the correctness of the result in our integrity checks.
  2. Managing any additional data (e.g. command status). This data is small but still needs to be managed and reflowed with this approach (perhaps using tracked Pins).

Aside from additional command data, this approach also doesn't add any new memory allocations unless we find we need to cache some of the ranges for the new semantic operations. We instead use some of the reserved bit space from our existing Cell and Row structures. And because semantic prompts only apply to the main screen, these just remain at their zero values on other screens.

I've implemented the guts of this in a local branch with good results so far.

Pin-based

  • Represent each OSC 133 prompt marker as a Pin-based structure associated with the screen
  • The tracked Pins will be maintained by the current page code across scrolls, reflows, etc.
  • All semantic read operations are derived from the "spans" between these Pin markers

I haven't built this out, but I think this approach might be trading the base-level simplicity of using tracked pins with the added need for more higher-level management data structures and routines (e.g. a screen-level cache of "semantic spans").

Aside from the benefit of getting the base-level tracking Pin capabilities "for free", it comes with the cost of the span management code and new memory allocations. I think this approach might be more attractive if we needed to store more than a small amount of data for each semantic zone.

Hyperlink-like

Instead of building directly on the existing Cell or Pin structures, we could introduce a custom SemanticZone structure with its own specific tracking logic, etc. This would follow the general approach we take with hyperlinks.

This approach has at least the same costs as the Pin-based approach, and we wouldn't get tracking "for free", but it would give us the flexibility to build a very specific implementation. In practice, though, I don't think there's any clear benefit to this level of complexity at this point. And unlike hyperlinks, we don't have the same allocation and memory management requirements for semantic prompts.


Overall, I think the Cell-based approach is the best fit, but I wanted to share these notes and solicit feedback before I get too far into an implementation.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
vt Control sequence related
Projects
None yet
Development

No branches or pull requests

2 participants