next-ls icon indicating copy to clipboard operation
next-ls copied to clipboard

feat: signature help

Open lucacervello opened this issue 1 year ago • 16 comments

I've reduced the scope of this MR.

~I've reused the Definition code and showed the signature.~

It doesn't work while you're writing code like String.replace( ~and it doesn't show the active parameter.~

https://github.com/elixir-tools/next-ls/assets/5053083/1541b481-344d-45f1-b167-22ee983a4944

lucacervello avatar Mar 12 '24 16:03 lucacervello

Also I had the thought, this needs to work for standard library and Erlang functions as well. Which those aren't* traced by the compiler cuz they're already compiled.

For those, I believe will need to read them from the runtime in some way (I'll leave you to figure that out)

I think we can ship a first version without that tho

Edit: typo "are" -> "aren't"

mhanberg avatar Mar 13 '24 19:03 mhanberg

Played with it and realized that I'm not sure this path forward will work.

this searched for the definition of the module/function before the cursor, but that implies the project has compiled and its in the references table.

I think want we actually want to do is extract the module and function before the cursor and then fetch the docs with Code.fetch_docs/1

that should return the function docs which will actually have a "signature" field that we can use

CleanShot 2024-03-26 at 15 10 59@2x

mhanberg avatar Mar 26 '24 19:03 mhanberg

@mhanberg I switched approach.

It works well for something like

Enum.map(list, fun)

It doesn't work for aliased or imported functions like

alias NextLS.Formatter

Formatter.format(code)

Because Code.fetch_docs doesn't find Formatter

lucacervello avatar Mar 29 '24 15:03 lucacervello

Gotcha, that should become available as I build out the "buffer environment".

I'll try this out today

mhanberg avatar Mar 29 '24 16:03 mhanberg

Gotcha, that should become available as I build out the "buffer environment".

I'll try this out today

Thank you, if you're happy with that limitation, I can cleanup the code later 👍

lucacervello avatar Mar 29 '24 16:03 lucacervello

Yeah the limitation is fine for now, it's basically already a limitation for autocomplete.

mhanberg avatar Mar 29 '24 16:03 mhanberg

Also, I think we should go ahead and make the active parameter work before merging.

I imagine you can take the ast you find and then find the parameter the cursor is inside and use that to determine the index to use.

mhanberg avatar Apr 04 '24 22:04 mhanberg

@mhanberg I added the active parameter, tests are working but I'm having trouble using it in my editor. I'll investigate more later.

lucacervello avatar Apr 09 '24 11:04 lucacervello

CleanShot 2024-04-12 at 13 19 19@2x can confirm that the active parameter seems to not be working in the editor, but i rebased on main (i just merged a big change #410 ) and it works other than that, for stdlib, deps, and project functions

mhanberg avatar Apr 12 '24 17:04 mhanberg

I think i need to make a patch to spitfire for this to work the way its currently coded.

mhanberg avatar Apr 12 '24 18:04 mhanberg

I was re reading the PR comments and I can't seem to remember what patch I needed to make to spitfire.

mhanberg avatar Apr 23 '24 12:04 mhanberg

Now spitfire has the function Spitfire.container_cursor_to_quoted, which is used to insert a __cursor__() marker in the ast where the cursor is.

I think what you can do here is use that function, create a zipper, find the cursor, then traverse up until you see the first function call, and that should be the function that should be used for signature help.

you might need to also "expand" the ast at the cursor like we do for completions to get the environment, which should help you resolve imports and aliases for that function.

mhanberg avatar May 16 '24 13:05 mhanberg

Now spitfire has the function Spitfire.container_cursor_to_quoted, which is used to insert a __cursor__() marker in the ast where the cursor is.

This could work but only for partial code like

Enum.map(

I think we also want to give SignatureHelp when the cursor is on valid code like

Enum.map([1, 2], fn n -> n + 1 end)

lucacervello avatar May 16 '24 14:05 lucacervello

Now spitfire has the function Spitfire.container_cursor_to_quoted, which is used to insert a __cursor__() marker in the ast where the cursor is.

This could work but only for partial code like

Enum.map(

I think we also want to give SignatureHelp when the cursor is on valid code like

Enum.map([1, 2], fn n -> n + 1 end)

You make it into a partial code snippet by truncating the document after the cursor position.

Basically if the cursor is the location line: 0, character: 30, you'd truncate it too look like Enum.map([1, 2], fn n -> n + and then run the following operations, which produces ast you can use

iex(2)> {:ok, ast} = Spitfire.container_cursor_to_quoted("Enum.map([1, 2], fn n -> n + ")
{:ok,
 {{:., [line: 1, column: 5],
   [
     {:__aliases__, [last: [line: 1, column: 1], line: 1, column: 1], [:Enum]},
     :map
   ]}, [closing: [line: 1, column: 45], line: 1, column: 6],
  [
    [1, 2],
    {:fn, [closing: [line: 1, column: 42], line: 1, column: 18],
     [
       {:->, [line: 1, column: 23],
        [
          [{:n, [line: 1, column: 21], nil}],
          {:+, [line: 1, column: 28],
           [
             {:n, [line: 1, column: 26], nil},
             {:__cursor__,
              [closing: [line: 1, column: 41], line: 1, column: 30], []}
           ]}
        ]}
     ]}
  ]}}
iex(3)> ast |> Macro.to_string() |> IO.puts
Enum.map([1, 2], fn n -> n + __cursor__() end)

mhanberg avatar May 16 '24 14:05 mhanberg

You make it into a partial code snippet by truncating the document after the cursor position.

Oh right, It make a lot of sense, dumb question, my bad 😅. Thank you.

I hope I have some time in the upcoming weeks to push this PR forward 🤞

lucacervello avatar May 16 '24 14:05 lucacervello

You make it into a partial code snippet by truncating the document after the cursor position.

Oh right, It make a lot of sense, dumb question, my bad 😅. Thank you.

I hope I have some time in the upcoming weeks to push this PR forward 🤞

No worries, its all volunteer work! Work on it when you have the time, energy, and interest.

mhanberg avatar May 16 '24 16:05 mhanberg