nvim-lspconfig icon indicating copy to clipboard operation
nvim-lspconfig copied to clipboard

LSP: filetype sent as language id breaks sourcekit-lsp

Open achilleas-k opened this issue 1 year ago • 9 comments
trafficstars

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

achilleas-k avatar Aug 06 '24 19:08 achilleas-k

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).

clason avatar Aug 06 '24 19:08 clason

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 avatar Aug 06 '24 19:08 achilleas-k

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:

  • https://github.com/swiftlang/sourcekit-lsp/blob/ae152de1bc6c715ce9f5aa1b257bda2de71743a0/Sources/LanguageServerProtocol/SupportTypes/Language.swift#L23
  • https://github.com/swiftlang/sourcekit-lsp/blob/ae152de1bc6c715ce9f5aa1b257bda2de71743a0/Sources/SourceKitLSP/LanguageServerType.swift#L22

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).

achilleas-k avatar Aug 06 '24 19:08 achilleas-k

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

clason avatar Aug 06 '24 19:08 clason

Right. Thanks for clarifying.

achilleas-k avatar Aug 06 '24 20:08 achilleas-k

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.

achilleas-k avatar Aug 06 '24 20:08 achilleas-k

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

clason avatar Aug 06 '24 22:08 clason

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

achilleas-k avatar Aug 07 '24 12:08 achilleas-k

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

mfussenegger avatar Aug 09 '24 08:08 mfussenegger

Closed by https://github.com/neovim/nvim-lspconfig/pull/3301

justinmk avatar May 04 '25 21:05 justinmk