Skip to content

Commit b8ff3bd

Browse files
bkhlgreghendershott
authored andcommitted
Handle command line args to racket-program/backend
The documentation already had examples of configurations like (racket-add-back-end "/ssh:headless:~/gui-project/" :racket-program "xvfb-run racket") This would (accidentally?) work for remote backends, because the way the SSH command is invoked ends up applying shell word splitting on the program. However, when I wanted to use this locally something like this: (racket-add-backend "/project/" :racket-program "podman run --rm --interactive --volume=/project/:/project/:z --workdir=/project/ […] docker.io/racket/racket/8.9-full" "racket") This wouldn't work because the `executable-find' call would try to find the path to an executable with that full string as a name. This commit adds the option of defining `racket-program` (or the back-end `:racket-program` option) as a list rather than a string, in which case the first element will be used as the command to call, and the rest of the elements as command line arguments.
1 parent ba49efe commit b8ff3bd

File tree

5 files changed

+80
-41
lines changed

5 files changed

+80
-41
lines changed

doc/racket-mode.texi

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3147,7 +3147,18 @@ Delete the ``compiled'' directories made by @ref{racket-mode-start-faster}.
31473147
@node racket-program
31483148
@subsection racket-program
31493149

3150-
Pathname of the Racket executable.
3150+
Pathname of the Racket executable or command line to launch it.
3151+
3152+
@itemize
3153+
@item
3154+
If the value of this variable is a string, it will be interpreted as a
3155+
simple command without arguments.
3156+
3157+
@item
3158+
If it is a list of strings, the first element will be taken to be the
3159+
executable, and the rest of the list command line arguments to pass to
3160+
it before any other arguments.
3161+
@end itemize
31513162

31523163
Note that a back end configuration can override this with a
31533164
non-nil @code{racket-program} property list value. See
@@ -4195,9 +4206,9 @@ are a few examples.
41954206
41964207
;; 4. For example's sake, assume for buffers visiting
41974208
;; /ssh:headless:~/gui-project/ we want :racket-program instead
4198-
;; to be "xvfb-run racket".
4209+
;; to be '("xvfb-run" "racket").
41994210
(racket-add-back-end "/ssh:headless:~/gui-project/"
4200-
:racket-program "xvfb-run racket")
4211+
:racket-program '("xvfb-run" "racket"))
42014212
@end lisp
42024213

42034214
If you use various versions of Racket by setting PATH values via

