1   =================================================================================
2   MASON AND LSPCONFIG                                             nixCats.LSPs
3                                                             nixCats.LSPs.mason
4   
5   This is a method you may use to make sure mason only tries to download stuff
6   when you did not install Neovim via nixCats
7   
8   It functions the same as what kickstart.nvim does for its mason setup.
9   However, when loaded via Nix,
10  it skips mason and passes them straight to nvim-lspconfig
11  
12  When installing via paq-nvim, install mason via paq-nvim. Then wherever you set up
13  mason, do this.
14  The stuff added to servers table is what is passed to lspconfig/mason
15  
16  
17    if nixCats('neonixdev') then
18      -- NOTE: Lazydev will make your Lua LSP stronger for Neovim config
19      -- NOTE: we are also using this as an opportunity to show you how to lazy load plugins!
20      -- This plugin was added to the optionalPlugins section of the main flake.nix of this repo.
21      -- Thus, it is not loaded and must be packadded.
22      vim.api.nvim_create_autocmd('FileType', {
23        group = vim.api.nvim_create_augroup('nixCats-lazydev', { clear = true }),
24        pattern = { 'lua' },
25        callback = function(event)
26          -- NOTE: Use `:nixCats pawsible` to see the names of all plugins downloaded via Nix for packad.
27          vim.cmd.packadd('lazydev.nvim')
28          require('lazydev').setup({
29            library = {
30            --   -- See the configuration section for more details
31            --   -- Load luvit types when the `vim.uv` word is found
32            --   -- { path = "luvit-meta/library", words = { "vim%.uv" } },
33              -- adds type hints for nixCats global
34              { path = require('nixCats').nixCatsPath .. '/lua', words = { "nixCats" } },
35            },
36          })
37        end
38      })
39      -- NOTE: use BirdeeHub/lze to manage the autocommands for you if the above seems tedious.
40      -- Or, use the wrapper for lazy.nvim included in the luaUtils template.
41      -- NOTE: AFTER DIRECTORIES WILL NOT BE SOURCED BY PACKADD!!!!!
42      -- this must be done by you manually if,
43      -- for example, you wanted to lazy load nvim-cmp sources
44  
45      servers.lua_ls = {
46        settings = {
47          Lua = {
48            formatters = {
49              ignoreComments = true,
50            },
51            signatureHelp = { enabled = true },
52            diagnostics = {
53              globals = { 'nixCats' },
54              disable = { 'missing-fields' },
55            },
56          },
57          telemetry = { enabled = false },
58        },
59        filetypes = { 'lua' },
60      }
61    if require('nixCatsUtils').isNixCats then
62      servers.nixd = {
63        settings = {
64          nixd = {
65            nixpkgs = {
66              -- nixd requires some configuration in flake based configs.
67              -- luckily, the nixCats plugin is here to pass whatever we need!
68              -- we passed this in via the `extra` table in our packageDefinitions
69              -- for additional configuration options, refer to:
70              -- https://github.com/nix-community/nixd/blob/main/nixd/docs/configuration.md
71              expr = [[import (builtins.getFlake "]] .. nixCats.extra("nixdExtras.nixpkgs") .. [[") { }   ]],
72            },
73            formatting = {
74              command = { "nixfmt" }
75            },
76            diagnostic = {
77              suppress = {
78                "sema-escaping-with"
79              }
80            }
81          }
82        }
83      }
84      -- If you integrated with your system flake,
85      -- you should pass inputs.self as nixdExtras.flake-path
86      -- that way it will ALWAYS work, regardless
87      -- of where your config actually was.
88  
89      -- If you are using a standalone flake, but installed it in your system
90      -- config, you may use override to add these values as well.
91      -- for more info on that, cd to an empty directory and run:
92      -- nix flake init -t github:BirdeeHub/nixCats-nvim#overriding
93      -- for a walkthrough of useage.
94  
95      -- otherwise flake-path could be an absolute path to your system flake, or nil or false
96      if nixCats.extra("nixdExtras.flake-path") then
97        local flakePath = nixCats.extra("nixdExtras.flake-path")
98        if nixCats.extra("nixdExtras.systemCFGname") then
99          -- (builtins.getFlake "<path_to_system_flake>").nixosConfigurations."<name>".options
100         servers.nixd.settings.nixd.options.nixos = {
101           expr = [[(builtins.getFlake "]] .. flakePath ..  [[").nixosConfigurations."]] ..
102             nixCats.extra("nixdExtras.systemCFGname") .. [[".options]]
103         }
104       end
105       if nixCats.extra("nixdExtras.homeCFGname") then
106         -- (builtins.getFlake "<path_to_system_flake>").homeConfigurations."<name>".options
107         servers.nixd.settings.nixd.options["home-manager"] = {
108           expr = [[(builtins.getFlake "]] .. flakePath .. [[").homeConfigurations."]]
109             .. nixCats.extra("nixdExtras.homeCFGname") .. [[".options]]
110         }
111       end
112     end
113   else
114     servers.rnix = {}
115     servers.nil_ls = {}
116   end
117 
118   end
119 
120   if not require('nixCatsUtils').isNixCats and nixCats('lspDebugMode') then
121     vim.lsp.set_log_level("debug")
122   end
123 
124   -- This is this flake's version of what kickstarter has set up for mason handlers.
125   -- This is a convenience function that calls lspconfig on the LSPs we downloaded via nix
126   -- This will not download your LSP --- Nix does that.
127 
128   --  Add any additional override configuration in the following tables. They will be passed to
129   --  the `settings` field of the server config. You must look up that documentation yourself.
130   --  All of them are listed in https://github.com/neovim/nvim-lspconfig/blob/master/doc/configs.md
131   --
132   --  If you want to override the default filetypes that your language server will attach to you can
133   --  define the property 'filetypes' to the map in question.
134   --  You may do the same thing with cmd
135 
136   -- servers.clangd = {}
137   -- servers.gopls = {}
138   -- servers.pyright = {}
139   -- servers.rust_analyzer = {}
140   -- servers.tsserver = {}
141   -- servers.html = { filetypes = { 'html', 'twig', 'hbs'} }
142 
143 
144   -- If you were to comment out this autocommand
145   -- and instead pass the on attach function directly to
146   -- nvim-lspconfig, it would do the same thing.
147   vim.api.nvim_create_autocmd('LspAttach', {
148     group = vim.api.nvim_create_augroup('nixCats-lsp-attach', { clear = true }),
149     callback = function(event)
150       require('myLuaConf.LSPs.caps-on_attach').on_attach(vim.lsp.get_client_by_id(event.data.client_id), event.buf)
151     end
152   })
153   if require('nixCatsUtils').isNixCats then
154     for server_name, cfg in pairs(servers) do
155       require('lspconfig')[server_name].setup({
156         capabilities = require('myLuaConf.LSPs.caps-on_attach').get_capabilities(server_name),
157         -- this line is interchangeable with the above LspAttach autocommand
158         -- on_attach = require('myLuaConf.LSPs.caps-on_attach').on_attach,
159         settings = (cfg or {}).settings,
160         filetypes = (cfg or {}).filetypes,
161         cmd = (cfg or {}).cmd,
162         root_pattern = (cfg or {}).root_pattern,
163       })
164     end
165 
166   else
167     require('mason').setup()
168     local mason_lspconfig = require 'mason-lspconfig'
169     mason_lspconfig.setup {
170       ensure_installed = vim.tbl_keys(servers),
171     }
172     mason_lspconfig.setup_handlers {
173       function(server_name)
174         require('lspconfig')[server_name].setup {
175           capabilities = require('myLuaConf.LSPs.caps-on_attach').get_capabilities(server_name),
176           -- this line is interchangeable with the above LspAttach autocommand
177           -- on_attach = require('myLuaConf.LSPs.caps-on_attach').on_attach,
178           settings = (servers[server_name] or {}).settings,
179           filetypes = (servers[server_name] or {}).filetypes,
180         }
181       end,
182     }
183   end
184 
185 ---------------------------------------------------------------------------------
186                                                  nixCats.LSPs.caps-on_attach
187 
188 The above snippet mentions another file at the end.
189 
190 caps-on_attach.lua or 'myLuaConf.LSPs.caps-on_attach'
191 
192 It is simply a file containing the function we want to run on LSP attach, and a
193 function to return our completion capabilities object.
194 
195 It looks like this:
196 
197 
198   local M = {}
199   function M.on_attach(_, bufnr)
200     -- we create a function that lets us more easily define mappings specific
201     -- for LSP related items. It sets the mode, buffer and description for us each time.
202 
203     local nmap = function(keys, func, desc)
204       if desc then
205         desc = 'LSP: ' .. desc
206       end
207 
208       vim.keymap.set('n', keys, func, { buffer = bufnr, desc = desc })
209     end
210 
211     nmap('<leader>rn', vim.lsp.buf.rename, '[R]e[n]ame')
212     nmap('<leader>ca', vim.lsp.buf.code_action, '[C]ode [A]ction')
213 
214     nmap('gd', vim.lsp.buf.definition, '[G]oto [D]efinition')
215     nmap('gr', require('telescope.builtin').lsp_references, '[G]oto [R]eferences')
216     nmap('gI', require('telescope.builtin').lsp_implementations, '[G]oto [I]mplementation')
217     nmap('<leader>D', vim.lsp.buf.type_definition, 'Type [D]efinition')
218     nmap('<leader>ds', require('telescope.builtin').lsp_document_symbols, '[D]ocument [S]ymbols')
219     nmap('<leader>ws', require('telescope.builtin').lsp_dynamic_workspace_symbols, '[W]orkspace [S]ymbols')
220 
221     -- See `:help K` for why this keymap
222     nmap('K', vim.lsp.buf.hover, 'Hover Documentation')
223     nmap('<C-k>', vim.lsp.buf.signature_help, 'Signature Documentation')
224 
225     -- Lesser used LSP functionality
226     nmap('gD', vim.lsp.buf.declaration, '[G]oto [D]eclaration')
227     nmap('<leader>wa', vim.lsp.buf.add_workspace_folder, '[W]orkspace [A]dd Folder')
228     nmap('<leader>wr', vim.lsp.buf.remove_workspace_folder, '[W]orkspace [R]emove Folder')
229     nmap('<leader>wl', function()
230       print(vim.inspect(vim.lsp.buf.list_workspace_folders()))
231     end, '[W]orkspace [L]ist Folders')
232 
233     -- Create a command `:Format` local to the LSP buffer
234     vim.api.nvim_buf_create_user_command(bufnr, 'Format', function(_)
235       vim.lsp.buf.format()
236     end, { desc = 'Format current buffer with LSP' })
237 
238   end
239 
240   function M.get_capabilities(server_name)
241     -- you may wish to know which server you're using to set different capabilities
242     -- if server_name is omitted, it will be nil
243 
244     -- nvim-cmp supports additional completion capabilities, so broadcast that to servers
245     -- if you make a package without it, make sure to check if it exists with nixCats!
246     local capabilities = vim.lsp.protocol.make_client_capabilities()
247     capabilities = vim.tbl_deep_extend('force', capabilities, require('cmp_nvim_lsp').default_capabilities())
248     capabilities.textDocument.completion.completionItem.snippetSupport = true
249     return capabilities
250   end
251   return M
252 
253 
254 
255 =================================================================================
256 vim:tw=78:ts=8:ft=help:norl: