kapusta 0.8.0 → 0.9.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +4 -4
- data/README.md +1 -1
- data/bin/fennel-parity +1 -0
- data/examples/hit-counter.kap +17 -0
- data/examples/parking-system.kap +18 -0
- data/examples/thread-styles.kap +41 -0
- data/lib/kapusta/ast.rb +1 -1
- data/lib/kapusta/compiler/normalizer.rb +22 -12
- data/lib/kapusta/formatter.rb +9 -1
- data/lib/kapusta/lsp/scope_walker.rb +55 -5
- data/lib/kapusta/reader.rb +28 -0
- data/lib/kapusta/version.rb +1 -1
- data/spec/examples_spec.rb +13 -0
- data/spec/lsp_spec.rb +86 -0
- metadata +4 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 520158590f1244ac17f70b58ded945f66be00060f6da89cebb366fefaf27b62e
|
|
4
|
+
data.tar.gz: 6773e0faa320f23cb15106e710f380a39093c9fc6e56cead8941c28e0ccf16c5
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
6
|
+
metadata.gz: 814d37c473287d2d1e54568c7d21c22d88703cd89da761100c1f20950e47cb18eb2ac4807aa596878ded72eb7049a6083d2b9de46bc76ce2ea55787f6993f61f
|
|
7
|
+
data.tar.gz: 3a15fc05522e617cf46e8709a55dc8497252503f2b995dffaa4f8995fc34a54e9bcc2a711cd501884203bf0113c7924f159377459de8f2524e9c371c018d8238
|
data/README.md
CHANGED
|
@@ -104,7 +104,7 @@ Kapusta keeps most core Fennel forms. The main differences come from Ruby's runt
|
|
|
104
104
|
Kapusta-specific additions:
|
|
105
105
|
|
|
106
106
|
- `module` and `class` for Ruby host structure, including file-header forms
|
|
107
|
-
- `ivar`
|
|
107
|
+
- `ivar` or `@var`) / `cvar` or `@@var` / `gvar` or `$var`
|
|
108
108
|
- `try` / `catch` / `finally` plus `raise` for exceptions
|
|
109
109
|
- `(ruby "...")` raw host escape hatch
|
|
110
110
|
- a trailing symbol-keyed hash is emitted as Ruby keyword arguments
|
data/bin/fennel-parity
CHANGED
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
(class HitCounter)
|
|
2
|
+
|
|
3
|
+
(set @@total 0)
|
|
4
|
+
|
|
5
|
+
(fn initialize [name] (set @name name))
|
|
6
|
+
|
|
7
|
+
(fn hit []
|
|
8
|
+
(set @@total (+ @@total 1))
|
|
9
|
+
(set $last-hitter @name)
|
|
10
|
+
@@total)
|
|
11
|
+
|
|
12
|
+
(let [a (HitCounter.new "alice")
|
|
13
|
+
b (HitCounter.new "bob")]
|
|
14
|
+
(print (a.hit))
|
|
15
|
+
(print (b.hit))
|
|
16
|
+
(print (a.hit))
|
|
17
|
+
(print $last-hitter))
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
(class ParkingSystem)
|
|
2
|
+
|
|
3
|
+
(fn initialize [big medium small]
|
|
4
|
+
(set @big big)
|
|
5
|
+
(set @medium medium)
|
|
6
|
+
(set @small small))
|
|
7
|
+
|
|
8
|
+
(fn add-car [car-type]
|
|
9
|
+
(if (and (= car-type 1) (> @big 0)) (do (set @big (- @big 1)) true)
|
|
10
|
+
(and (= car-type 2) (> @medium 0)) (do (set @medium (- @medium 1)) true)
|
|
11
|
+
(and (= car-type 3) (> @small 0)) (do (set @small (- @small 1)) true)
|
|
12
|
+
false))
|
|
13
|
+
|
|
14
|
+
(let [parking (ParkingSystem.new 1 1 0)]
|
|
15
|
+
(print (parking.add-car 1))
|
|
16
|
+
(print (parking.add-car 2))
|
|
17
|
+
(print (parking.add-car 3))
|
|
18
|
+
(print (parking.add-car 1)))
|
|
@@ -0,0 +1,41 @@
|
|
|
1
|
+
(fn positive? [n] (> n 0))
|
|
2
|
+
(fn square [n] (* n n))
|
|
3
|
+
(fn add [x y] (+ x y))
|
|
4
|
+
(fn mul [x y] (* x y))
|
|
5
|
+
(fn nonzero [n] (if (= n 0) nil n))
|
|
6
|
+
(fn non-empty [s] (if (= s "") nil s))
|
|
7
|
+
(fn wrap [s] (.. ">>" s "<<"))
|
|
8
|
+
(fn shout [s] (.. s "!"))
|
|
9
|
+
|
|
10
|
+
(fn keep [pred xs]
|
|
11
|
+
(icollect [_ x (ipairs xs)]
|
|
12
|
+
(when (pred x) x)))
|
|
13
|
+
|
|
14
|
+
(fn map [f xs]
|
|
15
|
+
(icollect [_ x (ipairs xs)]
|
|
16
|
+
(f x)))
|
|
17
|
+
|
|
18
|
+
(fn join [sep xs]
|
|
19
|
+
(var s "")
|
|
20
|
+
(each [_ x (ipairs xs)]
|
|
21
|
+
(if (= s "")
|
|
22
|
+
(set s (.. x))
|
|
23
|
+
(set s (.. s sep x))))
|
|
24
|
+
s)
|
|
25
|
+
|
|
26
|
+
(let [scores [-2 3 -1 4 0 5]
|
|
27
|
+
report (->> scores
|
|
28
|
+
(keep positive?)
|
|
29
|
+
(map square)
|
|
30
|
+
(join ", "))
|
|
31
|
+
adjusted (-> 7 (add 3) (mul 2) (square))
|
|
32
|
+
ok (-?> "hello" (non-empty) (wrap) (shout))
|
|
33
|
+
bad (-?> "" (non-empty) (wrap) (shout))
|
|
34
|
+
live (-?>> 5 (nonzero) (mul 3) (add 1))
|
|
35
|
+
dead (-?>> 0 (nonzero) (mul 3) (add 1))]
|
|
36
|
+
(print report)
|
|
37
|
+
(print adjusted)
|
|
38
|
+
(print ok)
|
|
39
|
+
(print bad)
|
|
40
|
+
(print live)
|
|
41
|
+
(print dead))
|
data/lib/kapusta/ast.rb
CHANGED
|
@@ -104,19 +104,29 @@ module Kapusta
|
|
|
104
104
|
end
|
|
105
105
|
|
|
106
106
|
def thread_short(forms, position)
|
|
107
|
-
forms[1..]
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
|
|
111
|
-
|
|
112
|
-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
107
|
+
steps = forms[1..]
|
|
108
|
+
return forms.first if steps.empty?
|
|
109
|
+
|
|
110
|
+
prev_temp = thread_temp
|
|
111
|
+
binding_items = [prev_temp, forms.first]
|
|
112
|
+
body = nil
|
|
113
|
+
last_index = steps.length - 1
|
|
114
|
+
steps.each_with_index do |form, i|
|
|
115
|
+
guarded = List.new([
|
|
116
|
+
Sym.new('if'),
|
|
117
|
+
List.new([Sym.new('='), prev_temp, nil]),
|
|
118
|
+
nil,
|
|
119
|
+
thread_step(prev_temp, form, position)
|
|
120
|
+
])
|
|
121
|
+
if i == last_index
|
|
122
|
+
body = guarded
|
|
123
|
+
else
|
|
124
|
+
temp = thread_temp
|
|
125
|
+
binding_items.push(temp, guarded)
|
|
126
|
+
prev_temp = temp
|
|
127
|
+
end
|
|
119
128
|
end
|
|
129
|
+
List.new([Sym.new('let'), Vec.new(binding_items), body])
|
|
120
130
|
end
|
|
121
131
|
|
|
122
132
|
def thread_step(memo, form, position)
|
data/lib/kapusta/formatter.rb
CHANGED
|
@@ -178,7 +178,7 @@ module Kapusta
|
|
|
178
178
|
|
|
179
179
|
case form
|
|
180
180
|
when Comment then form.text
|
|
181
|
-
when List then render_list(form, indent, top_level:)
|
|
181
|
+
when List then form.sigil ? render_sigil(form) : render_list(form, indent, top_level:)
|
|
182
182
|
when Vec then render_vec(form, indent, layout:, top_level:, force_expand:)
|
|
183
183
|
when HashLit then render_hash(form, indent)
|
|
184
184
|
when Quasiquote then render_prefix('`', form.form, indent, force_expand:)
|
|
@@ -189,6 +189,13 @@ module Kapusta
|
|
|
189
189
|
end
|
|
190
190
|
end
|
|
191
191
|
|
|
192
|
+
SIGIL_PREFIXES = { ivar: '@', cvar: '@@', gvar: '$' }.freeze
|
|
193
|
+
private_constant :SIGIL_PREFIXES
|
|
194
|
+
|
|
195
|
+
def render_sigil(list)
|
|
196
|
+
"#{SIGIL_PREFIXES.fetch(list.sigil)}#{list.items[1].name}"
|
|
197
|
+
end
|
|
198
|
+
|
|
192
199
|
def render_prefix(prefix, inner, indent, force_expand: false)
|
|
193
200
|
rendered = render(inner, indent + prefix.length, force_expand:)
|
|
194
201
|
lines = rendered.lines(chomp: true)
|
|
@@ -221,6 +228,7 @@ module Kapusta
|
|
|
221
228
|
|
|
222
229
|
"{#{rendered.join(' ')}}"
|
|
223
230
|
when List
|
|
231
|
+
return render_sigil(form) if form.sigil
|
|
224
232
|
return if contains_comments?(form.items)
|
|
225
233
|
return "##{flat_render(semantic_items(form.items)[1])}" if hashfn_literal?(form)
|
|
226
234
|
return if multiline_in_source?(form)
|
|
@@ -16,7 +16,7 @@ module Kapusta
|
|
|
16
16
|
end
|
|
17
17
|
end
|
|
18
18
|
|
|
19
|
-
SKIPPED_HEADS = %w[macros
|
|
19
|
+
SKIPPED_HEADS = %w[macros quasi-sym quasi-list
|
|
20
20
|
quasi-list-tail quasi-vec quasi-vec-tail quasi-hash quasi-gensym].freeze
|
|
21
21
|
|
|
22
22
|
DISPATCHERS = {
|
|
@@ -42,7 +42,10 @@ module Kapusta
|
|
|
42
42
|
'class' => :walk_module_class,
|
|
43
43
|
'hashfn' => :walk_hashfn,
|
|
44
44
|
'macro' => :walk_macro_def,
|
|
45
|
-
'import-macros' => :walk_import_macros
|
|
45
|
+
'import-macros' => :walk_import_macros,
|
|
46
|
+
'ivar' => :walk_sigil_form,
|
|
47
|
+
'cvar' => :walk_sigil_form,
|
|
48
|
+
'gvar' => :walk_sigil_form
|
|
46
49
|
}.freeze
|
|
47
50
|
|
|
48
51
|
attr_reader :bindings, :references, :root_scope
|
|
@@ -58,7 +61,9 @@ module Kapusta
|
|
|
58
61
|
@references = []
|
|
59
62
|
@scope_seq = 0
|
|
60
63
|
@root_scope = make_scope(nil, :file)
|
|
64
|
+
@gvar_scope = make_scope(nil, :gvars)
|
|
61
65
|
@in_module_or_class = 0
|
|
66
|
+
@sigil_scope_stack = [make_sigil_scopes]
|
|
62
67
|
end
|
|
63
68
|
|
|
64
69
|
def walk_top(forms)
|
|
@@ -132,7 +137,7 @@ module Kapusta
|
|
|
132
137
|
name_sym, supers, = split_class_args(form.items[1..] || [])
|
|
133
138
|
supers&.items&.each { |item| walk_form(item, scope) }
|
|
134
139
|
add_constant_binding(name_sym, scope, :class) if name_sym.is_a?(Sym)
|
|
135
|
-
|
|
140
|
+
inside_class do
|
|
136
141
|
remaining_forms.each { |item| walk_form(item, scope) }
|
|
137
142
|
end
|
|
138
143
|
end
|
|
@@ -154,6 +159,21 @@ module Kapusta
|
|
|
154
159
|
@in_module_or_class -= 1
|
|
155
160
|
end
|
|
156
161
|
|
|
162
|
+
def inside_class
|
|
163
|
+
inside_module_or_class do
|
|
164
|
+
@sigil_scope_stack.push(make_sigil_scopes)
|
|
165
|
+
begin
|
|
166
|
+
yield
|
|
167
|
+
ensure
|
|
168
|
+
@sigil_scope_stack.pop
|
|
169
|
+
end
|
|
170
|
+
end
|
|
171
|
+
end
|
|
172
|
+
|
|
173
|
+
def make_sigil_scopes
|
|
174
|
+
{ ivar: make_scope(nil, :ivars), cvar: make_scope(nil, :cvars) }
|
|
175
|
+
end
|
|
176
|
+
|
|
157
177
|
def walk_form(form, scope)
|
|
158
178
|
case form
|
|
159
179
|
when List then walk_list(form, scope)
|
|
@@ -291,6 +311,10 @@ module Kapusta
|
|
|
291
311
|
target = list.items[1]
|
|
292
312
|
value = list.items[2]
|
|
293
313
|
walk_form(value, scope) if value
|
|
314
|
+
if target.is_a?(List)
|
|
315
|
+
walk_form(target, scope)
|
|
316
|
+
return
|
|
317
|
+
end
|
|
294
318
|
return unless target.is_a?(Sym) && !target.dotted?
|
|
295
319
|
|
|
296
320
|
existing = scope.lookup(target.name)
|
|
@@ -301,6 +325,29 @@ module Kapusta
|
|
|
301
325
|
end
|
|
302
326
|
end
|
|
303
327
|
|
|
328
|
+
def walk_sigil_form(list, _scope)
|
|
329
|
+
return if list.items.length < 2
|
|
330
|
+
|
|
331
|
+
inner = list.items[1]
|
|
332
|
+
return unless inner.is_a?(Sym)
|
|
333
|
+
|
|
334
|
+
kind = list.head.name.to_sym
|
|
335
|
+
target_scope = sigil_target_scope(kind)
|
|
336
|
+
existing = target_scope.bindings[inner.name]
|
|
337
|
+
if existing
|
|
338
|
+
add_reference(inner, target_scope, existing)
|
|
339
|
+
else
|
|
340
|
+
add_binding(inner, target_scope, kind)
|
|
341
|
+
end
|
|
342
|
+
end
|
|
343
|
+
|
|
344
|
+
def sigil_target_scope(kind)
|
|
345
|
+
case kind
|
|
346
|
+
when :ivar, :cvar then @sigil_scope_stack.last.fetch(kind)
|
|
347
|
+
when :gvar then @gvar_scope
|
|
348
|
+
end
|
|
349
|
+
end
|
|
350
|
+
|
|
304
351
|
def walk_fn(list, scope)
|
|
305
352
|
items = list.items
|
|
306
353
|
if items[1].is_a?(Vec)
|
|
@@ -472,8 +519,11 @@ module Kapusta
|
|
|
472
519
|
|
|
473
520
|
add_constant_binding(name_sym, scope, kind) if name_sym.is_a?(Sym)
|
|
474
521
|
|
|
475
|
-
|
|
476
|
-
|
|
522
|
+
body = list.items[body_start..] || []
|
|
523
|
+
if kind == :class
|
|
524
|
+
inside_class { body.each { |form| walk_form(form, scope) } }
|
|
525
|
+
else
|
|
526
|
+
inside_module_or_class { body.each { |form| walk_form(form, scope) } }
|
|
477
527
|
end
|
|
478
528
|
end
|
|
479
529
|
|
data/lib/kapusta/reader.rb
CHANGED
|
@@ -95,6 +95,8 @@ module Kapusta
|
|
|
95
95
|
when '#' then read_hashfn
|
|
96
96
|
when '`' then read_quasiquote
|
|
97
97
|
when ',' then read_unquote
|
|
98
|
+
when '@' then peek_at(@pos + 1) == '@' ? read_sigil(:cvar, 2) : read_sigil(:ivar, 1)
|
|
99
|
+
when '$' then read_sigil(:gvar, 1)
|
|
98
100
|
when *CLOSING_DELIMS then raise unexpected_closing_delim(peek)
|
|
99
101
|
else
|
|
100
102
|
read_atom
|
|
@@ -117,6 +119,32 @@ module Kapusta
|
|
|
117
119
|
Quasiquote.new(read_form)
|
|
118
120
|
end
|
|
119
121
|
|
|
122
|
+
def read_sigil(kind, prefix_length)
|
|
123
|
+
return read_atom unless sigil_id_start?(peek_at(@pos + prefix_length))
|
|
124
|
+
|
|
125
|
+
position = source_position
|
|
126
|
+
prefix_length.times { advance }
|
|
127
|
+
name_position = source_position
|
|
128
|
+
name_start = @pos
|
|
129
|
+
advance until delim?(peek) || peek == '.'
|
|
130
|
+
inner = Sym.new(@src[name_start...@pos])
|
|
131
|
+
inner.line = name_position[0]
|
|
132
|
+
inner.column = name_position[1]
|
|
133
|
+
list = List.new([Sym.new(kind.to_s), inner])
|
|
134
|
+
list.sigil = kind
|
|
135
|
+
list.line = position[0]
|
|
136
|
+
list.column = position[1]
|
|
137
|
+
list
|
|
138
|
+
end
|
|
139
|
+
|
|
140
|
+
def peek_at(pos)
|
|
141
|
+
@src[pos]
|
|
142
|
+
end
|
|
143
|
+
|
|
144
|
+
def sigil_id_start?(char)
|
|
145
|
+
!char.nil? && char.match?(/[A-Za-z_]/)
|
|
146
|
+
end
|
|
147
|
+
|
|
120
148
|
def read_unquote
|
|
121
149
|
advance
|
|
122
150
|
if peek == '@'
|
data/lib/kapusta/version.rb
CHANGED
data/spec/examples_spec.rb
CHANGED
|
@@ -563,4 +563,17 @@ RSpec.describe 'examples' do
|
|
|
563
563
|
it 'macros-import-whole.kap' do
|
|
564
564
|
expect(run_example('macros-import-whole.kap')).to eq("7\n")
|
|
565
565
|
end
|
|
566
|
+
|
|
567
|
+
it 'parking-system.kap' do
|
|
568
|
+
expect(run_example('parking-system.kap')).to eq("true\ntrue\nfalse\nfalse\n")
|
|
569
|
+
end
|
|
570
|
+
|
|
571
|
+
it 'hit-counter.kap' do
|
|
572
|
+
expect(run_example('hit-counter.kap')).to eq(<<~OUT)
|
|
573
|
+
1
|
|
574
|
+
2
|
|
575
|
+
3
|
|
576
|
+
"alice"
|
|
577
|
+
OUT
|
|
578
|
+
end
|
|
566
579
|
end
|
data/spec/lsp_spec.rb
CHANGED
|
@@ -587,6 +587,92 @@ RSpec.describe Kapusta::LSP do
|
|
|
587
587
|
end
|
|
588
588
|
end
|
|
589
589
|
|
|
590
|
+
it 'renames an @ivar across methods within a class' do
|
|
591
|
+
text = "(class C)\n(fn one [] (set @counter 1))\n(fn two [] @counter)\n"
|
|
592
|
+
responses = run(
|
|
593
|
+
frame_initialize,
|
|
594
|
+
frame_did_open('file:///x.kap', text),
|
|
595
|
+
frame_rename(uri: 'file:///x.kap', **cursor_at(text, 'counter'), new_name: 'total')
|
|
596
|
+
)
|
|
597
|
+
changes = result_for(responses)['result']['documentChanges']
|
|
598
|
+
|
|
599
|
+
expect(changes.length).to eq(1)
|
|
600
|
+
edits = changes.first['edits']
|
|
601
|
+
expect(edits.map { |e| e['newText'] }).to eq(%w[total total])
|
|
602
|
+
expect(edits.map { |e| [e['range']['start']['line'], e['range']['start']['character']] })
|
|
603
|
+
.to contain_exactly([1, 17], [2, 12])
|
|
604
|
+
end
|
|
605
|
+
|
|
606
|
+
it 'renames @ivar without touching a same-named fn parameter or value reference' do
|
|
607
|
+
text = "(class C)\n(fn init [val] (set @counter val))\n"
|
|
608
|
+
responses = run(
|
|
609
|
+
frame_initialize,
|
|
610
|
+
frame_did_open('file:///x.kap', text),
|
|
611
|
+
frame_rename(uri: 'file:///x.kap', **cursor_at(text, 'counter'), new_name: 'total')
|
|
612
|
+
)
|
|
613
|
+
changes = result_for(responses)['result']['documentChanges']
|
|
614
|
+
|
|
615
|
+
expect(changes.length).to eq(1)
|
|
616
|
+
edits = changes.first['edits']
|
|
617
|
+
expect(edits.length).to eq(1)
|
|
618
|
+
expect(edits.first['newText']).to eq('total')
|
|
619
|
+
expect(edits.first['range']['start']).to eq('line' => 1, 'character' => 21)
|
|
620
|
+
end
|
|
621
|
+
|
|
622
|
+
it 'renames a $gvar within a file' do
|
|
623
|
+
text = "(set $last 1)\n(print $last)\n"
|
|
624
|
+
responses = run(
|
|
625
|
+
frame_initialize,
|
|
626
|
+
frame_did_open('file:///x.kap', text),
|
|
627
|
+
frame_rename(uri: 'file:///x.kap', **cursor_at(text, 'last'), new_name: 'latest')
|
|
628
|
+
)
|
|
629
|
+
changes = result_for(responses)['result']['documentChanges']
|
|
630
|
+
|
|
631
|
+
expect(changes.length).to eq(1)
|
|
632
|
+
edits = changes.first['edits']
|
|
633
|
+
expect(edits.map { |e| e['newText'] }).to eq(%w[latest latest])
|
|
634
|
+
end
|
|
635
|
+
|
|
636
|
+
it 'keeps @x and @@x in separate sigil namespaces' do
|
|
637
|
+
text = "(class C)\n(set @@flag 1)\n(fn show [] (set @flag 2))\n"
|
|
638
|
+
ivar_position = { line: 2, character: 18 }
|
|
639
|
+
responses = run(
|
|
640
|
+
frame_initialize,
|
|
641
|
+
frame_did_open('file:///x.kap', text),
|
|
642
|
+
frame_rename(uri: 'file:///x.kap', **ivar_position, new_name: 'mark')
|
|
643
|
+
)
|
|
644
|
+
changes = result_for(responses)['result']['documentChanges']
|
|
645
|
+
|
|
646
|
+
expect(changes.length).to eq(1)
|
|
647
|
+
edits = changes.first['edits']
|
|
648
|
+
expect(edits.length).to eq(1)
|
|
649
|
+
expect(edits.first['newText']).to eq('mark')
|
|
650
|
+
expect(edits.first['range']['start']).to eq('line' => 2, 'character' => 18)
|
|
651
|
+
end
|
|
652
|
+
|
|
653
|
+
it 'jumps to the first @@cvar binding from a later use site' do
|
|
654
|
+
text = "(class C)\n(set @@total 0)\n(fn add [] (set @@total (+ @@total 1)))\n"
|
|
655
|
+
use_index = text.rindex('@@total') + 2
|
|
656
|
+
prefix = text[0...use_index]
|
|
657
|
+
last_nl = prefix.rindex("\n")
|
|
658
|
+
pos = { line: prefix.count("\n"), character: last_nl ? use_index - last_nl - 1 : use_index }
|
|
659
|
+
|
|
660
|
+
responses = run(
|
|
661
|
+
frame_initialize,
|
|
662
|
+
frame_did_open('file:///x.kap', text),
|
|
663
|
+
frame_definition(uri: 'file:///x.kap', **pos)
|
|
664
|
+
)
|
|
665
|
+
result = result_for(responses)['result']
|
|
666
|
+
|
|
667
|
+
expect(result).to eq(
|
|
668
|
+
'uri' => 'file:///x.kap',
|
|
669
|
+
'range' => {
|
|
670
|
+
'start' => { 'line' => 1, 'character' => 7 },
|
|
671
|
+
'end' => { 'line' => 1, 'character' => 12 }
|
|
672
|
+
}
|
|
673
|
+
)
|
|
674
|
+
end
|
|
675
|
+
|
|
590
676
|
it 'escapes file URIs built during workspace scans' do
|
|
591
677
|
Dir.mktmpdir do |dir|
|
|
592
678
|
nested = File.join(dir, 'space dir')
|
metadata
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
|
2
2
|
name: kapusta
|
|
3
3
|
version: !ruby/object:Gem::Version
|
|
4
|
-
version: 0.
|
|
4
|
+
version: 0.9.0
|
|
5
5
|
platform: ruby
|
|
6
6
|
authors:
|
|
7
7
|
- Evgenii Morozov
|
|
@@ -57,6 +57,7 @@ files:
|
|
|
57
57
|
- examples/greet.kap
|
|
58
58
|
- examples/happy-number.kap
|
|
59
59
|
- examples/hashfn.kap
|
|
60
|
+
- examples/hit-counter.kap
|
|
60
61
|
- examples/import-helpers.kapm
|
|
61
62
|
- examples/kwargs.kap
|
|
62
63
|
- examples/leap-year.kap
|
|
@@ -81,6 +82,7 @@ files:
|
|
|
81
82
|
- examples/packet-router.kap
|
|
82
83
|
- examples/palindrome.kap
|
|
83
84
|
- examples/pangram.kap
|
|
85
|
+
- examples/parking-system.kap
|
|
84
86
|
- examples/pcall.kap
|
|
85
87
|
- examples/pipeline.kap
|
|
86
88
|
- examples/pivot-index.kap
|
|
@@ -103,6 +105,7 @@ files:
|
|
|
103
105
|
- examples/stack.kap
|
|
104
106
|
- examples/subtract-product-sum.kap
|
|
105
107
|
- examples/sum.kap
|
|
108
|
+
- examples/thread-styles.kap
|
|
106
109
|
- examples/threading.kap
|
|
107
110
|
- examples/tic-tac-toe.kap
|
|
108
111
|
- examples/tset.kap
|