racket-back-end.el

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -196,9 +196,9 @@ are a few examples.
196196
197197
;; 4. For example's sake, assume for buffers visiting
198198
;; /ssh:headless:~/gui-project/ we want :racket-program instead
199-
;; to be \"xvfb-run racket\".
199+
;; to be \\='(\"xvfb-run\" \"racket\").
200200
(racket-add-back-end \"/ssh:headless:~/gui-project/\"
201-
:racket-program \"xvfb-run racket\")
201+
:racket-program \\='(\"xvfb-run\" \"racket\"))
202202
#+END_SRC
203203
204204
If you use various versions of Racket by setting PATH values via
@@ -249,7 +249,12 @@ alongside each .envrc file:
249249
(signal 'wrong-type-argument (list type key v)))))
250250
(number-or-null-p (n) (or (not n) (numberp n))))
251251
(check #'stringp :directory)
252-
(check #'string-or-null-p :racket-program)
252+
(let ((racket-program (plist-get plist :racket-program)))
253+
(if (listp racket-program)
254+
(dolist (s racket-program)
255+
(unless (stringp s)
256+
(signal 'wrong-type-argument (list #'stringp :racket-program s))))
257+
(check #'stringp :racket-program)))
253258
(when (file-remote-p (plist-get plist :directory))
254259
(check #'stringp :remote-source-dir)
255260
(check #'file-name-absolute-p :remote-source-dir))
@@ -453,29 +458,33 @@ a possibly slow remote connection."
453458

454459
(defun racket--back-end-args->command (back-end racket-command-args)
455460
"Given RACKET-COMMAND-ARGS, prepend path to racket for BACK-END."
456-
(if (racket--back-end-local-p back-end)
457-
(cons (let ((racket-program (or (plist-get back-end :racket-program)
458-
racket-program)))
459-
(or (executable-find racket-program)
460-
(error
461-
"Cannot executable-find Racket:\n racket-program: %S\n exec-path: %S"
462-
racket-program
463-
exec-path)))
464-
racket-command-args)
465-
(pcase-let ((`(,host ,user ,port ,_name)
466-
(racket--file-name->host+user+port+name
467-
(plist-get back-end :directory))))
468-
`("ssh"
469-
,@(when port
470-
`("-p" ,(format "%s" port)))
471-
,(if user
472-
(format "%s@%s"
473-
user
474-
host)
475-
host)
476-
,(or (plist-get back-end :racket-program)
477-
racket-program) ;can't use `executable-find' remotely
478-
,@racket-command-args))))
461+
(let* ((racket-program (or (plist-get back-end :racket-program)
462+
racket-program))
463+
(command (if (stringp racket-program)
464+
(list racket-program)
465+
racket-program))
466+
(program (car command))
467+
(flags (cdr command)))
468+
(if (racket--back-end-local-p back-end)
469+
(let ((program (or (executable-find program)
470+
(error
471+
"Cannot executable-find Racket:\n racket-program: %S\n exec-path: %S"
472+
program
473+
exec-path))))
474+
(cons program (append flags racket-command-args)))
475+
(pcase-let ((`(,host ,user ,port ,_name)
476+
(racket--file-name->host+user+port+name
477+
(plist-get back-end :directory))))
478+
`("ssh"
479+
,@(when port
480+
`("-p" ,(format "%s" port)))
481+
,(if user
482+
(format "%s@%s"
483+
user
484+
host)
485+
host)
486+
,@command ;can't use `executable-find' remotely
487+
,@racket-command-args)))))
479488

480489
;;; File system watches
481490

racket-custom.el

Lines changed: 10 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -40,12 +40,20 @@
4040
(defvar racket--winp (eq 'windows-nt system-type))
4141

4242
(defcustom racket-program (if racket--winp "Racket.exe" "racket")
43-
"Pathname of the Racket executable.
43+
"Pathname of the Racket executable or command line to launch it.
44+
45+
- If the value of this variable is a string, it will be interpreted as a
46+
simple command without arguments.
47+
48+
- If it is a list of strings, the first element will be taken to be the
49+
executable, and the rest of the list command line arguments to pass to
50+
it before any other arguments.
4451
4552
Note that a back end configuration can override this with a
4653
non-nil `racket-program` property list value. See
4754
`racket-add-back-end'."
48-
:type '(file :must-match t)
55+
:type '(choice (string)
56+
(repeat string))
4957
:risky t)
5058

5159
(make-obsolete-variable 'racket-command-port nil "2020-04-25")

racket-doc.el

Lines changed: 9 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -60,11 +60,15 @@ Centralizes how to issue doc command and handle response correctly."
6060

6161
(defun racket--search-doc-locally (str)
6262
(racket--doc-assert-local-back-end)
63-
(call-process racket-program
64-
nil ;INFILE: none
65-
0 ;DESTINATION: discard/don't wait
66-
nil ;DISPLAY: none
67-
"-l" "raco" "docs" str))
63+
(let ((command (if (stringp racket-program)
64+
(list racket-program)
65+
racket-program)))
66+
(apply #'call-process `(,(car command)
67+
nil ;INFILE: none
68+
0 ;DESTINATION: discard/don't wait
69+
nil ;DISPLAY: none
70+
,@(cdr command)
71+
"-l" "raco" "docs" ,str))))
6872

6973
(provide 'racket-doc)
7074

racket-shell.el

Lines changed: 12 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
(require 'racket-custom)
1212
(require 'racket-util)
1313
(require 'shell)
14+
(require 'subr-x)
1415
(require 'term)
1516

1617
(defun racket-racket ()
@@ -34,11 +35,17 @@ variable `racket-shell-or-terminal-function'."
3435

3536
(defun racket--shell-or-terminal (args)
3637
(racket--save-if-changed)
37-
(let* ((exe (shell-quote-argument
38-
(if (file-name-absolute-p racket-program)
39-
(expand-file-name racket-program) ;handle e.g. ~/
40-
racket-program)))
41-
(cmd (concat exe " " args))
38+
(let* ((command (if (stringp racket-program)
39+
(list racket-program)
40+
racket-program))
41+
(program (car command))
42+
(exe (shell-quote-argument
43+
(if (file-name-absolute-p program)
44+
(expand-file-name program) ;handle e.g. ~/
45+
program)))
46+
(flags (mapcar (lambda (x) (shell-quote-argument x))
47+
(cdr command)))
48+
(cmd (concat exe " " (string-join flags " ") args))
4249
(win (selected-window)))
4350
(funcall racket-shell-or-terminal-function cmd)
4451
(select-window win)))

0 commit comments

Comments
 (0)