Skip to content

Commit 1724a87

Browse files
committed
Allows client to request a specific target. If not, all possible targets locations are returned.
1 parent 1d149c9 commit 1724a87

File tree

3 files changed

+88
-47
lines changed

3 files changed

+88
-47
lines changed

ocaml-lsp-server/src/custom_requests/req_merlin_jump.ml

Lines changed: 36 additions & 36 deletions
Original file line numberDiff line numberDiff line change
@@ -19,42 +19,39 @@ module JumpParams = struct
1919
type t =
2020
{ textDocument : TextDocumentIdentifier.t
2121
; position : Position.t
22+
; target : string option
2223
}
2324

2425
let t_of_yojson json =
2526
let open Yojson.Safe.Util in
2627
{ textDocument = json |> member "textDocument" |> TextDocumentIdentifier.t_of_yojson
2728
; position = json |> member "position" |> Position.t_of_yojson
29+
; target = json |> member "target" |> to_string_option
2830
}
2931
;;
3032

31-
let yojson_of_t { textDocument; position } =
33+
let yojson_of_t { textDocument; position; target } =
34+
let target =
35+
Option.value_map target ~default:[] ~f:(fun v -> [ "target", `String v ])
36+
in
3237
`Assoc
33-
[ "textDocument", TextDocumentIdentifier.yojson_of_t textDocument
34-
; "position", Position.yojson_of_t position
35-
]
38+
(("textDocument", TextDocumentIdentifier.yojson_of_t textDocument)
39+
:: ("position", Position.yojson_of_t position)
40+
:: target)
3641
;;
3742
end
3843

3944
module Jump = struct
4045
type t = (string * Position.t) list
4146

42-
let yojson_of_t (lst : t) : Yojson.Safe.t option =
43-
if List.is_empty lst
44-
then None
45-
else
46-
Some
47-
(`Assoc
48-
[ ( "jumps"
49-
, `List
50-
(List.map
51-
~f:(fun (target, position) ->
52-
`Assoc
53-
[ "target", `String target
54-
; "position", Position.yojson_of_t position
55-
])
56-
lst) )
57-
])
47+
let yojson_of_t (lst : t) : Yojson.Safe.t =
48+
let jumps =
49+
List.map
50+
~f:(fun (target, position) ->
51+
`Assoc [ "target", `String target; "position", Position.yojson_of_t position ])
52+
lst
53+
in
54+
`Assoc [ "jumps", `List jumps ]
5855
;;
5956
end
6057

@@ -65,8 +62,8 @@ module Request_params = struct
6562

6663
let yojson_of_t t = JumpParams.yojson_of_t t
6764

68-
let create ~uri ~position =
69-
{ JumpParams.textDocument = TextDocumentIdentifier.create ~uri; position }
65+
let create ~uri ~position ~target =
66+
{ JumpParams.textDocument = TextDocumentIdentifier.create ~uri; position; target }
7067
;;
7168
end
7269

@@ -78,27 +75,30 @@ let dispatch ~merlin ~position ~target =
7875
;;
7976

