lua-language-server icon indicating copy to clipboard operation
lua-language-server copied to clipboard

Two definitions for local function variables

Open tobias-haenel opened this issue 1 year ago • 2 comments

How are you using the lua-language-server?

NeoVim

Which OS are you using?

Linux

What is the issue affecting?

Other

Expected Behaviour

Using vim.lsp.buf.definition() to go to the definition of a local function variable (assigned with the = operator), should give only a single definition at the local variable name.

Actual Behaviour

Using vim.lsp.buf.definition() to go to the definition of a local function variable (assigned with the = operator), gives two definitions on the same line. One is located at the variable name and the other is located at the beginning of the function key word.

Reproduction steps

  1. Create a lua file with the following content:
local m = function() print "hello world" end

m()
  1. Move the cursor on the m() function call
  2. Execute the neovim command :lua vim.lsp.buf.definition()

Additional Notes

No response

Log File

[DEBUG][2023-12-16 17:31:59] .../lua/vim/lsp.lua:1391	"LSP[lua_ls]"	"client.request"	1	"textDocument/definition"	{  position = {    character = 0,    line = 2  },  textDocument = {    uri = "file:///home/tobias/.config/nvim/test.lua"  }}	<function 1>	147
[DEBUG][2023-12-16 17:31:59] .../vim/lsp/rpc.lua:284	"rpc.send"	{  id = 1559,  jsonrpc = "2.0",  method = "textDocument/definition",  params = {    position = {      character = 0,      line = 2    },    textDocument = {      uri = "file:///home/tobias/.config/nvim/test.lua"    }  }}
[DEBUG][2023-12-16 17:31:59] .../vim/lsp/rpc.lua:387	"rpc.receive"	{  id = 1559,  jsonrpc = "2.0",  result = { {      originSelectionRange = {        ["end"] = {          character = 1,          line = 2        },        start = {          character = 0,          line = 2        }      },      targetRange = {        ["end"] = {          character = 7,          line = 0        },        start = {          character = 6,          line = 0        }      },      targetSelectionRange = {        ["end"] = {          character = 7,          line = 0        },        start = {          character = 6,          line = 0        }      },      targetUri = "file:///home/tobias/.config/nvim/test.lua"    }, {      originSelectionRange = {        ["end"] = {          character = 1,          line = 2        },        start = {          character = 0,          line = 2        }      },      targetRange = {        ["end"] = {          character = 44,          line = 0        },        start = {          character = 10,          line = 0        }      },      targetSelectionRange = {        ["end"] = {          character = 44,          line = 0        },        start = {          character = 10,          line = 0        }      },      targetUri = "file:///home/tobias/.config/nvim/test.lua"    } }}
[DEBUG][2023-12-16 17:32:02] .../lua/vim/lsp.lua:1391	"LSP[lua_ls]"	"client.request"	1	"textDocument/codeLens"	{  textDocument = {    uri = "file:///home/tobias/.config/nvim/test.lua"  }}	<function 1>	147
[DEBUG][2023-12-16 17:32:02] .../vim/lsp/rpc.lua:284	"rpc.send"	{  id = 1560,  jsonrpc = "2.0",  method = "textDocument/codeLens",  params = {    textDocument = {      uri = "file:///home/tobias/.config/nvim/test.lua"    }  }}
[DEBUG][2023-12-16 17:32:02] .../vim/lsp/rpc.lua:387	"rpc.receive"	{  id = 1560,  jsonrpc = "2.0"}
[DEBUG][2023-12-16 17:32:02] .../lua/vim/lsp.lua:1391	"LSP[lua_ls]"	"client.request"	1	"textDocument/documentHighlight"	{  position = {    character = 0,    line = 2  },  textDocument = {    uri = "file:///home/tobias/.config/nvim/test.lua"  }}	<function 1>	147
[DEBUG][2023-12-16 17:32:02] .../vim/lsp/rpc.lua:284	"rpc.send"	{  id = 1561,  jsonrpc = "2.0",  method = "textDocument/documentHighlight",  params = {    position = {      character = 0,      line = 2    },    textDocument = {      uri = "file:///home/tobias/.config/nvim/test.lua"    }  }}
[DEBUG][2023-12-16 17:32:02] .../vim/lsp/rpc.lua:387	"rpc.receive"	{  id = 1561,  jsonrpc = "2.0",  result = { {      kind = 3,      range = {        ["end"] = {          character = 7,          line = 0        },        start = {          character = 6,          line = 0        }      }    }, {      kind = 2,      range = {        ["end"] = {          character = 1,          line = 2        },        start = {          character = 0,          line = 2        }      }    } }}
[TRACE][2023-12-16 17:32:02] ...lsp/handlers.lua:618	"default_handler"	"textDocument/documentHighlight"	{  ctx = '{\n  bufnr = 147,\n  client_id = 1,\n  method = "textDocument/documentHighlight",\n  params = {\n    position = {\n      character = 0,\n      line = 2\n    },\n    textDocument = {\n      uri = "file:///home/tobias/.config/nvim/test.lua"\n    }\n  }\n}',  result = { {      kind = 3,      range = {        ["end"] = {          character = 7,          line = 0        },        start = {          character = 6,          line = 0        }      }    }, {      kind = 2,      range = {        ["end"] = {          character = 1,          line = 2        },        start = {          character = 0,          line = 2        }      }    } }}

tobias-haenel avatar Dec 16 '23 16:12 tobias-haenel

I have also been experiencing this. Seems very similar to this old ticket.

eanyanwu avatar Jan 15 '24 21:01 eanyanwu

For neovim users, here's a monkey-patch you can add to your config that should let you get around this until a fix comes around from the lua-language-server side:

local locations_to_items = vim.lsp.util.locations_to_items
vim.lsp.util.locations_to_items = function (locations, offset_encoding)
  local lines = {}
  local loc_i = 1
  for _, loc in ipairs(vim.deepcopy(locations)) do
    local uri = loc.uri or loc.targetUri
    local range = loc.range or loc.targetSelectionRange
    if lines[uri .. range.start.line] then -- already have a location on this line
      table.remove(locations, loc_i) -- remove from the original list
    else
      loc_i = loc_i + 1
    end
    lines[uri .. range.start.line] = true
  end

  return locations_to_items(locations, offset_encoding)
end

rish987 avatar Feb 17 '24 10:02 rish987