Skip to content

Instantly share code, notes, and snippets.

@Risto-Stevcev
Last active October 15, 2023 00:56
Show Gist options
  • Save Risto-Stevcev/51b29b79b661caeee38341fa12365aa7 to your computer and use it in GitHub Desktop.
Save Risto-Stevcev/51b29b79b661caeee38341fa12365aa7 to your computer and use it in GitHub Desktop.
Conjure nodejs client attempt
(local a (require :conjure.aniseed.core))
;;(import-macros {: def} :aniseed)
(local extract (require :conjure.extract))
(local str (require :conjure.aniseed.string))
(local nvim (require :conjure.aniseed.nvim))
(local stdio (require :conjure.remote.stdio))
(local config (require :conjure.config))
(local text (require :conjure.text))
(local mapping (require :conjure.mapping))
(local client (require :conjure.client))
(local log (require :conjure.log))
(local ts (require :conjure.tree-sitter))
(local b64 (require :conjure.remote.transport.base64))
(config.merge {:client {:nodejs {:stdio {:mapping {:start :cs
:stop :cS
:interrupt :ei}
:command "tee /home/risto/foo"
:prompt-pattern "> "
:delay-stderr-ms 10}}}})
(local cfg (config.get-in-fn [:client :nodejs :stdio]))
(local state (client.new-state #(do
{:repl nil})))
(local buf-suffix :.js)
(local comment-prefix "// ")
(fn form-node? [node]
(or (= :variable_declaration (node:type))
(= :lexical_declaration (node:type)) (= :function_declaration (node:type))
(= :class_declaration (node:type)) (= :generator_function (node:type))
(= :arrow_function (node:type)) (= :function (node:type))
(= :new_expression (node:type)) (= :parenthesized_expression (node:type))
(= :statement_block (node:type)) (= :template_string (node:type))
(= :string (node:type)) (= :object (node:type)) (= :array (node:type))
(= :number (node:type)) (= :true (node:type)) (= :false (node:type))))
(fn with-repl-or-warn [f opts]
(log.dbg (str.join ["With repl or warn" "!"]))
(let [repl (state :repl)]
(if repl
(f repl)
;(do
;(log.append [(str.join comment-prefix "has repl")])
;(repl.send "TextEncoder;\n" (fn [msgs] (log.dbg "done")) {:batch? true})
;(log.append [(str.join comment-prefix "send repl")])
; (f repl))
(log.append [(str.join comment-prefix "No REPL running")
(str.join comment-prefix "Start REPL with "
(config.get-in [:mapping :prefix])
(cfg [:mapping :start]))]))))
(fn is-dots? [s]
(= (string.sub s 1 3) :str.join.))
(fn format-msg [msg]
(->> (text.split-lines msg)
(a.filter #(not= "" $1))
(a.filter #(not (is-dots? $1)))))
(fn get-console-output-msgs [msgs]
(->> (a.butlast msgs)
(a.map #(str.join comment-prefix "(out) " $1))))
(fn get-expression-result [msgs]
(let [result (a.last msgs)]
(if (or (a.nil? result) (is-dots? result))
nil
result)))
(fn unbatch [msgs]
(log.dbg "unbatch")
(->> msgs
(a.map #(or (a.get $1 :out) (a.get $1 :err)))
(str.join "")))
;(fn prep-code [s]
; (log.append s)
; (str.join s "\nif(isnothing(ans)) display(nothing) end\n"))
(fn log-repl-output [msgs]
(log.dbg "log-repl-output")
(let [msgs (-> msgs unbatch format-msg)
console-output-msgs (get-console-output-msgs msgs)
cmd-result (get-expression-result msgs)]
(when (not (a.empty? console-output-msgs))
(log.append console-output-msgs))
(when cmd-result
(log.append [cmd-result]))))
(fn eval-str [opts]
(log.dbg :eval-str)
;(log.dbg opts.code)
(with-repl-or-warn (fn [repl]
(repl.send (str.join opts.code "\n")
(fn [msgs]
(log.dbg "received msg")
(log-repl-output msgs)
(when opts.on-result
(let [msgs (-> msgs unbatch format-msg)
cmd-result (get-expression-result msgs)]
(opts.on-result cmd-result))))
{:batch? true}))))
(fn eval-file [opts]
(eval-str (a.assoc opts :code (a.slurp opts.file-path))))
(fn display-repl-status [status]
(let [repl (state :repl)]
(when repl
(log.append [(str.join comment-prefix
(a.pr-str (a.get-in repl [:opts :cmd])) " (" status
")")] {:break? true}))))
(fn stop []
(let [repl (state :repl)]
(when repl
(repl.destroy)
(display-repl-status :stopped)
(a.assoc (state) :repl nil))))
(fn start []
(if (state :repl)
(log.append [(str.join comment-prefix
"Can't start, REPL is already running.")
(str.join comment-prefix "Stop the REPL with "
(config.get-in [:mapping :prefix])
(cfg [:mapping :stop]))]
{:break? true})
(if (not (pcall #(if vim.treesitter.language.require_language
(vim.treesitter.language.require_language :javascript)
(vim.treesitter.require_language :javascript))))
(log.append [(str.join comment-prefix
"(error) The nodejs client requires a javascript treesitter parser in order to function.")
(str.join comment-prefix
"(error) See https://github.com/nvim-treesitter/nvim-treesitter")
(str.join comment-prefix
"(error) for installation instructions.")])
(a.assoc (state) :repl
(stdio.start {:prompt-pattern (cfg [:prompt-pattern])
:cmd (cfg [:command])
:delay-stderr-ms (cfg [:delay-stderr-ms])
:on-success (fn []
(log.dbg "on-success")
(display-repl-status :started)
(with-repl-or-warn (fn [repl]
(repl.send "(1 + 2);\n"
(fn [msgs]
(log.dbg "received msg2")
;;(log.dbg (str.join msgs))
;(log.append (-> msgs
; unbatch
; format-msg))
)
{:batch? true}))))
:on-error (fn [err]
(display-repl-status err))
:on-exit (fn [code signal]
(when (and (= :number (type code))
(> code 0))
(log.append [(str.join comment-prefix
"process exited with code "
code)]))
(when (and (= :number (type signal))
(> signal 0))
(log.append [(str.join comment-prefix
"process exited with signal "
signal)]))
(stop))
:on-stray-output (fn [msg]
(log.db "stray-output")
(log.dbg (-> [msg] unbatch
format-msg)
{:join-first? true}))})))))
(fn on-load []
(if (config.get-in [:client_on_load])
(do
(start))
(log.append ["Not starting repl"])))
(fn on-exit []
(stop))
(fn interrupt []
(with-repl-or-warn (fn [repl]
(log.append [(str.join comment-prefix
" Sending interrupt signal.")]
{:break? true})
(repl.send-signal vim.loop.constants.SIGINT))))
(fn on-filetype []
(mapping.buf :NodeJsStart (cfg [:mapping :start]) start
{:desc "Start the NodeJs REPL"})
(mapping.buf :NodeJsStop (cfg [:mapping :stop]) stop
{:desc "Stop the NodeJs REPL"})
(mapping.buf :NodeJsInterrupt (cfg [:mapping :interrupt]) interrupt
{:desc "Interrupt the current evaluation"}))
{: format-msg
:connect start
: with-repl-or-warn
: form-node?
: buf-suffix
: comment-prefix
: eval-str
: eval-file
: on-load
: on-exit
: on-filetype}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment