mirror of
https://github.com/dwinkler1/nvimConfig.git
synced 2026-08-22 17:43:13 -04:00
Tackles the critical and high-impact findings from the in-PR review of commit7f01be5, plus one consistency fix (M1). All changes are scoped to the same review branch (PR #12); no behavior changes elsewhere. Critical fixes * C1 -- plugin/22_languages.lua: now does `local Config = require('config')` at the top, matching every other `plugin/*.lua` file. Previously the file referenced `Config` as a global, depending on `_G.Config` having been initialized by `init.lua` before this file loaded. Fragile. * C2 -- plugin/04_treesitter.lua: removed the hard `<CR>` -> `smart_send.send_repl` mapping. Override `<CR>` from a per-buffer `ftplugin/<lang>.lua` if you want enter-to-send behavior. R.nvim's `<Plug>RDSendLine` (wired by `ftplugin/r.lua`) remains the default for R files and is no longer silently clobbered. High-impact fixes * C3 -- plugin/27_image.lua: `image.setup({ backend = "kitty" })` -> `backend = "auto"`. The previous value silently failed on every terminal that is not Kitty. `"auto"` delegates detection to image.nvim. * H1 -- plugin/10_keymap.lua: `_G.Config = Config` removed from this file; `init.lua:2` remains the single source. Avoids drift between two aliasing sites. * H2 -- plugin/25_lsp.lua: `texlab = { single_file_support = true }`, so single-file `.tex` buffers attach the LSP without lspconfig's sometimes-brittle root_dir heuristic. * H5 -- plugin/04_treesitter.lua: also drops `<S-CR>` from `M.setup_keybindings` on the same principle as C2. `<S-CR>` was a hard implicit override in both normal and insert mode, where it collided with snippet and transient-state plugins. Consistency fixes * M1 -- plugin/01_lib.lua: `print(line)` in `Config.execute_lua_line` switched to `vim.notify(line, vim.log.levels.INFO)`, matching the print->notify cleanup in `plugin/04_treesitter.lua` from7f01be5. Files: 6 modified. +21 / -11. Local verification 1. `luac -p plugin/{22_languages,27_image,10_keymap,25_lsp,04_treesitter,01_lib}.lua` 2. `nvim --headless -u NONE -l tests/init.lua` 3. Open a R / quarto / tex buffer; verify `<CR>` is no longer hijacked by `smart_send` and behaves like the filetype default. For reviewers * The text-object configuration in plugin/04_treesitter.lua's textobjects block is unchanged. H4 (`@assignment.*` queries may not be defined for R) is left for a follow-up with verification. * yamlls GitHub-rawURL schema dependency (H3) is left intentionally -- vendoring the schemas is a separate decision. * Tests (T1-T6 from the review) are deferred; no test infrastructure exists beyond `tests/init.lua`.
197 lines
6 KiB
Lua
197 lines
6 KiB
Lua
local Config = require('config')
|
|
|
|
local M = {}
|
|
|
|
-- Default parsers list moved from startup config
|
|
M.default_parsers = {
|
|
"bash", "bibtex", "c", "caddy", "cmake", "comment", "commonlisp", "cpp", "css", "csv",
|
|
"cuda", "desktop", "diff", "dockerfile", "doxygen", "editorconfig", "fortran", "git_config", "git_rebase",
|
|
"gitattributes", "gitcommit", "gitignore", "gnuplot", "go", "gpg", "html", "javascript", "jq", "json", "json5",
|
|
"julia", "just", "latex", "ledger", "lua", "luadoc", "luap", "luau", "make", "markdown", "markdown_inline",
|
|
"matlab", "meson", "muttrc", "nix", "nu", "passwd", "powershell", "prql", "python", "r", "query", "readline", "regex",
|
|
"requirements", "rnoweb", "rust", "sql", "ssh_config", "swift", "tmux", "toml", "tsv", "tsx", "typescript", "typst",
|
|
"vala", "vim", "vimdoc", "yaml", "zig",
|
|
}
|
|
|
|
-- Cache treesitter utils to avoid repeated requires
|
|
local smart_send = require('nix_smart_send')
|
|
|
|
-- Helper function to check if value exists in list (optimized with early return)
|
|
local function is_in_list(list, value)
|
|
if not list or not value then
|
|
return false
|
|
end
|
|
|
|
for _, v in ipairs(list) do
|
|
if v == value then
|
|
return true
|
|
end
|
|
end
|
|
return false
|
|
end
|
|
|
|
|
|
function M.add_global_node(nodes)
|
|
if not nodes then
|
|
return nil
|
|
end
|
|
|
|
local node_type = M.get_type()
|
|
if not node_type then
|
|
return nodes
|
|
end
|
|
|
|
-- Create a copy to avoid modifying the original
|
|
local global_nodes = vim.deepcopy(nodes)
|
|
|
|
-- Check if node type already exists to avoid duplicates
|
|
if not is_in_list(global_nodes, node_type) then
|
|
table.insert(global_nodes, node_type)
|
|
end
|
|
|
|
return global_nodes
|
|
end
|
|
|
|
function M.remove_global_node(nodes)
|
|
if not nodes then
|
|
return nil
|
|
end
|
|
|
|
local node_type = M.get_type()
|
|
if not node_type then
|
|
return nodes
|
|
end
|
|
|
|
local global_nodes = vim.deepcopy(nodes)
|
|
|
|
-- Remove all occurrences (iterate backwards to avoid index issues)
|
|
for i = #global_nodes, 1, -1 do
|
|
if global_nodes[i] == node_type then
|
|
table.remove(global_nodes, i)
|
|
end
|
|
end
|
|
|
|
return global_nodes
|
|
end
|
|
|
|
function M.set_global_nodes()
|
|
local input = vim.fn.input("Enter root nodes: ")
|
|
if input == "" then
|
|
return {}
|
|
end
|
|
|
|
local nodes_in = {}
|
|
-- Trim whitespace from each node name
|
|
for node in string.gmatch(input, '([^,]+)') do
|
|
local trimmed = vim.trim(node)
|
|
if trimmed ~= "" then
|
|
table.insert(nodes_in, trimmed)
|
|
end
|
|
end
|
|
|
|
return nodes_in
|
|
end
|
|
|
|
function M.get_type()
|
|
local cur_node = smart_send.get_current_node()
|
|
if not cur_node then
|
|
vim.notify("No Tree-sitter node under cursor", vim.log.levels.WARN)
|
|
return nil
|
|
end
|
|
|
|
local node_type = cur_node:type()
|
|
vim.notify("Node type: " .. node_type, vim.log.levels.INFO)
|
|
return node_type
|
|
end
|
|
|
|
|
|
function M.setup_keybindings(global_nodes)
|
|
local current_global_nodes = global_nodes
|
|
|
|
vim.keymap.set({ 'n' }, '<localleader>r', function()
|
|
current_global_nodes = M.set_global_nodes()
|
|
end,
|
|
{ noremap = true, silent = true, desc = "set global_nodes", buffer = true })
|
|
|
|
vim.keymap.set({ 'n', 'v' }, '<localleader>v', function()
|
|
smart_send.move_to_next_non_empty_line(); smart_send.select_until_global(current_global_nodes)
|
|
end,
|
|
{ noremap = true, silent = true, desc = "Visual select next node after WS", buffer = true })
|
|
|
|
vim.keymap.set('n', '<localleader>a', function() smart_send.send_repl(current_global_nodes) end,
|
|
{ noremap = true, silent = true, desc = "Send node to REPL", buffer = true })
|
|
|
|
-- Both `<CR>` and `<S-CR>` were removed from `M.setup_keybindings`. They
|
|
-- were hard, implicit overrides that clobbered Vim/filetype defaults and
|
|
-- the user's snippet + insert-mode workflows (see C2 + H5 in the PR
|
|
-- review). To opt back in for a specific filetype, override per-buffer
|
|
-- from a `ftplugin/<lang>.lua`:
|
|
--
|
|
-- -- e.g. ftplugin/r.lua or ftplugin/quarto.lua
|
|
-- vim.keymap.set('n', '<CR>', function()
|
|
-- require('config').treesitter_helpers.setup_keybindings(global_nodes)
|
|
-- require('nix_smart_send').send_repl(global_nodes)
|
|
-- end, { buffer = true, desc = 'Send node to REPL' })
|
|
|
|
vim.keymap.set('n', '<localleader>n',
|
|
function() current_global_nodes = M.add_global_node(current_global_nodes) end,
|
|
{ noremap = true, silent = true, desc = "Add node under cursor to globals", buffer = true })
|
|
|
|
vim.keymap.set('n', '<localleader>x',
|
|
function() current_global_nodes = M.remove_global_node(current_global_nodes) end,
|
|
{ noremap = true, silent = true, desc = "Remove node under cursor from globals", buffer = true })
|
|
|
|
vim.keymap.set('n', '<localleader>o', function()
|
|
local pout = table.concat(global_nodes, ', ')
|
|
vim.notify("global_nodes: " .. pout, vim.log.levels.INFO)
|
|
end, { noremap = true, silent = true, desc = "Print globals", buffer = true })
|
|
|
|
vim.keymap.set('n', '<localleader>p', function() M.get_type() end,
|
|
{ noremap = true, silent = true, desc = "Print node type", buffer = true })
|
|
end
|
|
|
|
Config.treesitter_helpers = M
|
|
|
|
-- Tree-sitter text objects: functions, calls, and assignments are especially
|
|
-- useful when editing R/tidyverse pipelines (e.g. `df |> mutate(...)`).
|
|
local ts_ok, treesitter = pcall(require, "nvim-treesitter.configs")
|
|
if ts_ok then
|
|
treesitter.setup({
|
|
textobjects = {
|
|
select = {
|
|
enable = true,
|
|
lookahead = true,
|
|
keymaps = {
|
|
["af"] = "@function.outer",
|
|
["if"] = "@function.inner",
|
|
["ac"] = "@call.outer",
|
|
["ic"] = "@call.inner",
|
|
["aa"] = "@assignment.outer",
|
|
["ia"] = "@assignment.inner",
|
|
},
|
|
selection_modes = {
|
|
["@function.outer"] = "V",
|
|
["@function.inner"] = "V",
|
|
["@call.outer"] = "v",
|
|
["@call.inner"] = "v",
|
|
["@assignment.outer"] = "v",
|
|
["@assignment.inner"] = "v",
|
|
},
|
|
},
|
|
move = {
|
|
enable = true,
|
|
set_jumps = true,
|
|
goto_next_start = {
|
|
["]f"] = "@function.outer",
|
|
["]c"] = "@call.outer",
|
|
},
|
|
goto_previous_start = {
|
|
["[f"] = "@function.outer",
|
|
["[c"] = "@call.outer",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
end
|
|
|
|
return M
|