Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Next release #19

Merged
merged 9 commits into from
Jan 2, 2025
Merged
17 changes: 17 additions & 0 deletions .github/workflows/release.yml
Original file line number Diff line number Diff line change
Expand Up @@ -45,3 +45,20 @@ jobs:
git add CHANGELOG.adoc
git commit -m "Update CHANGELOG" || exit 0
git push

create_pull_request:
needs: [changelog]
runs-on: ubuntu-latest
permissions:
contents: write
pull-requests: write
steps:
- uses: actions/checkout@v4
- name: Create Pull Request
uses: peter-evans/create-pull-request@v7
with:
title: Next release
branch: dev
base: main
labels: release
draft: true
4 changes: 2 additions & 2 deletions bb.edn
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@
org.clj-commons/digest {:mvn/version "1.4.100"}}

:__elin_internal__
{:command {:deps {nrepl/nrepl {:mvn/version "1.3.0"}
{:command {:deps {nrepl/nrepl {:mvn/version "1.3.1"}
refactor-nrepl/refactor-nrepl {:mvn/version "3.10.0"}
cider/cider-nrepl {:mvn/version "0.50.3"}}
cider/cider-nrepl {:mvn/version "0.51.0"}}
:middlewares [cider.nrepl/cider-middleware
refactor-nrepl.middleware/wrap-refactor]}}

Expand Down
2 changes: 1 addition & 1 deletion dev/analysis.edn

Large diffs are not rendered by default.

2 changes: 1 addition & 1 deletion doc/pages/getting_started/index.adoc
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ Alternatively, you can also start the REPL within the Elin server using the <<El

[source,shell]
----
$ clj -Sdeps '{:deps {nrepl/nrepl {:mvn/version "1.3.0"} cider/cider-nrepl {:mvn/version "0.50.3"}}}' -M -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware]" --interactive
$ clj -Sdeps '{:deps {nrepl/nrepl {:mvn/version "1.3.1"} cider/cider-nrepl {:mvn/version "0.51.0"}}}' -M -m nrepl.cmdline --middleware "[cider.nrepl/cider-middleware]" --interactive
----

Once the REPL is running, connect to the REPL using the <<ElinConnect>> command.
2 changes: 1 addition & 1 deletion plugin/elin.vim
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,7 @@ endif

" Connection
command! -nargs=? ElinConnect call elin#notify('elin.handler.connect/connect', <q-args> ? [str2nr(<q-args>)] : [])
command! -nargs=1 ElinInstantConnect call elin#notify('elin.handler.connect/instant', [<q-args>])
command! -nargs=? ElinInstantConnect call elin#notify('elin.handler.connect/instant', [<q-args>])
command! ElinDisconnect call elin#notify('elin.handler.connect/disconnect', [])
command! ElinJackIn call elin#notify('elin.handler.connect/jack-in', [])
command! ElinSwitchConnection call elin#notify('elin.handler.connect/switch', [])
Expand Down
18 changes: 12 additions & 6 deletions src/elin/error.clj
Original file line number Diff line number Diff line change
Expand Up @@ -148,9 +148,15 @@
`(let [~@(interleave (repeat sym) bindings)]
~sym)))

(defn error-or [& vs]
(some
#(when (and %
(not (error? %)))
%)
vs))
(defmacro error-or
"Evaluates exprs one at a time, from left to right.
If a form returns a logical true and not error value,
returns that value and doesn't evaluate any of the other expressions,
otherwise it returns the value of the last expression.
(or) returns nil."
[& vs]
(cons 'or
(map (fn [v]
`(when (and ~v (not (error? ~v)))
~v))
vs)))
3 changes: 2 additions & 1 deletion src/elin/function/lookup.clj
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@
(e/fault {:message (pr-str e)}))))

