diff --git a/modules/programs/nvim/plugins/default.nix b/modules/programs/nvim/plugins/default.nix index 7e61acc..3118eb9 100644 --- a/modules/programs/nvim/plugins/default.nix +++ b/modules/programs/nvim/plugins/default.nix @@ -111,7 +111,7 @@ with builtins; } { plugin = nvim-lspconfig; - event = [ "BufReadPre" "BufNewFile" ]; + event = [ "BufRead" "BufNewFile" ]; conf = readFile ./nvim-lspconfig.lua; dependencies = [ { @@ -126,6 +126,7 @@ with builtins; { plugin = lsp_lines-nvim; } { plugin = nvim-ufo; + conf = readFile ./nvim-ufo.lua; dependencies = [ { plugin = promise-async; } ]; diff --git a/modules/programs/nvim/plugins/nvim-lspconfig.lua b/modules/programs/nvim/plugins/nvim-lspconfig.lua index 7fbc917..81a1421 100644 --- a/modules/programs/nvim/plugins/nvim-lspconfig.lua +++ b/modules/programs/nvim/plugins/nvim-lspconfig.lua @@ -5,58 +5,27 @@ vim.diagnostic.config({ virtual_text = false, }) -vim.o.foldcolumn = "1" -- '0' is not bad -vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value -vim.o.foldlevelstart = 99 -vim.o.foldenable = true -vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep: ,foldclose:]] -vim.o.statuscolumn = "%= " - -- FIXME: figure out how to put on the other side without having to do a lot of shifting - .. "%s" -- sign column - .. "%{%" -- evaluate this, and then evaluate what it returns - .. "&number ?" - .. "(v:relnum ?" - -- when showing relative numbers, make sure to pad so things don't shift as you move the cursor - .. 'printf("%"..len(line("$")).."s", v:relnum)' - .. ":" - .. "v:lnum" - .. ")" - .. ":" - .. '""' - .. " " -- space between lines and fold - .. "%}" - .. "%= " - .. "%#FoldColumn#" -- highlight group for fold - .. "%{" -- expression for showing fold expand/colapse - .. "foldlevel(v:lnum) > foldlevel(v:lnum - 1)" -- any folds? - .. "? (foldclosed(v:lnum) == -1" -- currently open? - .. '? ""' -- point down - .. ': ""' -- point to right - .. ")" - .. ': " "' -- blank for no fold, or inside fold - .. "}" - .. "%= " -- spacing between end of column and start of text - --- Using ufo provider need remap `zR` and `zM`. If Neovim is 0.6.1, remap yourself -require("which-key").register({ - z = { - R = { require("ufo").openAllFolds, "Open all folds" }, - M = { require("ufo").closeAllFolds, "Close all folds" }, - }, -}) local capabilities = vim.lsp.protocol.make_client_capabilities() +-- NOTE for nvim-ufo -- Tell the server the capability of foldingRange, -- Neovim hasn't added foldingRange to default capabilities, users must add it manually capabilities.textDocument.foldingRange = { dynamicRegistration = false, lineFoldingOnly = true, } -require("ufo").setup() local lspconfig = require("lspconfig") local on_attach_def = function(client, bufnr) require("which-key").register({ - K = { vim.lsp.buf.hover, "Hover" }, + K = { + function() + local winid = require("ufo").peekFoldedLinesUnderCursor() + if not winid then + vim.lsp.buf.hover() + end + end, + "Hover", + }, [""] = { l = { d = { vim.diagnostic.open_float, "Open diagnostic window" }, diff --git a/modules/programs/nvim/plugins/nvim-ufo.lua b/modules/programs/nvim/plugins/nvim-ufo.lua new file mode 100644 index 0000000..3bdedeb --- /dev/null +++ b/modules/programs/nvim/plugins/nvim-ufo.lua @@ -0,0 +1,98 @@ +vim.o.foldcolumn = "1" -- '0' is not bad +vim.o.foldlevel = 99 -- Using ufo provider need a large value, feel free to decrease the value +vim.o.foldlevelstart = 99 +vim.o.foldenable = true +vim.o.fillchars = [[eob: ,fold: ,foldopen:,foldsep: ,foldclose:]] +vim.o.statuscolumn = "%s" -- sign column + .. "%=" + .. "%{%" -- evaluate this, and then evaluate what it returns + .. "&number ?" + .. "(v:relnum ?" + -- when showing relative numbers, make sure to pad so things don't shift as you move the cursor + .. 'printf("%"..len(line("$")).."s", v:relnum)' + .. ":" + .. "v:lnum" + .. ")" + .. ":" + .. '""' + .. "%}" + .. "%#FoldColumn#" -- highlight group for fold + .. "%{" -- expression for showing fold expand/colapse + .. "foldlevel(v:lnum) > foldlevel(v:lnum - 1)" -- any folds? + .. "? (foldclosed(v:lnum) == -1" -- currently open? + .. '? ""' -- point down + .. ': ""' -- point to right + .. ")" + .. ': " "' -- blank for no fold, or inside fold + .. "}" + .. " " + +local ftMap = { + vim = "indent", + python = { "indent" }, + git = "", +} + +---@param bufnr number +---@return Promise +local function customizeSelector(bufnr) + local function handleFallbackException(err, providerName) + if type(err) == "string" and err:match("UfoFallbackException") then + return require("ufo").getFolds(bufnr, providerName) + else + return require("promise").reject(err) + end + end + + return require("ufo") + .getFolds(bufnr, "lsp") + :catch(function(err) + return handleFallbackException(err, "treesitter") + end) + :catch(function(err) + return handleFallbackException(err, "indent") + end) +end + +local handler = function(virtText, lnum, endLnum, width, truncate) + local newVirtText = {} + local suffix = ("  %d "):format(endLnum - lnum) + local sufWidth = vim.fn.strdisplaywidth(suffix) + local targetWidth = width - sufWidth + local curWidth = 0 + for _, chunk in ipairs(virtText) do + local chunkText = chunk[1] + local chunkWidth = vim.fn.strdisplaywidth(chunkText) + if targetWidth > curWidth + chunkWidth then + table.insert(newVirtText, chunk) + else + chunkText = truncate(chunkText, targetWidth - curWidth) + local hlGroup = chunk[2] + table.insert(newVirtText, { chunkText, hlGroup }) + chunkWidth = vim.fn.strdisplaywidth(chunkText) + -- str width returned from truncate() may less than 2nd argument, need padding + if curWidth + chunkWidth < targetWidth then + suffix = suffix .. (" "):rep(targetWidth - curWidth - chunkWidth) + end + break + end + curWidth = curWidth + chunkWidth + end + table.insert(newVirtText, { suffix, "MoreMsg" }) + return newVirtText +end + +require("ufo").setup({ + provider_selector = function(_, filetype, _) + return ftMap[filetype] or customizeSelector + end, + fold_virt_text_handler = handler, +}) + +-- Using ufo provider need remap `zR` and `zM`. If Neovim is 0.6.1, remap yourself +require("which-key").register({ + z = { + R = { require("ufo").openAllFolds, "Open all folds" }, + M = { require("ufo").closeAllFolds, "Close all folds" }, + }, +})