Fork me on GitHub
#vim
<
2023-06-29
>
sheluchin11:06:32

Using Conjure/Fennel, is there some simple way to create a mapping that would take the Clojure form under the cursor, wrap it in a time call (as a simple example), and execute it? I've started reading about plugin development with Fennel, but it'll take a little while before I'm familiar enough to do stuff like this. Just wondering if there's any "shortcut" in Conjure for doing things like this.

Phillip Mates11:06:20

here is a related snippet that I use to send a form to the clojure REPL using the current filename, which is part of what you want:

(vim.keymap.set :n :<localleader>cs #(vim.cmd (.. "ConjureEval (nextjournal.clerk/show! \"" (vim.fn.expand "%:p") "\")")))

Phillip Mates12:06:30

so with those two together, what you're looking for should be

(set extract (require :conjure.extract))
(vim.keymap.set :n :<localleader>et #(vim.cmd (.. "ConjureEval (time " (. (extract.form {}) :content) ")")))

sheluchin12:06:17

@U02G8N0EX44 amazing, thanks very much! I think you meant (local extract ...) instead of set, but otherwise it works just as I wanted. This is a nice bit of ergonomics.

👍 2
sheluchin13:06:46

Any idea how to make it work when the form contains linebreaks?

(vim.keymap.set :n :<leader>et #(vim.cmd (.. "ConjureEval (print " (. (extract.form {}) :content) ")")))
; eval (command): (print {:x "1" :y "2"})
; (out) {:x 1, :y 2}
nil
; --------------------------------------------------------------------------------
; eval (command): (print {:x "1"
; (err) Syntax error reading source at (REPL:1:1).
; (err) EOF while reading, starting at line 1

Phillip Mates13:06:15

Not going through :ConjureEval but calling the conjure fnl function directly would probably do it

sheluchin14:06:53

Sweet, that does it:

(defn time-form [extra-opts]
  (let [form (extract.form {})]
    (when form
      (let [{: content : range} form]
        (eval.eval-str
          (a.merge
            {:code (str.join ["(time " content ")"])
             :range range
             :origin :current-form}
            extra-opts))
        form))))

(vim.keymap.set :n :<leader>et #(time-form {}))
Thanks again, @U02G8N0EX44!

Phillip Mates14:06:02

nice! it is a fun idea to be able to do custom wrappings like this

sheluchin14:06:31

Yeah, there's potential to do some interesting things. You can tap> or time forms, render charts using Reveal/Portal/etc., execute your HoneySQL data structures as queries, and so on. One thing that would improve this is if it didn't work by gluing strings together, but it's good enough for me for now.