(defn clojuredocs-lookup
"Returns a result of looking up the help of the function under the cursor in clojuredocs."
[{:as elin :component/keys [host nrepl]} export-edn-url]
(e/let [{:keys [lnum col]} (async/<!! (e.p.host/get-cursor-position! host))
{:keys [code]} (e.f.sexpr/get-expr elin lnum col)
Expand All @@ -89,7 +90,7 @@
resp (lookup elin ns-str code)]
[(:ns resp) (:name resp)])
(str/split code #"/" 2))]
(or (e.f.n.cider/clojuredocs-lookup!! nrepl ns-str name-str export-edn-url)
(or (e/error-or (e.f.n.cider/clojuredocs-lookup!! nrepl ns-str name-str export-edn-url))
(e/not-found))))

(m/=> get-java-rendering-data [:-> e.s.nrepl/?Lookup e.s.nrepl/?LookupJavaRenderingData])
Expand Down
40 changes: 36 additions & 4 deletions src/elin/handler/connect.clj
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,17 @@

(m/=> connect [:=> [:cat e.s.handler/?Elin] any?])
(defn connect
"Connect to nREPL server."
"Connect to nREPL server.

.Available parameters
[%autowidth,cols=\"a,a\"]
|===
| Parameter | Description

| `[]` | the port number and the hostname will be detected by interceptors automatically.
| `[port]` | `localhost` will be used as the hostname.
| `[hostname port]` | the specified hostname and port number will be used for connection.
|==="
[{:as elin :component/keys [host] :keys [message]}]
(let [[{:keys [hostname port]} error] (e.u.param/parse ?ConnectParams (:params message))]
(if error
Expand Down Expand Up @@ -84,13 +94,35 @@
(def ^:private ?InstantParams
[:catn
[:project
(apply vector :enum
(map name e.c.jack-in/supported-project-types))]])
(->> (map name e.c.jack-in/supported-project-types)
(cons "")
(apply vector :enum))]])

(defn- select-instant-connect-project
[elin]
(if-let [selected (->> (map name e.c.jack-in/supported-project-types)
(e.f.select/select-from-candidates elin))]
[selected nil]
[nil "No project is selected."]))

(defn instant
"Launch nREPL server of the specified project and connect to it."
"Launch nREPL server of the specified project and connect to it.

.Available parameters
[%autowidth,cols=\"a,a\"]
|===
| Parameter | Description

| `[]` | Select a project to launch nREPL server and connect to it.
| `[project]` | Connect to the nREPL server of the specified project.
|==="
[{:as elin :component/keys [host] :keys [message]}]
(let [[{:keys [project]} error] (e.u.param/parse ?InstantParams (:params message))
[project error] (if (and (or (not project)
(= "" project))
(not error))
(select-instant-connect-project elin)
[project error])
{:keys [port language]} (when-not error
(e.f.jack-in/launch-process elin {:forced-project (keyword project)}))]
(if error
Expand Down
8 changes: 7 additions & 1 deletion test/elin/error_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -7,4 +7,10 @@
(t/is (= 1 (sut/error-or 1)))
(t/is (= 1 (sut/error-or 1 (sut/fault) 2)))
(t/is (= 2 (sut/error-or (sut/fault) 2)))
(t/is (nil? (sut/error-or (sut/fault)))))
(t/is (nil? (sut/error-or (sut/fault))))

(let [called? (atom false)]
(t/is (= 1 (sut/error-or 1
(do (reset! called? true)
(sut/fault)))))
(t/is (false? @called?))))
43 changes: 43 additions & 0 deletions test/elin/function/lookup_test.clj
Original file line number Diff line number Diff line change
@@ -1,9 +1,12 @@
(ns elin.function.lookup-test
(:require
[clojure.test :as t]
[elin.error :as e]
[elin.function.clj-kondo :as e.f.clj-kondo]
[elin.function.lookup :as sut]
[elin.function.nrepl.cider :as e.f.n.cider]
[elin.function.sexpr :as e.f.sexpr]
[elin.protocol.host :as e.p.host]
[elin.test-helper :as h]))

(t/use-fixtures :once h/malli-instrument-fixture)
Expand All @@ -28,3 +31,43 @@
e.f.clj-kondo/lookup (constantly fallback-resp)]
(t/is (= fallback-resp
(sut/lookup (h/test-elin) "foo.bar" "baz")))))))))

