@@ -36,20 +36,46 @@ let rec startOfLident text i =
36
36
37
37
(* foo(... ~arg) from ~arg find foo *)
38
38
let findCallFromArgument text offset =
39
- let rec loop ~i ~nClosed =
39
+ let none = ([] , [] ) in
40
+ let rec loop identsSeen i =
41
+ let i = skipWhite text i in
40
42
if i > 0 then
41
43
match text.[i] with
42
- | '(' when nClosed > 0 -> loop ~i: (i - 1 ) ~n Closed:(nClosed - 1 )
44
+ | '}' ->
45
+ let i1 = findBackSkippingCommentsAndStrings text '{' '}' (i - 1 ) 0 in
46
+ if i1 > 0 then loop identsSeen i1 else none
47
+ | ')' ->
48
+ let i1 = findBackSkippingCommentsAndStrings text '(' ')' (i - 1 ) 0 in
49
+ if i1 > 0 then loop identsSeen i1 else none
50
+ | ']' ->
51
+ let i1 = findBackSkippingCommentsAndStrings text '[' ']' (i - 1 ) 0 in
52
+ if i1 > 0 then loop identsSeen i1 else none
53
+ | '"' ->
54
+ let i1 = findBack text '"' (i - 1 ) in
55
+ if i1 > 0 then loop identsSeen i1 else none
56
+ | '\' ' ->
57
+ let i1 = findBack text '\' ' (i - 1 ) in
58
+ if i1 > 0 then loop identsSeen i1 else none
59
+ | '`' ->
60
+ let i1 = findBack text '`' (i - 1 ) in
61
+ if i1 > 0 then loop identsSeen i1 else none
43
62
| '(' ->
44
63
let i1 = skipWhite text (i - 1 ) in
45
64
let i0 = startOfLident text i1 in
46
65
let funLident = String. sub text i0 (i1 - i0 + 1 ) in
47
- Str. split (Str. regexp_string " ." ) funLident
48
- | ')' -> loop ~i: (i - 1 ) ~n Closed:(nClosed + 1 )
49
- | _ -> loop ~i: (i - 1 ) ~n Closed
50
- else []
66
+ (Str. split (Str. regexp_string " ." ) funLident, identsSeen)
67
+ | 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '.' | '_' ->
68
+ let i1 = startOfLident text i in
69
+ let ident = String. sub text i1 (i - i1 + 1 ) in
70
+ if i1 - 1 > 0 then
71
+ match text.[i1 - 1 ] with
72
+ | '~' -> loop (ident :: identsSeen) (i1 - 2 )
73
+ | _ -> loop identsSeen (i1 - 1 )
74
+ else none
75
+ | _ -> loop identsSeen (i - 1 )
76
+ else none
51
77
in
52
- loop ~i: offset ~n Closed: 0
78
+ loop [] offset
53
79
54
80
(* skip A or #A or %A if present *)
55
81
let skipOptVariantExtension text i =
@@ -61,7 +87,7 @@ let skipOptVariantExtension text i =
61
87
if i > 0 then match text.[i] with '#' | '%' -> i - 1 | _ -> i else i
62
88
in
63
89
i
64
- | _ -> i
90
+ | _ -> i
65
91
else i
66
92
67
93
(* Figure out whether id should be autocompleted as component prop.
@@ -143,8 +169,8 @@ type pipe = PipeId of string | PipeArray | PipeString
143
169
144
170
type completable =
145
171
| Cdecorator of string (* * e.g. @module *)
146
- | Clabel of string list * string
147
- (* * e.g. (["M", "foo"], "label") for M.foo(...~label...) *)
172
+ | Clabel of string list * string * string list
173
+ (* * e.g. (["M", "foo"], "label", ["l1", "l2"] ) for M.foo(...~l1...~l2 ...~label...) *)
148
174
| Cpath of string list (* * e.g. ["M", "foo"] for M.foo *)
149
175
| Cjsx of string list * string * string list
150
176
(* * E.g. (["M", "Comp"], "id", ["id1", "id2"]) for <M.Comp id1=... id2=... ... id *)
@@ -201,8 +227,8 @@ let findCompletable text offset =
201
227
else Some (mkPath rest)
202
228
| '~' ->
203
229
let labelPrefix = suffix i in
204
- let funPath = findCallFromArgument text (i - 1 ) in
205
- Some (Clabel (funPath, labelPrefix))
230
+ let funPath, identsSeen = findCallFromArgument text (i - 1 ) in
231
+ Some (Clabel (funPath, labelPrefix, identsSeen ))
206
232
| '@' -> Some (Cdecorator (suffix i))
207
233
| 'a' .. 'z' | 'A' .. 'Z' | '0' .. '9' | '.' | '_' -> loop (i - 1 )
208
234
| ' ' when i = offset - 1 -> (
0 commit comments