Skip to content

Commit

Permalink
racket-repl: Re-implement as just running a file; closes #689
Browse files Browse the repository at this point in the history
Narrowly, this fixes the kind of problem as in #689 where a setting
like racket-pretty-print only takes effect via a run.

Broadly, this makes this command follow the the main intended use case
-- a REPL is associated with running a file. Now the command is just a
shortcut for running a file with a certain name (and creating that
file if it doesn't exist).

Also, this fits better in a hash-lang world. If say someone mostly
works with #lang rhombus, and wants "give me a quick REPL" to use
that, now they can instead of getting #lang racket/base.

Finally, this lets the doc string explain that the REPL is always
just about running some file. If a user wanted to have "several init
files", well, they're really talking about running several source
files frequently, which of course they can already do. And if they
want a quick key binding for each one, that's an easy customization
nearly any end user can do for themselves.

TL;DR: Years ago when some folks asked for a racket-repl command, this
is probably how I should have done it: A trivial variation of
racket-run.
  • Loading branch information
greghendershott committed Dec 11, 2023
1 parent e8cbeff commit 8b2eb39
Show file tree
Hide file tree
Showing 6 changed files with 69 additions and 48 deletions.
1 change: 1 addition & 0 deletions doc/generate.el
Original file line number Diff line number Diff line change
Expand Up @@ -204,6 +204,7 @@
racket-images-keep-last
racket-images-system-viewer
racket-pretty-print
racket-repl-command-file
"Other variables"
racket-indent-curly-as-sequence
racket-indent-sequence-depth
Expand Down
33 changes: 18 additions & 15 deletions doc/racket-mode.texi
Original file line number Diff line number Diff line change
Expand Up @@ -226,6 +226,7 @@ REPL variables
* racket-images-keep-last::
* racket-images-system-viewer::
* racket-pretty-print::
* racket-repl-command-file::
Other variables
Expand Down Expand Up @@ -997,7 +998,7 @@ Major mode for editing Racket source files.
@item @kbd{C-c C-t}
@tab @ref{racket-test}
@item @kbd{C-c C-z}
@tab @ref{racket-repl}
@tab @code{racket-edit-switch-to-repl}
@item @kbd{C-c C-k}
@tab @ref{racket-run-module-at-point}
@item @kbd{C-c C-c}
Expand Down Expand Up @@ -1618,7 +1619,7 @@ can contribute more colors; see the customization variable
@item @kbd{C-c C-t}
@tab @ref{racket-test}
@item @kbd{C-c C-z}
@tab @ref{racket-repl}
@tab @code{racket-edit-switch-to-repl}
@item @kbd{C-c C-k}
@tab @ref{racket-run-module-at-point}
@item @kbd{C-c C-c}
Expand Down Expand Up @@ -2321,26 +2322,22 @@ simply the outermost, file module.
@node racket-repl
@subsection racket-repl

@kbd{C-c C-z}
@kbd{M-x} @code{racket-repl}

Show a Racket REPL buffer in some window.

@strong{IMPORTANT}

The main, intended use of Racket Mode's REPL is that you
@code{find-file} some specific .rkt file, then run it using
@code{find-file} some specific file, then run it using a command like
@ref{racket-run} or @ref{racket-run-module-at-point}. The resulting REPL
will correspond to those definitions and match your expectations.

If you really want to start a REPL for no file in particular,
then you could use this @ref{racket-repl} command. But the resulting
REPL will have a minimal ``#lang racket/base'' namespace. You
could enter ``(require racket)'' if you want the equivalent of
``#lang racket''. You could also ``(require racket/enter)'' if
you want things like ``enter!''. But in some sense you'd be
``using it wrong''. If you actually don't want to use Racket
Mode's REPL as intended, then consider using a plain Emacs
@code{shell} buffer to run command-line Racket.
Therefore this @ref{racket-repl} command -- which is intended as a
convenience for people who want a way to ``just get a quick
REPL'' -- is actually implemented as just running the file named
in the customization variable @ref{racket-repl-command-file}. By
default when that file doesn't exist, it is created to contain
just ``#lang racket/base''. You may edit the file to use a
different lang, require other modules, or whatever.

@node racket-repl-describe
@subsection racket-repl-describe
Expand Down Expand Up @@ -3304,6 +3301,7 @@ classic @ref{racket-mode} for rackety module languages:
* racket-images-keep-last::
* racket-images-system-viewer::
* racket-pretty-print::
* racket-repl-command-file::
@end menu

@node racket-repl-buffer-name-function
Expand Down Expand Up @@ -3401,6 +3399,11 @@ The image viewer program to use for @code{racket-view-image}.

Use pretty-print instead of print in REPL@?

@node racket-repl-command-file
@subsection racket-repl-command-file

Name of the file used by @ref{racket-repl}.

@node Other variables
@section Other variables

Expand Down
9 changes: 8 additions & 1 deletion racket-custom.el
Original file line number Diff line number Diff line change
Expand Up @@ -392,7 +392,6 @@ will use this to decide whether to submit your input, yet."
:safe #'booleanp
:group 'racket-repl)


(defcustom racket-before-run-hook nil
"Normal hook done before various Racket Mode run commands.
Expand Down Expand Up @@ -423,6 +422,14 @@ from the variable `racket-repl-buffer-name'."
:risky t
:group 'racket-repl)

(defcustom racket-repl-command-file
(expand-file-name "repl.rkt"
(locate-user-emacs-file (file-name-as-directory "racket-mode")))
"Name of the file used by `racket-repl'."
:tag "REPL Command File"
:type 'file
:group 'racket-repl)

;;; Other

(defgroup racket-other nil
Expand Down
2 changes: 1 addition & 1 deletion racket-hash-lang.el
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@
(racket--easy-keymap-define
`((("C-c C-c"
"C-c C-k") ,#'racket-run-module-at-point)
("C-c C-z" ,#'racket-repl)
("C-c C-z" ,#'racket-edit-switch-to-repl)
("<f5>" ,#'racket-run-and-switch-to-repl)
("M-C-<f5>" ,#'racket-racket)
("C-<f5>" ,#'racket-test)
Expand Down
2 changes: 1 addition & 1 deletion racket-mode.el
Original file line number Diff line number Diff line change
Expand Up @@ -44,7 +44,7 @@
(racket--easy-keymap-define
'((("C-c C-c"
"C-c C-k") racket-run-module-at-point)
("C-c C-z" racket-repl)
("C-c C-z" racket-edit-switch-to-repl)
("<f5>" racket-run-and-switch-to-repl)
("M-C-<f5>" racket-racket)
("C-<f5>" racket-test)
Expand Down
70 changes: 40 additions & 30 deletions racket-repl.el
Original file line number Diff line number Diff line change
Expand Up @@ -508,30 +508,37 @@ even when the module language doesn't provide any binding for
(defun racket-repl (&optional noselect)
"Show a Racket REPL buffer in some window.
*IMPORTANT*
The main, intended use of Racket Mode's REPL is that you
`find-file' some specific .rkt file, then run it using
`find-file' some specific file, then run it using a command like
`racket-run' or `racket-run-module-at-point'. The resulting REPL
will correspond to those definitions and match your expectations.
If you really want to start a REPL for no file in particular,
then you could use this `racket-repl' command. But the resulting
REPL will have a minimal \"#lang racket/base\" namespace. You
could enter \"(require racket)\" if you want the equivalent of
\"#lang racket\". You could also \"(require racket/enter)\" if
you want things like \"enter!\". But in some sense you'd be
\"using it wrong\". If you actually don't want to use Racket
Mode's REPL as intended, then consider using a plain Emacs
`shell' buffer to run command-line Racket."
Therefore this `racket-repl' command -- which is intended as a
convenience for people who want a way to \"just get a quick
REPL\" -- is actually implemented as just running the file named
in the customization variable `racket-repl-command-file'. By
default when that file doesn't exist, it is created to contain
just \"#lang racket/base\". You may edit the file to use a
different lang, require other modules, or whatever."
(interactive "P")
(racket-call-racket-repl-buffer-name-function)
(racket--repl-ensure-buffer-and-session
nil
(lambda (repl-buffer)
(racket--repl-refresh-namespace-symbols)
(unless noselect
(select-window (get-buffer-window repl-buffer t))))))
;; Create file if it doesn't exist
(unless (file-exists-p racket-repl-command-file)
(let ((dir (file-name-directory racket-repl-command-file)))
(unless (file-exists-p dir)
(make-directory dir t)))
(write-region ";; Used by M-x racket-repl; you may edit\n#lang racket/base\n"
nil racket-repl-command-file))
;; Visit the file without selecting it, and run it.
(let ((racket-repl-buffer-name-function #'racket-repl-buffer-name-unique))
(with-current-buffer (find-file-noselect racket-repl-command-file)
(racket--repl-run
(list racket-repl-command-file)
nil
nil
(lambda ()
(display-buffer racket-repl-buffer-name)
(unless noselect
(select-window (get-buffer-window racket-repl-buffer-name t))))))))

;;; Run

Expand Down Expand Up @@ -649,9 +656,7 @@ the variable `racket-before-run-hook'."
(`(4) 'high)
(`(16) 'debug)
(_ racket-error-context))
(lambda ()
(display-buffer racket-repl-buffer-name)
(select-window (get-buffer-window racket-repl-buffer-name t)))))
#'racket-edit-switch-to-repl))

(defun racket-test (&optional prefix)
"Run the \"test\" submodule.
Expand Down Expand Up @@ -916,13 +921,21 @@ This displays the buffer but does not change the selected window."
(lambda (_id)
(funcall continue repl-buf)))))))

;;; Misc
;;; Switch between associcated edit and REPL buffers

(defun racket-edit-switch-to-repl ()
"Select REPL buffer associated with the edit buffer."
(interactive)
(racket--assert-edit-mode)
(when-let (repl-buf (get-buffer racket-repl-buffer-name))
(when (buffer-live-p repl-buf)
(display-buffer repl-buf)
(select-window (get-buffer-window repl-buf t)))))

(defun racket-repl-file-name ()
"Return the file running in the REPL, or nil.
The result can be nil if the REPL is not started, or if it is
running no particular file."
The result can be nil if the REPL is not started."
(when (racket--repl-session-id)
(racket--cmd/await (racket--repl-session-id) `(path))))

Expand All @@ -935,12 +948,9 @@ running no particular file."
(and buf-file repl-file (string-equal buf-file repl-file)))))

(defun racket-repl-switch-to-edit ()
"Switch to the window for the buffer of the file running in the REPL.
If no buffer is visting the file, `find-file' it in `other-window'.
"Select edit buffer of the file running in the REPL.
If the REPL is running no file -- if the prompt is `>` -- use the
most recent `racket-mode' buffer, if any."
If no buffer is visting the file, `find-file' it in `other-window'."
(interactive)
(pcase (racket-repl-file-name)
((and (pred stringp) path)
Expand Down

0 comments on commit 8b2eb39

Please sign in to comment.