diff --git a/CHANGES.md b/CHANGES.md index bed03fee7..030b9455b 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -6,6 +6,8 @@ called `duneDiganostics` and it may be set to `{ enable: false }` to disable diagnostics. (#1221) +- Support folding of `ifthenelse` expressions (#1031) + # 1.17.0 ## Fixes diff --git a/ocaml-lsp-server/src/folding_range.ml b/ocaml-lsp-server/src/folding_range.ml index 262f1aa7c..cb87546e6 100644 --- a/ocaml-lsp-server/src/folding_range.ml +++ b/ocaml-lsp-server/src/folding_range.ml @@ -188,6 +188,13 @@ let fold_over_parsetree (parsetree : Mreader.parsetree) = let lident_range = Range.of_loc lident.Asttypes.loc in let expr_range = Range.of_loc expr.Parsetree.pexp_loc in push { Range.start = lident_range.end_; end_ = expr_range.end_ }) + | Pexp_ifthenelse (if_expr, then_expr, else_expr) -> + let loc = + { if_expr.pexp_loc with loc_end = then_expr.pexp_loc.loc_end } + in + Range.of_loc loc |> push; + self.expr self then_expr; + Option.iter else_expr ~f:(self.expr self) | Pexp_apply _ | Pexp_while _ | Pexp_for _ @@ -202,7 +209,6 @@ let fold_over_parsetree (parsetree : Mreader.parsetree) = | Pexp_fun _ | Pexp_poly _ | Pexp_sequence _ - | Pexp_ifthenelse _ | Pexp_constraint _ | Pexp_function _ | Pexp_newtype _ diff --git a/ocaml-lsp-server/test/e2e/__tests__/textDocument-foldingRange.test.ts b/ocaml-lsp-server/test/e2e/__tests__/textDocument-foldingRange.test.ts index 8fca05b6e..78a3eeee7 100644 --- a/ocaml-lsp-server/test/e2e/__tests__/textDocument-foldingRange.test.ts +++ b/ocaml-lsp-server/test/e2e/__tests__/textDocument-foldingRange.test.ts @@ -757,6 +757,13 @@ describe("textDocument/foldingRange", () => { "startCharacter": 0, "startLine": 0, }, + Object { + "endCharacter": 6, + "endLine": 10, + "kind": "region", + "startCharacter": 5, + "startLine": 1, + }, Object { "endCharacter": 29, "endLine": 4, @@ -1457,4 +1464,59 @@ describe("textDocument/foldingRange", () => { ] `); }); + + it("returns folding ranges for Pexp_ifthenelse", async () => { + openDocument(outdent` + if tool_name = "ocamldep" then + if is_self_reference ~input_name ~loc lid then + {type_decl with ptype_manifest = None} + else {type_decl with ptype_manifest = Some manifest} + else + let x = + let () = Stdlib.print_endline "one" in + let () = Stdlib.print_endline "two" in + () + in + let y = + let () = Stdlib.print_endline "one" in + let () = Stdlib.print_endline "two" in + () + in + () + `); + + let result = await foldingRange(); + expect(result).toMatchInlineSnapshot(` + Array [ + Object { + "endCharacter": 54, + "endLine": 3, + "kind": "region", + "startCharacter": 3, + "startLine": 0, + }, + Object { + "endCharacter": 42, + "endLine": 2, + "kind": "region", + "startCharacter": 5, + "startLine": 1, + }, + Object { + "endCharacter": 6, + "endLine": 8, + "kind": "region", + "startCharacter": 2, + "startLine": 5, + }, + Object { + "endCharacter": 6, + "endLine": 13, + "kind": "region", + "startCharacter": 2, + "startLine": 10, + }, + ] + `); + }); });