Khady / merlin-eldoc

Type and doc on hover for OCaml and Reason in emacs
GNU General Public License v3.0
43 stars 3 forks source link

A way to persist type documentation after point is moved? #18

Closed juszczakn closed 6 years ago

juszczakn commented 6 years ago

This issue might be unwanted or outside of the scope of this library. Something comparable might also already be possible, not sure.

I'm an OCaml noob and I find myself constantly forgetting the arity of functions or their keywords as I'm trying to call them.

An example of this is Core's Map.append: Map.append ~lower_bound:some_map ...wait, was the second key higher_bound or upper_bound?

And then I have to move the cursor back to the function call and re-read the definition. If there's more than one keyword parameter like this, it can involve a lot of cursor travel and be annoying.

Alternatively:

Also, thanks for this, for saving me from all that C-c C-t nonsense :D

Khady commented 6 years ago

A way to toggle-lock the current doc message so that it isn't overwritten?

The message is not printed by merlin-eldoc but by eldoc. So I have no control on this part. But you can switch to the *merlin-types* buffer. It contains the text of the last message printed by merlin-eldoc if merlin has not been called since then. Probably I should use a dedicated *merlin-eldoc-types* buffer.

Contextually choosing the nearest function call and displaying it's definition?

I'd like to have this. It is on my todo list as it looks more like other eldoc plugins. To make it very good it would be great to be able to highlight to type of the parameter at point in the function signature. But I don't know if it is possible with merlin. I will try to have a look at the protocol.

One thing that can help you in the mean time is to ask merlin for completion by hand.

Map.append ~lower_bound:some_map POINT

In this situation with cursor at POINT, if you ask for completion, merlin will suggest you first the list of named parameters of the function. At least with company.

image

Also, thanks for this, for saving me from all that C-c C-t nonsense :D

Happy to know it helps :)

Khady commented 6 years ago

For the record, there is the same kind of feature request for ocaml in vscode: https://github.com/reasonml-editor/vscode-reasonml/issues/4

And I spent some time looking at the merlin protocol today. It doesn't seem possible to display the whole signature of the function that is currently getting applied in a predictable way. Because of cases like this:

let fun1 ~param1 ~param2 ~param3 p p' =
  param1 + param2 + param3 + p + p'

let v = fun1 ~param1:(1 + POINT

Here it is hard to detect it is using the infix operator + and get its signature. Or even the signature of fun1.

However what I can get is a message like at the bottom of the screenshot in my previous comment.

let fun1 ~param1 ~param2 ~param3 p p' =
  param1 + param2 + param3 + p + p'

let v = fun1 ~param1:(1 + POINT

Would give Expected argument type: int.

let fun1 ~param1 ~param2 ~param3 p p' =
  param1 + param2 + param3 + p + p'

let v = fun1 POINT

Would give Expected argument type: int or labels ~param1 ~param2 ~param3

let fun2 ~p ~g =
  p +. (float g)

let v = fun2 POINT 

Would give Expected labels: ~p ~g

Do you think something like this could fit your expectations?

juszczakn commented 6 years ago

That seems pretty close to the general idea, and might be helpful.

Does the argument information for the function call show again after the completion of a provided argument?

ie.

let fun2 ~p ~g =
  p +. (float g)

let v = fun2 ~p:3.4 POINT 

Would give Expected labels: ~g ?

Khady commented 6 years ago

Yes. As long as there are remaining arguments missing it will show the hint.

I have a first version working. It needs a little bit of cleanup but the general idea is working. Will try to finish this soon.

Khady commented 6 years ago

@juszczakn I pushed my work in 8a6cea1d8. It also contains examples in the readme. Does the result looks fine to you?

juszczakn commented 6 years ago

Seems good to me. One odd thing I notice is that if you hit backspace, it deletes the message? Is that just how eldoc works?

For example, List.map ~f:(fun x -> x) my_list POINT, if I then delete my_list, it no longer shows any hint.

Not really a big deal, seems like an edge case. Could just be annoying when fiddling with whitespace and whatnot.

I also proofread the README changes, just a few minor grammar things I pointed out. The explanations and examples look good to me :+1:

Khady commented 6 years ago

I think it is related to eldoc configuration and that merlin-eldoc can't do much about it. And you might be able to fix this using eldoc-message-commands or something related. I remember reading on the internet people who added commands after which eldoc should be triggered.

Thank you for the review. Not a native english speaker, so it is always good to have someone helping on this side.