Fork me on GitHub
#emacs
<
2018-04-12
>
andrea.crotti13:04:15

ah brilliant didn't know about the , trick @dpsutton

nha15:04:23

Am I the only one occasionally capturing a value in the REPL? Did someone make emacs helpers for this? (I am aware of https://github.com/vvvvalvalval/scope-capture btw, not really what I am after) In other words, how do I go from:

(defn test-fn [a b]
  (let [c [a b]]
    ;; <- cursor there
    [(+ a b) c]))
to
(defn test-fn [a b]
  (let [c [a b]]
    (def a a)
    (def b b)
    (def c c)
    [(+ a b) c]))
Using a bit of elisp? I could type for instance “my-emacs-def-insert-cmd” “a” ENTER “b” ENTER “c” ENTER ENTER and have this generated? That would be a welcome addition to my particular workflow. Anyone doing this?

richiardiandrea15:04:05

@nha I think @dpsutton has something like that and I probably have the same. Not at the keyboard now, will check and write later.

❤️ 4
dpsutton15:04:37

let me dig it up. you have to run it while stepping through with the debugger

dpsutton15:04:36

(defun cider-debug-create-local-let (start end)
  "During debugging, grab the locally bound vars and create a let
  binding. Place this let binding in the kill ring for future use."
  (interactive "r")
  (if cider--debug-mode-response
      (nrepl-dbind-response cider--debug-mode-response (locals)
        (let* ((code (buffer-substring-no-properties start end))
               (bindings (apply #'append locals))
               (formatted-bindings (mapconcat 'identity bindings " ")))
          (kill-new (format "(let [%s]\n %s)" formatted-bindings code))
          (message "copied let form to kill ring")))
    (message "No debugging information found.")))
while in the debugger, get to a stack frame that includes the vars you want to capture. then invoke this function. it grabs the local state from the debugger and formats them into a let binding

😎 4
dpsutton15:04:04

oh and do it while highlighting code

dpsutton15:04:23

with a region, it will capture that region as the body of the let and the locals in your debugger state as the let bindings above it

dpsutton15:04:40

(kill-new (format "(let [%s]\n %s)" formatted-bindings code)) is the formatting

nha15:04:56

Oh I see. Interesting, I don’t use the debugger though (I probably should, although I am quite sure some of our params are too big for it)

nha16:04:02

I suspect what I am after is simpler (ie. does not require any of cider’s functionality) - but my elisp is still fairly weak

dpsutton16:04:36

depends on how smart you want it. you could create an interactive function that would ask for a list of variable names and then insert a bunch of (def [name] [name]) inside a do block

dpsutton16:04:32

trivial example:

(defun ask-for-variable-names (names)
  (interactive "sEnter the variable names: ")
  (let ((bindings (mapcar (lambda (name)
                            (format "(def %s %s)" name name))
                          (s-split " " names))))
    (kill-new (format "(do %s)"
                      (s-join "\n" bindings)))))

❤️ 4