From 52d95db28c5b1d5f02f1528d2b563c3ad9f282dd Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Tue, 13 Sep 2022 18:09:26 +0200 Subject: [PATCH 1/2] Use Merlin Enclosing command instead of Shape. The enclosing command is the dedicated Merlin command to provide meaningfull growing and shrinking selection. --- ocaml-lsp-server/src/ocaml_lsp_server.ml | 36 ++++++------------------ 1 file changed, 8 insertions(+), 28 deletions(-) diff --git a/ocaml-lsp-server/src/ocaml_lsp_server.ml b/ocaml-lsp-server/src/ocaml_lsp_server.ml index 71fb46765..0cc279a9f 100644 --- a/ocaml-lsp-server/src/ocaml_lsp_server.ml +++ b/ocaml-lsp-server/src/ocaml_lsp_server.ml @@ -538,39 +538,19 @@ let selection_range (state : State.t) match Document.kind doc with | `Other -> Fiber.return [] | `Merlin merlin -> - let selection_range_of_shapes (cursor_position : Position.t) - (shapes : Query_protocol.shape list) : SelectionRange.t option = - let rec ranges_of_shape parent s = - let selectionRange = - let range = Range.of_loc s.Query_protocol.shape_loc in - { SelectionRange.range; parent } - in - match s.Query_protocol.shape_sub with - | [] -> [ selectionRange ] - | xs -> List.concat_map xs ~f:(ranges_of_shape (Some selectionRange)) - in - (* try to find the nearest range inside first, then outside *) - let nearest_range = - let ranges = List.concat_map ~f:(ranges_of_shape None) shapes in - List.min ranges ~f:(fun r1 r2 -> - let inc (r : SelectionRange.t) = - Position.compare_inclusion cursor_position r.range - in - match (inc r1, inc r2) with - | `Outside x, `Outside y -> Position.compare x y - | `Outside _, `Inside -> Gt - | `Inside, `Outside _ -> Lt - | `Inside, `Inside -> Range.compare_size r1.range r2.range) - in - nearest_range + let rec selection_range_of_enclosings = function + | hd :: tl -> + let parent = selection_range_of_enclosings tl in + Some { SelectionRange.range = Range.of_loc hd; parent } + | [] -> None in let+ ranges = Fiber.sequential_map positions ~f:(fun x -> - let+ shapes = - let command = Query_protocol.Shape (Position.logical x) in + let+ enclosings = + let command = Query_protocol.Enclosing (Position.logical x) in Document.Merlin.dispatch_exn merlin command in - selection_range_of_shapes x shapes) + selection_range_of_enclosings enclosings) in List.filter_opt ranges From ebb41cd06f64031db24696a34452e757c327d2cc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ulysse=20G=C3=A9rard?= Date: Mon, 19 Sep 2022 15:32:59 +0200 Subject: [PATCH 2/2] Add changelog entry for #836 (shape <> enclosing) --- CHANGES.md | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 36d616230..49d566a86 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -26,6 +26,11 @@ - Fix signatureHelp on .mll files: avoid "Document.dune" exceptions +- Use Merlin's `enclosing` command instead of `shape` to answer `selectionRange` + queries since it is the more appropriate one. This notably removes the need + for checking which enclosing is the closest to the cursor since Merlin already + does it. (#860) + # 1.13.1 ## Fixes