Open thblt opened 1 year ago
I want to avoid complaints from other users. But maybe we can add this as wrapper around cargo-run ? I've seen this kind of request before so other users would certainly also benefit.
Do you mean rust-run
? There's no cargo-run
defined in my Emacs.
Yeah, I mean rust-run.
This is how I've implemented this in my Emacs:
(defvar-local thblt/rust-run-target nil
"The current binary target, set by `thblt/rust-run'.")
(defun thblt/rust-run (target)
"Like `rust-run', but prompt for a target if necessary.
The last run target is stored in `thblt/rust-run-target'. To
force target selection, use a prefix argument."
;; Notice this could be generalized to all targets, eg for `rust-build'.
(interactive
(list
(let*
((json
(with-temp-buffer
(call-process "cargo" nil (current-buffer) nil
"metadata" "--format-version" "1")
(goto-char (point-min))
(json-parse-buffer :null-object nil)))
;; !! this is a bit dirty. !!
(members
(seq-map (lambda (wm)
(car (split-string wm " ")))
(gethash "workspace_members" json)))
(targets
(-flatten ; from dash.el, but not strictly required.
(seq-map (lambda (v)
(seq-keep (lambda (target)
(when
(seq-contains-p
;; Filter out non-binary targets.
(gethash "kind" target) "bin" 'string=)
(gethash "name" target))) v))
(seq-map (lambda (package)
(gethash "targets" package))
(seq-filter
(lambda (pkg)
(seq-contains-p members
(gethash "name" pkg)))
(gethash "packages" json))))))
(default-run
(gethash "default_run"
(car
(seq-filter
(lambda (item)
;;(string= "raoc2021" (gethash "name" item))
t )
(gethash "packages" json))))))
(or default-run
(and (not current-prefix-arg)
(member thblt/rust-run-target targets)
thblt/rust-run-target)
(completing-read "Target: " targets)))))
;; Save buffers
(when-let (project-current (project-current))
(mapc (lambda (buf) (with-current-buffer buf (when (buffer-file-name) (save-buffer))))
(project-buffers project-current)))
;; Compile
(rust--compile "%s run %s --bin %s" rust-cargo-bin rust-cargo-default-arguments target)
;; @TODO Should we still save if this is the default target?
(when (called-interactively-p 'any) (setq thblt/rust-run-target target)))
This is a draft, of course.
Its main advantage is that it has no visible effect in all cases where rust-run
“just works”, ie projects with a single binary target or an explicit default target. The prompt only appears if called with a prefix arg or if the call to cargo run
would have failed.
I may have misunderstood which possible complaints you were referring to. My point above is that the change is a noop in all cases where rust-run worked as expected, and does the right thing (IMHO) in other cases.
rust-run
fails ifcargo run
needs a--bin
argument, which is the case if:default-run
It is probably reasonably easy to support this. A possible interface update to
rust-run
could simply prompt for a target name iff both conditions above hold (multiple binary target, no default) OR it's called with an argument. The chosen target's name could be saved somewhere so further invocations ofrust-run
can just reuse it (unless called with an arg)This is a quick and dirty way to get all binary targets from the current workspace, and the default target:
What do you think?