neovim / nvim-lspconfig

Quickstart configs for Nvim LSP
Apache License 2.0
10.62k stars 2.08k forks source link

denols: broken code navigation once inside a remote module #1332

Closed marcelbeumer closed 2 years ago

marcelbeumer commented 3 years ago

Description

See detailed reproduction steps below. When navigation into a remote module with lua vim.lsp.buf.definition() nvim starts showing errors with shape of: An unexpected identifier (deno://<url of remote modue>).

Neovim version

NVIM v0.6.0-dev+470-ga1e8199ff Build type: Release LuaJIT 2.1.0-beta3

Nvim-lspconfig version

7f902f9

Operating system and version

macOS 11.6

Affected language servers

denols

Steps to reproduce

  1. git clone https://github.com/marcelbeumer/deno-oak-test
  2. cd deno-oak-test
  3. deno cache server.ts
  4. nvim -nu minimal.lua
  5. :e server.ts
  6. 2ggw (to go to Application)
  7. gd (to lua vim.lsp.buf.definition())
  8. <C-K> (to lua vim.lsp.buf.signature_help() on the word Application)

Error now shows: denols: -32602: An unexpected specifier (deno://https/deno.land/x/oak%40v9.0.1/applicati on.ts) was provided. See screenshot

Screen Shot 2021-10-21 at 13 13 16

Actual behavior

Error when doing code navigaiton inside external module

Expected behavior

Code navigaiton inside external module works. I assume the deno language server is capable of doing it as the official vscode extension does work well on this example repo.

Minimal config

vim.cmd [[set runtimepath=$VIMRUNTIME]]
vim.cmd [[set packpath=/tmp/nvim/site]]

local package_root = '/tmp/nvim/site/pack'
local install_path = package_root .. '/packer/start/packer.nvim'

local function load_plugins()
  require('packer').startup {
    {
      'wbthomason/packer.nvim',
      'neovim/nvim-lspconfig',
    },
    config = {
      package_root = package_root,
      compile_path = install_path .. '/plugin/packer_compiled.lua',
    },
  }
end

_G.load_config = function()
  vim.lsp.set_log_level 'trace'
  if vim.fn.has 'nvim-0.5.1' == 1 then
    require('vim.lsp.log').set_format_func(vim.inspect)
  end
  local nvim_lsp = require 'lspconfig'
  local on_attach = function(_, bufnr)
    local function buf_set_keymap(...)
      vim.api.nvim_buf_set_keymap(bufnr, ...)
    end
    local function buf_set_option(...)
      vim.api.nvim_buf_set_option(bufnr, ...)
    end

    buf_set_option('omnifunc', 'v:lua.vim.lsp.omnifunc')

    -- Mappings.
    local opts = { noremap = true, silent = true }
    buf_set_keymap('n', 'gD', '<Cmd>lua vim.lsp.buf.declaration()<CR>', opts)
    buf_set_keymap('n', 'gd', '<Cmd>lua vim.lsp.buf.definition()<CR>', opts)
    buf_set_keymap('n', 'K', '<Cmd>lua vim.lsp.buf.hover()<CR>', opts)
    buf_set_keymap('n', 'gi', '<cmd>lua vim.lsp.buf.implementation()<CR>', opts)
    buf_set_keymap('n', '<C-k>', '<cmd>lua vim.lsp.buf.signature_help()<CR>', opts)
    buf_set_keymap('n', '<space>wa', '<cmd>lua vim.lsp.buf.add_workspace_folder()<CR>', opts)
    buf_set_keymap('n', '<space>wr', '<cmd>lua vim.lsp.buf.remove_workspace_folder()<CR>', opts)
    buf_set_keymap('n', '<space>wl', '<cmd>lua print(vim.inspect(vim.lsp.buf.list_workspace_folders()))<CR>', opts)
    buf_set_keymap('n', '<space>D', '<cmd>lua vim.lsp.buf.type_definition()<CR>', opts)
    buf_set_keymap('n', '<space>rn', '<cmd>lua vim.lsp.buf.rename()<CR>', opts)
    buf_set_keymap('n', 'gr', '<cmd>lua vim.lsp.buf.references()<CR>', opts)
    buf_set_keymap('n', '<space>e', '<cmd>lua vim.lsp.diagnostic.show_line_diagnostics()<CR>', opts)
    buf_set_keymap('n', '[d', '<cmd>lua vim.lsp.diagnostic.goto_prev()<CR>', opts)
    buf_set_keymap('n', ']d', '<cmd>lua vim.lsp.diagnostic.goto_next()<CR>', opts)
    buf_set_keymap('n', '<space>q', '<cmd>lua vim.lsp.diagnostic.set_loclist()<CR>', opts)
  end

  -- Add the server that troubles you here
  local name = 'denols'
  if not name then
    print 'You have not defined a server name, please edit minimal_init.lua'
  end
  if not nvim_lsp[name].document_config.default_config.cmd and not cmd then
    print [[You have not defined a server default cmd for a server
      that requires it please edit minimal_init.lua]]
  end

  nvim_lsp[name].setup {
    cmd = cmd,
    on_attach = on_attach,
  }

  print [[You can find your log at $HOME/.cache/nvim/lsp.log. Please paste in a github issue under a details tag as described in the issue template.]]
end

if vim.fn.isdirectory(install_path) == 0 then
  vim.fn.system { 'git', 'clone', 'https://github.com/wbthomason/packer.nvim', install_path }
  load_plugins()
  require('packer').sync()
  vim.cmd [[autocmd User PackerComplete ++once lua load_config()]]
else
  load_plugins()
  require('packer').sync()
  _G.load_config()
end

Health check

lspconfig: require("lspconfig.health").check()

LSP log

https://gist.github.com/marcelbeumer/e1d39a132d64bd870942a71c26f88726

zakinomiya commented 2 years ago

@marcelbeumer I have the same problem and am now taking a look at the sources.

I reckon the problem is that denols only accepts URIs whose form is in deno:/~ or deno:asset/ (in case of builtin libraries) but neovim builtin lsp only sends URIs in the form of deno://~.

nvim-lspconfig addresses this difference by defining util functions to convert URIs of deno style and neovim style back and forth before and after each request, but when calling the neovim lsp function(vim.lsp.buf.definition) directly, it sends deno://~ and therefore denols doesn't know where the code is, so responds back the error you mentioned above.

Calling :DenolsDefinition works in my environment, so I guees it should be fine if you bind the key(gd) to call :DenolsDefinition when using denols (seems a bit ugly though) I am not really familiar with the internal workings of neovim and nvim-lspconfig, so still figuring out the way to fix this. Maybe I will issue a PR. Just FYI 👍

mjlbach commented 2 years ago

I think it might be the case that we need to split the deno config out into it's own plugin, and override the definition handlers to use the appropriate URIs. I don't want to add explicit handling of deno URIs to the neovim core handlers.

mjlbach commented 2 years ago

You can test #1638