dots-of-war/eggs/nvim/fnl/dots/plugins/lsp.fnl
2024-12-21 22:42:30 +01:00

263 lines
12 KiB
Fennel

(local {: autoload : a : utils} (require :dots.prelude))
(local lsp (autoload :lspconfig))
(local lsp-configs (autoload :lspconfig/configs))
(local cmp_nvim_lsp (autoload :cmp_nvim_lsp))
(fn setup []
; TODO check https://github.com/neovim/nvim-lspconfig/blob/master/ADVANCED_README.md for default config for all of them
(tset vim.lsp.handlers :textDocument/publishDiagnostics
(vim.lsp.with vim.lsp.diagnostic.on_publish_diagnostics
{:update_in_insert false
:virtual_text {:prefix "◆"}
:signs false
:severity_sort true}))
(fn on_attach [client bufnr]
(if client.server_capabilities.documentHighlight
(do
(utils.highlight "LspReferenceRead" {:gui "underline"})
(utils.highlight "LspReferenceText" {:gui "underline"})
(utils.highlight "LspReferenceWrite" {:gui "underline"})
(vim.api.nvim_exec
"augroup lsp_document_highlight
autocmd! * <buffer>
autocmd CursorHold <buffer> lua vim.lsp.buf.document_highlight()
autocmd CursorMoved <buffer> lua vim.lsp.buf.clear_references()
augroup END"
false))))
(fn better_root_pattern [patterns except-patterns]
"match path if one of the given patterns is matched, EXCEPT if one of the except-patterns is matched"
(fn [path]
(when (not ((lsp.util.root_pattern except-patterns) path))
((lsp.util.root_pattern patterns) path))))
; advertise snippet support
(local default-capabilities
(let [capabilities (vim.lsp.protocol.make_client_capabilities)]
(set capabilities.textDocument.completion.completionItem.snippetSupport true)
(cmp_nvim_lsp.default_capabilities capabilities)))
(fn init-lsp [lsp-name ?opts]
"initialize a language server with defaults"
(let [merged-opts (a.merge {:on_attach on_attach :capabilities default-capabilities} (or ?opts {}))]
((. lsp lsp-name :setup) merged-opts)))
(init-lsp :jsonls {:commands {:Format [ #(vim.lsp.buf.range_formatting [] [0 0] [(vim.fn.line "$") 0])]}})
(init-lsp :denols {:root_dir (better_root_pattern [".git"] ["package.json"])})
(init-lsp :hls {:settings {:languageServerHaskell {:formattingProvider "stylish-haskell"}}})
(init-lsp :ocamllsp)
(init-lsp :vimls)
(init-lsp :gopls)
(init-lsp :bashls)
(init-lsp :erlangls)
(init-lsp :yamlls)
(init-lsp :html)
(init-lsp :svelte)
(init-lsp :elmls)
(init-lsp :texlab)
(init-lsp :pyright)
;(init-lsp :ltex {:settings {:ltex {:dictionary {:de-DE [":~/.config/ltex-ls/dictionary.txt"]}
;:disabledRules {:de-DE [":~/.config/ltex-ls/disabledRules.txt"]}
;:hiddenFalsePositives {:de-DE [":~/.config/ltex-ls/hiddenFalsePositives.txt"]}
;:additionalRules {:motherTongue "de-DE"}}}})
(init-lsp :vls)
;(init-lsp :clangd)
;(init-lsp :ccls)
(init-lsp :perlls)
(init-lsp :powershell_es {:bundle_path "/home/leon/powershell"})
;(ltex-ls.init)
(init-lsp :clangd)
(init-lsp :cssls {:filestypes ["css" "scss" "less" "stylus"]
:root_dir (lsp.util.root_pattern ["package.json" ".git"])
:settings {:css {:validate true}
:less {:validate true}
:scss {:validate true}}})
(lsp.ts_ls.setup {:root_dir (lsp.util.root_pattern "package.json")
:on_attach (fn [client bufnr]
(set client.resolved_capabilities.document_formatting false)
(on_attach client bufnr))})
(let [
rustaceanvim (require "rustaceanvim")
rustaceanvim-config (require "rustaceanvim.config")
extension-path "/home/leon/.vscode/extensions/vadimcn.vscode-lldb-1.6.8/"
codelldb-path (.. extension-path "adapter/codelldb")
liblldb-path (.. extension-path "lldb/lib/liblldb.so")
features nil]
(set vim.g.rustaceanvim {:tools {:inlay_hints {:show_parameter_hints false}
:autoSetHints false}
:dap {:adapter (rustaceanvim-config.get_codelldb_adapter codelldb-path liblldb-path)}
:server {:on_attach on_attach
:capabilities default-capabilities
:settings {:rust-analyzer {:cargo {:loadOutDirsFromCheck true
:features (or features "all")
:noDefaultFeatures (~= nil features)}
:procMacro {:enable true}
:diagnostics {:enable false ;; native rust analyzer diagnostics
:experimental {:enable false}}
:checkOnSave {:overrideCommand ["cargo" "clippy" "--workspace" "--message-format=json" "--all-targets" "--all-features"]}}}}}))
;:cmd ["/home/leon/coding/prs/rust-analyzer/target/release/rust-analyzer"]}}))
(when (or true (not lsp.fennel_language_server))
(tset lsp-configs :fennel_language_server
{:default_config {:cmd "/Users/leon/.cargo/bin/fennel-language-server"
:filetypes [:fennel]
:single_file_support true
:root_dir (lsp.util.root_pattern ["fnl" "init.lua"])
:settings {:fennel {:workspace {:library (vim.api.nvim_list_runtime_paths)}
:diagnostics {:globals [:vim]}}}}}))
(init-lsp :fennel_language_server
{:root_dir (lsp.util.root_pattern ["fnl" "init.lua"])
:settings {:fennel {:workspace {:library (vim.api.nvim_list_runtime_paths)}
:diagnostics {:globals [:vim :comment]}}}})
;
;
; (let [sumneko_root_path (.. vim.env.HOME "/.local/share/lua-language-server")
; sumneko_binary (.. sumneko_root_path "/bin/Linux/lua-language-server"))
; (init-lsp
; :lua_ls
; {:cmd [sumneko_binary "-E" (.. sumneko_root_path "/main.lua")]
; :settings {:Lua {:runtime {:version "LuaJIT"
; :path (vim.split package.path ";")}
; :diagnostics {:globals ["vim"]}
; :workspace {:library {(vim.fn.expand "$VIMRUNTIME/lua") true
; (vim.fn.expand "$VIMRUNTIME/lua/vim/lsp") true}}
; :telemetry false}}}))
(comment
(when (not lsp.prolog_lsp)
(tset lsp-configs :prolog_lsp
{:default_config {:cmd ["swipl" "-g" "use_module(library(lsp_server))." "-g" "lsp_server:main" "-t" "halt" "--" "stdio"]
:filetypes ["prolog"]
:root_dir (fn [fname] (or (lsp.util.find_git_ancestor fname) (vim.loop.os_homedir)))
:settings {}}}))
(lsp.prolog_lsp.setup {}))
(comment
(let [ewwls-path "/home/leon/coding/projects/ls-eww/crates/ewwls/target/debug/ewwls"]
(when (vim.fn.filereadable ewwls-path)
(when (not lsp.ewwls)
(set lsp-configs.ewwls
{:default_config {:cmd [ewwls-path]
:filetypes ["yuck"]
:root_dir (fn [fname] (or (lsp.util.find_git_ancestor fname) (vim.loop.os_homedir)))
:settings {}}}))
(init-lsp :ewwls))))
; Idris2 ----------------------------------------------------------- <<<<<
(local autostart-semantic-highlighting true)
(fn refresh-semantic-highlighting []
(when autostart-semantic-highlighting
(vim.lsp.buf_request 0
:textDocument/semanticTokens/full
{:textDocument (vim.lsp.util.make_text_document_params)}
nil)
vim.NIL))
(when (not lsp.idris2_lsp)
(set lsp-configs.idris2_lsp
{:default_config
{:cmd [:idris2-lsp]
:filetypes [:idris2]
:on_new_config (fn [new-config new-root-dir]
(set new-config.cmd {1 :idris2-lsp})
(set new-config.capabilities.workspace.semanticTokens {:refreshSupport true}))
:root_dir (fn [fname]
(local scandir (require :plenary.scandir))
(fn find-ipkg-ancestor [fname]
(lsp.util.search_ancestors
fname
(fn [path]
(local res (scandir.scan_dir path {:depth 1 :search_pattern ".+%.ipkg"}))
(when (not (vim.tbl_isempty res)) path))))
(or (or (find-ipkg-ancestor fname)
(lsp.util.find_git_ancestor fname))
(vim.loop.os_homedir)))
:settings {}}}))
(lsp.idris2_lsp.setup
{:on_attach refresh-semantic-highlighting
:autostart true
:handlers {:workspace/semanticTokens/refresh refresh-semantic-highlighting
:textDocument/semanticTokens/full
(fn [err method result client-id bufnr config]
(let [client (vim.lsp.get_client_by_id client-id)
legend client.server_capabilities.semanticTokensProvider.legend
token-types legend.tokenTypes
data result.data
ns (vim.api.nvim_create_namespace :nvim-lsp-semantic)]
(vim.api.nvim_buf_clear_namespace bufnr ns 0 (- 1))
(local tokens {})
(var (prev-line prev-start) (values nil 0))
(for [i 1 (length data) 5]
(local delta-line (. data i))
(set prev-line
(or (and prev-line (+ prev-line delta-line))
delta-line))
(local delta-start (. data (+ i 1)))
(set prev-start (or (and (= delta-line 0) (+ prev-start delta-start))
delta-start))
(local token-type (. token-types (+ (. data (+ i 3)) 1)))
(vim.api.nvim_buf_add_highlight bufnr
ns
(.. :LspSemantic_ token-type)
prev-line
prev-start
(+ prev-start (. data (+ i 2)))))))}})
(vim.cmd "highlight link LspSemantic_type Include")
(vim.cmd "highlight link LspSemantic_function Identifier")
(vim.cmd "highlight link LspSemantic_struct Number")
(vim.cmd "highlight LspSemantic_variable guifg=gray")
(vim.cmd "highlight link LspSemantic_keyword Structure")
; --------------------------------- >>>>>
(set vim.opt.signcolumn "yes")
; Cleanup links in markdown documentation
(fn cleanup-markdown [contents]
(if (= contents.kind "markdown")
(tset contents :value (string.gsub contents.value "%[([^%]]+)%]%(([^%)]+)%)" "[%1]")))
contents)
(let [previous-handler (. vim.lsp.handlers :textDocument/hover)]
(tset vim.lsp.handlers :textDocument/hover
(fn [a result b c]
(if (not (and result result.contents))
(previous-handler a result b c)
(let [new-contents (cleanup-markdown result.contents)]
(tset result :contents new-contents)
(previous-handler a result b c)))))))
[(utils.plugin :williamboman/mason.nvim {:config #((. (require :mason) :setup))})
(utils.plugin :williamboman/mason-lspconfig.nvim {:config {:ensure_installed ["rust_analyzer"]}})
(utils.plugin :neovim/nvim-lspconfig {:event "VeryLazy" :lazy true :config setup})]
; vim:foldmarker=<<<<<,>>>>>