neovim / neovim

Vim-fork focused on extensibility and usability
https://neovim.io
Other
83.84k stars 5.73k forks source link

LSP: Network paths in Windows (`\\Mac\Home\projects\distant`) cause invalid string values with LSP servers #18909

Open chipsenkbeil opened 2 years ago

chipsenkbeil commented 2 years ago

Description

I originally filed this issue against rust-tools.nvim, but realized it affected all language servers: https://github.com/simrat39/rust-tools.nvim/issues/205.

The gist is that I'm running Windows within my Mac using Parallels and mounting a directory from my Mac onto the Windows machine.

The path is \\Mac\Home\projects\distant for my Rust project, which isn't a traditional path like C:\path\to\distant. I'm making the assumption that the path is what is causing the issue, otherwise there's some problem with the mounted directory. I can compile my code, run it, and open files within neovim for highlighting with treesitter without issue.

Error found within lsp.log

[ERROR][2022-06-08 19:55:51] .../vim/lsp/rpc.lua:420    "rpc"   "C:\\Users\\senkwich\\AppData\\Local\\nvim-data\\lsp_servers\\rust_analyzer\\rust-analyzer" "stderr"    '[ERROR rust_analyzer] Unexpected error: Failed to deserialize InitializeParams: invalid value: string "file://%5c%5cMac%5cHome%5cprojects%5cdistant%5csrc%5cbuf.rs", expected invalid domain character; {"capabilities":{"callHierarchy":{"dynamicRegistration":false},"workspace":{"symbol":{"dynamicRegistration":false,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]},"hierarchicalWorkspaceSymbolSupport":true},"workspaceFolders":true,"applyEdit":true,"workspaceEdit":{"resourceOperations":["rename","create","delete"]}},"experimental":{"serverStatusNotification":true,"snippetTextEdit":true,"codeActionGroup":true,"commands":{"commands":["rust-analyzer.runSingle","rust-analyzer.debugSingle","rust-analyzer.showReferences","rust-analyzer.gotoLocation","editor.action.triggerParameterHints"]},"ssr":true,"hoverActions":true,"hoverRange":true},"window":{"showMessage":{"messageActionItem":{"additionalPropertiesSupport":false}},"showDocument":{"support":false},"workDoneProgress":true},"textDocument":{"synchronization":{"didSave":true,"dynamicRegistration":false,"willSave":false,"willSaveWaitUntil":false},"publishDiagnostics":{"relatedInformation":true,"tagSupport":{"valueSet":[1,2]}},"completion":{"completionItem":{"deprecatedSupport":false,"documentationFormat":["markdown","plaintext"],"resolveSupport":{"properties":["documentation","detail","additionalTextEdits"]},"snippetSupport":true,"commitCharactersSupport":false,"preselectSupport":false},"dynamicRegistration":false,"completionItemKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]},"contextSupport":false},"typeDefinition":{"linkSupport":true},"rename":{"prepareSupport":true,"dynamicRegistration":false},"signatureHelp":{"signatureInformation":{"documentationFormat":["markdown","plaintext"],"parameterInformation":{"labelOffsetSupport":true},"activeParameterSupport":true},"dynamicRegistration":false},"documentSymbol":{"dynamicRegistration":false,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]},"hierarchicalDocumentSymbolSupport":true},"documentHighlight":{"dynamicRegistration":false},"declaration":{"linkSupport":true},"definition":{"linkSupport":true},"references":{"dynamicRegistration":false},"hover":{"contentFormat":["markdown","plaintext"],"dynamicRegistration":false},"codeAction":{"resolveSupport":{"properties":["edit"]},"dynamicRegistration":false,"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","Empty","QuickFix","Refactor","RefactorExtract","RefactorInline","RefactorRewrite","Source","SourceOrganizeImports","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}},"dataSupport":true},"implementation":{"linkSupport":true}}},"trace":"off","workspaceFolders":[{"uri":"file://%5c%5cMac%5cHome%5cprojects%5cdistant%5csrc%5cbuf.rs","name":"\\\\\\\\Mac\\\\Home\\\\projects\\\\distant\\\\src\\\\buf.rs"}],"rootPath":"/\\\\\\\\Mac\\\\Home\\\\projects\\\\distant\\\\src\\\\buf.rs","processId":13764,"clientInfo":{"name":"Neovim","version":"0.7.0"},"initializationOptions":{"detachedFiles":["\\\\\\\\Mac\\\\Home\\\\projects\\\\distant\\\\src\\\\buf.rs"]},"rootUri":"file://%5c%5cMac%5cHome%5cprojects%5cdistant%5csrc%5cbuf.rs"}\nFailed to deserialize InitializeParams: invalid value: string "file://%5c%5cMac%5cHome%5cprojects%5cdistant%5csrc%5cbuf.rs", expected invalid domain character; {"capabilities":{"callHierarchy":{"dynamicRegistration":false},"workspace":{"symbol":{"dynamicRegistration":false,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]},"hierarchicalWorkspaceSymbolSupport":true},"workspaceFolders":true,"applyEdit":true,"workspaceEdit":{"resourceOperations":["rename","create","delete"]}},"experimental":{"serverStatusNotification":true,"snippetTextEdit":true,"codeActionGroup":true,"commands":{"commands":["rust-analyzer.runSingle","rust-analyzer.debugSingle","rust-analyzer.showReferences","rust-analyzer.gotoLocation","editor.action.triggerParameterHints"]},"ssr":true,"hoverActions":true,"hoverRange":true},"window":{"showMessage":{"messageActionItem":{"additionalPropertiesSupport":false}},"showDocument":{"support":false},"workDoneProgress":true},"textDocument":{"synchronization":{"didSave":true,"dynamicRegistration":false,"willSave":false,"willSaveWaitUntil":false},"publishDiagnostics":{"relatedInformation":true,"tagSupport":{"valueSet":[1,2]}},"completion":{"completionItem":{"deprecatedSupport":false,"documentationFormat":["markdown","plaintext"],"resolveSupport":{"properties":["documentation","detail","additionalTextEdits"]},"snippetSupport":true,"commitCharactersSupport":false,"preselectSupport":false},"dynamicRegistration":false,"completionItemKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25]},"contextSupport":false},"typeDefinition":{"linkSupport":true},"rename":{"prepareSupport":true,"dynamicRegistration":false},"signatureHelp":{"signatureInformation":{"documentationFormat":["markdown","plaintext"],"parameterInformation":{"labelOffsetSupport":true},"activeParameterSupport":true},"dynamicRegistration":false},"documentSymbol":{"dynamicRegistration":false,"symbolKind":{"valueSet":[1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26]},"hierarchicalDocumentSymbolSupport":true},"documentHighlight":{"dynamicRegistration":false},"declaration":{"linkSupport":true},"definition":{"linkSupport":true},"references":{"dynamicRegistration":false},"hover":{"contentFormat":["markdown","plaintext"],"dynamicRegistration":false},"codeAction":{"resolveSupport":{"properties":["edit"]},"dynamicRegistration":false,"codeActionLiteralSupport":{"codeActionKind":{"valueSet":["","Empty","QuickFix","Refactor","RefactorExtract","RefactorInline","RefactorRewrite","Source","SourceOrganizeImports","quickfix","refactor","refactor.extract","refactor.inline","refactor.rewrite","source","source.organizeImports"]}},"dataSupport":true},"implementation":{"linkSupport":true}}},"trace":"off","workspaceFolders":[{"uri":"file://%5c%5cMac%5cHome%5cprojects%5cdistant%5csrc%5cbuf.rs","name":"\\\\\\\\Mac\\\\Home\\\\projects\\\\distant\\\\src\\\\buf.rs"}],"rootPath":"/\\\\\\\\Mac\\\\Home\\\\projects\\\\distant\\\\src\\\\buf.rs","processId":13764,"clientInfo":{"name":"Neovim","version":"0.7.0"},"initializationOptions":{"detachedFiles":["\\\\\\\\Mac\\\\Home\\\\projects\\\\distant\\\\src\\\\buf.rs"]},"rootUri":"file://%5c%5cMac%5cHome%5cprojects%5cdistant%5csrc%5cbuf.rs"}\n'

