Skip to content

Commit d3e51d9

Browse files
authored
Merge pull request #23 from CFiggers/dev
v0.0.5
2 parents 2bc9f6b + 76cd314 commit d3e51d9

File tree

8 files changed

+404
-253
lines changed

8 files changed

+404
-253
lines changed

README.md

Lines changed: 9 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,7 @@ Other editors that implement LSP client protocols, either built-in or through ed
4545
- Sublime Text
4646
- Helix
4747
- Kakoune
48+
- Zed
4849

4950
If you get Janet LSP working with any of these options, please let me know!
5051

@@ -61,16 +62,22 @@ $ jpm deps
6162
$ jpm build
6263
```
6364

64-
Both a stand-alone (albeit _dynamically_ linked) binary executable and a .jimage (Janet image) file will be generated.
65+
A .jimage (Janet image) file will be generated in `/build`. Using a .jimage file makes Janet LSP fully cross-platform (wherever there is a compatible Janet binary on the user's path). But it also means that you must have a Janet binary to use Janet LSP (this author struggles to imagine a scenario where you would both need the LSP and NOT have Janet itself installed).
6566

6667
### Installing
6768

68-
After running the commands above, the following command will copy the `janet-lsp` binary to a location that can be executed via the command line.
69+
After running the commands above, the following command will copy the `janet-lsp` binscript to a location that can be executed via the command line.
6970

7071
```shell
7172
$ jpm install
7273
```
7374

75+
Test successful install by running the following:
76+
77+
```shell
78+
$ janet-lsp --version
79+
```
80+
7481
### Debug Console
7582

7683
Starting in version 0.0.3, you can start a debug console by passing `--console` to any invocation of Janet LSP, including any of the following:

project.janet

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,11 @@
11
(declare-project
22
:name "janet-lsp"
33
:description "A Language Server (LSP) for the Janet Programming Language"
4-
:version "0.0.4"
4+
:version "0.0.5"
55
:dependencies ["https://github.com/janet-lang/spork.git"
6-
"https://github.com/ianthehenry/judge.git"])
6+
"https://github.com/CFiggers/jayson.git"
7+
"https://github.com/ianthehenry/judge.git"
8+
"https://github.com/CFiggers/cmd.git"])
79

810
# (def cflags
911
# (case (os/which)

src/doc.janet

Lines changed: 8 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,9 +18,14 @@
1818
(when col (string ", column " col))))
1919
"\n\n"
2020
(if d
21-
(string/join (-> (string/split "\n" d)
22-
(array/insert 1 "```")
23-
(array/insert 0 "```janet")) "\n")
21+
(let [parts (string/split "\n" d)]
22+
(if (every? ((juxt |(string/has-prefix? "(" $)
23+
|(string/has-suffix? ")" $))
24+
(parts 0)))
25+
(string/join (-> parts
26+
(array/insert 1 "```")
27+
(array/insert 0 "```janet")) "\n")
28+
d))
2429
"No documentation found.\n"))))
2530

2631
(deftest "test make-module-entry: string/trim"

src/lookup.janet

Lines changed: 2 additions & 235 deletions
Original file line numberDiff line numberDiff line change
@@ -4,13 +4,6 @@
44
(defn lookup [{:line line :character character} source]
55
(string/from-bytes (((string/split "\n" source) line) character)))
66

7-
(deftest "lookup"
8-
(test (lookup {:line 0 :character 0} "1\n23\n45") "1")
9-
(test (lookup {:line 1 :character 0} "1\n23\n45") "2")
10-
(test (lookup {:line 1 :character 1} "1\n23\n45") "3")
11-
(test (lookup {:line 2 :character 0} "1\n23\n45") "4")
12-
(test (lookup {:line 2 :character 1} "1\n23\n45") "5"))
13-
147
(def word-peg
158
(peg/compile
169
~{:s (set " \t\0\f\v") :s* (any :s) :s+ (some :s)
@@ -29,122 +22,18 @@
2922
(break)))
3023
ret)))
3124

