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

[Question] How to use as a crossterm backend? #6

Open
teohhanhui opened this issue Jul 10, 2020 · 2 comments
Open

[Question] How to use as a crossterm backend? #6

teohhanhui opened this issue Jul 10, 2020 · 2 comments

Comments

@teohhanhui
Copy link

This crate has two features:

  • ...
  • crossterm-support: Provides a wrapper type that let's crossterm use xterm.js as a backend (located here). This enables xterm.js to be used with, for example,the tui crate. Usually you won't have to enable this feature yourself; you should be able to just use crossterm and pass it a [Terminal].

I can't figure out what this means: "You should be able to just use crossterm and pass it a Terminal."

And a more general question: I have an app which uses tui / crossterm. I'd like to be able to run it in the browser, in addition to Linux / macOS / Windows which are already supported. Do you have any suggestions on structure, so that all the xterm.js glue code is separated from the rest? Thanks!

@rrbutani
Copy link
Owner

rrbutani commented Oct 28, 2020

Hey I'm really sorry; I just saw this issue.

I can't figure out what this means: "You should be able to just use crossterm and pass it a Terminal."

I was planning to get patches to crossterm and the tui crate merged that used this crate so that browser support is actually as seamless as the README alleges it is. Unfortunately I got sidetracked and never actually finished making the PRs.

This is more or less the API the README is describing.

And a more general question: I have an app which uses tui / crossterm. I'd like to be able to run it in the browser, in addition to Linux / macOS / Windows which are already supported. Do you have any suggestions on structure, so that all the xterm.js glue code is separated from the rest? Thanks!

This is what I was trying to do as well and actually why I made this crate!

The short answer is that: In general I think if you have your app only use the tui API and use the crossterm functions and macros (like write!) only where needed (i.e. on startup to enable mouse capture, etc.) getting your app to run in a browser with xterm.js should be pretty straightforward.

The longer answer is that you also have to be careful how you actually run your application (as in, how the thing that's usually called an event loop is set up) and how your app is structured; more on this below.

The examples in this repo don't aim to be runnable on desktop and the web, but they are all essentially unchanged from the examples they are based on with the exception of the main methods (and a couple of other things related to compiling to wasm and running in browsers).

I actually do have an example that does run on the web and on desktop here. That app is structured to have a library crate that both a desktop binary and a web binary crate depend on. The code is a little rough but I think comparing main for the desktop app with run for the web version and looking at the run_with_crossterm and run_with_xtermjs functions in the library crate should maybe provide some answers.

A couple of other odds and ends:

  • the one other thing that's relevant and very different between the desktop and web version of that app is the event loop
    • the setup we ended up with is somewhat subpar and highly specific to that application
    • if we had to do it over, I think I'd use async pervasively throughout the app; the lack of async trait methods is why we did not do this but I think the upsides (i.e. not having this kind of weird internal difference in how the app's event loop runs and actually being able to use async web APIs (i.e. most of them) in components) make it worth it
  • depending on what your app does and how it's structured, the fact that you need to use web APIs (i.e. things in web-sys) to do what you'd normally just use std for will either be not a problem at all or will make supporting the web and desktops extremely difficult
    • fortunately our app was very self contained (the thing at it's core was designed for microcontrollers and is #![no_std]) so this wasn't a big deal for us
    • but, if your app isn't as self contained you'll want a way to accommodate asynchronous operations in whatever abstraction it is you're using for you app
      • for us, this is our Widget trait (which is basically the tui crate's StatefulWidget trait — it didn't exist when we wrote ours)
      • in our case, "accomodat[ing] asynchronous operations" would mean making the update method on that trait async
      • it's kind of painful to retrofit this kind of change later on which is why I think it's worth mentioning/keeping ranting about it

@rrbutani
Copy link
Owner

rrbutani commented Oct 28, 2020

I do still plan to get the patches to tui (here) and crossterm (here) merged in but I don't think that's going to happen in the near future.

It's possible to use this stuff right now, as the project I linked to does, but unfortunately I think if you try to use my forks of crossterm and tui like the UTP project does you'll run into problems with wasm-bindgen (I had to fork that crate as well for some features xterm-js-sys needed and got busy before I could get those changes upstreamed) since wasm-bindgen intentionally does not follow semver and since they've had a few releases since I last updated my fork.

If you're interested in using this crate with crossterm/tui let me know and I can at least update my forks right away. And again, apologies for the very late response.

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

No branches or pull requests

2 participants