1
0
Fork 0

nvim: LSP utility functions

This commit is contained in:
Daniel Kempkens 2022-05-04 15:03:51 +02:00
parent 674e1bda01
commit a6065908bd
6 changed files with 134 additions and 32 deletions

View file

@ -11,7 +11,8 @@
npairs (require :nvim-autopairs) npairs (require :nvim-autopairs)
gitsigns (require :gitsigns) gitsigns (require :gitsigns)
repl (require :nifoc.repl) repl (require :nifoc.repl)
formatting (require :nifoc.formatting)] formatting (require :nifoc.formatting)
nifoc-lsp (require :nifoc.lsp)]
(fn map-entry [key cmd opts] (fn map-entry [key cmd opts]
(vim.tbl_extend :keep {1 key 2 cmd} opts)) (vim.tbl_extend :keep {1 key 2 cmd} opts))
@ -108,7 +109,9 @@
#(telescope-builtin.lsp_implementations telescope-dropdown) #(telescope-builtin.lsp_implementations telescope-dropdown)
{:buffer bufnr :desc "Find Implementations"}) {:buffer bufnr :desc "Find Implementations"})
(keymap.set :n :K vim.lsp.buf.hover (keymap.set :n :K vim.lsp.buf.hover
{:buffer bufnr :desc "Show Documentation"})) {:buffer bufnr :desc "Show Documentation"})
(keymap.set :n :<leader>ddsc nifoc-lsp.symbols-under-cursor
{:buffer bufnr :desc "Document Symbols Under Cursor"}))
(fn mod.terminal-open [bufnr] (fn mod.terminal-open [bufnr]
(let [map-opts {:buffer bufnr}] (let [map-opts {:buffer bufnr}]

View file

@ -1,4 +1,3 @@
;; Based on https://github.com/nvim-lua/lsp-status.nvim
(let [mod {} (let [mod {}
current-function-symbols {:Class " " current-function-symbols {:Class " "
:Enum "ﴳ " :Enum "ﴳ "
@ -9,10 +8,22 @@
:Namespace " " :Namespace " "
:Package " " :Package " "
:Struct "ﴳ "} :Struct "ﴳ "}
spinner-frames ["⣾" "⣽" "⣻" "⢿" "⡿" "⣟" "⣯" "⣷"]
client-notifications {}
lsp-proto vim.lsp.protocol lsp-proto vim.lsp.protocol
set-bufvar vim.api.nvim_buf_set_var set-bufvar vim.api.nvim_buf_set_var
augroup (vim.api.nvim_create_augroup :NifocLsp {:clear true}) augroup (vim.api.nvim_create_augroup :NifocLsp {:clear true})
aucmd vim.api.nvim_create_autocmd] aucmd vim.api.nvim_create_autocmd]
(fn filter-sorted-table [test list]
(let [results []]
(each [_ item (ipairs list)]
(when (test item)
(table.insert results item)))
results))
;; Current LSP Context
;; Based on https://github.com/nvim-lua/lsp-status.nvim
(fn extract-symbols [acc items] (fn extract-symbols [acc items]
(if (= items nil) (if (= items nil)
acc acc
@ -28,7 +39,7 @@
(set sym-range.end.line (+ sym-range.end.line 1)))) (set sym-range.end.line (+ sym-range.end.line 1))))
(table.insert acc {:range sym-range : kind :text item.name}) (table.insert acc {:range sym-range : kind :text item.name})
(when item.children (when item.children
(extract-symbols item.children acc))) (extract-symbols acc item.children)))
acc))) acc)))
(fn current-function-symbol? [item] (fn current-function-symbol? [item]
@ -42,24 +53,112 @@
(and (= line sym.end.line) (> char sym.end.character)) false (and (= line sym.end.line) (> char sym.end.character)) false
true))) true)))
(fn handle-symbols-under-cursor [err result ctx config]
(when (and (= err nil) (= (type result) :table))
(let [symbols (extract-symbols [] result)
cursor-pos (vim.api.nvim_win_get_cursor 0)]
(print (.. "Symbols at under current position (" (. cursor-pos 1) ":"
(. cursor-pos 2) ")"))
(each [_ sym (ipairs symbols)]
(when (cursor-in-range? cursor-pos sym.range)
(print (.. sym.kind ": " sym.text " (" sym.range.start.line ":"
sym.range.start.character " - " sym.range.end.line ":"
sym.range.end.character ")")))))))
(fn handle-update-current-context [err result ctx config] (fn handle-update-current-context [err result ctx config]
(set-bufvar ctx.bufnr :nifoc_lsp_current_context "") (var context-levels [])
(when (and (= err nil) (= (type result) :table)) (when (and (= err nil) (= (type result) :table))
(let [filtered-symbols (->> result (extract-symbols []) (let [filtered-symbols (->> result (extract-symbols [])
(vim.tbl_filter current-function-symbol?)) (filter-sorted-table current-function-symbol?))
cursor-pos (vim.api.nvim_win_get_cursor 0)] cursor-pos (vim.api.nvim_win_get_cursor 0)]
(for [i (length filtered-symbols) 1 -1] (each [_ sym (ipairs filtered-symbols)]
(local sym (. filtered-symbols i))
(when (cursor-in-range? cursor-pos sym.range) (when (cursor-in-range? cursor-pos sym.range)
(let [current-context (.. (. current-function-symbols sym.kind) " " (let [current-context (.. (. current-function-symbols sym.kind)
sym.text)] sym.text)]
(set-bufvar ctx.bufnr :nifoc_lsp_current_context current-context))))))) (table.insert context-levels current-context))))))
(set-bufvar ctx.bufnr :nifoc_lsp_current_context
(table.concat context-levels "  "))
(vim.api.nvim_command :redrawstatus))
(fn update-current-context [bufnr] (fn update-current-context [bufnr]
(let [params {:textDocument (vim.lsp.util.make_text_document_params bufnr)}] (let [params {:textDocument (vim.lsp.util.make_text_document_params bufnr)}]
(vim.lsp.buf_request bufnr :textDocument/documentSymbol params (vim.lsp.buf_request bufnr :textDocument/documentSymbol params
handle-update-current-context))) handle-update-current-context)))
;; Progress Notifications
;; Based on: https://github.com/rcarriga/nvim-notify/wiki/Usage-Recipes#progress-updates
(fn get-notification-data [client-id token]
(when (= (. client-notifications client-id) nil)
(tset client-notifications client-id {}))
(when (= (. client-notifications client-id token) nil)
(tset client-notifications client-id token {}))
(. client-notifications client-id token))
(fn update-notifcation-spinner [client-id token]
(let [notification-data (get-notification-data client-id token)]
(when notification-data.spinner
(let [new-spinner (% (+ notification-data.spinner 1)
(length spinner-frames))]
(set notification-data.spinner new-spinner)
(set notification-data.notification
(vim.notify nil nil
{:hide_from_history true
:icon (. spinner-frames new-spinner)
:replace notification-data.notification}))
(vim.defer_fn #(update-notifcation-spinner client-id token))))))
(fn format-notifcation-title [title client-name]
(.. client-name (if (> (length title) 0) (.. ": " title) "")))
(fn format-notifcation-message [message percentage]
(.. (if percentage (.. percentage "%\t") "") (if message message "")))
(fn handle-progress [err result ctx]
(let [client-id ctx.client_id
val result.value
kind val.kind
lsp-client (vim.lsp.get_client_by_id client-id)
client-name lsp-client.name
notification-data (get-notification-data client-id result.token)]
(if (= kind :begin)
(let [message (format-notifcation-message val.message val.percentage)]
(set notification-data.notification
(vim.notify message :info
{:title (format-notifcation-title val.title
client-name)
:icon (. spinner-frames 1)
:timeout false
:hide_from_history false}))
(set notification-data.spinner 1)
(update-notifcation-spinner client-id result.token))
(and (= kind :report) notification-data)
(let [message (format-notifcation-message val.message val.percentage)]
(set notification-data.notification
(vim.notify message :info
{:replace notification-data.notification
:hide_from_history false})))
(and (= kind :end) notification-data)
(let [message (if val.message
(format-notifcation-message val.message)
:Complete)]
(set notification-data.notification
(vim.notify message :info
{:icon ""
:replace notification-data.notification
:timeout 3000}))
(set notification-data.spinner nil)))))
;; Public Interface
(fn mod.register-progress-handler []
(tset vim.lsp.handlers :$/progress handle-progress))
(fn mod.symbols-under-cursor []
(let [params {:textDocument (vim.lsp.util.make_text_document_params 0)}]
(vim.lsp.buf_request 0 :textDocument/documentSymbol params
handle-symbols-under-cursor)))
(fn mod.on-attach [client bufnr] (fn mod.on-attach [client bufnr]
(when client.server_capabilities.documentSymbolProvider (when client.server_capabilities.documentSymbolProvider
(aucmd [:CursorHold] (aucmd [:CursorHold]

View file

@ -31,15 +31,10 @@
(.. ftype " " icon)) (.. ftype " " icon))
"no ft"))) "no ft")))
(fn mod.gitsigns-formatter [status] (fn mod.gitsigns-diff-source []
(let [{: added : changed : removed} status (let [signs vim.b.gitsigns_status_dict]
result {}] (when signs
(maybe-insert-git-status "%%#GitSignsStatuslineAdd# %s" added result) {:added signs.added :modified signs.changed :removed signs.removed})))
(maybe-insert-git-status "%%#GitSignsStatuslineChange# %s" changed
result)
(maybe-insert-git-status "%%#GitSignsStatuslineDelete# %s" removed
result)
(table.concat result " ")))
(fn mod.current-function [] (fn mod.current-function []
(let [ctx vim.b.nifoc_lsp_current_context] (let [ctx vim.b.nifoc_lsp_current_context]

View file

@ -1,5 +1,4 @@
(let [gitsigns (require :gitsigns) (let [gitsigns (require :gitsigns)]
ns (require :nifoc.statusline)]
(gitsigns.setup {:signs {:add {:hl :GitSignsAdd (gitsigns.setup {:signs {:add {:hl :GitSignsAdd
:text "│" :text "│"
:numhl :GitSignsAddNr :numhl :GitSignsAddNr
@ -22,7 +21,6 @@
:linehl :GitSignsChangeLn}} :linehl :GitSignsChangeLn}}
:numhl false :numhl false
:linehl false :linehl false
:status_formatter ns.gitsigns-formatter
:diff_opts {:internal true} :diff_opts {:internal true}
:preview_config {:border :rounded}})) :preview_config {:border :rounded}}))

View file

@ -21,6 +21,7 @@
(vim.lsp.with vim.lsp.handlers.hover {:border :rounded})) (vim.lsp.with vim.lsp.handlers.hover {:border :rounded}))
(tset vim.lsp.handlers :textDocument/signatureHelp (tset vim.lsp.handlers :textDocument/signatureHelp
(vim.lsp.with vim.lsp.handlers.signature_help {:border :rounded})) (vim.lsp.with vim.lsp.handlers.signature_help {:border :rounded}))
(nifoc-lsp.register-progress-handler)
;; Servers ;; Servers
(let [default-capabilities (vim.lsp.protocol.make_client_capabilities) (let [default-capabilities (vim.lsp.protocol.make_client_capabilities)
capabilities (cmp.update_capabilities default-capabilities) capabilities (cmp.update_capabilities default-capabilities)
@ -37,6 +38,7 @@
:html :html
:rnix :rnix
:sqls :sqls
:svelte
:taplo :taplo
:yamlls]] :yamlls]]
;; Default ;; Default

View file

@ -7,7 +7,11 @@
:icons_enabled true} :icons_enabled true}
:sections {; Left :sections {; Left
:lualine_a [:mode] :lualine_a [:mode]
:lualine_b ["b:gitsigns_status" :lualine_b [{1 :diff
:source ns.gitsigns-diff-source
:symbols {:added " "
:modified " "
:removed " "}}
{1 :diagnostics {1 :diagnostics
:sources [:nvim_diagnostic] :sources [:nvim_diagnostic]
:symbols {:error " " :symbols {:error " "
@ -23,3 +27,4 @@
ns.spell-enabled?] ns.spell-enabled?]
:lualine_y [ns.current-line-percent] :lualine_y [ns.current-line-percent]
:lualine_z [ns.line-column]}})) :lualine_z [ns.line-column]}}))