nvim: LSP utility functions
This commit is contained in:
parent
674e1bda01
commit
a6065908bd
6 changed files with 134 additions and 32 deletions
|
@ -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}]
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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]
|
||||||
|
|
|
@ -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}}))
|
||||||
|
|
||||||
|
|
|
@ -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
|
||||||
|
|
|
@ -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]}}))
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue