99 inherit ( lib . options ) mkEnableOption mkOption ;
1010 inherit ( lib . strings ) optionalString ;
1111 inherit ( lib . modules ) mkIf mkMerge ;
12- inherit ( lib . nvim . types ) mkGrammarOption ;
12+ inherit ( lib . nvim . types ) mkGrammarOption enum attrNames ;
1313 inherit ( lib . nvim . dag ) entryAfter ;
1414 inherit ( lib . nvim . lua ) expToLua ;
15+ inherit ( lib . meta ) getExe ;
16+ inherit ( lib . generators ) mkLuaInline ;
17+ inherit ( lib . nvim . attrsets ) mapListToAttrs ;
1518 inherit ( pkgs ) haskellPackages ;
1619
1720 cfg = config . vim . languages . haskell ;
21+
22+ defaultServers = [ "hls" ] ;
23+ servers = {
24+ hls = {
25+ enable = true ;
26+ cmd = [ ( getExe pkgs . haskellPackages . haskell-language-server ) "--debug" ] ;
27+ filetypes = [ "haskell" "lhaskell" ] ;
28+ on_attach =
29+ mkLuaInline
30+ /*
31+ lua
32+ */
33+ ''
34+ function(client, bufnr, ht)
35+ default_on_attach(client, bufnr, ht)
36+ local opts = { noremap = true, silent = true, buffer = bufnr }
37+ vim.keymap.set('n', '<localleader>cl', vim.lsp.codelens.run, opts)
38+ vim.keymap.set('n', '<localleader>hs', ht.hoogle.hoogle_signature, opts)
39+ vim.keymap.set('n', '<localleader>ea', ht.lsp.buf_eval_all, opts)
40+ vim.keymap.set('n', '<localleader>rr', ht.repl.toggle, opts)
41+ vim.keymap.set('n', '<localleader>rf', function()
42+ ht.repl.toggle(vim.api.nvim_buf_get_name(0))
43+ end, opts)
44+ vim.keymap.set('n', '<localleader>rq', ht.repl.quit, opts)
45+ end,
46+ '' ;
47+ root_dir =
48+ mkLuaInline
49+ /*
50+ lua
51+ */
52+ ''
53+ function(bufnr, on_dir)
54+ local root_pattern = function(...)
55+ local patterns = M.tbl_flatten { ... }
56+ return function(startpath)
57+ startpath = M.strip_archive_subpath(startpath)
58+ for _, pattern in ipairs(patterns) do
59+ local match = M.search_ancestors(startpath, function(path)
60+ for _, p in ipairs(vim.fn.glob(table.concat({ escape_wildcards(path), pattern }, '/'), true, true)) do
61+ if vim.uv.fs_stat(p) then
62+ return path
63+ end
64+ end
65+ end)
66+
67+ if match ~= nil then
68+ return match
69+ end
70+ end
71+ end
72+ end
73+
74+ local fname = vim.api.nvim_buf_get_name(bufnr)
75+ on_dir(root_pattern('hie.yaml', 'stack.yaml', 'cabal.project', '*.cabal', 'package.yaml')(fname))
76+ end
77+ '' ;
78+ settings = {
79+ haskell = {
80+ formattingProvider = "ormolu" ;
81+ cabalFormattingProvider = "cabalfmt" ;
82+ } ;
83+ } ;
84+ } ;
85+ } ;
1886in {
1987 options . vim . languages . haskell = {
2088 enable = mkEnableOption "Haskell support" ;
2593 } ;
2694
2795 lsp = {
28- enable = mkEnableOption "LSP support for Haskell" // { default = config . vim . lsp . enable ; } ;
29- package = mkOption {
30- description = "Haskell LSP package or command to run the Haskell LSP" ;
31- example = ''[ (lib.getExe pkgs.haskellPackages.haskell-language-server) "--debug" ]'' ;
32- default = haskellPackages . haskell-language-server ;
33- type = either package ( listOf str ) ;
96+ enable = mkEnableOption "Haskell LSP support" // { default = config . vim . lsp . enable ; } ;
97+ servers = mkOption {
98+ description = "Haskell LSP server to use" ;
99+ type = listOf ( enum ( attrNames servers ) ) ;
100+ default = defaultServers ;
34101 } ;
35102 } ;
36103
@@ -52,12 +119,21 @@ in {
52119 } ;
53120 } )
54121
122+ ( mkIf cfg . lsp . enable {
123+ vim . lsp . servers =
124+ mapListToAttrs ( n : {
125+ name = n ;
126+ value = servers . ${ n } ;
127+ } )
128+ cfg . lsp . servers ;
129+ } )
130+
55131 ( mkIf ( cfg . dap . enable || cfg . lsp . enable ) {
56132 vim = {
57133 startPlugins = [ "haskell-tools-nvim" ] ;
58134 luaConfigRC . haskell-tools-nvim =
59135 entryAfter
60- [ "lsp-setup " ]
136+ [ "lsp-servers " ]
61137 ''
62138 vim.g.haskell_tools = {
63139 ${ optionalString cfg . lsp . enable ''
67143 enable = true,
68144 },
69145 },
70- hls = {
71- cmd = ${
72- if isList cfg . lsp . package
73- then expToLua cfg . lsp . package
74- else ''{"${ cfg . lsp . package } /bin/haskell-language-server-wrapper", "--lsp"}''
75- } ,
76- on_attach = function(client, bufnr, ht)
77- default_on_attach(client, bufnr, ht)
78- local opts = { noremap = true, silent = true, buffer = bufnr }
79- vim.keymap.set('n', '<localleader>cl', vim.lsp.codelens.run, opts)
80- vim.keymap.set('n', '<localleader>hs', ht.hoogle.hoogle_signature, opts)
81- vim.keymap.set('n', '<localleader>ea', ht.lsp.buf_eval_all, opts)
82- vim.keymap.set('n', '<localleader>rr', ht.repl.toggle, opts)
83- vim.keymap.set('n', '<localleader>rf', function()
84- ht.repl.toggle(vim.api.nvim_buf_get_name(0))
85- end, opts)
86- vim.keymap.set('n', '<localleader>rq', ht.repl.quit, opts)
87- end,
88- },
146+ -- Configured through vim.lsp.config
147+ hls = {},
89148 '' }
90149 ${ optionalString cfg . dap . enable ''
91150 dap = {
0 commit comments