Seems like language servers, at least rust-analyzer and sumneko_lua, don't like the path and give this error:

Unexpected error: Failed to deserialize InitializeParams: invalid value: string "file://%5c%5cMac%5cHome%5cprojects%5cdistant%5csrc%5cbuf.rs", expected invalid domain character;

Mac

Attaches to the buffer without issue.

image

Windows (failing)

Seems to detect that a server is available, but does not attach. Also there are extra fields in :LspInfo than I was expecting.

image

Windows (succeeding)

If I clone the repository within my VM, this works without issue.

image

Neovim version

NVIM v0.7.0
Build type: RelWithDebInfo
LuaJIT 2.1.0-beta3
Compiled by runneradmin@fv-az320-113

Features: -acl +iconv +tui
See ":help feature-compile"

   system vimrc file: "$VIM\sysinit.vim"
  fall-back for $VIM: "C:/Program Files/nvim/share/nvim"

Run :checkhealth for more info

Nvim-lspconfig version

No response

Operating system and version

Windows 11

Affected language servers

all

Steps to reproduce

  1. Create a Windows image using Parallels on Mac M1
  2. Mount a Rust project from the Mac to within the Windows image
  3. Open a file using neovim and observe that the lsp client does not attach

With a minimal config used, the client exits

Client 1 quit with exit code 101 and signal 0

