Skip to content

Commit da34cd2

Browse files
committed
Add download server
1 parent e255bbb commit da34cd2

File tree

6 files changed

+149
-29
lines changed

6 files changed

+149
-29
lines changed

src/main/clojure/com/github/clojure_lsp/intellij/extension/general_settings.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,7 +87,7 @@
8787
:listen [:action (fn [_]
8888
(doseq [project (db/all-projects)]
8989
(server/shutdown! project)
90-
(server/start-server! project)))]) "wrap"]]) "span"]
90+
(server/start! project)))]) "wrap"]]) "span"]
9191
[(s/label :text "* requires LSP restart"
9292
:font (s.font/font :size 14)
9393
:foreground (s.color/color 110 110 110)) "wrap"]]

src/main/clojure/com/github/clojure_lsp/intellij/extension/language_server_factory.clj

Lines changed: 31 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55
(:require
66
[com.github.clojure-lsp.intellij.server :as server]
77
[com.github.ericdallo.clj4intellij.logger :as logger]
8-
[com.github.ericdallo.clj4intellij.tasks :as tasks]
98
[com.rpl.proxy-plus :refer [proxy+]])
109
(:import
1110
[com.intellij.execution.configurations GeneralCommandLine]
@@ -14,52 +13,59 @@
1413
[com.redhat.devtools.lsp4ij.client LanguageClientImpl]
1514
[com.redhat.devtools.lsp4ij.client.features LSPClientFeatures]
1615
[com.redhat.devtools.lsp4ij.server OSProcessStreamConnectionProvider]
16+
[java.io File]
17+
[java.util List]
1718
[org.eclipse.lsp4j InitializeParams]
1819
[org.eclipse.lsp4j.services LanguageServer]))
1920

2021
(set! *warn-on-reflection* true)
2122

22-
(defn -createConnectionProvider [_ ^Project project]
23-
(doto (proxy+
24-
[]
25-
OSProcessStreamConnectionProvider)
26-
(.setCommandLine (GeneralCommandLine. ["/home/greg/dev/clojure-lsp/clojure-lsp" "listen"]))))
23+
(defonce ^:private server (atom {:status :not-found
24+
:path nil}))
25+
26+
(defn -createConnectionProvider [_ ^Project _project]
27+
(logger/info "---> connection" (:path @server))
28+
(let [server-path (or (some-> ^File (:path @server)
29+
(.getCanonicalPath))
30+
"mocked-server-path")
31+
command [server-path "listen"]]
32+
(logger/info "--------> starting" command)
33+
(doto (proxy+
34+
[]
35+
OSProcessStreamConnectionProvider)
36+
(.setCommandLine (GeneralCommandLine. ^List command)))))
2737

2838
(defn -createLanguageClient [_ ^Project project]
2939
(LanguageClientImpl. project))
3040

3141
;; TODO custom server methods
3242
(defn -getServerInterface [_] LanguageServer)
3343

34-
(defonce ^:private server (atom {:status :not-found}))
35-
3644
(defn ^:private install-server [project]
3745
(swap! server assoc :status :installing)
38-
(tasks/run-background-task!
46+
(server/install-server
3947
project
40-
"Installing clojure-lsp"
41-
(fn [indicator]
42-
(tasks/set-progress indicator "Clojure LSP: downloading server")
43-
(Thread/sleep 5000) ;; Simulate download server
44-
45-
(swap! server assoc :status :installed)
46-
(server/start-server! project))))
48+
(fn [{:keys [status path]}]
49+
(swap! server assoc :status status :path path)))
50+
(server/start! project))
4751