32-
(test (peg/match word-peg "(defn main [& args] (+ 1 1))")
33-
@[[0 "" 0]
34-
[1 "defn" 5]
35-
[6 "main" 10]
36-
[11 "[&" 13]
37-
[14 "args]" 19]
38-
[20 "" 20]
39-
[21 "+" 22]
40-
[23 "1" 24]
41-
[25 "1" 26]
42-
[27 "" 27]])
43-
44-
(test (peg/match word-peg "") nil)
45-
46-
(defn word-at [location source]
25+
(defn word-at :tested [location source]
4726
(let [{:character character-pos :line line-pos} location
4827
line ((string/split "\n" source) line-pos)
4928
parsed (or (sort-by last (or (peg/match word-peg line) @[[0 "" 0]])))
5029
word (or (first-where |(>= ($ 2) character-pos) parsed) (last parsed))]
5130
{:range [(word 0) (word 2)] :word (word 1)}))
5231

53-
(test (word-at {:line 0 :character 16} "(def- parse-peg\n") {:range [6 14] :word "parse-peg"})
54-
55-
(test (word-at {:line 1 :character 0} "(import )\n") {:range [0 0] :word ""})
56-
5732
(def sexp-peg
5833
(peg/compile
5934
~{:s-exp (group (* (position) (* "(" (any (+ (drop :s-exp) (to (set "()")))) ")") (position)))
6035
:main (some (+ (if :s-exp 1) 1))}))
6136

62-
(test (peg/match sexp-peg "(defn main [& args] (+ 1 1))") @[@[0 28] @[20 27]])
63-
64-
(test (peg/match sexp-peg "(+ 1 (- 1 1))") @[@[0 13] @[5 12]])
65-
66-
(deftest "advanced sexp-peg test"
67-
(def sample
68-
``
69-
(import spork)
70-
71-
(defmacro first-where [pred ds]
72-
(with-syms [$pred $ds]
73-
~(let [,$pred ,pred ,$ds ,ds]
74-
(var ret "")
75-
(for i 0 (length ,$ds)
76-
(when (,$pred (,$ds i))
77-
(set ret (,$ds i))
78-
(break)))
79-
ret)))
80-
81-
(defn main [& args]
82-
(+ 1 1)
83-
(let [a 1 b 2]
84-
(first-where |(< (first $) 0) [[-2 :a] [-1 :b] [0 :c]])))
85-
``)
86-
(test (peg/match sexp-peg sample)
87-
@[@[0 14]
88-
@[16 263]
89-
@[50 262]
90-
@[78 261]
91-
@[114 126]
92-
@[134 249]
93-
@[143 156]
94-
@[169 248]
95-
@[175 192]
96-
@[183 191]
97-
@[207 225]
98-
@[216 224]
99-
@[240 247]
100-
@[282 390]
101-
@[304 311]
102-
@[314 389]
103-
@[333 388]
104-
@[347 362]
105-
@[350 359]]))
106-
107-
(deftest "slicing"
108-
(def sample
109-
``
110-
(import spork)
111-
112-
(defmacro first-where [pred ds]
113-
(with-syms [$pred $ds]
114-
~(let [,$pred ,pred ,$ds ,ds]
115-
(var ret "")
116-
(for i 0 (length ,$ds)
117-
(when (,$pred (,$ds i))
118-
(set ret (,$ds i))
119-
(break)))
120-
ret)))
121-
122-
(defn main [& args]
123-
(+ 1 1)
124-
(let [a 1 b 2]
125-
(first-where |(< (first $) 0) [[-2 :a] [-1 :b] [0 :c]])))
126-
``)
127-
(test (map |[$ (string/slice sample ($ 0) ($ 1))] @[@[0 14] @[16 263] @[50 262] @[78 261] @[114 126] @[134 249] @[143 156] @[169 248] @[175 192] @[183 191] @[207 225] @[216 224] @[240 247] @[282 390] @[304 311] @[314 389] @[333 388] @[347 362] @[350 359]])
128-
@[[@[0 14] "(import spork)"]
129-
[@[16 263] "(defmacro first-where [pred ds]\n (with-syms [$pred $ds]\n ~(let [,$pred ,pred ,$ds ,ds]\n (var ret \"\")\n (for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))\n ret)))"]
130-
[@[50 262] "(with-syms [$pred $ds]\n ~(let [,$pred ,pred ,$ds ,ds]\n (var ret \"\")\n (for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))\n ret))"]
131-
[@[78 261] "(let [,$pred ,pred ,$ds ,ds]\n (var ret \"\")\n (for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))\n ret)"]
132-
[@[114 126] "(var ret \"\")"]
133-
[@[134 249] "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"]
134-
[@[143 156] "(length ,$ds)"]
135-
[@[169 248] "(when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break))"]
136-
[@[175 192] "(,$pred (,$ds i))"]
137-
[@[183 191] "(,$ds i)"]
138-
[@[207 225] "(set ret (,$ds i))"]
139-
[@[216 224] "(,$ds i)"]
140-
[@[240 247] "(break)"]
141-
[@[282 390] "(defn main [& args]\n (+ 1 1)\n (let [a 1 b 2]\n (first-where |(< (first $) 0) [[-2 :a] [-1 :b] [0 :c]])))"]
142-
[@[304 311] "(+ 1 1)"]
143-
[@[314 389] "(let [a 1 b 2]\n (first-where |(< (first $) 0) [[-2 :a] [-1 :b] [0 :c]]))"]
144-
[@[333 388] "(first-where |(< (first $) 0) [[-2 :a] [-1 :b] [0 :c]])"]
145-
[@[347 362] "(< (first $) 0)"]
146-
[@[350 359] "(first $)"]]))
147-
14837
(defn sexp-at [location source]
14938
(let [{:character character-pos :line line-pos} location
15039
idx (+ character-pos (sum (map (comp inc length) (array/slice (string/split "\n" source) 0 line-pos))))
@@ -153,72 +42,7 @@
15342
{:source (string/slice source ;sexp-range) :range sexp-range}
15443
{:source "" :range @[line-pos character-pos]})))
15544

156-
(test (sexp-at {:line 2 :character 3} "(def a-startup-symbol [])\n\nsymbol\n\n(import spork/argparse)")
157-
{:range @[2 3] :source ""})
158-
159-
(test (sexp-at {:character 15 :line 2} "(def a-startup-symbol [])\n\n(import spork/argparse)")
160-
{:range @[27 50] :source "(import spork/argparse)"})
161-
162-
(deftest "sexp-at"
163-
(def sample
164-
``
165-
(import spork)
166-
167-
(defmacro first-where [pred ds]
168-
(with-syms [$pred $ds]
169-
~(let [,$pred ,pred ,$ds ,ds]
170-
(var ret "")
171-
(for i 0 (length ,$ds)
172-
(when (,$pred (,$ds i))
173-
(set ret (,$ds i))
174-
(break)))
175-
ret)))
176-
177-
(defn main [& args]
178-
(+ 1 1)
179-
(let [a 1 b 2]
180-
(first-where |(< (first $) 0) [[-2 :a] [-1 :b] [0 :c]])))
181-
``)
182-
(test (map |[$ (sexp-at {:character $ :line 7} sample)] (range 0 37))
183-
@[[0 {:range @[134 249] :source "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"}]
184-
[1 {:range @[134 249] :source "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"}]
185-
[2 {:range @[134 249] :source "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"}]
186-
[3 {:range @[134 249] :source "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"}]
187-
[4 {:range @[134 249] :source "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"}]
188-
[5 {:range @[134 249] :source "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"}]
189-
[6 {:range @[134 249] :source "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"}]
190-
[7 {:range @[134 249] :source "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"}]
191-
[8 {:range @[134 249] :source "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"}]
192-
[9 {:range @[134 249] :source "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"}]
193-
[10 {:range @[134 249] :source "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"}]
194-
[11 {:range @[134 249] :source "(for i 0 (length ,$ds)\n (when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break)))"}]
195-
[12 {:range @[169 248] :source "(when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break))"}]
196-
[13 {:range @[169 248] :source "(when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break))"}]
197-
[14 {:range @[169 248] :source "(when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break))"}]
198-
[15 {:range @[169 248] :source "(when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break))"}]
199-
[16 {:range @[169 248] :source "(when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break))"}]
200-
[17 {:range @[169 248] :source "(when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break))"}]
201-
[18 {:range @[175 192] :source "(,$pred (,$ds i))"}]
202-
[19 {:range @[175 192] :source "(,$pred (,$ds i))"}]
203-
[20 {:range @[175 192] :source "(,$pred (,$ds i))"}]
204-
[21 {:range @[175 192] :source "(,$pred (,$ds i))"}]
205-
[22 {:range @[175 192] :source "(,$pred (,$ds i))"}]
206-
[23 {:range @[175 192] :source "(,$pred (,$ds i))"}]
207-
[24 {:range @[175 192] :source "(,$pred (,$ds i))"}]
208-
[25 {:range @[175 192] :source "(,$pred (,$ds i))"}]
209-
[26 {:range @[183 191] :source "(,$ds i)"}]
210-
[27 {:range @[183 191] :source "(,$ds i)"}]
211-
[28 {:range @[183 191] :source "(,$ds i)"}]
212-
[29 {:range @[183 191] :source "(,$ds i)"}]
213-
[30 {:range @[183 191] :source "(,$ds i)"}]
214-
[31 {:range @[183 191] :source "(,$ds i)"}]
215-
[32 {:range @[183 191] :source "(,$ds i)"}]
216-
[33 {:range @[183 191] :source "(,$ds i)"}]
217-
[34 {:range @[183 191] :source "(,$ds i)"}]
218-
[35 {:range @[175 192] :source "(,$pred (,$ds i))"}]
219-
[36 {:range @[169 248] :source "(when (,$pred (,$ds i))\n (set ret (,$ds i))\n (break))"}]]))
220-
221-
(defn- to-index [location source]
45+
(defn to-index [location source]
22246
(let [{:character character-pos :line line-pos} location
22347
lines (string/split "\n" source)
22448
pre-lines (array/slice lines 0 line-pos)
@@ -229,60 +53,3 @@
22953
(comment prin "pre-length: ") (comment pp pre-length)
23054
(comment prin "character-pos: ") (comment pp character-pos)
23155
(+ character-pos pre-length)))
232-
233-
(deftest "to-index"
234-
(def sample
235-
``
236-
(import spork)
237-
238-
(defmacro first-where [pred ds]
239-
(with-syms [$pred $ds]
240-
~(let [,$pred ,pred ,$ds ,ds]
241-
(var ret "")
242-
(for i 0 (length ,$ds)
243-
(when (,$pred (,$ds i))
244-
(set ret (,$ds i))
245-
(break)))
246-
ret)))
247-
248-
(defn main [& args]
249-
(+ 1 1)
250-
(let [a 1 b 2]
251-
(first-where |(< (first $) 0) [[-2 :a] [-1 :b] [0 :c]])))
252-
``)
253-
(to-index {:character 3 :line 7} sample))
254-
255-
# tests
256-
257-
(deftest "test word-peg1"
258-
(def sample "word not a word")
259-
(test (peg/match word-peg sample)
260-
@[[0 "word" 4]
261-
[5 "not" 8]
262-
[9 "a" 10]
263-
[11 "word" 14]]))
264-
265-
(deftest "test word-at1"
266-
(test (map |(word-at {:line 0 :character $} "word not a word") (range 15)) @[{:range [0 4] :word "word"} {:range [0 4] :word "word"} {:range [0 4] :word "word"} {:range [0 4] :word "word"} {:range [0 4] :word "word"} {:range [5 8] :word "not"} {:range [5 8] :word "not"} {:range [5 8] :word "not"} {:range [5 8] :word "not"} {:range [9 10] :word "a"} {:range [9 10] :word "a"} {:range [11 14] :word "word"} {:range [11 14] :word "word"} {:range [11 14] :word "word"} {:range [11 14] :word "word"}]))
267-
268-
(deftest "test word-peg2"
269-
(def sample "(defn main [& args] (print \"hello world\"))")
270-
(test (peg/match word-peg sample) @[[0 "" 0] [1 "defn" 5] [6 "main" 10] [11 "[&" 13] [14 "args]" 19] [20 "" 20] [21 "print" 26] [27 "\"hello" 33] [34 "world\"" 40] [41 "" 41]]))
271-
272-
(deftest "test word-peg3"
273-
(test (map |(word-at {:line 0 :character $} "(defn main [& args] (print \"hello world\"))") (range 42)) @[{:range [0 0] :word ""} {:range [1 5] :word "defn"} {:range [1 5] :word "defn"} {:range [1 5] :word "defn"} {:range [1 5] :word "defn"} {:range [1 5] :word "defn"} {:range [6 10] :word "main"} {:range [6 10] :word "main"} {:range [6 10] :word "main"} {:range [6 10] :word "main"} {:range [6 10] :word "main"} {:range [11 13] :word "[&"} {:range [11 13] :word "[&"} {:range [11 13] :word "[&"} {:range [14 19] :word "args]"} {:range [14 19] :word "args]"} {:range [14 19] :word "args]"} {:range [14 19] :word "args]"} {:range [14 19] :word "args]"} {:range [14 19] :word "args]"} {:range [20 20] :word ""} {:range [21 26] :word "print"} {:range [21 26] :word "print"} {:range [21 26] :word "print"} {:range [21 26] :word "print"} {:range [21 26] :word "print"} {:range [21 26] :word "print"} {:range [27 33] :word "\"hello"} {:range [27 33] :word "\"hello"} {:range [27 33] :word "\"hello"} {:range [27 33] :word "\"hello"} {:range [27 33] :word "\"hello"} {:range [27 33] :word "\"hello"} {:range [27 33] :word "\"hello"} {:range [34 40] :word "world\""} {:range [34 40] :word "world\""} {:range [34 40] :word "world\""} {:range [34 40] :word "world\""} {:range [34 40] :word "world\""} {:range [34 40] :word "world\""} {:range [34 40] :word "world\""} {:range [41 41] :word ""}]))
274-
275-
(deftest "word-at-peg: line 0, character 12, of \"word not a word\n23\n45\""
276-
(test (word-at {:line 0 :character 12} "word not a word\n23\n45") {:range [11 14] :word "word"}))
277-
278-
(deftest "word-at-peg: line 1, character 6, of \"\nword not a word\n23\n45\""
279-
(test (word-at {:line 1 :character 6} "\nword not a word\n23\n45") {:range [5 8] :word "not"}))
280-
281-
(deftest "word-at-peg: line 0, character 0, of \"word\""
282-
(test (word-at {:line 0 :character 0} "word") {:range [0 3] :word "word"}))
283-
284-
(deftest "word-at-peg: line 0, character 4, of \" word \""
285-
(test (word-at {:line 0 :character 4} " word ") {:range [1 5] :word "word"}))
286-
287-
(deftest "word-at-peg: line 0, character 0, of \" \""
288-
(test (word-at {:line 0 :character 0} " ") {:range [1 3] :word ""}))

src/main.janet

Lines changed: 9 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -13,7 +13,7 @@
1313

1414
(use judge)
1515

16-
(def version "0.0.3")
16+
(def version "0.0.5")
1717

1818
(def jpm-defs (require "../libs/jpm-defs"))
1919

@@ -51,11 +51,9 @@
5151

5252
(if (dyn :push-diagnostics)
5353
(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]))
54+
[:ok state {:method "textDocument/publishDiagnostics"
55+
:params {:uri uri
56+
:diagnostics d}} :notify true])
5957
[:noresponse state])))
6058

6159
(defn on-document-diagnostic [state params]
@@ -217,8 +215,8 @@
217215

218216
(defn line-ending []
219217
(case (os/which)
220-
:windows "\n\n"
221-
"\r\n\r\n"))
218+
:windows "\r\n\r\n"
219+
"\n\n"))
222220

223221
(defn read-offset []
224222
(case (os/which)
@@ -239,10 +237,11 @@
239237
(let [input (file/read stdin :line)
240238
content-length (+ (parse-content-length input) (read-offset))
241239
input (file/read stdin content-length)]
242-
(json/decode input)))
240+
(json/decode input)))
243241

244242
(defn message-loop [&named state]
245-
(let [message (read-message)]
243+
(let [message (read-message)]
244+
(logging/log (string/format "got: %q" message))
246245
(match (handle-message message state)
247246
[:ok new-state & response] (do
248247
(logging/log "successful rpc")
@@ -285,7 +284,6 @@
285284

286285
(defn start-language-server []
287286
(print "Starting LSP")
288-
(logging/log "Starting LSP")
289287
(when (dyn :debug) (spit "janetlsp.log.txt" ""))
290288

291289
(merge-module root-env jpm-defs nil true)

0 commit comments

Comments
 (0)