From 92551aa390811b159ef9ecb03bbaa0d8c30cb536 Mon Sep 17 00:00:00 2001 From: Lucccyo Date: Thu, 20 Nov 2025 15:03:05 +0100 Subject: [PATCH 1/3] Add cram test to reproduce the issue --- .../test-dirs/signature-help/issue_fun_name.t | 191 ++++++++++++++++++ 1 file changed, 191 insertions(+) create mode 100644 tests/test-dirs/signature-help/issue_fun_name.t diff --git a/tests/test-dirs/signature-help/issue_fun_name.t b/tests/test-dirs/signature-help/issue_fun_name.t new file mode 100644 index 000000000..a2ac4a44b --- /dev/null +++ b/tests/test-dirs/signature-help/issue_fun_name.t @@ -0,0 +1,191 @@ + $ cat > test.ml <<'EOF' + > let v = List.map Fun.id [] + > EOF + +Valid + $ $MERLIN single signature-help -position 1:4 -filename test < test.ml + { + "class": "return", + "value": {}, + "notifications": [] + } + + $ $MERLIN single signature-help -position 1:18 -filename test < test.ml + { + "class": "return", + "value": { + "signatures": [ + { + "label": "List.map : ('a -> 'a) -> 'a list -> 'a list", + "parameters": [ + { + "label": [ + 11, + 21 + ] + }, + { + "label": [ + 25, + 32 + ] + } + ] + } + ], + "activeParameter": 0, + "activeSignature": 0 + }, + "notifications": [] + } + + $ $MERLIN single signature-help -position 1:21 -filename test < test.ml + { + "class": "return", + "value": { + "signatures": [ + { + "label": "List.map : ('a -> 'a) -> 'a list -> 'a list", + "parameters": [ + { + "label": [ + 11, + 21 + ] + }, + { + "label": [ + 25, + 32 + ] + } + ] + } + ], + "activeParameter": 0, + "activeSignature": 0 + }, + "notifications": [] + } + + $ $MERLIN single signature-help -position 1:24 -filename test < test.ml + { + "class": "return", + "value": { + "signatures": [ + { + "label": "List.map : ('a -> 'a) -> 'a list -> 'a list", + "parameters": [ + { + "label": [ + 11, + 21 + ] + }, + { + "label": [ + 25, + 32 + ] + } + ] + } + ], + "activeParameter": 1, + "activeSignature": 0 + }, + "notifications": [] + } + + $ cat > t.ml <<'EOF' + > module M : sig + > val f : int -> unit + > end = struct + > let f (_ : int) = () + > end + > + > let () = M.f (* keep whitespace *) + > EOF + + $ $MERLIN single signature-help -position 7:13 -filename test < t.ml + { + "class": "return", + "value": { + "signatures": [ + { + "label": "M.f : int -> unit", + "parameters": [ + { + "label": [ + 6, + 9 + ] + } + ] + } + ], + "activeParameter": 0, + "activeSignature": 0 + }, + "notifications": [] + } + + +FIXME: Signature help should not appear on the name of the function: + $ $MERLIN single signature-help -position 1:9 -filename test < test.ml + { + "class": "return", + "value": { + "signatures": [ + { + "label": "List.map : ('a -> 'a) -> 'a list -> 'a list", + "parameters": [ + { + "label": [ + 11, + 21 + ] + }, + { + "label": [ + 25, + 32 + ] + } + ] + } + ], + "activeParameter": 0, + "activeSignature": 0 + }, + "notifications": [] + } + + $ $MERLIN single signature-help -position 1:14 -filename test < test.ml + { + "class": "return", + "value": { + "signatures": [ + { + "label": "List.map : ('a -> 'a) -> 'a list -> 'a list", + "parameters": [ + { + "label": [ + 11, + 21 + ] + }, + { + "label": [ + 25, + 32 + ] + } + ] + } + ], + "activeParameter": 0, + "activeSignature": 0 + }, + "notifications": [] + } From c3a8540eea215c53bc9a6cc014c8379ee0a3bf2a Mon Sep 17 00:00:00 2001 From: Lucccyo Date: Thu, 20 Nov 2025 15:06:17 +0100 Subject: [PATCH 2/3] Allow the signature help only after the function name --- src/frontend/query_commands.ml | 23 +++++---- src/kernel/msource.ml | 11 +++++ src/kernel/msource.mli | 2 + .../test-dirs/signature-help/issue_fun_name.t | 48 +------------------ 4 files changed, 28 insertions(+), 56 deletions(-) diff --git a/src/frontend/query_commands.ml b/src/frontend/query_commands.ml index 75fc431be..20331222c 100644 --- a/src/frontend/query_commands.ml +++ b/src/frontend/query_commands.ml @@ -898,16 +898,19 @@ let dispatch pipeline (type a) : a Query_protocol.t -> a = function in match application_signature with | Some s -> - let prefix = - let fun_name = Option.value ~default:"_" s.function_name in - sprintf "%s : " fun_name - in - Some - { label = prefix ^ s.signature; - parameters = List.map ~f:(param (String.length prefix)) s.parameters; - active_param = Option.value ~default:0 s.active_param; - active_signature = 0 - } + if (Msource.compare_logical (Msource.get_logical source position) (Msource.get_logical source s.function_position)) < 0 then None + else ( + let prefix = + let fun_name = Option.value ~default:"_" s.function_name in + sprintf "%s : " fun_name + in + Some + { label = prefix ^ s.signature; + parameters = List.map ~f:(param (String.length prefix)) s.parameters; + active_param = Option.value ~default:0 s.active_param; + active_signature = 0 + } + ) | None -> None) | Version -> Printf.sprintf "The Merlin toolkit version %s, for Ocaml %s\n" diff --git a/src/kernel/msource.ml b/src/kernel/msource.ml index b975cc556..0f3c5c9f0 100644 --- a/src/kernel/msource.ml +++ b/src/kernel/msource.ml @@ -105,6 +105,17 @@ let get_logical { text } = function done; `Logical (!line, offset - !cnum) +let compare_logical x y : int = + match x, y with + | `Logical (row_x, col_x), + `Logical (row_y, col_y) -> + let delta_row = row_x - row_y in + if delta_row = 0 then col_x - col_y else delta_row + | _ -> failwith "Only `Logical expected." + +let compare_logical (`Logical ((row_x: int), (col_x : int))) (`Logical ((row_y:int), (col_y: int))) = + compare (row_x, col_x) (row_y, col_y) + let get_lexing_pos t ~filename pos = let (`Offset o) = get_offset t pos in let (`Logical (line, col)) = get_logical t pos in diff --git a/src/kernel/msource.mli b/src/kernel/msource.mli index ff0b72b9e..f163a3c53 100644 --- a/src/kernel/msource.mli +++ b/src/kernel/msource.mli @@ -27,6 +27,8 @@ val get_offset : t -> [< position ] -> [> `Offset of int ] val get_logical : t -> [< position ] -> [> `Logical of int * int ] +val compare_logical : [< `Logical of int * int ] -> [< `Logical of int * int ] -> int + val get_lexing_pos : t -> filename:string -> [< position ] -> Lexing.position (** {1 Managing content} *) diff --git a/tests/test-dirs/signature-help/issue_fun_name.t b/tests/test-dirs/signature-help/issue_fun_name.t index a2ac4a44b..13ab044ed 100644 --- a/tests/test-dirs/signature-help/issue_fun_name.t +++ b/tests/test-dirs/signature-help/issue_fun_name.t @@ -135,57 +135,13 @@ FIXME: Signature help should not appear on the name of the function: $ $MERLIN single signature-help -position 1:9 -filename test < test.ml { "class": "return", - "value": { - "signatures": [ - { - "label": "List.map : ('a -> 'a) -> 'a list -> 'a list", - "parameters": [ - { - "label": [ - 11, - 21 - ] - }, - { - "label": [ - 25, - 32 - ] - } - ] - } - ], - "activeParameter": 0, - "activeSignature": 0 - }, + "value": {}, "notifications": [] } $ $MERLIN single signature-help -position 1:14 -filename test < test.ml { "class": "return", - "value": { - "signatures": [ - { - "label": "List.map : ('a -> 'a) -> 'a list -> 'a list", - "parameters": [ - { - "label": [ - 11, - 21 - ] - }, - { - "label": [ - 25, - 32 - ] - } - ] - } - ], - "activeParameter": 0, - "activeSignature": 0 - }, + "value": {}, "notifications": [] } From 25ac81b0c0de19b4cdce4a4893a4b96b4dfdb711 Mon Sep 17 00:00:00 2001 From: Lucccyo Date: Thu, 20 Nov 2025 15:43:15 +0100 Subject: [PATCH 3/3] Update changelog --- CHANGES.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGES.md b/CHANGES.md index 82f439ebf..19737a797 100644 --- a/CHANGES.md +++ b/CHANGES.md @@ -2,6 +2,7 @@ unreleased ========== + merlin library + - Signature help should not appear on the function name (#1997) - Fix completion not working for inlined records labels (#1978, fixes #1977) - Perform buffer indexing only if the query requires it (#1990 and #1991) - Stop unnecessarily forcing substitutions when initializing short-paths graph (#1988)