Skip to content

Commit

Permalink
Support multiple REPL buffers; closes #338
Browse files Browse the repository at this point in the history
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.
  • Loading branch information
greghendershott committed Feb 23, 2020
1 parent 8a6e652 commit d97d665
Show file tree
Hide file tree
Showing 8 changed files with 181 additions and 58 deletions.
16 changes: 16 additions & 0 deletions racket-custom.el
Original file line number Diff line number Diff line change
Expand Up @@ -147,6 +147,22 @@ Set to nil to disable the mode line completely."
:tag "REPL"
:group 'racket)

(defcustom racket-repl-buffer-name-function nil
"How to associate `racket-mode' edit buffers with `racket-repl-mode' buffers.
The default is nil which is equivalent to
`racket-repl-buffer-name-shared': One REPL buffer is shared.
Other predefined choices include `racket-repl-buffer-name-unique'
and `racket-repl-buffer-name-project'. Any such function takes no
arguments, should look at `buffer-file-name' if necessary, and
either `setq-default' or `setq-local' the variable
`racket-repl-buffer-name' to a desired `racket-repl-mode' buffer
name. As a result, `racket-run' commands will use a buffer of
that name, creating it if necessary."
:tag "REPL Buffer Name Function"
:type 'function
:group 'racket-repl)

(defcustom racket-memory-limit 2048
"Terminate the Racket process if memory use exceeds this value in MB.
Expand Down
6 changes: 3 additions & 3 deletions racket-debug.el
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ file-local variable.")
;;;###autoload
(defun racket--debug-send-definition (beg end)
(racket--cmd/async
racket--repl-session-id
(racket--repl-session-id)
(save-excursion
(goto-char beg)
(list 'debug-eval
Expand Down Expand Up @@ -121,7 +121,7 @@ file-local variable.")
(let ((info (if value-prompt-p
(racket--debug-prompt-for-new-values)
racket--debug-break-info)))
(racket--cmd/async racket--repl-session-id
(racket--cmd/async (racket--repl-session-id)
`(debug-resume (,next-break ,info))))
(racket-debug-mode -1)
(setq racket--debug-break-positions nil)
Expand Down Expand Up @@ -186,7 +186,7 @@ file-local variable.")

(defun racket-debug-disable ()
(interactive)
(racket--cmd/async racket--repl-session-id `(debug-disable))
(racket--cmd/async (racket--repl-session-id) `(debug-disable))
(racket-debug-mode -1)
(setq racket--debug-break-positions nil)
(setq racket--debug-break-locals nil)
Expand Down
2 changes: 1 addition & 1 deletion racket-logger.el
Original file line number Diff line number Diff line change
Expand Up @@ -174,7 +174,7 @@ use `pop-to-buffer'."
(racket-logger--connect))
;; Give it a window if necessary
(unless (get-buffer-window racket-logger--buffer-name)
(pcase (get-buffer-window racket--repl-buffer-name)
(pcase (get-buffer-window racket-repl-buffer-name)
(`() (pop-to-buffer (get-buffer racket-logger--buffer-name)))
(win (set-window-buffer (split-window win)
(get-buffer racket-logger--buffer-name)))))
Expand Down
5 changes: 5 additions & 0 deletions racket-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -31,12 +31,14 @@

(require 'racket-edit)
(require 'racket-xp)
(require 'racket-custom)
(require 'racket-smart-open)
(require 'racket-imenu)
(require 'racket-profile)
(require 'racket-logger)
(require 'racket-stepper)
(require 'racket-repl)
(require 'racket-repl-buffer-name)
(require 'racket-collection)
(require 'racket-bug-report)
(require 'racket-util)
Expand Down Expand Up @@ -133,6 +135,9 @@
"Racket"
"Major mode for editing Racket.
\\{racket-mode-map}"
(if racket-repl-buffer-name-function
(funcall racket-repl-buffer-name-function)
(racket-repl-name-shared))
(racket--common-variables)
(racket--variables-imenu)
(hs-minor-mode t)
Expand Down
4 changes: 2 additions & 2 deletions racket-profile.el
Original file line number Diff line number Diff line change
Expand Up @@ -49,7 +49,7 @@ delete compiled/*.zo files."
(lambda (_n/a)
(message "Getting profile results...")
(racket--cmd/async
racket--repl-session-id
(racket--repl-session-id)
`(get-profile)
(lambda (results)
(message "")
Expand All @@ -63,7 +63,7 @@ delete compiled/*.zo files."
(defun racket--profile-refresh ()
(interactive)
(setq racket--profile-results
(racket--cmd/await racket--repl-session-id
(racket--cmd/await (racket--repl-session-id)
`(get-profile)))
(racket--profile-draw))

Expand Down
54 changes: 54 additions & 0 deletions racket-repl-buffer-name.el
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
;;; racket-repl-buffer-name.el -*- lexical-binding: t; -*-

;; Copyright (c) 2013-2020 by Greg Hendershott.
;; Portions Copyright (C) 1985-1986, 1999-2013 Free Software Foundation, Inc.

;; Author: Greg Hendershott
;; URL: https://github.com/greghendershott/racket-mode

;; License:
;; This is free software; you can redistribute it and/or modify it
;; under the terms of the GNU General Public License as published by
;; the Free Software Foundation; either version 2, or (at your option)
;; any later version. This is distributed in the hope that it will be
;; useful, but without any warranty; without even the implied warranty
;; of merchantability or fitness for a particular purpose. See the GNU
;; General Public License for more details. See
;; http://www.gnu.org/licenses/ for details.

;;; Some values suitable for `racket-repl-buffer-name-function',
;;; which set the variable `racket-repl-buffer-name'.

(require 'racket-custom)
(require 'racket-repl)

;;;###autoload
(defun racket-repl-buffer-name-shared ()
"All `racket-mode' edit buffers share one `racket-repl-mode' buffer."
(interactive)
(setq-default racket-repl-buffer-name "*Racket REPL*"))

;;;###autoload
(defun racket-repl-buffer-name-unique ()
"Each `racket-mode' edit buffer gets its own `racket-repl-mode' buffer."
(interactive)
(let ((name (concat "*Racket REPL "
(buffer-file-name)
"*")))
(setq-local racket-repl-buffer-name name)))

;;;###autoload
(defun racket-repl-buffer-name-project ()
"Files belonging to a projectile project share a `racket-repl-mode' buffer"
(interactive)
(let* ((project (if (fboundp 'projectile-project-name)
(projectile-project-name)
(file-name-directory (buffer-file-name))))
(name (concat "*Racket REPL project \""
project
"\"*")))
(setq-local racket-repl-buffer-name name)))

(provide 'racket-repl-buffer-name)

;; racket-repl-buffer-name.el ends here

0 comments on commit d97d665

Please sign in to comment.