Fork me on GitHub
#calva
<
2021-10-14
>
esp114:10:28

Hi - I'm trying to see if I can get Calva jack-in to work with an https://github.com/mfikes/esprit ClojureScript repl running on a microcontroller(!) The Esprit docs show how to https://cljdoc.org/d/esprit/esprit/1.0.0/doc/project-setup#emacscider, so I tried to adapt that into a custom Calva connect sequence that runs the piggieback/esprit repl, and it looked like it worked - the repl was promoted to a cljs repl - but when I try to actually do anything, nothing works. The following commands to toggle an LED attached to pin 13 on and off work as expected in a command line clj repl, but do nothing in the Calva jack-in repl:

cljs꞉cljs.user꞉> 
(js/digitalWrite js/D13 js/HIGH)
true
cljs꞉cljs.user꞉> 
(js/digitalWrite js/D13 js/LOW)
true
In addition to not appearing to function, I also noticed that eval-ing anything non-nil in the Calva repl simply prints `true` instead of the actual expected value (eval-ing nil prints `nil`):
cljs꞉cljs.user꞉> 
1
true
cljs꞉cljs.user꞉> 
"abc"
true
cljs꞉cljs.user꞉> 
:blah
true
cljs꞉cljs.user꞉> 
nil
nil
I originally thought it might have been a problem with pretty printing, but I have pprint disabled in Calva. Here is the custom connect sequence I used for reference:
"calva.replConnectSequences": [
        {
            "name": "esprit",
            "projectType": "deps.edn",
            "nReplPortFile": [".nrepl-port"],
            "cljsType": {
                "dependsOn": "User provided",
                "isStarted": true,
                "connectCode": "(do (require 'esprit.repl) (cider.piggieback/cljs-repl (esprit.repl/repl-env)))"
            }
        }
    ],
Any ideas on what I might be doing wrong?

pez14:10:47

I wonder if this can be part of the problem: > Additionally, CIDER’s default printing function must be changed to `pr` as we don’t provide support for `cljs.pprint` at this time. I don’t think we can configure that in Calva. I could be wrong though, and will have to check. In any case, we really should, so I think an issue about it is in place.

hoppy15:10:49

@U0ETXRFEW I never actually got all that kit to work with calva - but that was many months ago. This is probably an @U04VDQDDY question, if he still has interest in the thing. I don't believe that Vouch is actually using that stack for anything commercial. I've got a couple of his gadgets sitting around if that helps. I do know that there is a pretty nifty shim in there on the espurino to reload the JS post-compile, but that is above my pay grade.

pez15:10:08

I’m thinking that as this works with CIDER we can figure out how to make it work in Calva. Do you remember if you reach a similar dead end and @U06BTJLTU, @U19EVCEBV?

hoppy15:10:22

seems right. Unfortunately I don't have any Wrover class boards on my person ATM, will have to wait until this eve to fiddle with things, but I'll throw a little time at it.

hoppy15:10:47

you basically wanting to add another repl type to the trophy case 😜 ?

pez16:10:16

Haha, maybe not just yet, but I would love for it to be configurable as a custom repl type. Here it seems that it is very close. I’ll check about that printing function now. Unfortunately I don’t have the gears and tools (or something resembling the knowledge) to fiddle with getting this repl to work myself. But with some coop here, hopefully we can fix it.

pez19:10:30

OK, so chores, but now I have checked. We don’t currently support setting the printer to whatever. I created an issue for it https://github.com/BetterThanTomorrow/calva/issues/1340 It shouldn’t be too hard to fix. If it is enough to make it work, we will see, I guess.

esp120:10:06

Thanks for looking into this! I'm more than happy to help test this, and if you want to test it yourself it's actually very easy to do: I just got one of https://www.amazon.com/gp/product/B07QDFP3WC/ref=ppx_yo_dt_b_asin_title_o03_s00?ie=UTF8&amp;psc=1, plugged it into my computer via a micro usb cable, and ran https://cljdoc.org/d/esprit/esprit/1.0.0/doc/getting-started to get a cli repl.

hoppy00:10:08

@U0ETXRFEW, if you want, I'll send you one of my boards

❤️ 1
pez15:10:03

Very tempting!

pez15:10:33

@U06BTJLTU, you can try to start/connect the cljs repl manually? It gets a bit weird because Calva is a bit flaky around this, but anyway. If you set the connectCode to "". Then the cljs REPL should remain a clj one, and you can evaluate the connect code there and see if you get any errors that can guide us.

