diff --git a/modules/plugins/languages/haskell.nix b/modules/plugins/languages/haskell.nix index ac18fe555..ec2fe86a9 100644 --- a/modules/plugins/languages/haskell.nix +++ b/modules/plugins/languages/haskell.nix @@ -4,7 +4,7 @@ pkgs, ... }: let - inherit (builtins) isList attrNames; + inherit (builtins) isList attrNames elem; inherit (lib.types) either package enum listOf str; inherit (lib.options) mkEnableOption mkOption; inherit (lib.strings) optionalString; @@ -12,55 +12,60 @@ inherit (lib.nvim.types) mkGrammarOption; inherit (lib.nvim.dag) entryAfter; inherit (lib.nvim.lua) toLuaObject; - inherit (lib.meta) getExe'; + inherit (lib.nvim.attrsets) mapListToAttrs; inherit (lib.generators) mkLuaInline; inherit (pkgs) haskellPackages; cfg = config.vim.languages.haskell; - defaultServers = ["hls"]; + defaultServers = ["haskell-tools"]; + serverCommon = { + filetypes = ["haskell" "lhaskell"]; + root_dir = + mkLuaInline + /* + lua + */ + '' + function(bufnr, on_dir) + local fname = vim.api.nvim_buf_get_name(bufnr) + on_dir(util.root_pattern('hie.yaml', 'stack.yaml', 'cabal.project', '*.cabal', 'package.yaml')(fname)) + end + ''; + }; servers = { - hls = { - enable = false; - cmd = [(getExe' pkgs.haskellPackages.haskell-language-server "haskell-language-server-wrapper") "--lsp"]; - filetypes = ["haskell" "lhaskell"]; - on_attach = - mkLuaInline - /* - lua - */ - '' - function(client, bufnr) - local ht = require("haskell-tools") - 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 - ''; - root_dir = - mkLuaInline - /* - lua - */ - '' - function(bufnr, on_dir) - local fname = vim.api.nvim_buf_get_name(bufnr) - on_dir(util.root_pattern('hie.yaml', 'stack.yaml', 'cabal.project', '*.cabal', 'package.yaml')(fname)) - end - ''; - settings = { - haskell = { - formattingProvider = "ormolu"; - cabalFormattingProvider = "cabalfmt"; - }; + hls = + serverCommon + // { + enable = true; + cmd = ["haskell-language-server-wrapper" "--lsp"]; + }; + + haskell-tools = + serverCommon + // { + # haskell-tools is already started by haskell-tools.nvim via ftplugin + enable = false; + on_attach = + mkLuaInline + /* + lua + */ + '' + function(client, bufnr) + local ht = require("haskell-tools") + 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 + ''; }; - }; }; in { options.vim.languages.haskell = { @@ -98,7 +103,26 @@ in { }; }) - (mkIf (cfg.dap.enable || cfg.lsp.enable) { + (mkIf cfg.lsp.enable { + vim.lsp.servers = + mapListToAttrs (n: { + name = n; + value = servers.${n}; + }) + cfg.lsp.servers; + }) + + (mkIf (cfg.dap.enable && cfg.lsp.enable && !elem "haskell-tools" cfg.lsp.servers) { + warnings = [ + ( + "You appear to have enabled vim.languages.haskell.dap, which implicitly " + + "causes haskell-tools-nvim plugin to be added. Make sure you also add " + + "'haskell-tools' server to vim.languages.haskell.lsp.servers" + ) + ]; + }) + + (mkIf (cfg.dap.enable || (cfg.lsp.enable && elem "haskell-tools" cfg.lsp.servers)) { vim = { startPlugins = ["haskell-tools-nvim"]; luaConfigRC.haskell-tools-nvim = @@ -113,7 +137,6 @@ in { enable = true, }, }, - hls = ${toLuaObject servers.hls}, ''} ${optionalString cfg.dap.enable '' dap = {