4852
;; TODO client features
4953
(defn -createClientFeatures [_]
5054
(proxy+ [] LSPClientFeatures
5155
(isEnabled [_this ^VirtualFile file]
52-
(logger/info "-----> isEnabled" @server)
53-
(case (:status @server)
54-
:installing
55-
false
56+
(logger/info "---> checking isEnabled")
57+
(let [r (case (:status @server)
58+
:installing
59+
false
5660

57-
:installed
58-
true
61+
:installed
62+
true
5963

60-
:not-found
61-
(do (install-server (.guessProjectForFile (ProjectLocator/getInstance) file))
62-
false)))
64+
:not-found
65+
(do (install-server (.guessProjectForFile (ProjectLocator/getInstance) file))
66+
false))]
67+
(logger/info "-----> isEnabled result" r)
68+
r))
6369
(initializeParams [_ ^InitializeParams params]
6470
(.setWorkDoneToken params "clojure-lsp-startup")
6571
(.setInitializationOptions params {"dependency-scheme" "jar"

src/main/clojure/com/github/clojure_lsp/intellij/extension/status_bar_factory.clj

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -56,7 +56,7 @@
5656
DumbAwareAction
5757
(actionPerformed [_ _event]
5858
(server/shutdown! project)
59-
(server/start-server! project))))
59+
(server/start! project))))
6060

6161
(defn ^:private status-bar-title [project]
6262
(str "Clojure LSP: " (name (lsp-client/server-status project))))
Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,17 @@
1+
(ns com.github.clojure-lsp.intellij.notification
2+
(:import
3+
[com.intellij.notification NotificationGroupManager NotificationType]
4+
[com.intellij.openapi.project Project]))
5+
6+
(set! *warn-on-reflection* true)
7+
8+
(def ^:private type->notification-type
9+
{:error NotificationType/ERROR
10+
:warning NotificationType/WARNING
11+
:info NotificationType/INFORMATION})
12+
13+
(defn show-notification! [{:keys [project type title message]}]
14+
(-> (NotificationGroupManager/getInstance)
15+
(.getNotificationGroup "Clojure LSP notifications")
16+
(.createNotification ^String title ^String message ^NotificationType (type->notification-type type))
17+
(.notify ^Project project)))

src/main/clojure/com/github/clojure_lsp/intellij/server.clj

Lines changed: 97 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,11 +1,106 @@
11
(ns com.github.clojure-lsp.intellij.server
2+
(:require
3+
[clojure.java.io :as io]
4+
[clojure.string :as string]
5+
[com.github.clojure-lsp.intellij.config :as config]
6+
[com.github.clojure-lsp.intellij.db :as db]
7+
[com.github.clojure-lsp.intellij.notification :as notification]
8+
[com.github.clojure-lsp.intellij.server :as server]
9+
[com.github.ericdallo.clj4intellij.logger :as logger]
10+
[com.github.ericdallo.clj4intellij.tasks :as tasks])
211
(:import
312
[com.intellij.openapi.project Project]
4-
[com.redhat.devtools.lsp4ij LanguageServerManager]))
13+
[com.intellij.openapi.project Project]
14+
[com.redhat.devtools.lsp4ij LanguageServerManager]
15+
[java.io File]
16+
[java.util.zip ZipInputStream]))
517

618
(set! *warn-on-reflection* true)
719