8077
let on_request ~params state =
78+
let open Fiber.O in
8179
Fiber.of_thunk (fun () ->
8280
let params = (Option.value ~default:(`Assoc []) params :> Yojson.Safe.t) in
8381
let params = JumpParams.t_of_yojson params in
8482
let uri = params.textDocument.uri in
8583
let position = params.position in
8684
let doc = Document_store.get state.State.store uri in
87-
let targets = JumpParams.targets in
8885
match Document.kind doc with
8986
| `Other -> Fiber.return `Null
9087
| `Merlin merlin ->
91-
Fiber.map
92-
(Fiber.parallel_map targets ~f:(fun target ->
93-
dispatch ~merlin ~position ~target
94-
|> Fiber.map ~f:(function
95-
| `Error _ -> None
96-
| `Found pos ->
97-
(match Position.of_lexical_position pos with
98-
| None -> None
99-
| Some position -> Some (target, position)))))
100-
~f:(fun results ->
101-
match List.filter_map results ~f:Fun.id with
102-
| [] -> `Null
103-
| lst -> Jump.yojson_of_t lst |> Option.value ~default:`Null))
88+
let targets =
89+
match params.target with
90+
| None -> JumpParams.targets
91+
| Some target -> [ target ]
92+
in
93+
let+ results =
94+
Fiber.parallel_map targets ~f:(fun target ->
95+
dispatch ~merlin ~position ~target
96+
|> Fiber.map ~f:(function
97+
| `Error _ -> None
98+
| `Found pos ->
99+
(match Position.of_lexical_position pos with
100+
| None -> None
101+
| Some position -> Some (target, position))))
102+
in
103+
Jump.yojson_of_t (List.filter_map results ~f:Fun.id))
104104
;;

ocaml-lsp-server/src/custom_requests/req_merlin_jump.mli

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ module Request_params : sig
44
type t
55

66
val yojson_of_t : t -> Json.t
7-
val create : uri:DocumentUri.t -> position:Position.t -> t
7+
val create : uri:DocumentUri.t -> position:Position.t -> target:string option -> t
88
end
99

1010
type t

ocaml-lsp-server/test/e2e-new/merlin_jump.ml

Lines changed: 51 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,10 @@ open Test.Import
22
module Req = Ocaml_lsp_server.Custom_request.Merlin_jump
33

44
module Util = struct
5-
let call_jump position client =
5+
let call_jump position ?target client =
66
let uri = DocumentUri.of_path "test.ml" in
77
let params =
8-
Req.Request_params.create ~uri ~position
8+
Req.Request_params.create ~uri ~position ~target
99
|> Req.Request_params.yojson_of_t
1010
|> Jsonrpc.Structured.t_of_yojson
1111
|> Option.some
@@ -14,18 +14,18 @@ module Util = struct
1414
Client.request client req
1515
;;
1616

17-
let test ~line ~character ~source =
17+
let test ~line ~character ~source ?target () =
1818
let position = Position.create ~character ~line in
1919
let request client =
2020
let open Fiber.O in
21-
let+ response = call_jump position client in
21+
let+ response = call_jump position client ?target in
2222
Test.print_result response
2323
in
2424
Helpers.test source request
2525
;;
2626
end
2727

28-
let%expect_test "Get location of the next match case" =
28+
let%expect_test "Get all jumps including the next match case" =
2929
let source =
3030
{|
3131
let find_vowel x =
@@ -40,7 +40,7 @@ match x with
4040
in
4141
let line = 3 in
4242
let character = 2 in
43-
Util.test ~line ~character ~source;
43+
Util.test ~line ~character ~source ();
4444
[%expect
4545
{|
4646
{
@@ -56,6 +56,35 @@ match x with
5656
} |}]
5757
;;
5858

59+
let%expect_test "Get location of the next match case" =
60+
let source =
61+
{|
62+
let find_vowel x =
63+
match x with
64+
| 'A' -> true
65+
| 'E' -> true
66+
| 'I' -> true
67+
| 'O' -> true
68+
| 'U' -> true
69+
| _ -> false
70+
|}
71+
in
72+
let line = 3 in
73+
let character = 2 in
74+
Util.test ~line ~character ~source ~target:"match-next-case" ();
75+
[%expect
76+
{|
77+
{
78+
"jumps": [
79+
{
80+
"target": "match-next-case",
81+
"position": { "character": 2, "line": 4 }
82+
}
83+
]
84+
}
85+
|}]
86+
;;
87+
5988
let%expect_test "Get location of a the module" =
6089
let source =
6190
{|type a = Foo | Bar
@@ -79,8 +108,9 @@ end|}
79108
in
80109
let line = 10 in
81110
let character = 3 in
82-
Util.test ~line ~character ~source;
83-
[%expect {|
111+
Util.test ~line ~character ~source ();
112+
[%expect
113+
{|
84114
{
85115
"jumps": [
86116
{ "target": "module", "position": { "character": 2, "line": 7 } }
@@ -92,6 +122,17 @@ let%expect_test "Same line should output no locations" =
92122
let source = {|let x = 5 |} in
93123
let line = 1 in
94124
let character = 5 in
95-
Util.test ~line ~character ~source;
96-
[%expect {| null |}]
125+
Util.test ~line ~character ~source ();
126+
[%expect {| { "jumps": [] } |}]
127+
;;
128+
129+
let%expect_test "Ask for a non-existing target" =
130+
let source = {|
131+
let find_vowel x = ()
132+
|} in
133+
let line = 1 in
134+
let character = 2 in
135+
Util.test ~line ~character ~source ~target:"notatarget" ();
136+
[%expect
137+
{| { "jumps": [] } |}]
97138
;;

0 commit comments

Comments
 (0)