javaterminal / TerminalFX

Java FX Terminal Emulator
MIT License
277 stars 52 forks source link

Add support for non-process-based terminals #19

Open byteit101 opened 5 years ago

byteit101 commented 5 years ago

I tried to keep the API changes limited, though I did have to break it in some places, hence the version bump included. The change now allows the view be provided with an implementation of the new Pty interface, and it will display it as such, whether it is process-based (as before) or in-process. The existing implementations were moved to new classes GenericTerminal<? extends Pty> from Terminal and ExternalProcessPty for the actual existing process launching. Terminal remains as a specialization of GenericTerminal<ExternalProcessPty> with the same API.

I have successfully used it with a Linux-specific in-memory openpty() based system, though didn't drop that implementation in to this PR as it would drag in a boatload of dependencies. I did include an example FileCapturePty implementation though.

It is conceivable to break the API more to get a cleaner API, though I wasn't sure which was preferred, so went the less invasive route. Feedback is much appreciated.

rahmanusta commented 5 years ago

Hi @byteit101, I'm glad your contribution. I would like to merge the request but first I need to understand what non-process based terminals are :) Can you share with me a demo that use that feature with TerminalFX? And, so maybe we can share this demo with community. What do you think? Thanks.

byteit101 commented 5 years ago

Non-process based terminals are PTY's that don't use fork and assign to STDIN/STDOUT, instead being an in-process thread on new file descriptors that are not STDIN/STDOUT. I've created this demo for a JRuby-based application, which lets me interactively work in a JRubyFX context without mucking with STDIN/STDOUT. Thus the entire context of the parent thread is available to be mucked with, in contrast to forking off a process.

The ruby source is https://gist.github.com/byteit101/9b0e9bbb0f145acecc8537ed9075a629 and requires a JRuby installation (RVM is handy if you want to install jruby), though you can see a screenshot here:

Screenshot from 2019-04-03 15-26-49

The terminal has access to the JavaFX context (root) and can modify it at will as it's all in the same process.

The TerminalFX interop is lines 67 (the Pty implementaion), 76 (the PTY open in-process), 79 (the thread I used), and 148-164 (creating and returning the TerminalFX terminal with a new JrubyPtyImpl that launches the Pry shell on the given PTY io).

I don't show it here, but $stdout.puts "hello" would print out to the controlling terminal that launched the process, while $io.puts "hello" would print to the TerminalFX terminal.

Hope that answered your question? You can share this as you can use jruby and rubygems through maven, though as I originally mentioned, that would drag in a lot of dependencies.

LinusCDE commented 4 years ago

Bump. This would be a welcome change.

I'm currently working on a port of a simulator and as such am integrating a terminal.

My solution is to not start any process (set starters to "") and rewire the readers. This seems to have some efficiency problems though which I still need to fix.

The most dump fix would be to run cat and command() everything into it.

EDIT: As to why: There are a lot of scenarios where you might just need to view to render VT100 output. It's also an easy way to get varying colors and keep compatibility for a terminal mode.