aboutsummaryrefslogtreecommitdiffstats
path: root/lua/pi/lsp/init.lua
blob: ebc8fabfc8b251f9601cd044cb916f34f1fb48b4 (plain)
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
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
return {
  setup = function(ops)
    ops = vim.tbl_deep_extend("force", require "pi.lsp.default", ops)

    -- Configure LSP border for native LSP
    local orig_open_floating_preview = vim.lsp.util.open_floating_preview
    vim.lsp.util.open_floating_preview = function(contents, syntax, opts, ...)
      opts = opts or {}
      opts.border = opts.border or "single"
      return orig_open_floating_preview(contents, syntax, opts, ...)
    end
    
    for server, options in pairs(ops.servers) do
      if options.enable == true then
        local ok, definition = pcall(require, "pi.lsp.servers." .. server)
        local server_options
        if not ok then
          server_options = ops.default_options(options)
        else
          server_options = definition(options)
        end
        
        -- Setup the server with native LSP
        local client_config = vim.tbl_extend("force", {
          name = server,
          cmd = server_options.cmd or ops.get_server_cmd(server),
          root_dir = server_options.root_dir or ops.get_default_root_dir(),
          settings = server_options.settings,
          init_options = server_options.init_options,
          on_attach = server_options.on_attach,
          capabilities = server_options.capabilities,
          filetypes = server_options.filetypes,
        }, server_options)
        
        -- Auto-start LSP for appropriate filetypes
        if client_config.filetypes then
          vim.api.nvim_create_autocmd("FileType", {
            pattern = client_config.filetypes,
            callback = function(ev)
              -- Only start if no client of this type is already attached
              local clients = vim.lsp.get_clients({ bufnr = ev.buf, name = server })
              if #clients == 0 then
                -- Create a copy of config for this buffer
                local buf_config = vim.deepcopy(client_config)
                if buf_config.root_dir and type(buf_config.root_dir) == "function" then
                  buf_config.root_dir = buf_config.root_dir(vim.api.nvim_buf_get_name(ev.buf))
                end
                vim.lsp.start(buf_config, {
                  bufnr = ev.buf,
                })
              end
            end,
          })
        end
      end
    end

    -- TODO: implement null ls with options
    require "pi.lsp.null-ls"

    local servers = {}
    for server, options in pairs(ops.servers) do
      table.insert(servers, string.format("%s <%s>", server, options.enable))
    end

    -- TODO: create an auto command that on write of the configuration, calls again the setup and restart the server if it's up.
    -- can get the client by name of the file

    vim.api.nvim_create_user_command("PiLSP", function()
      vim.ui.select(servers, { prompt = "LSP Servers" }, function(server)
        if server == nil then
          return
        end

        server = string.match(server, "^(.+) <")
        local path = string.format("%s/lua/pi/lsp/servers/%s.lua", vim.fn.stdpath "config", server)
        if vim.fn.filereadable(path) == 0 then
          local create = vim.fn.confirm("Server Does Not exist. Create new server?", "&Yes\n&No\n&Cancel")
          if create ~= 1 then
            return
          end
        end

        local uri = vim.uri_from_fname(path)
        local buffer = vim.uri_to_bufnr(uri)

        vim.api.nvim_win_set_buf(0, buffer)
      end)
    end, {})
  end,
}