Actual behavior

LSP client is not created and does not attach to the buffer

Expected behavior

LSP client starts and properly attaches to the buffer.

Minimal config

local on_windows = vim.loop.os_uname().version:match 'Windows'

local function join_paths(...)
    local path_sep = on_windows and '\\' or '/'
    local result = table.concat({ ... }, path_sep)
    return result
end

vim.cmd [[set runtimepath=$VIMRUNTIME]]

local temp_dir = vim.loop.os_getenv 'TEMP' or '/tmp'

vim.cmd('set packpath=' .. join_paths(temp_dir, 'nvim', 'site'))

local package_root = join_paths(temp_dir, 'nvim', 'site', 'pack')
local install_path = join_paths(package_root, 'packer', 'start', 'packer.nvim')
local compile_path = join_paths(install_path, 'plugin', 'packer_compiled.lua')

local function load_plugins()
    require('packer').startup({
        function(use)
            use {
                { 'wbthomason/packer.nvim' },
                { 'neovim/nvim-lspconfig' },
                {
                    'simrat39/rust-tools.nvim',
                    config = function()
                        require('rust-tools').setup({
                            server = {
                                cmd = { vim.fn.stdpath('data') .. '\\lsp_servers\\rust_analyzer\\rust-analyzer' }
                            }
                        })
                    end
                }
            }
        end,
        config = {
            package_root = package_root,
            compile_path = compile_path,
        },
    })
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_option(...)
            vim.api.nvim_buf_set_option(bufnr, ...)
        end

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

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

    -- Add the server that troubles you here
    local name = 'pyright'
    local cmd = { 'pyright-langserver', '--stdio' } -- needed for elixirls, omnisharp, sumneko_lua
    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

LSP log

https://gist.github.com/chipsenkbeil/964321062669031f4fa5ec33c91e427a

chipsenkbeil commented 2 years ago

Now that I know what the error is, this might be more relevant to file against neovim itself? I'm not sure what the fix is, unless there's something neovim or nvim-lspconfig is doing to garble the path before sending it to the LSP server.

justinmk commented 2 years ago

this might be more relevant to file against neovim itself?

I think so.

chipsenkbeil commented 2 years ago

I'm guessing that the mounted path is actually a network path on Windows. \\Mac\Home is a specific directory mounted into my VM using Windows networking. So my guess is that any network path is going to fail with neovim. I tested both rls and rust-analyzer on VS Code using my network path and they work, so it is possible to have a language server work with a network path! 😄

image
FrancescoLuzzi commented 1 year ago

nvim version 0.9.2 I've encountered the same issue on windows 10 while using nvim-tree since it always resolves the filepath as UNC