From f8cef4a4ab55a7a30d729875283607a578df7301 Mon Sep 17 00:00:00 2001 From: Pizie Dust Date: Thu, 30 Jan 2025 20:03:02 +0100 Subject: [PATCH 1/6] get_all implementation to get list of possible jumps --- src/analysis/jump.ml | 58 ++++++++++++++++++++++++++++++++----------- src/analysis/jump.mli | 3 +++ 2 files changed, 47 insertions(+), 14 deletions(-) diff --git a/src/analysis/jump.ml b/src/analysis/jump.ml index 396a098d4e..35b7faed62 100644 --- a/src/analysis/jump.ml +++ b/src/analysis/jump.ml @@ -136,19 +136,30 @@ let find_case_pos cases pos direction = in let case = find_pos pos cases direction in match case with - | Some location -> `Found location + | Some location -> location | None -> ( match direction with | Next -> raise No_next_match_case | Prev -> raise No_prev_match_case) -let get typed_tree pos target = +let get_enclosings typed_tree pos = let roots = Mbrowse.of_typedtree typed_tree in - let enclosings = - match Mbrowse.enclosing pos [ roots ] with - | [] -> [] - | l -> List.map ~f:snd l - in + + match Mbrowse.enclosing pos [ roots ] with + | [] -> [] + | l -> List.map ~f:snd l + +let get_node_position target pos node = + match target with + | "match-next-case" -> find_case_pos (get_cases_from_match node) pos Next + | "match-prev-case" -> + find_case_pos (List.rev (get_cases_from_match node)) pos Prev + | _ -> + let node_loc = Browse_raw.node_real_loc Location.none node in + node_loc.Location.loc_start + +let get typed_tree pos target = + let enclosings = get_enclosings typed_tree pos in let all_preds = [ ("fun", fun_pred); ("let", let_pred); @@ -173,19 +184,38 @@ let get typed_tree pos target = else let nodes = skip_non_moving pos enclosings in let node = find_node preds nodes in - match target with - | "match-next-case" -> find_case_pos (get_cases_from_match node) pos Next - | "match-prev-case" -> - find_case_pos (List.rev (get_cases_from_match node)) pos Prev - | _ -> - let node_loc = Browse_raw.node_real_loc Location.none node in - `Found node_loc.Location.loc_start + `Found (get_node_position target pos node) with | No_predicate target -> `Error ("No predicate for " ^ target) | No_matching_target -> `Error "No matching target" | No_next_match_case -> `Error "No next case found" | No_prev_match_case -> `Error "No previous case found" +let get_all typed_tree pos = + let enclosings = get_enclosings typed_tree pos in + let predicates = + [ ("fun", fun_pred); + ("let", let_pred); + ("module", module_pred); + ("module-type", module_type_pred); + ("match", match_pred); + ("match-next-case", match_pred); + ("match-prev-case", match_pred) + ] + in + let nodes = skip_non_moving pos enclosings in + let results = + List.filter_map + ~f:(fun (target, pred) -> + match find_node [ pred ] nodes with + | exception No_matching_target -> None + | node -> + let position = get_node_position target pos node in + Some (target, position)) + predicates + in + results + let phrase typed_tree pos target = let roots = Mbrowse.of_typedtree typed_tree in (* Select nodes around cursor. diff --git a/src/analysis/jump.mli b/src/analysis/jump.mli index 8c244f92ff..9c6e8fd838 100644 --- a/src/analysis/jump.mli +++ b/src/analysis/jump.mli @@ -33,6 +33,9 @@ val get : string -> [> `Error of string | `Found of Lexing.position ] +val get_all : + Mtyper.typedtree -> Std.Lexing.position -> (string * Lexing.position) list + val phrase : Mtyper.typedtree -> Std.Lexing.position -> From c91b01b9f121a6f3846508b8122c5985324921ef Mon Sep 17 00:00:00 2001 From: Pizie Dust Date: Fri, 31 Jan 2025 02:54:14 +0100 Subject: [PATCH 2/6] add changelog --- CHANGES.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGES.md b/CHANGES.md index 1322fe29b2..826288fdfa 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -1,3 +1,9 @@ +unrealeased +=========== + ++ merlin binary + - A new `get_all` function in jump module to return all possible targets (#1891) + merlin 5.4.1 ============ Mon Jan 13 10:55:42 CET 2025 From 21092f54c6abcf0b237101d359c8277bd05ec195 Mon Sep 17 00:00:00 2001 From: Pizie Dust Date: Fri, 31 Jan 2025 04:43:18 +0100 Subject: [PATCH 3/6] refactor --- src/analysis/jump.ml | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/src/analysis/jump.ml b/src/analysis/jump.ml index 35b7faed62..b5acaa8638 100644 --- a/src/analysis/jump.ml +++ b/src/analysis/jump.ml @@ -158,9 +158,7 @@ let get_node_position target pos node = let node_loc = Browse_raw.node_real_loc Location.none node in node_loc.Location.loc_start -let get typed_tree pos target = - let enclosings = get_enclosings typed_tree pos in - let all_preds = +let predicates = [ ("fun", fun_pred); ("let", let_pred); ("module", module_pred); @@ -193,16 +191,6 @@ let get typed_tree pos target = let get_all typed_tree pos = let enclosings = get_enclosings typed_tree pos in - let predicates = - [ ("fun", fun_pred); - ("let", let_pred); - ("module", module_pred); - ("module-type", module_type_pred); - ("match", match_pred); - ("match-next-case", match_pred); - ("match-prev-case", match_pred) - ] - in let nodes = skip_non_moving pos enclosings in let results = List.filter_map From 4a3c57f3a0cb75e8797e568221ccc61f7e53d48b Mon Sep 17 00:00:00 2001 From: Pizie Dust Date: Fri, 31 Jan 2025 04:43:52 +0100 Subject: [PATCH 4/6] don't raise exception when match-prev or match-next is not possible --- src/analysis/jump.ml | 47 ++++++++++++++++++++------------------------ 1 file changed, 21 insertions(+), 26 deletions(-) diff --git a/src/analysis/jump.ml b/src/analysis/jump.ml index b5acaa8638..f603c8347a 100644 --- a/src/analysis/jump.ml +++ b/src/analysis/jump.ml @@ -95,8 +95,6 @@ let rec find_map ~f = function exception No_matching_target exception No_predicate of string -exception No_next_match_case -exception No_prev_match_case (* Returns first node on the list matching a predicate *) let rec find_node preds nodes = @@ -134,13 +132,7 @@ let find_case_pos cases pos direction = in if check then Some pat_loc.loc_start else find_pos pos tail direction in - let case = find_pos pos cases direction in - match case with - | Some location -> location - | None -> ( - match direction with - | Next -> raise No_next_match_case - | Prev -> raise No_prev_match_case) + find_pos pos cases direction let get_enclosings typed_tree pos = let roots = Mbrowse.of_typedtree typed_tree in @@ -156,24 +148,26 @@ let get_node_position target pos node = find_case_pos (List.rev (get_cases_from_match node)) pos Prev | _ -> let node_loc = Browse_raw.node_real_loc Location.none node in - node_loc.Location.loc_start + Some node_loc.Location.loc_start let predicates = - [ ("fun", fun_pred); - ("let", let_pred); - ("module", module_pred); - ("module-type", module_type_pred); - ("match", match_pred); - ("match-next-case", match_pred); - ("match-prev-case", match_pred) - ] - in + [ ("fun", fun_pred); + ("let", let_pred); + ("module", module_pred); + ("module-type", module_type_pred); + ("match", match_pred); + ("match-next-case", match_pred); + ("match-prev-case", match_pred) + ] + +let get typed_tree pos target = + let enclosings = get_enclosings typed_tree pos in let targets = Str.split (Str.regexp "[, ]") target in try let preds = List.map targets ~f:(fun target -> match - List.find_some all_preds ~f:(fun (name, _) -> name = target) + List.find_some predicates ~f:(fun (name, _) -> name = target) with | Some (_, f) -> f | None -> raise (No_predicate target)) @@ -182,12 +176,12 @@ let predicates = else let nodes = skip_non_moving pos enclosings in let node = find_node preds nodes in - `Found (get_node_position target pos node) + match get_node_position target pos node with + | Some loc -> `Found loc + | None -> `Error ("No matching case found for " ^ target) with | No_predicate target -> `Error ("No predicate for " ^ target) | No_matching_target -> `Error "No matching target" - | No_next_match_case -> `Error "No next case found" - | No_prev_match_case -> `Error "No previous case found" let get_all typed_tree pos = let enclosings = get_enclosings typed_tree pos in @@ -197,9 +191,10 @@ let get_all typed_tree pos = ~f:(fun (target, pred) -> match find_node [ pred ] nodes with | exception No_matching_target -> None - | node -> - let position = get_node_position target pos node in - Some (target, position)) + | node -> ( + match get_node_position target pos node with + | Some position -> Some (target, position) + | None -> None)) predicates in results From cd599432b5f99da1b9d00fc33a0cee25374be743 Mon Sep 17 00:00:00 2001 From: Pizie Dust Date: Fri, 31 Jan 2025 04:44:43 +0100 Subject: [PATCH 5/6] update test --- tests/test-dirs/motion/jump_match.t | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/tests/test-dirs/motion/jump_match.t b/tests/test-dirs/motion/jump_match.t index 842d0ec09f..82aa5ababf 100644 --- a/tests/test-dirs/motion/jump_match.t +++ b/tests/test-dirs/motion/jump_match.t @@ -54,7 +54,7 @@ Test when there's no next case $ $MERLIN single jump -target match-next-case -position 13:2 -filename test.ml < test.ml { "class": "return", - "value": "No next case found", + "value": "No matching case found for match-next-case", "notifications": [] } @@ -62,7 +62,7 @@ Test when there's no previous case $ $MERLIN single jump -target match-prev-case -position 3:2 -filename test.ml < test.ml { "class": "return", - "value": "No previous case found", + "value": "No matching case found for match-prev-case", "notifications": [] } From e865363ceda5266e183117c385db50929765a92b Mon Sep 17 00:00:00 2001 From: Pizie Dust Date: Mon, 3 Feb 2025 18:11:37 +0100 Subject: [PATCH 6/6] refactoring --- src/analysis/jump.ml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/src/analysis/jump.ml b/src/analysis/jump.ml index f603c8347a..62a63a98ff 100644 --- a/src/analysis/jump.ml +++ b/src/analysis/jump.ml @@ -191,10 +191,10 @@ let get_all typed_tree pos = ~f:(fun (target, pred) -> match find_node [ pred ] nodes with | exception No_matching_target -> None - | node -> ( - match get_node_position target pos node with - | Some position -> Some (target, position) - | None -> None)) + | node -> + Option.map + ~f:(fun pos -> (target, pos)) + (get_node_position target pos node)) predicates in results