From aa236a7f7e9c0aaae52618ec962d1f61c74e39e9 Mon Sep 17 00:00:00 2001 From: Kalle Jepsen Date: Fri, 4 Oct 2024 10:22:04 +0200 Subject: [PATCH 1/3] languages/scala: Add scala language support Adds LSP support for Scala via nvim-metals --- configuration.nix | 1 + flake.lock | 17 ++++ flake.nix | 6 ++ modules/plugins/languages/default.nix | 1 + modules/plugins/languages/scala.nix | 141 ++++++++++++++++++++++++++ 5 files changed, 166 insertions(+) create mode 100644 modules/plugins/languages/scala.nix diff --git a/configuration.nix b/configuration.nix index b21b26aa..ff9af12a 100644 --- a/configuration.nix +++ b/configuration.nix @@ -68,6 +68,7 @@ isMaximal: { lsp.server = "clangd"; }; + scala.enable = isMaximal; rust = { enable = isMaximal; crates.enable = isMaximal; diff --git a/flake.lock b/flake.lock index 7775fb1f..eb34f95c 100644 --- a/flake.lock +++ b/flake.lock @@ -1149,6 +1149,22 @@ "type": "github" } }, + "plugin-nvim-metals": { + "flake": false, + "locked": { + "lastModified": 1728033462, + "narHash": "sha256-XqOkZ/5eex1mrNUf6vrJjDjibBbb0bSMYSciKAoVD0A=", + "owner": "ksonj", + "repo": "nvim-metals", + "rev": "4d86c32f6c028de197e28dab0f6a0250c0d1c16a", + "type": "github" + }, + "original": { + "owner": "ksonj", + "repo": "nvim-metals", + "type": "github" + } + }, "plugin-nvim-navbuddy": { "flake": false, "locked": { @@ -1863,6 +1879,7 @@ "plugin-nvim-docs-view": "plugin-nvim-docs-view", "plugin-nvim-lightbulb": "plugin-nvim-lightbulb", "plugin-nvim-lspconfig": "plugin-nvim-lspconfig", + "plugin-nvim-metals": "plugin-nvim-metals", "plugin-nvim-navbuddy": "plugin-nvim-navbuddy", "plugin-nvim-navic": "plugin-nvim-navic", "plugin-nvim-neoclip": "plugin-nvim-neoclip", diff --git a/flake.nix b/flake.nix index 987e3e59..9f45eb6f 100644 --- a/flake.nix +++ b/flake.nix @@ -206,6 +206,12 @@ flake = false; }; + plugin-nvim-metals = { + url = "github:ksonj/nvim-metals"; + flake = false; + }; + + # Copying/Registers plugin-registers = { url = "github:tversteeg/registers.nvim"; diff --git a/modules/plugins/languages/default.nix b/modules/plugins/languages/default.nix index 28c1fd8f..1c2e2bac 100644 --- a/modules/plugins/languages/default.nix +++ b/modules/plugins/languages/default.nix @@ -19,6 +19,7 @@ in { ./python.nix ./r.nix ./rust.nix + ./scala.nix ./sql.nix ./svelte.nix ./tailwind.nix diff --git a/modules/plugins/languages/scala.nix b/modules/plugins/languages/scala.nix new file mode 100644 index 00000000..417cefbc --- /dev/null +++ b/modules/plugins/languages/scala.nix @@ -0,0 +1,141 @@ +{ + config, + pkgs, + lib, + ... +}: let + inherit (lib) types optionalString; + inherit (lib.modules) mkIf mkMerge; + inherit (lib.nvim.types) mkGrammarOption; + inherit (lib.nvim.binds) mkMappingOption; + inherit (lib.options) mkOption mkEnableOption; + inherit (lib.nvim.dag) entryAfter; + + mkBinding = binding: "vim.api.nvim_buf_set_keymap(bufnr, 'n', '${binding.value}', 'lua ${binding.action}', {noremap=true, silent=true, desc='${binding.description}'})"; + + listCommandsBinding = { + value = cfg.lsp.extraMappings.listCommands; + description = "List Metals commands"; + action = + if config.vim.telescope.enable + then ''require("telescope").extensions.metals.commands()'' + else ''require("metals").commands()''; + }; + + cfg = config.vim.languages.scala; + + usingDap = config.vim.debugger.nvim-dap.enable && cfg.dap.enable; + usingLualine = config.vim.statusline.lualine.enable; +in { + options.vim.languages.scala = { + enable = mkEnableOption "Scala language support"; + treesitter = { + enable = mkEnableOption "Scala treesitter" // {default = config.vim.languages.enableTreesitter;}; + package = mkGrammarOption pkgs "scala"; + }; + lsp = { + enable = mkEnableOption "Scala LSP support (metals)" // {default = config.vim.languages.enableLSP;}; + package = mkOption { + type = types.package; + default = pkgs.metals; + description = '' + metals package to use + ''; + }; + extraMappings = { + listCommands = mkMappingOption "List Metals commands" "lc"; + }; + }; + dap = { + enable = mkOption { + description = "Scala Debug Adapter support"; + type = types.bool; + default = config.vim.languages.enableDAP; + }; + config = mkOption { + description = "Lua configuration for dap"; + type = types.str; + default = '' + dap.configurations.scala = { + { + type = "scala", + request = "launch", + name = "RunOrTest", + metals = { + runType = "runOrTestFile", + --args = { "firstArg", "secondArg", "thirdArg" }, -- here just as an example + }, + }, + { + type = "scala", + request = "launch", + name = "Test Target", + metals = { + runType = "testTarget", + }, + }, + } + ''; + }; + }; + }; + config = mkIf cfg.enable ( + mkMerge [ + (mkIf cfg.treesitter.enable { + vim.treesitter.enable = true; + vim.treesitter.grammars = [cfg.treesitter.package]; + }) + (mkIf (cfg.lsp.enable || cfg.dap.enable) { + vim = { + startPlugins = ["nvim-metals"]; + luaConfigRC.nvim-metals = entryAfter ["lsp-setup"] '' + -- Scala nvim-metals config + local metals_caps = capabilities -- from lsp-setup + + local attach_metals_keymaps = function(client, bufnr) + attach_keymaps(client, bufnr) -- from lsp-setup + ${mkBinding listCommandsBinding} + end + + metals_config = require('metals').bare_config() + ${optionalString usingLualine "metals_config.init_options.statusBarProvider = 'on'"} + + metals_config.capabilities = metals_caps + metals_config.on_attach = function(client, bufnr) + ${optionalString usingDap "require('metals').setup_dap()"} + attach_metals_keymaps(client, bufnr) + end + metals_config.settings = { + metalsBinaryPath = "${cfg.lsp.package}/bin/metals", + showImplicitArguments = true, + showImplicitConversionsAndClasses = true, + showInferredType = true, + excludedPackages = { + "akka.actor.typed.javadsl", + "com.github.swagger.akka.javadsl" + }, + + } + + metals_config.handlers["textDocument/publishDiagnostics"] = vim.lsp.with( + vim.lsp.diagnostic.on_publish_diagnostics, { + virtual_text = { + prefix = '⚠', + } + } + ) + + + -- without doing this, autocommands that deal with filetypes prohibit messages from being shown + vim.opt_global.shortmess:remove("F") + + vim.cmd([[augroup lsp]]) + vim.cmd([[autocmd!]]) + vim.cmd([[autocmd FileType java,scala,sbt lua require('metals').initialize_or_attach(metals_config)]]) + vim.cmd([[augroup end]]) + ''; + }; + }) + ] + ); +} From 7c5122abb0906305fae8464969627c748db92569 Mon Sep 17 00:00:00 2001 From: Kalle Jepsen Date: Sat, 5 Oct 2024 16:12:19 +0200 Subject: [PATCH 2/3] Format --- flake.nix | 1 - 1 file changed, 1 deletion(-) diff --git a/flake.nix b/flake.nix index 9f45eb6f..4181f0ad 100644 --- a/flake.nix +++ b/flake.nix @@ -211,7 +211,6 @@ flake = false; }; - # Copying/Registers plugin-registers = { url = "github:tversteeg/registers.nvim"; From 9d02a48553a90bff4296fbd8594f65fab803b315 Mon Sep 17 00:00:00 2001 From: Kalle Jepsen Date: Mon, 7 Oct 2024 12:27:38 +0200 Subject: [PATCH 3/3] Apply suggested improvements --- flake.lock | 10 +++--- flake.nix | 2 +- modules/plugins/languages/scala.nix | 47 ++++++++++++++--------------- 3 files changed, 28 insertions(+), 31 deletions(-) diff --git a/flake.lock b/flake.lock index eb34f95c..16bd5d17 100644 --- a/flake.lock +++ b/flake.lock @@ -1152,15 +1152,15 @@ "plugin-nvim-metals": { "flake": false, "locked": { - "lastModified": 1728033462, - "narHash": "sha256-XqOkZ/5eex1mrNUf6vrJjDjibBbb0bSMYSciKAoVD0A=", - "owner": "ksonj", + "lastModified": 1728295172, + "narHash": "sha256-ja/+MNxZ3H9io9jDwm5rhE6iKNi86a22eCOY75g19O8=", + "owner": "scalameta", "repo": "nvim-metals", - "rev": "4d86c32f6c028de197e28dab0f6a0250c0d1c16a", + "rev": "f861db9fda55939797ac1b05238c49b0dcdc3bdb", "type": "github" }, "original": { - "owner": "ksonj", + "owner": "scalameta", "repo": "nvim-metals", "type": "github" } diff --git a/flake.nix b/flake.nix index 4181f0ad..fb9f03cc 100644 --- a/flake.nix +++ b/flake.nix @@ -207,7 +207,7 @@ }; plugin-nvim-metals = { - url = "github:ksonj/nvim-metals"; + url = "github:scalameta/nvim-metals"; flake = false; }; diff --git a/modules/plugins/languages/scala.nix b/modules/plugins/languages/scala.nix index 417cefbc..6326dec0 100644 --- a/modules/plugins/languages/scala.nix +++ b/modules/plugins/languages/scala.nix @@ -4,23 +4,17 @@ lib, ... }: let - inherit (lib) types optionalString; + inherit (lib) types optionalString mkPackageOption; inherit (lib.modules) mkIf mkMerge; inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.binds) mkMappingOption; inherit (lib.options) mkOption mkEnableOption; inherit (lib.nvim.dag) entryAfter; - mkBinding = binding: "vim.api.nvim_buf_set_keymap(bufnr, 'n', '${binding.value}', 'lua ${binding.action}', {noremap=true, silent=true, desc='${binding.description}'})"; - - listCommandsBinding = { - value = cfg.lsp.extraMappings.listCommands; - description = "List Metals commands"; - action = - if config.vim.telescope.enable - then ''require("telescope").extensions.metals.commands()'' - else ''require("metals").commands()''; - }; + listCommandsAction = + if config.vim.telescope.enable + then ''require("telescope").extensions.metals.commands()'' + else ''require("metals").commands()''; cfg = config.vim.languages.scala; @@ -29,23 +23,22 @@ in { options.vim.languages.scala = { enable = mkEnableOption "Scala language support"; + treesitter = { enable = mkEnableOption "Scala treesitter" // {default = config.vim.languages.enableTreesitter;}; package = mkGrammarOption pkgs "scala"; }; + lsp = { enable = mkEnableOption "Scala LSP support (metals)" // {default = config.vim.languages.enableLSP;}; - package = mkOption { - type = types.package; - default = pkgs.metals; - description = '' - metals package to use - ''; + package = mkPackageOption pkgs "metals" { + default = ["metals"]; }; extraMappings = { listCommands = mkMappingOption "List Metals commands" "lc"; }; }; + dap = { enable = mkOption { description = "Scala Debug Adapter support"; @@ -79,6 +72,7 @@ in { }; }; }; + config = mkIf cfg.enable ( mkMerge [ (mkIf cfg.treesitter.enable { @@ -88,13 +82,12 @@ in { (mkIf (cfg.lsp.enable || cfg.dap.enable) { vim = { startPlugins = ["nvim-metals"]; - luaConfigRC.nvim-metals = entryAfter ["lsp-setup"] '' - -- Scala nvim-metals config + pluginRC.nvim-metals = entryAfter ["lsp-setup"] '' local metals_caps = capabilities -- from lsp-setup local attach_metals_keymaps = function(client, bufnr) attach_keymaps(client, bufnr) -- from lsp-setup - ${mkBinding listCommandsBinding} + vim.api.nvim_buf_set_keymap(bufnr, 'n', '${cfg.lsp.extraMappings.listCommands}', 'lua ${listCommandsAction}', {noremap=true, silent=true, desc='Show all Metals commands'}) end metals_config = require('metals').bare_config() @@ -125,14 +118,18 @@ in { } ) - -- without doing this, autocommands that deal with filetypes prohibit messages from being shown vim.opt_global.shortmess:remove("F") - vim.cmd([[augroup lsp]]) - vim.cmd([[autocmd!]]) - vim.cmd([[autocmd FileType java,scala,sbt lua require('metals').initialize_or_attach(metals_config)]]) - vim.cmd([[augroup end]]) + local lsp_group = vim.api.nvim_create_augroup('lsp', { clear = true }) + + vim.api.nvim_create_autocmd('FileType', { + group = lsp_group, + pattern = {'java', 'scala', 'sbt'}, + callback = function() + require('metals').initialize_or_attach(metals_config) + end, + }) ''; }; })