neovim / nvim-lspconfig

Quickstart configs for Nvim LSP
Apache License 2.0
10.32k stars 2.05k forks source link

LSP: filetype sent as language id breaks sourcekit-lsp #3264

Open achilleas-k opened 1 month ago

achilleas-k commented 1 month ago

Problem

I'm having trouble getting the lsp to work with objective c files and sourcekit-lsp. The filetype is detected as objc, but it seems sourcekit-lsp calls it objective-c. Adding objc to the filetypes in the config enables the connection with the lsp, but no lsp-based features actually work (completion, inline warnings, etc).

I suspect the issue might be that sourcekit-lsp expects the filetype to be objective-c and neovim is passing objc.

Steps to reproduce using "nvim -u minimal_init.lua"

Here's a minimal config:

-- init.lua  
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"  
if not vim.loop.fs_stat(lazypath) then  
   vim.fn.system({  
       "git",  
       "clone",  
       "--filter=blob:none",  
       "https://github.com/folke/lazy.nvim.git",  
       "--branch=stable",  
       lazypath  
   })  
end  
vim.opt.rtp:prepend(lazypath)  
require("lazy").setup({  
   "neovim/nvim-lspconfig",  
   config = function()  
       local lspconfig = require('lspconfig')  
       lspconfig.sourcekit.setup {  
           capabilities = {  
               workspace = {  
                   didChangeWatchedFiles = {  
                       dynamicRegistration = true,  
                   },  
               },  
           },  
       }  

       vim.api.nvim_create_autocmd('LspAttach', {  
           desc = "LSP Actions",  
           callback = function(args)  
               vim.keymap.set("n", "K", vim.lsp.buf.hover, {noremap = true, silent = true})  
               vim.keymap.set("n", "gd", vim.lsp.buf.definition, {noremap = true, silent = true})  
           end,  
       })  
   end,  
})

and launching nvim with that config on a .m objc file shows the following :LspInfo

Language client log: /Users/achilleas/.local/state/nvim-debug/lsp.log
Detected filetype:   objc

0 client(s) attached to this buffer:

Configured servers list: sourcekit

Forcing the filetype detection by adding

filetypes = { 'swift', 'c', 'cpp', 'objective-c', 'objc', 'objective-cpp' },

makes it appear like it's working:

Language client log: /Users/achilleas/.local/state/nvim-debug/lsp.log  
Detected filetype:   objc  

1 client(s) attached to this buffer:  

Client: sourcekit (id: 1, bufnr: [1])  
  filetypes:       swift, c, cpp, objective-c, objc, objective-cpp  
  autostart:       true  
  root directory:  /Users/achilleas/projects/nvim-debug  
  cmd:             /usr/bin/sourcekit-lsp  

Configured servers list: sourcekit

but none of the lsp functionality actually works.

The included log file is from after the filetypes line was added.

Expected behavior

Completion and checks from sourcekit-lsp to work with objective c files.

Neovim version (nvim -v)

NVIM v0.10.1

Language server name/version

sourcekit-lsp (part of Xcode 15.4)

Operating system/version

macOS Sonoma 14.5

Log file

https://gist.github.com/achilleas-k/fe2409175dc0be879b729ccf7e7ebdeb

clason commented 1 month ago

Filetypes are purely a Neovim thing; the server cares not. The issue is usually with project detection; sourcekit is finicky in this regard (read the documentation).

In any case, this issue belongs at nvim-lspconfig (on mobile so can't transfer it now).

achilleas-k commented 1 month ago

In any case, this issue belongs at nvim-lspconfig (on mobile so can't transfer it now).

Thanks. I was going to post the issue there but the warning in the README made me consider this might be an LSP client issue.

achilleas-k commented 1 month ago

Filetypes are purely a Neovim thing; the server cares not.

The reason I suspected it might be a language ID issue is that the sourcekit-lsp can handle multiple types. Poking around the lsp sources, I see a few places where behaviour is switched based on the language:

I have to assume that the language ID that neovim sends through to the lsp must play a role here (and there's no language matching objc).

clason commented 1 month ago

It does not send any language ID at all; that is simply not part of the protocol.

achilleas-k commented 1 month ago

Right. Thanks for clarifying.

achilleas-k commented 1 month ago

It does not send any language ID at all; that is simply not part of the protocol.

Sorry, I don't know much about the protocol but based on all the references I saw when researching this issue, I wanted to figure out why I thought what I did.

So I went looking and found the spec for the TextDocumentItem, which includes a languageId and the paragraph below that says:

Text documents have a language identifier to identify a document on the server side when it handles more than one language to avoid re-interpreting the file extension. If a document refers to one of the programming languages listed below it is recommended that clients use those ids. ... Objective-C objective-c

Then based on the fact that the lsp client in neovim just uses the filetype as the language ID, I added the following to my config:

lspconfig.sourcekit.setup {
    filetypes = { 'swift', 'c', 'cpp', 'objective-c', 'objc', 'objective-cpp' },
    get_language_id = function(_, ftype)
        if ftype == "objc" then
            return "objective-c"
        end
        return ftype
    end,
    ...
}

and now the lsp works.

Now I'm happy that my issue was solved, but this tells me that, based on the spec, the lsp client in neovim should be replacing objc with objective-c when talking to the server.

Assuming it does send a language id and I'm not misinterpreting everything above.

clason commented 1 month ago

You learn something new every day. Sorry for giving you the runaround!

achilleas-k commented 1 month ago

No worries. It was equally educational for me too :)

mfussenegger commented 1 month ago

Moved it again to lspconfig because the mapping needs to be added there. Similar to https://github.com/neovim/nvim-lspconfig/blob/652386deae739e38fa1bcf2f06e3e7de9b3436ba/lua/lspconfig/server_configurations/ocamllsp.lua#L12