conjure

Marshall Abrams 2025-02-22T21:03:00.763049Z

There's a useful https://github.com/Olical/conjure/wiki/Integrating-with-Clay-and-data-visualisation-tools in the Conjure wiki that provides nvim key mappings for displaying an expression or a namespace in https://github.com/scicloj/clay. However, the mappings don't work unless one has required scicloj.clay.v2.api in some namespace at some point in the nrepl session. I have a fix that automatically performs the needed require, and I can make the change in the wiki page. However, the fix is based on a lot of trial and error. I don't know much about the aspects of nvim, Conjure, and Fennel involved. I'm wondering whether anyone would be kind enough to scan through the code and tell me whether they think this way of doing things is a bad idea (or not the best idea). The code that sets up the keymappings is what's already there in the wiki. My addition is to use a mutable Fennel variable in a new function require-clay-if-needed, so that the require happens only once. In theory it would make sense to run the require-clay-if-needed function in the on-filetype function below, and that does work. However, it causes the the nrepl to be connected an extra time and disconnected unnecessarily when on-filetype is first run. Not sure why. So instead I run require-clay-if-needed in the keymapping callback functions.

;; nvim functions and keymappings to evaluate scicloj Clay files
(module viz.lnvim
  {autoload {a aniseed.core
             str aniseed.string
             nvim aniseed.nvim
             eval conjure.eval
             extract conjure.extract}}

(var clay-not-yet-required true)

(defn require-clay-if-needed []
  "scicloj.clay.v2.api needs to be required in order for the eval-* functions
  to work, but this only needs to happen once per nrepl session.  This function
  ensures that this happens."
  (when clay-not-yet-required
    (set clay-not-yet-required false)
    (eval.eval-str 
      {:origin "custom-clay-wrapper"
       :code "(require 'scicloj.clay.v2.api)"})))

(defn eval-clojure-for-form-viz []
  "Display the result of the form that the cursor is in."
  (require-clay-if-needed)
  (eval.eval-str
    {:origin "custom-clay-wrapper"
     :code (str.join
             ""
             ["(scicloj.clay.v2.api/make! {:source-path \"" (nvim.fn.expand "%.") "\" :single-form `" (a.get (extract.form {:root? true}) :content) "})"])}))

(defn eval-clojure-for-ns-viz []
  "Display the entire namespace, typically a Clay source file."
  (require-clay-if-needed)
  (eval.eval-str
    {:origin "custom-clay-wrapper"
     :code (str.join
             ""
             ["(scicloj.clay.v2.api/make! {:source-path \"" (nvim.fn.expand "%.") "\"})"])}))

(defn on-filetype []
  "Map ev to eval-clojure-for-form-viz and env to
  eval-clojure-for-ns-viz."
  (nvim.buf_set_keymap
    0 :n "ev" ""
    {:callback eval-clojure-for-form-viz})
  (nvim.buf_set_keymap
    0 :n "env" ""
    {:callback eval-clojure-for-ns-viz}) )

(def augroup (nvim.create_augroup :viz.lnvim {}))
(nvim.create_autocmd
  :Filetype
  {:group augroup
   :pattern ["clojure"]
   :callback on-filetype})

Slackbot 2025-02-22T21:09:42.000359Z

This message was deleted.

Marshall Abrams 2025-02-22T21:16:20.480459Z

Well darn. Now I'm getting the multiple nrepl connect/disconnect even with the require in the callback. That's new.

; Sponsored by @extradosages ❤
; --------------------------------------------------------------------------------
; eval (custom-clay-wrapper): (require 'scicloj.clay.v2.api)
; --------------------------------------------------------------------------------
; localhost:55829 (disconnected): /Users/marshall/docs/src/clojure/tableplot/.nrepl-port
; --------------------------------------------------------------------------------
; localhost:55829 (connected): /Users/marshall/docs/src/clojure/tableplot/.nrepl-port
; --------------------------------------------------------------------------------
; localhost:55829 (connected): /Users/marshall/docs/src/clojure/tableplot/.nrepl-port
; --------------------------------------------------------------------------------
; Assumed session: Great Pyrenees (Clojure)
; --------------------------------------------------------------------------------
; Assumed session: Cavalier King Charles Spaniel (Clojure)