greghendershott / racket-mode

Emacs major and minor modes for Racket: edit, REPL, check-syntax, debug, profile, packages, and more.
https://www.racket-mode.com/
GNU General Public License v3.0
682 stars 93 forks source link

one REPL for one Racket buffer #338

Closed capfredf closed 4 years ago

capfredf commented 6 years ago

Is there a way to start multiple REPL processes and somehow bind them to their corresponding buffer respectively?

greghendershott commented 6 years ago

No, there's not.

Currently the assumption is many:1 -- that all racket-mode (.rkt file editing) buffers share a singleton racket-repl-mode buffer.

The assumption is baked into many things. (As a result, there's not even any trick equivalent to the old, "Rename the *shell* buffer to something like *shell1*, then you can M-x shell to open another one".)


Of course anything is possible. My initial gut reaction is not enthusiastic. Not only would this require un-baking the assumption. It would need some new UI for managing multiple "sessions", preferences for when to make a new session vs. reuse an existing one, which edits buffer(s) are associate(d) with which edit buffers, and so on.

None of that is rocket science. But it would be a fair amount of work to do initially, and then clean up bugs, and maintain over time.

So I wouldn't want to add and maintain it, unless some critical mass of people were going to use it, and were willing to talk about how it ought to work and get some consensus.

Maybe if other folks want this, strongly, they could add a thumbs-up reaction here to "vote" for it?

greghendershott commented 6 years ago

So those are at least three different ways I can imagine. Maybe, with discussion and thought, it would be clear how some are special cases of others, and it really boils down to X and Y. I think I'm just saying, I'd like some of that thought/discussion to happen, with enough people participating, before sitting down and writing a bunch of code. :smile:

capfredf commented 6 years ago

@greghendershott Thank you so much for the detail explanation.

The assumption is baked into many things. (As a result, there's not even any trick equivalent to the old, "Rename the shell buffer to something like shell1, then you can M-x shell to open another one".)

This doesn't work for racket mode, as far as I know. For instance, I open a repl for tmp.rkt and rename the repl buffer to tmp repl. And then I open tmp2.rkt and use the command "run the file in REPL" , Racket Mode will open another repl buffer with an error in it, saying the address and port number is being used. If I run the file in REPL again, the result of evaluation of "tmp2.rkt" will be still shown in the repl for tmp.rkt. (Looks like the emacs client in Racket mode just look for the first available port.)

Also, just to clarify: Would you like exactly 1:1 -- every racket-mode buffer gets (if/when it is M-x racket-run) its own racket-repl-mode buffer? If so, that's a reasonable thing to want.

People who used to be DrRacket users would like it. This mirrors the relation between a file(buffer) and its repl in DrRacket.

For myself, I'm happy with the status quo. But if I wanted something, I might want it oriented around projectile: Each project uses its own racket-repl-mode buffer.

This works for me at least, since the majority of my work are project-based.

If we can get M:1 (M >= 1) mappings between buffers and repls implemented under the hood, I guess we can have both options above? 😁

greghendershott commented 6 years ago

Also, just to clarify: Would you like exactly 1:1 -- every racket-mode buffer gets (if/when it is M-x racket-run) its own racket-repl-mode buffer? If so, that's a reasonable thing to want.

People who used to be DrRacket users would like it. This mirrors the relation between a file(buffer) and its repl in DrRacket.

Oh. Wow. I actually forgot that DrRacket does this. (My only excuse: I used DrR pretty heavily in my first couple years using Racket... but much less frequently in recent years. And, I don't think I ever had a workflow that relied on that. But I can see how that would be useful.)

greghendershott commented 4 years ago

Update: I've been doing a lot of work on a check-syntax branch.

That led me to change the communication approach, on another branch off that, new-comm.

Before: The REPL I/O was the stdin/stdout of the Racket back end. Commands were sent over a TCP connection.

Drawback: The new racket-xp-mode makes it common to want the back end server for its commands, without needing to start a REPL, too.

After: The communication channels are basically flipped. The back send stdin/stdout is for commands. (Bonus: This is available more quickly.) Now the REPL uses a TCP connection.

Insight: Before, how could we have multiple REPLs if a process has just one stdin/stdout? Now, it's no big deal. Just open a TCP connection for each REPL session.

So, that switcheroo been mostly working fine on the back end for a few days now, with minimal changes on the front end just to keep things working. But now I've gone on to take advantage of this, and have the front end explicitly support multiple REPL sessions. Including letting you pick the strategy. Commit d97d665.

This is on a branch off a branch off master. Needs more work and testing. But I'm hopeful I can merge into master before, say, another year elapses. :smile:

greghendershott commented 4 years ago

See instead commit d8bb85d. I derped by making a last-minute name change and neglecting to re-run tests locally. (Again, this is just on a topic branch, for now.)

capfredf commented 4 years ago

Thank you @greghendershott