8-
(defn start-server! [^Project project]
20+
(def ^:private latest-version-uri
21+
"https://raw.githubusercontent.com/clojure-lsp/clojure-lsp/master/lib/resources/CLOJURE_LSP_RELEASED_VERSION")
22+
23+
(def ^:private download-artifact-uri
24+
"https://github.com/clojure-lsp/clojure-lsp/releases/download/%s/%s")
25+
26+
(defn ^:private os-name []
27+
(let [os-name (string/lower-case (System/getProperty "os.name" "generic"))]
28+
(cond
29+
(string/includes? os-name "win") :windows
30+
(string/includes? os-name "mac") :macos
31+
:else :linux)))
32+
33+
(defn ^:private os-arch []
34+
(if (= "aarch64" (System/getProperty "os.arch"))
35+
:aarch64
36+
:amd64))
37+
38+
(def ^:private artifacts
39+
{:linux {:amd64 "clojure-lsp-native-static-linux-amd64.zip"
40+
:aarch64 "clojure-lsp-native-linux-aarch64.zip"}
41+
:macos {:amd64 "clojure-lsp-native-macos-amd64.zip"
42+
:aarch64 "clojure-lsp-native-macos-aarch64.zip"}
43+
:windows {:amd64 "clojure-lsp-native-windows-amd64.zip"}})
44+
45+
(defn ^:private unzip-file [input ^File dest-file]
46+
(with-open [stream (-> input io/input-stream ZipInputStream.)]
47+
(loop [entry (.getNextEntry stream)]
48+
(when entry
49+
(if (.isDirectory entry)
50+
(when-not (.exists dest-file)
51+
(.mkdirs dest-file))
52+
(clojure.java.io/copy stream dest-file))
53+
(recur (.getNextEntry stream))))))
54+
55+
(defn ^:private download-server! [project indicator ^File download-path ^File server-version-path latest-version]
56+
(tasks/set-progress indicator "LSP: Downloading clojure-lsp")
57+
(let [platform (os-name)
58+
arch (os-arch)
59+
artifact-name (get-in artifacts [platform arch])
60+
uri (format download-artifact-uri latest-version artifact-name)
61+
dest-server-file download-path
62+
dest-path (.getCanonicalPath dest-server-file)]
63+
(logger/info "Downloading clojure-lsp from" uri)
64+
(unzip-file (io/input-stream uri) dest-server-file)
65+
(doto (io/file dest-server-file)
66+
(.setWritable true)
67+
(.setReadable true)
68+
(.setExecutable true))
69+
(spit server-version-path latest-version)
70+
(db/assoc-in project [:downloaded-server-path] dest-path)
71+
(logger/info "Downloaded clojure-lsp to" dest-path)))
72+
73+
(defn install-server [project installed-fn]
74+
(tasks/run-background-task!
75+
project
76+
"Clojure LSP download"
77+
(fn [indicator]
78+
(tasks/set-progress indicator "Clojure LSP: downloading server")
79+
(let [download-path (config/download-server-path)
80+
server-version-path (config/download-server-version-path)
81+
latest-version* (delay (try (string/trim (slurp latest-version-uri)) (catch Exception _ nil)))
82+
custom-server-path (db/get-in project [:settings :server-path])]
83+
(cond
84+
custom-server-path
85+
(installed-fn {:status :installed :path custom-server-path})
86+
87+
(and (.exists download-path)
88+
(or (not @latest-version*) ;; on network connection issues we use any downloaded server
89+
(= (try (slurp server-version-path) (catch Exception _ :error-checking-local-version))
90+
@latest-version*)))
91+
(installed-fn {:status :installed :path download-path})
92+
93+
@latest-version*
94+
(do (download-server! project indicator download-path server-version-path @latest-version*)
95+
(installed-fn {:status :installed :path download-path}))
96+
97+
:else
98+
(notification/show-notification! {:project project
99+
:type :error
100+
:title "Clojure LSP download error"
101+
:message "There is no server downloaded and there was a network issue to download the latest one"}))))))
102+
103+
(defn start! [^Project project]
9104
(.start (LanguageServerManager/getInstance project) "clojure-lsp"))
10105

11106
(defn shutdown! [^Project project]

src/main/resources/META-INF/plugin.xml

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@
6161
id="com.github.clojure_lsp.intellij.extension.GeneralSettingsConfigurable"
6262
displayName="Clojure LSP"/>
6363
<lineIndentProvider implementation="com.github.clojure_lsp.intellij.extension.LineIndentProvider"/>
64+
<notificationGroup id="Clojure LSP notifications"
65+
displayType="BALLOON"/>
6466
</extensions>
6567

6668
<applicationListeners>

0 commit comments

Comments
 (0)