pez16:10:39

Also, I don’t know if you have pprint enabled. Disabling it should make nREPL use it’s default printer, which should be its equivalent to pr

esp118:10:36

@U0ETXRFEW I have pprint disabled (I confirmed that the pprint button in the lower right is grayed out). Here is a transcript of the interaction with connectCode: "" . Unfortunately there aren't really any errors being printed:

; This is the Calva evaluation results output window.
; TIPS: The keyboard shortcut `ctrl+alt+c o` shows and focuses this window
;   when connected to a REPL session.
; Please see  for more info.
; Happy coding! ♥️

; Jacking in...
; Starting Jack-in Terminal: clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version,"0.8.3"},cider/cider-nrepl {:mvn/version,"0.26.0"},cider/piggieback {:mvn/version,"0.5.2"}}}'  -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware cider.piggieback/wrap-cljs-repl]"
; Hooking up nREPL sessions...
; Connected session: clj
; TIPS: 
;   - You can edit the contents here. Use it as a REPL if you like.
;   - `alt+enter` evaluates the current top level form.
;   - `ctrl+enter` evaluates the current form.
;   - `alt+up` and `alt+down` traverse up and down the REPL command history
;      when the cursor is after the last contents at the prompt
;   - Clojure lines in stack traces are peekable and clickable.
clj꞉user꞉> 
; Creating cljs repl session...
; Connecting cljs repl: esprit...
;   The Calva Connection Log might have more connection progress information.
; Connected session: cljs
; TIPS: You can choose which REPL to use (clj or cljs):
;    *Calva: Toggle REPL connection*
;    (There is a button in the status bar for this)
; Jack-in done.
cljs꞉cljs.user꞉> 
;; this is what I see immediately after jack-in with an empty connect code.
;; note that the prompt says clj:cljs.user, but if I eval anything here, e.g.:
1
1
clj꞉user꞉> 
;; it gets evaluated correctly, but the prompt switches back to clj:user
;; ok let's try to start up the esprit repl:
(cider.piggieback/cljs-repl ((requiring-resolve 'esprit.repl/repl-env)))

Connecting to ESP32 WROVER ...

To quit, type: :cljs/quit
nil
clj꞉cljs.user꞉> 
;; it looks like it connected, but if I try to eval anything, e.g.:
1
true
cljs꞉cljs.user꞉> 
;; it just returns true.
;; let's try some other basic stuff:
"abc"
true
cljs꞉cljs.user꞉> 
:xyz
true
cljs꞉cljs.user꞉> 
[1 2 3]
true
cljs꞉cljs.user꞉> 
{:foo :bar}
true
cljs꞉cljs.user꞉> 
nil
nil
cljs꞉cljs.user꞉> 
;; ok well at least evaluating nil returns nil instead of true
;; we can still use :cljs/quit to quit:
:cljs/quit
nil
clj꞉user꞉> 
;; and we're back to the clj:user prompt

esp118:10:24

And here is the updated connect sequence I used for the above for reference:

"calva.replConnectSequences": [
        {
            "name": "esprit",
            "projectType": "deps.edn",
            "nReplPortFile": [".nrepl-port"],
            "cljsType": {
                "dependsOn": "User provided",
                "isStarted": true,
                "connectCode": ""
            }
        }
    ],

esp119:10:30

Is there some way to intercept and log what is going on with the repl interaction?

esp122:10:42

oh cool - is this in a .vsix somewhere? or can you point me to instructions on how to build one so i can test?

esp123:10:15

@U0ETXRFEW here's the repl log I see from the following interaction:

; This is the Calva evaluation results output window.
; TIPS: The keyboard shortcut `ctrl+alt+c o` shows and focuses this window
;   when connected to a REPL session.
; Please see  for more info.
; Happy coding! ♥️

; Jacking in...
; Starting Jack-in Terminal: clojure -Sdeps '{:deps {nrepl/nrepl {:mvn/version,"0.8.3"},cider/cider-nrepl {:mvn/version,"0.26.0"},cider/piggieback {:mvn/version,"0.5.2"}}}'  -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware cider.piggieback/wrap-cljs-repl]"
; Hooking up nREPL sessions...
; Connected session: clj
; TIPS: 
;   - You can edit the contents here. Use it as a REPL if you like.
;   - `alt+enter` evaluates the current top level form.
;   - `ctrl+enter` evaluates the current form.
;   - `alt+up` and `alt+down` traverse up and down the REPL command history
;      when the cursor is after the last contents at the prompt
;   - Clojure lines in stack traces are peekable and clickable.
clj꞉user꞉> 
; Creating cljs repl session...
; Connecting cljs repl: esprit...
;   The Calva Connection Log might have more connection progress information.
; Connected session: cljs
; TIPS: You can choose which REPL to use (clj or cljs):
;    *Calva: Toggle REPL connection*
;    (There is a button in the status bar for this)
; Jack-in done.
cljs꞉cljs.user꞉> 
(cider.piggieback/cljs-repl ((requiring-resolve 'esprit.repl/repl-env)))

Connecting to ESP32 WROVER ...

To quit, type: :cljs/quit
nil
clj꞉cljs.user꞉> 
12345
true
cljs꞉cljs.user꞉> 
"abcde"
true
And the corresponding nREPL Messages:
<- received
{
  id: '1',
  ns: 'user',
  session: '279ec703-ad3e-4dd6-aafd-e9d3ca20c3ae',
  value: '#namespace[user]'
}

<- received
{
  id: '1',
  session: '279ec703-ad3e-4dd6-aafd-e9d3ca20c3ae',
  status: [ 'done' ]
}

<- received
{
  'changed-namespaces': {
    'clojure.core': { aliases: {}, interns: [Object] },
    user: { aliases: {}, interns: {} }
  },
  id: '1',
  'repl-type': 'clj',
  session: '279ec703-ad3e-4dd6-aafd-e9d3ca20c3ae',
  status: [ 'state' ]
}

<- received
{
  id: '2',
  'new-session': 'feff83a9-9e8f-4a9c-912b-ddc872b16d49',
  session: '446475a9-a3b5-4558-95e4-6bcd3460d6c0',
  status: [ 'done' ]
}

-> sent
{
  op: 'init-debugger',
  id: '4',
  session: 'feff83a9-9e8f-4a9c-912b-ddc872b16d49'
}

-> sent
{
  op: 'clone',
  session: 'feff83a9-9e8f-4a9c-912b-ddc872b16d49',
  id: '5'
}

<- received
{
  id: '5',
  'new-session': 'de0a7b4c-2587-4649-bf77-2516e628c777',
  session: 'feff83a9-9e8f-4a9c-912b-ddc872b16d49',
  status: [ 'done' ]
}

<- received
{
  aux: {
    'cider-version': {
      incremental: 0,
      major: 0,
      minor: 26,
      qualifier: [],
      'version-string': '0.26.0'
    },
    'current-ns': 'user'
  },
  id: '3',
  ops: {
    'add-middleware': {},
    apropos: {},
    'cider-version': {},
    classpath: {},
    'clear-profile': {},
    'clojuredocs-lookup': {},
    'clojuredocs-refresh-cache': {},
    clone: {},
    close: {},
    complete: {},
    'complete-doc': {},
    'complete-flush-caches': {},
    completions: {},
    'content-type-middleware': {},
    'debug-input': {},
    'debug-instrumented-defs': {},
    'debug-middleware': {},
    describe: {},
    eldoc: {},
    'eldoc-datomic-query': {},
    eval: {},
    'fn-deps': {},
    'fn-refs': {},
    'format-code': {},
    'format-edn': {},
    'get-max-samples': {},
    info: {},
    'init-debugger': {},
    'inspect-clear': {},
    'inspect-def-current-value': {},
    'inspect-get-path': {},
    'inspect-next-page': {},
    'inspect-pop': {},
    'inspect-prev-page': {},
    'inspect-push': {},
    'inspect-refresh': {},
    'inspect-set-max-atom-length': {},
    'inspect-set-max-coll-size': {},
    'inspect-set-page-size': {},
    interrupt: {},
    'is-var-profiled': {},
    'load-file': {},
    lookup: {},
    'ls-middleware': {},
    'ls-sessions': {},
    macroexpand: {},
    'ns-aliases': {},
    'ns-list': {},
    'ns-list-vars-by-name': {},
    'ns-load-all': {},
    'ns-path': {},
    'ns-vars': {},
    'ns-vars-with-meta': {},
    'out-subscribe': {},
    'out-unsubscribe': {},
    'profile-summary': {},
    'profile-var-summary': {},
    refresh: {},
    'refresh-all': {},
    'refresh-clear': {},
    resource: {},
    'resources-list': {},
    retest: {},
    'set-max-samples': {},
    'sideloader-provide': {},
    'sideloader-start': {},
    slurp: {},
    'spec-example': {},
    'spec-form': {},
    'spec-list': {},
    stacktrace: {},
    stdin: {},
    'swap-middleware': {},
    test: {},
    'test-all': {},
    'test-stacktrace': {},
    'test-var-query': {},
    'toggle-profile': {},
    'toggle-profile-ns': {},
    'toggle-trace-ns': {},
    'toggle-trace-var': {},
    'track-state-middleware': {},
    undef: {}
  },
  session: 'feff83a9-9e8f-4a9c-912b-ddc872b16d49',
  status: [ 'done' ],
  versions: {
    clojure: { incremental: 3, major: 1, minor: 10, 'version-string': '1.10.3' },
    java: {
      incremental: '12',
      major: '11',
      minor: '0',
      'version-string': '11.0.12'
    },
    nrepl: { incremental: 3, major: 0, minor: 8, 'version-string': '0.8.3' }
  }
}

-> sent
{
  id: '6',
  op: 'eval',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  code: '',
  stdout: [Function: stdout],
  stderr: [Function: stderr],
  pprint: false
}

<- received
{
  id: '6',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  status: [ 'done' ]
}

<- received
{
  'changed-namespaces': {
    'clojure.core': { aliases: {}, interns: [Object] },
    user: { aliases: {}, interns: {} }
  },
  id: '6',
  'repl-type': 'clj',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  status: [ 'state' ]
}

-> sent
{
  id: '7',
  op: 'eval',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  code: "(cider.piggieback/cljs-repl ((requiring-resolve 'esprit.repl/repl-env)))",
  file: '/Users/edwin/Projects/esp32-wordclock/.calva/output-window/output.calva-repl',
  line: 28,
  column: 1,
  stdout: [Function: stdout],
  stderr: [Function: stderr],
  pprint: false
}

<- received
{
  id: '7',
  out: '\nConnecting to ESP32 WROVER ...\n\n',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777'
}

<- received
{
  id: '7',
  out: 'To quit, type: :cljs/quit\n',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777'
}

<- received
{
  id: '7',
  ns: 'cljs.user',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  value: 'nil'
}

<- received
{
  id: '7',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  status: [ 'done' ]
}

<- received
{
  'changed-namespaces': {
    'cljs.core': {},
    'cljs.pprint': { aliases: [Object], interns: [Object] },
    'cljs.repl': { aliases: [Object], interns: [Object] },
    'cljs.user': { aliases: [Object], interns: [Object] },
    'goog.Uri': { aliases: [], interns: [Object] },
    'goog.array': { aliases: [], interns: [Object] },
    'goog.math.Integer': { aliases: [], interns: [Object] },
    'goog.math.Long': { aliases: [], interns: {} },
    'goog.object': { aliases: [], interns: [Object] },
    'goog.string': { aliases: [], interns: [Object] },
    'goog.string.StringBuffer': { aliases: [], interns: [Object] },
    'goog.string.format': { aliases: [], interns: [Object] }
  },
  id: '7',
  'repl-type': 'cljs',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  status: [ 'state' ]
}

-> sent
{
  id: '8',
  op: 'eval',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  code: '12345',
  file: '/Users/edwin/Projects/esp32-wordclock/.calva/output-window/output.calva-repl',
  line: 35,
  column: 1,
  stdout: [Function: stdout],
  stderr: [Function: stderr],
  pprint: false
}

<- received
{
  id: '8',
  ns: 'cljs.user',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  value: 'true'
}

<- received
{
  id: '8',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  status: [ 'done' ]
}

<- received
{
  'changed-namespaces': {},
  id: '8',
  'repl-type': 'cljs',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  status: [ 'state' ]
}

-> sent
{
  id: '9',
  op: 'eval',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  code: '"abcde"',
  file: '/Users/edwin/Projects/esp32-wordclock/.calva/output-window/output.calva-repl',
  line: 38,
  column: 1,
  stdout: [Function: stdout],
  stderr: [Function: stderr],
  pprint: false
}

<- received
{
  id: '9',
  ns: 'cljs.user',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  value: 'true'
}

<- received
{
  id: '9',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  status: [ 'done' ]
}

<- received
{
  'changed-namespaces': {},
  id: '9',
  'repl-type': 'cljs',
  session: 'de0a7b4c-2587-4649-bf77-2516e628c777',
  status: [ 'state' ]
}