diff --git a/configuration.nix b/configuration.nix index 3802f758..3be1d39b 100644 --- a/configuration.nix +++ b/configuration.nix @@ -79,6 +79,7 @@ isMaximal: { dart.enable = false; ocaml.enable = false; elixir.enable = false; + haskell.enable = false; tailwind.enable = false; svelte.enable = false; diff --git a/docs/release-notes/rl-0.8.md b/docs/release-notes/rl-0.8.md index 52a9ae64..36209ff7 100644 --- a/docs/release-notes/rl-0.8.md +++ b/docs/release-notes/rl-0.8.md @@ -8,3 +8,9 @@ `languages.typst.extensions.typst-preview-nvim`. - Add a search widget to the options page in the nvf manual. + +[amadaluzia](https://github.com/amadaluzia): + +[haskell-tools.nvim]: https://github.com/MrcJkb/haskell-tools.nvim + +- Add Haskell support under `vim.languages.haskell` using [haskell-tools.nvim] diff --git a/flake.lock b/flake.lock index d5532b4b..dc9cd81a 100644 --- a/flake.lock +++ b/flake.lock @@ -684,6 +684,22 @@ "type": "github" } }, + "plugin-haskell-tools-nvim": { + "flake": false, + "locked": { + "lastModified": 1734222260, + "narHash": "sha256-gZVN9ADPO5wFOaf19FydCneb7aKTT9K1vcLoBURPEjk=", + "owner": "mrcjkb", + "repo": "haskell-tools.nvim", + "rev": "943b77b68a79d3991523ba4d373063c9355c6f55", + "type": "github" + }, + "original": { + "owner": "mrcjkb", + "repo": "haskell-tools.nvim", + "type": "github" + } + }, "plugin-highlight-undo": { "flake": false, "locked": { @@ -2091,6 +2107,7 @@ "plugin-gitsigns-nvim": "plugin-gitsigns-nvim", "plugin-glow-nvim": "plugin-glow-nvim", "plugin-gruvbox": "plugin-gruvbox", + "plugin-haskell-tools-nvim": "plugin-haskell-tools-nvim", "plugin-highlight-undo": "plugin-highlight-undo", "plugin-hop-nvim": "plugin-hop-nvim", "plugin-icon-picker-nvim": "plugin-icon-picker-nvim", diff --git a/flake.nix b/flake.nix index 65c802f2..161ba43f 100644 --- a/flake.nix +++ b/flake.nix @@ -720,5 +720,10 @@ url = "github:otavioschwanck/new-file-template.nvim"; flake = false; }; + + plugin-haskell-tools-nvim = { + url = "github:mrcjkb/haskell-tools.nvim"; + flake = false; + }; }; } diff --git a/modules/plugins/languages/default.nix b/modules/plugins/languages/default.nix index a69d3e8d..48945b38 100644 --- a/modules/plugins/languages/default.nix +++ b/modules/plugins/languages/default.nix @@ -14,6 +14,7 @@ in { ./hcl.nix ./kotlin.nix ./html.nix + ./haskell.nix ./java.nix ./lua.nix ./markdown.nix diff --git a/modules/plugins/languages/haskell.nix b/modules/plugins/languages/haskell.nix new file mode 100644 index 00000000..f8e17b75 --- /dev/null +++ b/modules/plugins/languages/haskell.nix @@ -0,0 +1,104 @@ +{ + config, + lib, + pkgs, + ... +}: let + inherit (builtins) isList; + inherit (lib.types) either package listOf str; + inherit (lib.options) mkEnableOption mkOption; + inherit (lib.strings) optionalString; + inherit (lib.modules) mkIf mkMerge; + inherit (lib.nvim.types) mkGrammarOption; + inherit (lib.nvim.dag) entryAfter; + inherit (lib.nvim.lua) expToLua; + inherit (pkgs) haskellPackages; + + cfg = config.vim.languages.haskell; +in { + options.vim.languages.haskell = { + enable = mkEnableOption "Haskell support"; + + treesitter = { + enable = mkEnableOption "Treesitter support for Haskell" // {default = config.vim.languages.enableTreesitter;}; + package = mkGrammarOption pkgs "haskell"; + }; + + lsp = { + enable = mkEnableOption "LSP support for Haskell" // {default = config.vim.languages.enableLSP;}; + package = mkOption { + description = "Haskell LSP package or command to run the Haskell LSP"; + example = ''[ (lib.getExe pkgs.haskellPackages.haskell-language-server) "--debug" ]''; + default = haskellPackages.haskell-language-server; + type = either package (listOf str); + }; + }; + + dap = { + enable = mkEnableOption "DAP support for Haskell" // {default = config.vim.languages.enableDAP;}; + package = mkOption { + description = "Haskell DAP package or command to run the Haskell DAP"; + default = haskellPackages.haskell-debug-adapter; + type = either package (listOf str); + }; + }; + }; + + config = mkIf cfg.enable (mkMerge [ + (mkIf cfg.treesitter.enable { + vim.treesitter = { + enable = true; + grammars = [cfg.treesitter.package]; + }; + }) + + (mkIf (cfg.dap.enable || cfg.lsp.enable) { + vim = { + startPlugins = ["haskell-tools-nvim"]; + luaConfigRC.haskell-tools-nvim = + entryAfter + ["lsp-setup"] + '' + vim.g.haskell_tools = { + ${optionalString cfg.lsp.enable '' + -- LSP + tools = { + hover = { + enable = true, + }, + }, + hls = { + cmd = ${ + if isList cfg.lsp.package + then expToLua cfg.lsp.package + else ''{"${cfg.lsp.package}/bin/haskell-language-server-wrapper"}'' + }, + on_attach = function(client, bufnr, ht) + default_on_attach(client, bufnr, ht) + local opts = { noremap = true, silent = true, buffer = bufnr } + vim.keymap.set('n', 'cl', vim.lsp.codelens.run, opts) + vim.keymap.set('n', 'hs', ht.hoogle.hoogle_signature, opts) + vim.keymap.set('n', 'ea', ht.lsp.buf_eval_all, opts) + vim.keymap.set('n', 'rr', ht.repl.toggle, opts) + vim.keymap.set('n', 'rf', function() + ht.repl.toggle(vim.api.nvim_buf_get_name(0)) + end, opts) + vim.keymap.set('n', 'rq', ht.repl.quit, opts) + end, + }, + ''} + ${optionalString cfg.dap.enable '' + dap = { + cmd = ${ + if isList cfg.dap.package + then expToLua cfg.dap.package + else ''${cfg.dap.package}/bin/haskell-debug-adapter'' + }, + }, + ''} + } + ''; + }; + }) + ]); +} diff --git a/modules/plugins/languages/rust.nix b/modules/plugins/languages/rust.nix index ec1887cb..7e9cb627 100644 --- a/modules/plugins/languages/rust.nix +++ b/modules/plugins/languages/rust.nix @@ -13,7 +13,7 @@ inherit (lib.types) bool package str listOf either enum; inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.lua) expToLua; - inherit (lib.nvim.dag) entryAnywhere; + inherit (lib.nvim.dag) entryAfter entryAnywhere; cfg = config.vim.languages.rust; @@ -127,7 +127,7 @@ in { vim = { startPlugins = ["rustaceanvim"]; - luaConfigRC.rustaceanvim = entryAnywhere '' + pluginRC.rustaceanvim = entryAfter ["lsp-setup"] '' vim.g.rustaceanvim = { ${optionalString cfg.lsp.enable '' -- LSP