(t/deftest clojuredocs-lookup
(let [elin (h/test-elin)
test-url "https://example.com"]
(t/testing "Positive"
(with-redefs [e.p.host/get-cursor-position! (h/async-constantly {:lnum 1 :col 1})
e.f.sexpr/get-expr (constantly {:code "(bar)"})
e.f.sexpr/get-namespace (constantly "foo")
sut/lookup (constantly {:ns "foo" :name "bar"})
e.f.n.cider/clojuredocs-lookup!! (fn [_ ns-str sym-str edn-url]
(if (and (= "foo" ns-str)
(= "bar" sym-str)
(= test-url edn-url))
"SUCCESS"
(e/not-found)))]
(t/is (= "SUCCESS"
(sut/clojuredocs-lookup elin test-url)))))

(t/testing "Negative"
(t/testing "Failed to get cursor position"
(with-redefs [e.p.host/get-cursor-position! (h/async-constantly (e/fault {:message "test error"}))]
(let [resp (sut/clojuredocs-lookup elin test-url)]
(t/is (true? (e/fault? resp)))
(t/is (= "test error" (ex-message resp))))))

(t/testing "Failed to get expression"
(with-redefs [e.p.host/get-cursor-position! (h/async-constantly {:lnum 1 :col 1})
e.f.sexpr/get-expr (constantly (e/fault {:message "test error"}))]
(let [resp (sut/clojuredocs-lookup elin test-url)]
(t/is (true? (e/fault? resp)))
(t/is (= "test error" (ex-message resp))))))

(t/testing "Failed to lookup"
(with-redefs [e.p.host/get-cursor-position! (h/async-constantly {:lnum 1 :col 1})
e.f.sexpr/get-expr (constantly {:code "(bar)"})
e.f.sexpr/get-namespace (constantly "foo")
sut/lookup (constantly {:ns "foo" :name "bar"})
e.f.n.cider/clojuredocs-lookup!! (constantly (e/fault))]
(let [resp (sut/clojuredocs-lookup elin test-url)]
(t/is (true? (e/not-found? resp)))))))))
79 changes: 79 additions & 0 deletions test/elin/handler/connect_test.clj
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,11 @@
(:require
[clojure.string :as str]
[clojure.test :as t]
[elin.constant.jack-in :as e.c.jack-in]
[elin.function.jack-in :as e.f.jack-in]
[elin.function.select :as e.f.select]
[elin.handler.connect :as sut]
[elin.message :as e.message]
[elin.protocol.nrepl :as e.p.nrepl]
[elin.test-helper :as h]))

Expand Down Expand Up @@ -56,3 +60,78 @@

(t/is (= ["Already connected to localhost:1234"]
(h/get-outputs host)))))))

(t/deftest instant-test
(let [context (h/test-elin)]
(t/testing "Selected project"
(t/testing "Positive"
(let [context (assoc-in context [:message :params] [""])
launched (atom [])
connected (atom [])
test-project "test-project"
test-port (rand-int 10000)]
(with-redefs [e.f.select/select-from-candidates (constantly test-project)
e.f.jack-in/launch-process (fn [_ {:keys [forced-project]}]
(swap! launched conj forced-project)
{:port test-port :language (name forced-project)})
sut/connect* (fn [_ params]
(swap! connected conj params))]
(t/is (= [{:hostname "localhost"
:port test-port
:language test-project
:wait? true}]
(sut/instant context)))

(t/is (= [{:hostname "localhost"
:port test-port
:language test-project
:wait? true}]
@connected))

(t/is (= [(keyword test-project)]
@launched)))))

(t/testing "Negative"
(t/testing "No selection"
(let [context (assoc-in context [:message :params] [""])
error (atom [])]
(with-redefs [e.f.select/select-from-candidates (constantly nil)
e.message/error (fn [_ & texts] (swap! error concat texts) nil)]
(t/is (nil? (sut/instant context)))
(t/is (= ["Invalid parameter" "No project is selected."]
@error)))))))

(t/testing "Specified project"
(t/testing "Positive"
(let [context (assoc-in context [:message :params] [(name e.c.jack-in/babashka)])
launched (atom [])
connected (atom [])
test-port (rand-int 10000)]
(with-redefs [e.f.jack-in/launch-process (fn [_ {:keys [forced-project]}]
(swap! launched conj forced-project)
{:port test-port :language "clojure"})
sut/connect* (fn [_ params]
(swap! connected conj params))]
(t/is (= [{:hostname "localhost"
:port test-port
:language "clojure"
:wait? true}]
(sut/instant context)))

(t/is (= [{:hostname "localhost"
:port test-port
:language "clojure"
:wait? true}]
@connected))

(t/is (= [e.c.jack-in/babashka]
@launched)))))

(t/testing "Negative"
(t/testing "Invalid project"
(let [context (assoc-in context [:message :params] ["invalid project"])
error (atom [])]
(with-redefs [e.message/error (fn [_ & texts] (swap! error concat texts) nil)]
(t/is (nil? (sut/instant context)))
(t/is (= "Invalid parameter"
(first @error))))))))))
5 changes: 5 additions & 0 deletions test/elin/test_helper.clj
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
(ns elin.test-helper
(:require
[babashka.nrepl.server :as b.n.server]
[clojure.core.async :as async]
[elin.component.session-storage :as e.c.session-storage]
[elin.config :as e.config]
[elin.test-helper.clj-kondo :as h.clj-kondo]
Expand Down Expand Up @@ -87,3 +88,7 @@
:column (rand-int 10)
:line (rand-int 10)}
m))

(defn async-constantly [v]
(fn [& _]
(async/go v)))
Loading