From 1182c545dd63f5bfea2730c52cd276b322ad1668 Mon Sep 17 00:00:00 2001 From: Oliver Caldwell Date: Sat, 14 May 2022 11:50:17 +0100 Subject: [PATCH] Support checking for multiple nREPL ops in one go, support the new completions op if the CIDER one isn't there #137 --- fnl/conjure/client/clojure/nrepl/action.fnl | 61 ++++++++++++--------- fnl/conjure/client/clojure/nrepl/server.fnl | 35 ++++++++---- lua/conjure/client/clojure/nrepl/action.lua | 46 +++++++++------- lua/conjure/client/clojure/nrepl/server.lua | 44 +++++++++------ 4 files changed, 114 insertions(+), 72 deletions(-) diff --git a/fnl/conjure/client/clojure/nrepl/action.fnl b/fnl/conjure/client/clojure/nrepl/action.fnl index 334b1854..9613843b 100644 --- a/fnl/conjure/client/clojure/nrepl/action.fnl +++ b/fnl/conjure/client/clojure/nrepl/action.fnl @@ -130,8 +130,8 @@ (server.eval opts (eval-cb-fn opts))))))) (defn- with-info [opts f] - (server.with-conn-and-op-or-warn - :info + (server.with-conn-and-ops-or-warn + [:info] (fn [conn] (server.send {:op :info @@ -536,8 +536,8 @@ msgs)))))))))))) (defn- refresh-impl [op] - (server.with-conn-and-op-or-warn - op + (server.with-conn-and-ops-or-warn + [op] (fn [conn] (server.send (a.merge @@ -578,8 +578,8 @@ (try-ensure-conn (fn [] (log.append ["; Clearing refresh cache"] {:break? true}) - (server.with-conn-and-op-or-warn - :refresh-clear + (server.with-conn-and-ops-or-warn + [:refresh-clear] (fn [conn] (server.send {:op :refresh-clear @@ -656,38 +656,49 @@ (cfg [:completion :cljs :use_suitable])) (defn completions [opts] - (server.with-conn-and-op-or-warn - :complete - (fn [conn] + (server.with-conn-and-ops-or-warn + [:complete :completions] + (fn [conn ops] (server.send - {:op :complete - :session conn.session - :ns opts.context - :symbol opts.prefix - :context (when (cfg [:completion :with_context]) - (extract-completion-context opts.prefix)) - :extra-metadata [:arglists :doc] - :enhanced-cljs-completion? (when (enhanced-cljs-completion?) "t")} + (if + ;; CIDER + ops.complete + {:op :complete + :session conn.session + :ns opts.context + :symbol opts.prefix + :context (when (cfg [:completion :with_context]) + (extract-completion-context opts.prefix)) + :extra-metadata [:arglists :doc] + :enhanced-cljs-completion? (when (enhanced-cljs-completion?) "t")} + + ;; nREPL 0.8+ + ops.completions + {:op :completions + :session conn.session + :ns opts.context + :prefix opts.prefix}) + (nrepl.with-all-msgs-fn - (fn [msgs] - (->> (a.get (a.last msgs) :completions) - (a.map clojure->vim-completion) - (opts.cb)))))) + (fn [msgs] + (->> (a.get (a.last msgs) :completions) + (a.map clojure->vim-completion) + (opts.cb)))))) {:silent? true :else opts.cb})) (defn out-subscribe [] (try-ensure-conn) (log.append ["; Subscribing to out"] {:break? true}) - (server.with-conn-and-op-or-warn - :out-subscribe + (server.with-conn-and-ops-or-warn + [:out-subscribe] (fn [conn] (server.send {:op :out-subscribe})))) (defn out-unsubscribe [] (try-ensure-conn) (log.append ["; Unsubscribing from out"] {:break? true}) - (server.with-conn-and-op-or-warn - :out-unsubscribe + (server.with-conn-and-ops-or-warn + [:out-unsubscribe] (fn [conn] (server.send {:op :out-unsubscribe})))) diff --git a/fnl/conjure/client/clojure/nrepl/server.fnl b/fnl/conjure/client/clojure/nrepl/server.fnl index 502bd621..75b75cac 100644 --- a/fnl/conjure/client/clojure/nrepl/server.fnl +++ b/fnl/conjure/client/clojure/nrepl/server.fnl @@ -195,19 +195,32 @@ (fn [msg] (a.assoc (state.get :conn) :describe msg)))) -(defn with-conn-and-op-or-warn [op f opts] +(defn with-conn-and-ops-or-warn [op-names f opts] + "Takes a sequential table of op names and calls your function f with an + associative table of the shape {:op-name true} if any exist. If not, your + function is not called and a warning is displayed." (with-conn-or-warn (fn [conn] - (if (a.get-in conn [:describe :ops op]) - (f conn) - (do - (when (not (a.get opts :silent?)) - (log.append - [(.. "; Unsupported operation: " op) - "; Ensure the CIDER middleware is installed and up to date" - "; https://docs.cider.mx/cider-nrepl/usage.html"])) - (when (a.get opts :else) - (opts.else))))) + (let [found-ops + (a.reduce + (fn [acc op] + (if (a.get-in conn [:describe :ops op]) + (a.assoc acc op true) + acc)) + {} + op-names)] + + (if (not (a.empty? found-ops)) + (f conn found-ops) + (do + (when (not (a.get opts :silent?)) + (log.append + ["; None of the required operations are supported by this nREPL." + "; Ensure your nREPL is up to date." + "; Consider installing or updating the CIDER middleware." + "; https://docs.cider.mx/cider-nrepl/usage.html"])) + (when (a.get opts :else) + (opts.else)))))) opts)) (defn connect [{: host : port : cb : port_file_path}] diff --git a/lua/conjure/client/clojure/nrepl/action.lua b/lua/conjure/client/clojure/nrepl/action.lua index 1036e9f8..d31464c8 100644 --- a/lua/conjure/client/clojure/nrepl/action.lua +++ b/lua/conjure/client/clojure/nrepl/action.lua @@ -223,7 +223,7 @@ local function with_info(opts, f) end return server.send({op = "info", ns = (opts.context or "user"), symbol = opts.code, session = conn.session}, _35_) end - return server["with-conn-and-op-or-warn"]("info", _34_) + return server["with-conn-and-ops-or-warn"]({"info"}, _34_) end _2amodule_locals_2a["with-info"] = with_info local function java_info__3elines(_37_) @@ -666,7 +666,7 @@ local function refresh_impl(op) end return server.send(a.merge({op = op, session = conn.session, after = cfg({"refresh", "after"}), before = cfg({"refresh", "before"}), dirs = cfg({"refresh", "dirs"})}), _117_) end - return server["with-conn-and-op-or-warn"](op, _116_) + return server["with-conn-and-ops-or-warn"]({op}, _116_) end _2amodule_locals_2a["refresh-impl"] = refresh_impl local function refresh_changed() @@ -694,7 +694,7 @@ local function refresh_clear() end return server.send({op = "refresh-clear", session = conn.session}, nrepl["with-all-msgs-fn"](_123_)) end - return server["with-conn-and-op-or-warn"]("refresh-clear", _122_) + return server["with-conn-and-ops-or-warn"]({"refresh-clear"}, _122_) end return try_ensure_conn(_121_) end @@ -784,43 +784,51 @@ local function enhanced_cljs_completion_3f() end _2amodule_locals_2a["enhanced-cljs-completion?"] = enhanced_cljs_completion_3f local function completions(opts) - local function _139_(conn) + local function _139_(conn, ops) local _140_ - if cfg({"completion", "with_context"}) then - _140_ = extract_completion_context(opts.prefix) + if ops.complete then + local _141_ + if cfg({"completion", "with_context"}) then + _141_ = extract_completion_context(opts.prefix) + else + _141_ = nil + end + local _143_ + if enhanced_cljs_completion_3f() then + _143_ = "t" + else + _143_ = nil + end + _140_ = {op = "complete", session = conn.session, ns = opts.context, symbol = opts.prefix, context = _141_, ["extra-metadata"] = {"arglists", "doc"}, ["enhanced-cljs-completion?"] = _143_} + elseif ops.completions then + _140_ = {op = "completions", session = conn.session, ns = opts.context, prefix = opts.prefix} else _140_ = nil end - local _142_ - if enhanced_cljs_completion_3f() then - _142_ = "t" - else - _142_ = nil - end - local function _144_(msgs) + local function _146_(msgs) return opts.cb(a.map(clojure__3evim_completion, a.get(a.last(msgs), "completions"))) end - return server.send({op = "complete", session = conn.session, ns = opts.context, symbol = opts.prefix, context = _140_, ["extra-metadata"] = {"arglists", "doc"}, ["enhanced-cljs-completion?"] = _142_}, nrepl["with-all-msgs-fn"](_144_)) + return server.send(_140_, nrepl["with-all-msgs-fn"](_146_)) end - return server["with-conn-and-op-or-warn"]("complete", _139_, {["silent?"] = true, ["else"] = opts.cb}) + return server["with-conn-and-ops-or-warn"]({"complete", "completions"}, _139_, {["silent?"] = true, ["else"] = opts.cb}) end _2amodule_2a["completions"] = completions local function out_subscribe() try_ensure_conn() log.append({"; Subscribing to out"}, {["break?"] = true}) - local function _145_(conn) + local function _147_(conn) return server.send({op = "out-subscribe"}) end - return server["with-conn-and-op-or-warn"]("out-subscribe", _145_) + return server["with-conn-and-ops-or-warn"]({"out-subscribe"}, _147_) end _2amodule_2a["out-subscribe"] = out_subscribe local function out_unsubscribe() try_ensure_conn() log.append({"; Unsubscribing from out"}, {["break?"] = true}) - local function _146_(conn) + local function _148_(conn) return server.send({op = "out-unsubscribe"}) end - return server["with-conn-and-op-or-warn"]("out-unsubscribe", _146_) + return server["with-conn-and-ops-or-warn"]({"out-unsubscribe"}, _148_) end _2amodule_2a["out-unsubscribe"] = out_unsubscribe return _2amodule_2a \ No newline at end of file diff --git a/lua/conjure/client/clojure/nrepl/server.lua b/lua/conjure/client/clojure/nrepl/server.lua index 69a91bf7..535339ae 100644 --- a/lua/conjure/client/clojure/nrepl/server.lua +++ b/lua/conjure/client/clojure/nrepl/server.lua @@ -232,13 +232,23 @@ local function capture_describe() return send({op = "describe"}, _35_) end _2amodule_locals_2a["capture-describe"] = capture_describe -local function with_conn_and_op_or_warn(op, f, opts) +local function with_conn_and_ops_or_warn(op_names, f, opts) local function _36_(conn) - if a["get-in"](conn, {"describe", "ops", op}) then - return f(conn) + local found_ops + local function _37_(acc, op) + if a["get-in"](conn, {"describe", "ops", op}) then + return a.assoc(acc, op, true) + else + return acc + end + end + found_ops = a.reduce(_37_, {}, op_names) + a.println("---", op_names, found_ops) + if not a["empty?"](found_ops) then + return f(conn, found_ops) else if not a.get(opts, "silent?") then - log.append({("; Unsupported operation: " .. op), "; Ensure the CIDER middleware is installed and up to date", "; https://docs.cider.mx/cider-nrepl/usage.html"}) + log.append({"; None of the required operations are supported by this nREPL.", "; Ensure your nREPL is up to date.", "; Consider installing or updating the CIDER middleware.", "; https://docs.cider.mx/cider-nrepl/usage.html"}) else end if a.get(opts, "else") then @@ -250,35 +260,35 @@ local function with_conn_and_op_or_warn(op, f, opts) end return with_conn_or_warn(_36_, opts) end -_2amodule_2a["with-conn-and-op-or-warn"] = with_conn_and_op_or_warn -local function connect(_40_) - local _arg_41_ = _40_ - local host = _arg_41_["host"] - local port = _arg_41_["port"] - local cb = _arg_41_["cb"] - local port_file_path = _arg_41_["port_file_path"] +_2amodule_2a["with-conn-and-ops-or-warn"] = with_conn_and_ops_or_warn +local function connect(_42_) + local _arg_43_ = _42_ + local host = _arg_43_["host"] + local port = _arg_43_["port"] + local cb = _arg_43_["cb"] + local port_file_path = _arg_43_["port_file_path"] if state.get("conn") then disconnect() else end - local function _43_(err) + local function _45_(err) display_conn_status(err) return disconnect() end - local function _44_() + local function _46_() display_conn_status("connected") capture_describe() assume_or_create_session() return eval_preamble(cb) end - local function _45_(err) + local function _47_(err) if err then return display_conn_status(err) else return disconnect() end end - local function _47_(msg) + local function _49_(msg) if msg.status["unknown-session"] then log.append({"; Unknown session, correcting"}) assume_or_create_session() @@ -290,10 +300,10 @@ local function connect(_40_) return nil end end - local function _50_(result) + local function _52_(result) return ui["display-result"](result) end - return a.assoc(state.get(), "conn", a["merge!"](nrepl.connect({host = host, port = port, ["on-failure"] = _43_, ["on-success"] = _44_, ["on-error"] = _45_, ["on-message"] = _47_, ["default-callback"] = _50_}), {["seen-ns"] = {}, port_file_path = port_file_path})) + return a.assoc(state.get(), "conn", a["merge!"](nrepl.connect({host = host, port = port, ["on-failure"] = _45_, ["on-success"] = _46_, ["on-error"] = _47_, ["on-message"] = _49_, ["default-callback"] = _52_}), {["seen-ns"] = {}, port_file_path = port_file_path})) end _2amodule_2a["connect"] = connect return _2amodule_2a \ No newline at end of file