aboutsummaryrefslogtreecommitdiffstats
path: root/lua/pi
diff options
context:
space:
mode:
authorElvis Claros Castro <elvis@claros.ar>2026-09-27 12:46:49 -0300
committerElvis Claros Castro <elvis@claros.ar>2026-09-27 12:46:49 -0300
commitdf7c711e2a49d51249350f52c63274b72aacb739 (patch)
tree426da3b65371f857f3ee3d9893d7ff3279aac02e /lua/pi
parenta0bd84df02ce235123dfc939327e8bd33dffdd7e (diff)
downloadnvim-conf-df7c711e2a49d51249350f52c63274b72aacb739.tar.gz
nvim-conf-df7c711e2a49d51249350f52c63274b72aacb739.zip
Migración de plugins a funcionalidad nativa: statusline y treesitter propios, se quitan mason, lualine, mini, notify y otros
Diffstat (limited to 'lua/pi')
-rw-r--r--lua/pi/animations.lua71
-rw-r--r--lua/pi/dap/configs/cpp.lua46
-rw-r--r--lua/pi/lsp/attach.lua2
-rw-r--r--lua/pi/lsp/default.lua4
-rw-r--r--lua/pi/lsp/init.lua13
-rw-r--r--lua/pi/lsp/mason.lua33
-rw-r--r--lua/pi/snips/ft/go.lua24
-rw-r--r--lua/pi/treesitter.lua248
8 files changed, 327 insertions, 114 deletions
diff --git a/lua/pi/animations.lua b/lua/pi/animations.lua
index 3ff711f..e4bc859 100644
--- a/lua/pi/animations.lua
+++ b/lua/pi/animations.lua
@@ -1,48 +1,39 @@
-local redraw_buffer = function()
- local Animation = require "animation"
- local fps = 15 -- frames per second
- local easing = require "animation.easing"
-
- local buffer = 0
- local len = 0
- local place_holder = {}
+-- Animación de "retipeo" del buffer, con vim.uv (antes dependía de animation.nvim).
+local fps = 15 -- un caracter por frame, como la versión original
+local redraw_buffer = function()
+ local buffer = vim.api.nvim_get_current_buf()
local lines = vim.api.nvim_buf_get_lines(buffer, 0, -1, true)
- for _, line in ipairs(lines) do
- len = len + string.len(line)
+ local place_holder = {}
+ for _ = 1, #lines do
table.insert(place_holder, "")
end
-
- vim.api.nvim_buf_set_lines(buffer, 0, #lines, true, place_holder)
-
- local duration = math.ceil(len / fps * 1000)
-
- local i = 1
- local line_nr = 1
- local insertLine = ""
-
- local function callback()
- if lines[line_nr] == nil then
- return true
- end
- local char = string.sub(lines[line_nr], i, i)
- if char == nil then
- return true
- end
- insertLine = insertLine .. char
- i = i + 1
- vim.api.nvim_buf_set_lines(buffer, line_nr - 1, line_nr, true, { insertLine })
-
- if insertLine == lines[line_nr] then
- i = 1
- line_nr = line_nr + 1
- insertLine = ""
- end
- end
-
- local animation = Animation(duration, fps, easing.line, callback)
- animation:run()
+ vim.api.nvim_buf_set_lines(buffer, 0, -1, true, place_holder)
+
+ local line_nr, col = 1, 0
+ local timer = assert(vim.uv.new_timer())
+
+ timer:start(
+ 0,
+ math.floor(1000 / fps),
+ vim.schedule_wrap(function()
+ if not vim.api.nvim_buf_is_valid(buffer) or line_nr > #lines then
+ timer:stop()
+ timer:close()
+ return
+ end
+
+ col = col + 1
+ local line = lines[line_nr]
+ vim.api.nvim_buf_set_lines(buffer, line_nr - 1, line_nr, true, { line:sub(1, col) })
+
+ if col >= #line then
+ line_nr = line_nr + 1
+ col = 0
+ end
+ end)
+ )
end
return {
diff --git a/lua/pi/dap/configs/cpp.lua b/lua/pi/dap/configs/cpp.lua
index a2718b0..4f47345 100644
--- a/lua/pi/dap/configs/cpp.lua
+++ b/lua/pi/dap/configs/cpp.lua
@@ -1,24 +1,47 @@
local dap = require("dap")
+-- gdb DAP nativo (gdb >= 14). No usa runInTerminal, así que evita el bug
+-- de nvim-dap `terminals.acquire` en Neovim 0.13-dev. La salida del programa
+-- aparece en la consola/repl de dap-ui.
+dap.adapters.gdb = {
+ type = "executable",
+ command = "gdb",
+ args = { "--interpreter=dap", "--eval-command", "set print pretty on" },
+}
+
+-- Adaptador cpptools/OpenDebugAD7 (Microsoft) como fallback.
dap.adapters.cppdbg = {
id = 'cppdbg',
type = 'executable',
command = '/home/elvis/.local/share/nvim/mason/packages/cpptools/extension/debugAdapters/bin/OpenDebugAD7',
}
+local function pick_program()
+ return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
+end
+
+local function pick_args()
+ return vim.split(vim.fn.input('Program arguments: ', ''), " ")
+end
+
dap.configurations.cpp = {
{
- name = "Launch file",
+ name = "Launch (gdb)",
+ type = "gdb",
+ request = "launch",
+ program = pick_program,
+ cwd = "${workspaceFolder}",
+ args = pick_args,
+ stopAtBeginningOfMainSubprogram = true, -- equivalente a stopAtEntry en gdb DAP
+ },
+ {
+ name = "Launch (cppdbg / cpptools)",
type = "cppdbg",
request = "launch",
- program = function()
- return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
- end,
+ program = pick_program,
cwd = '${workspaceFolder}',
stopAtEntry = true,
- args = function()
- return vim.split(vim.fn.input('Program arguments: ', ''), " ")
- end,
+ args = pick_args,
},
{
name = 'Attach to gdbserver :1234',
@@ -28,14 +51,9 @@ dap.configurations.cpp = {
miDebuggerServerAddress = 'localhost:1234',
miDebuggerPath = '/usr/bin/gdb',
cwd = '${workspaceFolder}',
- program = function()
- return vim.fn.input('Path to executable: ', vim.fn.getcwd() .. '/', 'file')
- end,
- args = function()
- return vim.split(vim.fn.input('Program arguments: ', ''), " ")
- end,
+ program = pick_program,
+ args = pick_args,
},
}
dap.configurations.c = dap.configurations.cpp
-
diff --git a/lua/pi/lsp/attach.lua b/lua/pi/lsp/attach.lua
index 7030cbd..e05f3f3 100644
--- a/lua/pi/lsp/attach.lua
+++ b/lua/pi/lsp/attach.lua
@@ -23,7 +23,7 @@ return function(client, bufnr)
vim.keymap.set("n", "gr", function() Snacks.picker.lsp_references() end, { buffer = bufnr, desc = "LSP References of symbol on cursor" })
vim.keymap.set("n", "<leader>pv", function() Snacks.picker.lsp_workspace_symbols() end, { buffer = bufnr, desc = "LSP find symbol on the project" })
vim.keymap.set("n", "<leader>pd", function() Snacks.picker.lsp_symbols() end, { buffer = bufnr, desc = "LSP document symbols" })
- vim.keymap.set("n", "<C-S-[>", function() Snacks.picker.lsp_definitions() end, { buffer = bufnr, desc = "LSP go to definition" })
+ vim.keymap.set("n", "gd", function() Snacks.picker.lsp_definitions() end, { buffer = bufnr, desc = "LSP go to definition" })
vim.bo.omnifunc = "v:lua.vim.lsp.omnifunc"
diff --git a/lua/pi/lsp/default.lua b/lua/pi/lsp/default.lua
index efde87a..1f4dfb0 100644
--- a/lua/pi/lsp/default.lua
+++ b/lua/pi/lsp/default.lua
@@ -35,10 +35,6 @@ local server_commands = {
}
return {
- mason = {
- enable = true,
- auto_install = false,
- },
get_server_cmd = function(server)
return server_commands[server] or { server }
end,
diff --git a/lua/pi/lsp/init.lua b/lua/pi/lsp/init.lua
index de6e95b..ebc8fab 100644
--- a/lua/pi/lsp/init.lua
+++ b/lua/pi/lsp/init.lua
@@ -10,7 +10,6 @@ return {
return orig_open_floating_preview(contents, syntax, opts, ...)
end
- local mason_servers = {}
for server, options in pairs(ops.servers) do
if options.enable == true then
local ok, definition = pcall(require, "pi.lsp.servers." .. server)
@@ -53,19 +52,7 @@ return {
end,
})
end
-
- table.insert(mason_servers, server)
- end
- end
-
- -- Mason
- if ops.mason.enable then
- local mason_ops = {}
- if ops.mason.auto_install == true then
- mason_ops.ensure_installed = mason_servers
end
- local mason_lspconfig = require "mason-lspconfig"
- mason_lspconfig.setup(mason_ops)
end
-- TODO: implement null ls with options
diff --git a/lua/pi/lsp/mason.lua b/lua/pi/lsp/mason.lua
deleted file mode 100644
index 6c959a6..0000000
--- a/lua/pi/lsp/mason.lua
+++ /dev/null
@@ -1,33 +0,0 @@
-local mason_lspconfig = require "mason-lspconfig"
-local servers = require "pi.lsp.servers"
-
--- Note: This file is deprecated in favor of native LSP configuration
--- Keeping for reference/compatibility
-
-local mason_servers = {}
-
--- Since we're using native LSP, we'll check for executables differently
-local server_commands = {
- lua_ls = "lua-language-server",
- gopls = "gopls",
- ts_ls = "typescript-language-server",
- -- Add other servers as needed
-}
-
-for server, _ in pairs(servers) do
- local cmd = server_commands[server] or server
- if vim.fn.executable(cmd) == 0 then
- table.insert(mason_servers, server)
- end
-end
-
-mason_lspconfig.setup {
- -- ensure_installed = mason_servers,
-}
-
--- filter the list for the ones not globally installed
--- require("mason-tool-installer").setup {
--- ensure_installed = vim.tbl_filter(function (tool)
--- return vim.fn.executable(tool) == 0
--- end, require "pi.lsp.tools"),
--- }
diff --git a/lua/pi/snips/ft/go.lua b/lua/pi/snips/ft/go.lua
index 9c3977f..4490e63 100644
--- a/lua/pi/snips/ft/go.lua
+++ b/lua/pi/snips/ft/go.lua
@@ -8,9 +8,6 @@ local i = ls.insert_node
local rep = require("luasnip.extras").rep
local fmt = require("luasnip.extras.fmt").fmt
-local ts_locals = require "nvim-treesitter.locals"
-local ts_utils = require "nvim-treesitter.ts_utils"
-
local get_node_text = vim.treesitter.get_node_text
vim.treesitter.query.set(
@@ -71,19 +68,28 @@ local handlers = {
end,
}
+-- `nvim-treesitter.locals`/`ts_utils` no existen en la rama `main`; subimos a
+-- mano por los padres del nodo bajo el cursor hasta la función que lo contiene.
local function go_result_type(info)
- local cursor_node = ts_utils.get_node_at_cursor()
- local scope = ts_locals.get_scope_tree(cursor_node, 0)
-
local function_node
- for _, v in ipairs(scope) do
- if v:type() == "function_declaration" or v:type() == "method_declaration" or v:type() == "func_literal" then
- function_node = v
+ local node = vim.treesitter.get_node()
+ while node do
+ local kind = node:type()
+ if kind == "function_declaration" or kind == "method_declaration" or kind == "func_literal" then
+ function_node = node
break
end
+ node = node:parent()
+ end
+
+ if not function_node then
+ return
end
local query = vim.treesitter.query.get("go", "LuaSnip_Result")
+ if not query then
+ return
+ end
for _, node in query:iter_captures(function_node, 0) do
if handlers[node:type()] then
return handlers[node:type()](node, info)
diff --git a/lua/pi/treesitter.lua b/lua/pi/treesitter.lua
new file mode 100644
index 0000000..d137ac5
--- /dev/null
+++ b/lua/pi/treesitter.lua
@@ -0,0 +1,248 @@
+-- Integración de treesitter para Neovim 0.13 + nvim-treesitter rama `main`.
+--
+-- La rama `main` es una reescritura sin sistema de módulos: sólo instala parsers
+-- y provee queries. Highlight, indent, folds e injections los da Neovim, así que
+-- el enganche lo hacemos nosotros en un autocomando FileType.
+
+local M = {}
+
+local install_dir = vim.fs.joinpath(vim.fn.stdpath "data", "site")
+
+--- Parsers que queremos siempre disponibles.
+M.ensure_installed = {
+ "bash",
+ "blade",
+ "css",
+ "dockerfile",
+ "cpp",
+ "elixir",
+ "erlang",
+ "go",
+ "gomod",
+ "html",
+ "javascript",
+ "json",
+ "latex",
+ "lua",
+ "luadoc",
+ "markdown",
+ "markdown_inline",
+ "nix",
+ "php",
+ "php_only",
+ "phpdoc",
+ "python",
+ "query",
+ "regex",
+ "rust",
+ "sql",
+ "svelte",
+ "twig",
+ "typescript",
+ "typst",
+ "vim",
+ "yaml",
+}
+
+--- Filetypes de buffers de plugins que reusan el parser de otro lenguaje.
+M.language_aliases = {
+ codecompanion = "markdown",
+ snacks_notif = "markdown",
+ oil = "markdown",
+}
+
+--- Filetypes donde no queremos highlight ni indent de treesitter.
+M.disabled_filetypes = {
+ oil = true,
+ snacks_notif = true,
+}
+
+---@param lang string
+---@return boolean
+local function parser_available(lang)
+ return #vim.api.nvim_get_runtime_file("parser/" .. lang .. ".so", false) > 0
+end
+
+--- Reemplazo de `auto_install`: instala el parser que falte, una sola vez por
+--- lenguaje y sin bloquear, y engancha el buffer cuando termina.
+local installing = {} ---@type table<string, true>
+
+---@param lang string
+---@param on_ready fun()
+local function install_missing(lang, on_ready)
+ if installing[lang] then
+ return
+ end
+ local ok, parsers = pcall(require, "nvim-treesitter.parsers")
+ if not ok or not parsers[lang] then
+ return
+ end
+ installing[lang] = true
+ require("nvim-treesitter").install({ lang }):await(function()
+ installing[lang] = nil
+ vim.schedule(on_ready)
+ end)
+end
+
+---@param buf integer
+local function attach(buf)
+ if not vim.api.nvim_buf_is_valid(buf) then
+ return
+ end
+
+ local ft = vim.bo[buf].filetype
+ if ft == "" or M.disabled_filetypes[ft] then
+ return
+ end
+
+ local lang = vim.treesitter.language.get_lang(ft)
+ if not lang then
+ return
+ end
+
+ if not parser_available(lang) then
+ install_missing(lang, function()
+ attach(buf)
+ end)
+ return
+ end
+
+ if not pcall(vim.treesitter.start, buf, lang) then
+ return
+ end
+
+ -- Indent de nvim-treesitter (experimental, era el módulo `indent` en master).
+ -- Sólo si el lenguaje trae query `indents`; si no, dejamos el indentexpr del
+ -- ftplugin, que es mejor que un fallback vacío.
+ if vim.treesitter.query.get(lang, "indents") then
+ vim.bo[buf].indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
+ end
+end
+
+function M.setup()
+ require("nvim-treesitter").setup { install_dir = install_dir }
+
+ for ft, lang in pairs(M.language_aliases) do
+ vim.treesitter.language.register(lang, ft)
+ end
+
+ vim.filetype.add {
+ pattern = {
+ [".*%.blade%.php"] = "blade",
+ },
+ }
+
+ require("nvim-treesitter").install(M.ensure_installed)
+
+ vim.api.nvim_create_autocmd("FileType", {
+ group = vim.api.nvim_create_augroup("pi_treesitter", { clear = true }),
+ callback = function(args)
+ attach(args.buf)
+ end,
+ })
+
+ -- El autocomando llega tarde para los buffers que ya se abrieron al arrancar.
+ for _, buf in ipairs(vim.api.nvim_list_bufs()) do
+ if vim.api.nvim_buf_is_loaded(buf) then
+ attach(buf)
+ end
+ end
+
+ M.setup_incremental_selection()
+end
+
+--------------------------------------------------------------------------------
+-- Selección incremental
+--
+-- El módulo `incremental_selection` desapareció con la rama `main` y Neovim no
+-- trae equivalente. Esto reimplementa los cuatro mapeos que había: gnn / grn /
+-- grc / grm.
+--------------------------------------------------------------------------------
+
+local stacks = {} ---@type table<integer, TSNode[]>
+
+---@param node TSNode
+local function select_node(node)
+ local srow, scol, erow, ecol = node:range()
+ if ecol == 0 and erow > srow then
+ erow = erow - 1
+ ecol = #(vim.api.nvim_buf_get_lines(0, erow, erow + 1, false)[1] or "")
+ end
+ if vim.fn.mode() ~= "n" then
+ vim.cmd "normal! \27"
+ end
+ vim.fn.setpos("'<", { 0, srow + 1, scol + 1, 0 })
+ vim.fn.setpos("'>", { 0, erow + 1, math.max(ecol, 1), 0 })
+ vim.cmd "normal! gv"
+end
+
+---@return TSNode[]
+local function stack()
+ local buf = vim.api.nvim_get_current_buf()
+ stacks[buf] = stacks[buf] or {}
+ return stacks[buf]
+end
+
+local function init_selection()
+ local node = vim.treesitter.get_node()
+ if not node then
+ return
+ end
+ local s = stack()
+ for i = #s, 1, -1 do
+ s[i] = nil
+ end
+ s[1] = node
+ select_node(node)
+end
+
+--- Sube al ancestro más chico que sea estrictamente más grande que el actual.
+---@param predicate? fun(node: TSNode, from: TSNode): boolean
+local function grow(predicate)
+ local s = stack()
+ local node = s[#s] or vim.treesitter.get_node()
+ if not node then
+ return
+ end
+ local parent = node:parent()
+ while parent do
+ local same = vim.deep_equal({ parent:range() }, { node:range() })
+ if not same and (not predicate or predicate(parent, node)) then
+ s[#s + 1] = parent
+ select_node(parent)
+ return
+ end
+ parent = parent:parent()
+ end
+ select_node(node)
+end
+
+local function shrink()
+ local s = stack()
+ if #s > 1 then
+ s[#s] = nil
+ end
+ local node = s[#s]
+ if node then
+ select_node(node)
+ end
+end
+
+function M.setup_incremental_selection()
+ local map = vim.keymap.set
+ map("n", "gnn", init_selection, { desc = "Treesitter: iniciar selección" })
+ map("x", "grn", function()
+ grow()
+ end, { desc = "Treesitter: expandir al nodo padre" })
+ map("x", "grc", function()
+ -- "scope": el primer ancestro que abarque más líneas que el nodo actual.
+ grow(function(parent, from)
+ local psrow, _, perow = parent:range()
+ local srow, _, erow = from:range()
+ return (perow - psrow) > (erow - srow)
+ end)
+ end, { desc = "Treesitter: expandir al scope" })
+ map("x", "grm", shrink, { desc = "Treesitter: reducir selección" })
+end
+
+return M