|
23 | 23 | (defn parse-content-length [input]
|
24 | 24 | (scan-number (string/trim ((string/split ":" input) 1))))
|
25 | 25 |
|
| 26 | +(defn run-diagnostics [uri content] |
| 27 | + (let [items @[] |
| 28 | + eval-result (eval/eval-buffer content (path/basename uri))] |
| 29 | + |
| 30 | + (each res eval-result |
| 31 | + (match res |
| 32 | + {:location [line col] :message message} |
| 33 | + (array/push items |
| 34 | + {:range |
| 35 | + {:start {:line (max 0 (dec line)) :character col} |
| 36 | + :end {:line (max 0 (dec line)) :character col}} |
| 37 | + :message message}))) |
| 38 | + |
| 39 | + items)) |
| 40 | + |
26 | 41 | (defn on-document-change
|
27 | 42 | ``
|
28 | 43 | Handler for the ["textDocument/didChange"](https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocument_didChange) event.
|
|
32 | 47 | [state params]
|
33 | 48 | (let [content (get-in params ["contentChanges" 0 "text"])
|
34 | 49 | uri (get-in params ["textDocument" "uri"])]
|
35 |
| - |
36 | 50 | (put-in state [:documents uri] @{:content content})
|
37 |
| - |
38 |
| - (pp (eval/eval-buffer content (path/basename uri))) |
39 |
| - |
40 |
| - [:noresponse state])) |
41 |
| - |
| 51 | + |
| 52 | + (if (dyn :push-diagnostics) |
| 53 | + (let [d (run-diagnostics uri content)] |
| 54 | + (if (empty? d) |
| 55 | + [:noresponse state] |
| 56 | + [:ok state {:method "textDocument/publishDiagnostics" |
| 57 | + :params {:uri uri |
| 58 | + :diagnostics d}} :notify true])) |
| 59 | + [:noresponse state]))) |
42 | 60 |
|
43 | 61 | (defn on-document-diagnostic [state params]
|
44 | 62 | (let [uri (get-in params ["textDocument" "uri"])
|
45 | 63 | content (get-in state [:documents uri :content])
|
46 |
| - items @[] |
47 |
| - eval-result (eval/eval-buffer content (path/basename uri))] |
48 |
| - |
49 |
| - (each res eval-result |
50 |
| - (match res |
51 |
| - {:location [line col] :message message} |
52 |
| - (array/push items |
53 |
| - {:range |
54 |
| - {:start {:line (max 0 (dec line)) :character col} |
55 |
| - :end {:line (max 0 (dec line)) :character col}} |
56 |
| - :message message}))) |
| 64 | + diagnostics (run-diagnostics uri content)] |
57 | 65 |
|
58 | 66 | [:ok state {:kind "full"
|
59 |
| - :items items}])) |
| 67 | + :items diagnostics}])) |
60 | 68 |
|
61 | 69 | (defn on-document-formatting [state params]
|
62 | 70 | (let [uri (get-in params ["textDocument" "uri"])
|
|
69 | 77 | [:ok state :json/null]
|
70 | 78 | (do (put-in state [:documents uri] {:content new-content})
|
71 | 79 | [:ok state [{:range {:start {:line 0 :character 0}
|
72 |
| - :end {:line 1000000 :character 1000000}} |
| 80 | + :end {:line 1000000 :character 1000000}} |
73 | 81 | :newText new-content}]]))))
|
74 | 82 |
|
75 | 83 | (defn on-document-open [state params]
|
|
141 | 149 | that this server provides so the client knows what it can request.
|
142 | 150 | ``
|
143 | 151 | [state params]
|
| 152 | + (logging/log (string/format "on-initialize called with these params: %m" params)) |
| 153 | + |
| 154 | + (if-let [diagnostic? (get-in params ["capabilities" "textDocument" "diagnostic"])] |
| 155 | + (setdyn :push-diagnostics false) |
| 156 | + (setdyn :push-diagnostics true)) |
| 157 | + |
144 | 158 | [:ok state {:capabilities {:completionProvider {:resolveProvider true}
|
145 | 159 | :textDocumentSync {:openClose true
|
146 | 160 | :change 1 # send the Full document https://microsoft.github.io/language-server-protocol/specifications/lsp/3.17/specification/#textDocumentSyncKind
|
|
182 | 196 | (let [id (get message "id")
|
183 | 197 | method (get message "method")
|
184 | 198 | params (get message "params")]
|
185 |
| - (comment logging/log (string/format "handle-message received method request: %m" method)) |
| 199 | + (logging/log (string/format "handle-message received method request: %m" method)) |
186 | 200 | (case method
|
187 | 201 | "initialize" (on-initialize state params)
|
188 | 202 | "initialized" [:noresponse state]
|
|
225 | 239 | (let [input (file/read stdin :line)
|
226 | 240 | content-length (+ (parse-content-length input) (read-offset))
|
227 | 241 | input (file/read stdin content-length)]
|
228 |
| - # (print "spork/json and jayson are identical: " (deep= (json/decode input) (jayson/decode input))) |
229 | 242 | (json/decode input)))
|
230 | 243 |
|
231 | 244 | (defn message-loop [&named state]
|
232 | 245 | (let [message (read-message)]
|
233 | 246 | (match (handle-message message state)
|
234 |
| - [:ok new-state response] (do |
| 247 | + [:ok new-state & response] (do |
235 | 248 | (logging/log "successful rpc")
|
236 |
| - (write-response stdout (rpc/success-response (get message "id") response)) |
| 249 | + (write-response stdout (rpc/success-response (get message "id") ;response)) |
237 | 250 | (message-loop :state new-state))
|
238 | 251 | [:noresponse new-state] (message-loop :state new-state)
|
239 | 252 |
|
240 |
| - [:error new-state error] (pp "unhandled error response") |
| 253 | + [:error new-state err] (printf "unhandled error response: %m" err) |
241 | 254 | [:exit] (do (file/flush stdout) (ev/sleep 2) nil))))
|
242 | 255 |
|
243 | 256 | (defn find-all-module-files [path &opt search-jpm-tree explicit results]
|
|
271 | 284 | (map |(string "./" $))))
|
272 | 285 |
|
273 | 286 | (defn start-language-server []
|
274 |
| - # (setdyn :debug true) |
275 | 287 | (print "Starting LSP")
|
276 | 288 | (logging/log "Starting LSP")
|
277 | 289 | (when (dyn :debug) (spit "janetlsp.log.txt" ""))
|
278 | 290 |
|
| 291 | + (merge-module root-env jpm-defs nil true) |
279 | 292 | (setdyn :eval-env (make-env root-env))
|
280 | 293 |
|
281 |
| - # (merge-module (dyn :eval-env) (((curenv) 'module/paths) :value)) |
282 |
| - (merge-module (dyn :eval-env) jpm-defs) |
283 |
| - |
284 | 294 | (each path (find-unique-paths (find-all-module-files (os/cwd) (not ((dyn :opts) :dont-search-jpm-tree))))
|
285 | 295 | (cond
|
286 | 296 | (string/has-suffix? ".janet" path) (array/push (((dyn :eval-env) 'module/paths) :value) [path :source])
|
|
324 | 334 | --stdio (flag) "Use STDIO."
|
325 | 335 | [--debug -d] (flag) "Print debug messages."
|
326 | 336 | [--console -c] (flag) "Start a debug console instead of starting the Language Server."
|
327 |
| - [--debug-port -p] (optional :int++) "What port to start the debug console on. Defaults to 8037."] |
| 337 | + [--debug-port -p] (optional :int++) "What port to start or connect to the debug console on. Defaults to 8037."] |
328 | 338 |
|
329 | 339 | (default stdio true)
|
330 | 340 | (default debug-port 8037)
|
|
336 | 346 | :debug-port debug-port})
|
337 | 347 |
|
338 | 348 | (setdyn :opts opts)
|
339 |
| - (setdyn :debug debug) |
| 349 | + (when debug (setdyn :debug true)) |
340 | 350 | (setdyn :out stderr)
|
341 | 351 |
|
342 | 352 | (if console
|
|
0 commit comments