Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Getting "failed get highlight parameter 0 0" #51

Closed
henrique-ezcater opened this issue Jul 25, 2021 · 14 comments
Closed

Getting "failed get highlight parameter 0 0" #51

henrique-ezcater opened this issue Jul 25, 2021 · 14 comments

Comments

@henrique-ezcater
Copy link

Hello!

I am trying get highlight of the parameters in the pop-up, but as soon as I type ( to provide the parameters I get the error failed get highlight parameter 0 0.
This is using pyright and the following python code can be used to reproduce it:

import os

def bla(a: int, b: int, c: int, d: int):
    print(f"a #{a}, b #{b}, c #{c}, d #{d}")

def x(a):
    print("hey! %s" % a)
    bla(

Here is a screenshot:

image

Here is the debug output:

שׁ  |1: insert enter
שׁ  |1: insert enter
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: signature triggered
שׁ  |1: sig result |2: {
  activeParameter = 4,
  activeSignature = 0,
  signatures = { {
      activeParameter = 0,
      label = "(a: int, b: int, c: int, d: int) -> None",
      parameters = { {
          label = { 1, 7 }
        }, {
          label = { 9, 15 }
        }, {
          label = { 17, 23 }
        }, {
          label = { 25, 31 }
        } }
    } }
}
 |3: {
  border = "single",
  check_client_handlers = true,
  check_pumvisible = true,
  line_to_cursor = "    bla(",
  trigger_from_lsp_sig = true,
  triggered_chars = { "(", ",", ")" }
}

שׁ  |1: no next param
שׁ  |1: md lines |2: { "```python", "(a: int, b: int, c: int, d: int) -> None", "```" }

שׁ  |1: label: |2: (a: int, b: int, c: int, d: int) -> None |3: 0 |4: 1 |5: 4 |6: {
  activeParameter = 0,
  label = "(a: int, b: int, c: int, d: int) -> None",
  parameters = { {
      label = { 1, 7 }
    }, {
      label = { 9, 15 }
    }, {
      label = { 17, 23 }
    }, {
      label = { 25, 31 }
    } }
}

שׁ  |1: win config |2: {
  border = { "╭", "─", "╮", "│", "╯", "─", "╰", "│" },
  check_client_handlers = true,
  check_pumvisible = true,
  close_events = { "BufHidden", "InsertLeavePre" },
  focus_id = "textDocument/signatureHelplsp_signature795",
  line_to_cursor = "    bla(",
  max_height = 12,
  max_width = 120,
  offset_x = -1,
  stylize_markdown = true,
  trigger_from_lsp_sig = true,
  triggered_chars = { "(", ",", ")" },
  zindex = 200
}

שׁ  |1: extmark |2: 0 |3: 0
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start
שׁ  |1: timer start

From a quick glance at the code, I couldn't figure out the issue. I got here:

local nextParameter = signature.parameters[activeParameter + 1]

Can't really tell why that is returning nil? Or perhaps I am following the code incorrectly. My lua skillz aren't that great.

Any ideas?

Thanks!

@tiagovla
Copy link

I have the same issue.

@ray-x
Copy link
Owner

ray-x commented Jul 26, 2021

What LSP you are using?

@tiagovla
Copy link

In my case pyright with built in neovim LSP.

@henrique-ezcater
Copy link
Author

henrique-ezcater commented Jul 26, 2021

Same here, using pyright.
I also tested in ruby files with solargraph and have the same issue.

@ray-x
Copy link
Owner

ray-x commented Jul 26, 2021

I think this issue is caused by pyright.

The log you posted:

{
  activeParameter = 4,
  activeSignature = 0,
  signatures = { {
      activeParameter = 0,
      label = "(a: int, b: int, c: int, d: int) -> None",
      parameters = { {
          label = { 1, 7 }
        }, {
          label = { 9, 15 }
        }, {
          label = { 17, 23 }
        }, {
          label = { 25, 31 }
        } }
    } }
}

Check this:

  activeParameter = 4,
  activeSignature = 0,

activeSignature=0, this means it is Zero-based numbering. But activeParameter=4. This is incorrect. I think what pyright means is activeParameter=3

@henrique-ezcater
Copy link
Author

Isn't the activeParameter outside of the signatures the count of parameters? I think that the correct would be for the code to be using the internal activeParameter for indexing then, no?

@henrique-ezcater
Copy link
Author

I am thinking that perhaps this here needs to be changed:

local activeParameter = result.activeParameter or signature.active_parameter
or signature.activeParameter

The code there perhaps should read:

  local activeParameter = signature.activeParameter + 1

@ray-x
Copy link
Owner

ray-x commented Jul 26, 2021

Different LSP sending activeParameter back in slight different way and that is why

local activeParameter = result.activeParameter or signature.active_parameter 
                             or signature.activeParameter

But activeParameter=4 is incorrect. All LSP activeParameter is 0 based.

@henrique-ezcater
Copy link
Author

I had success replacing that line with:

  local activeParameter = signature.activeParameter or signature.active_parameter or result.activeParameter

It works now with pyright.

With solargraph the issue seems to be on the solargraph side as the response from solargraph does not contain the signatures object. I will open an issue with them.

@henrique-ezcater
Copy link
Author

I just checked the spec for signatureHelp, here is that it says:

	/**
	 * The index of the active parameter.
	 *
	 * If provided, this is used in place of `SignatureHelp.activeParameter`.
	 *
	 * @since 3.16.0
	 */
	activeParameter?: uinteger;

So the code should really read the way I pasted in my previous reply:

  local activeParameter = signature.activeParameter or signature.active_parameter or result.activeParameter

The activeParameter inside the signature object has precedence over the one outside of it in the result object. Does that make sense?

Here is the link to the documentation: https://microsoft.github.io/language-server-protocol/specifications/specification-3-17/#signatureHelp

@ray-x
Copy link
Owner

ray-x commented Jul 26, 2021

I do not know why the designer decided to send an out of range index to indicate it to be 0 in 3.17 . What a nice pitfall!

I pushed my changes.

@henrique-ezcater
Copy link
Author

I checked the changes there, and I think you should still change the order for setting the activeParameter as I mentioned above. The signature.activeParameter should have precedence over result.activeParameter.
With your change, if you have a function with let's say, 3 arguments, and you try to add a 4th argument to it, the first argument gets re-highlighted:

image

@ray-x
Copy link
Owner

ray-x commented Jul 26, 2021

@henrique-ezcater
I strictly adhere to spec of 3.17

activeParameter:
* If omitted or the value lies outside the range of signatures[activeSignature].parameters
* defaults to 0 if the active signature has parameters.

And I also override activeParameter with signature.activeParameter if it present:

  if result.activeParameter ~= nil and result.activeParameter < #signature.parameters then
    activeParameter = result.activeParameter
  else
    activeParameter = 0
  end

  if signature.activeParameter ~= nil then
    activeParameter = signature.activeParameter
  end

I am avoiding doing hacky things for a specific LSP. I can do a special fix for pyright when I know the exact behaviour so I can know the fix will not break other LSP.

@henrique-ezcater
Copy link
Author

Yeah, I've checked the code again and I noticed I had missed part of the logic. Seems like this is in accordance to the spec.
Thanks for the fix!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants