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

one REPL for one Racket buffer #338

Closed
capfredf opened this issue Oct 4, 2018 · 7 comments
Closed

one REPL for one Racket buffer #338

capfredf opened this issue Oct 4, 2018 · 7 comments

Comments

@capfredf
Copy link
Sponsor Contributor

capfredf commented Oct 4, 2018

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

@greghendershott
Copy link
Owner

greghendershott commented Oct 4, 2018

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
Copy link
Owner

  • 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.

  • 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.

  • Whereas I can imagine other people saying, "Yeah, well, I want to supply my own Emacs Lisp functions you should call that completely determine how the whole thing works".


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. 😄

@capfredf
Copy link
Sponsor Contributor Author

capfredf commented Oct 6, 2018

@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
Copy link
Owner

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 greghendershott changed the title one REPL for one Racket buffer one REPL for one Racket buffer Oct 21, 2018
greghendershott added a commit that referenced this issue Feb 23, 2020
This was fairly short strokes from the work already done in the back
end related to REPL sessions now being TCP connections to the back end
server, and having it handle multiple such sessions. This just wasn't
exposed, yet, in the Emacs front end.

After mulling this over, and not wanting to write a whole bunch of
ceremonial code for "sessions", I realized that Emacs variable
semantics provide a simple, reliable way to handle this.

The variable `racket-repl-buffer-name' determines, in a `racket-mode'
edit buffer, the name of the `racket-repl-mode' buffer that it is
associated with. Like any Emacs variable, this may be global, or,
`setq-local' may be used to set a unique value for each buffer.

As a result, different strategies for associating one or more edit
buffers to one or more REPL buffers, all boil down to setting that
`racket-repl-buffer-name' variable as desired.

A new customization variable, `racket-repl-buffer-name-function', is
called when each `racket-mode' edit buffer is created.

- The default function is `racket-repl-buffer-name-shared', which sets
  the REPL buffer name to "*Racket REPL*". In other words, this is the
  status quo where all edit buffers share the same REPL.

- Another such function is `racket-repl-buffer-name-unique', which
  sets the REPL buffer name to something like "*Racket REPL:
  /path/to/foo.rkt*". In other words, somewhat like Dr Racket, each
  edit buffer gets its own, unique REPL buffer. (Currently there is
  no UX attempting to position them adjacently.)

- Another such function is `racket-repl-buffer-name-project', which
  names the REPL based on the projectile project name, if any. In
  other words, edit buffers in the same project share a REPL.

You get the idea. The user may supply any such function which sets the
desired REPL buffer name, possibly looking at `buffer-file-name' for
the `racket-mode' edit buffer as in the last two examples.
@greghendershott
Copy link
Owner

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. 😄

greghendershott added a commit that referenced this issue Feb 23, 2020
This was fairly short strokes from the work already done in the back
end related to REPL sessions now being TCP connections to the back end
server, and having it handle multiple such sessions. This just wasn't
exposed, yet, in the Emacs front end.

After mulling this over, and not wanting to write a whole bunch of
ceremonial code for "sessions", I realized that Emacs variable
semantics provide a simple, reliable way to handle this.

The variable `racket-repl-buffer-name' determines, in a `racket-mode'
edit buffer, the name of the `racket-repl-mode' buffer that it is
associated with. Like any Emacs variable, this may be global, or,
`setq-local' may be used to set a unique value for each buffer.

As a result, different strategies for associating one or more edit
buffers to one or more REPL buffers, all boil down to setting that
`racket-repl-buffer-name' variable as desired.

A new customization variable, `racket-repl-buffer-name-function', is
called when each `racket-mode' edit buffer is created.

- The default function is `racket-repl-buffer-name-shared', which sets
  the REPL buffer name to "*Racket REPL*". In other words, this is the
  status quo where all edit buffers share the same REPL.

- Another such function is `racket-repl-buffer-name-unique', which
  sets the REPL buffer name to something like "*Racket REPL:
  /path/to/foo.rkt*". In other words, somewhat like Dr Racket, each
  edit buffer gets its own, unique REPL buffer. (Currently there is
  no UX attempting to position them adjacently.)

- Another such function is `racket-repl-buffer-name-project', which
  names the REPL based on the projectile project name, if any. In
  other words, edit buffers in the same project share a REPL.

You get the idea. The user may supply any such function which sets the
desired REPL buffer name, possibly looking at `buffer-file-name' for
the `racket-mode' edit buffer as in the last two examples.
@greghendershott
Copy link
Owner

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
Copy link
Sponsor Contributor Author

capfredf commented Mar 3, 2020

Thank you @greghendershott

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

No branches or pull requests

2 participants