initial config push
This commit is contained in:
6
lua/plugins/cmp.lua
Normal file
6
lua/plugins/cmp.lua
Normal file
@@ -0,0 +1,6 @@
|
||||
require("blink.cmp").setup({
|
||||
keymap = { preset = "default" },
|
||||
sources = {
|
||||
default = { "lsp", "path", "buffer" },
|
||||
},
|
||||
})
|
||||
133
lua/plugins/lsp.lua
Normal file
133
lua/plugins/lsp.lua
Normal file
@@ -0,0 +1,133 @@
|
||||
require("mason").setup()
|
||||
|
||||
-- Add mason bin to PATH so vim.lsp.enable can find installed servers
|
||||
vim.env.PATH = vim.fn.stdpath("data") .. "/mason/bin:" .. vim.env.PATH
|
||||
|
||||
require("mason-lspconfig").setup({
|
||||
ensure_installed = {
|
||||
"gopls",
|
||||
"bashls",
|
||||
"ansiblels",
|
||||
"yamlls",
|
||||
},
|
||||
})
|
||||
|
||||
vim.lsp.config("gopls", {
|
||||
cmd = { "gopls" },
|
||||
filetypes = { "go", "gomod", "gowork", "gotmpl" },
|
||||
root_markers = { "go.mod", "go.work", ".git" },
|
||||
settings = {
|
||||
gopls = {
|
||||
analyses = {
|
||||
unusedparams = true,
|
||||
shadow = true,
|
||||
nilness = true,
|
||||
unusedwrite = true,
|
||||
useany = true,
|
||||
},
|
||||
staticcheck = true,
|
||||
gofumpt = true,
|
||||
},
|
||||
},
|
||||
})
|
||||
vim.lsp.config("bashls", {
|
||||
cmd = { "bash-language-server", "start" },
|
||||
filetypes = { "sh", "bash" },
|
||||
})
|
||||
vim.lsp.config("ansiblels", {
|
||||
cmd = { "ansible-language-server", "--stdio" },
|
||||
filetypes = { "yaml.ansible" },
|
||||
root_markers = { "ansible.cfg", ".ansible-lint", "playbooks" },
|
||||
})
|
||||
vim.lsp.config("yamlls", {
|
||||
cmd = { "yaml-language-server", "--stdio" },
|
||||
filetypes = { "yaml", "yaml.docker-compose" },
|
||||
})
|
||||
|
||||
vim.lsp.enable({ "gopls", "bashls", "ansiblels", "yamlls" })
|
||||
|
||||
-- Diagnostics UI
|
||||
vim.diagnostic.config({
|
||||
virtual_text = true,
|
||||
signs = true,
|
||||
underline = true,
|
||||
update_in_insert = false,
|
||||
float = { border = "rounded" },
|
||||
})
|
||||
|
||||
-- LSP keymaps (set when an LSP attaches)
|
||||
vim.api.nvim_create_autocmd("LspAttach", {
|
||||
group = vim.api.nvim_create_augroup("lsp_keymaps", { clear = true }),
|
||||
callback = function(ev)
|
||||
local opts = { buffer = ev.buf }
|
||||
|
||||
-- Jump to definition, reusing an existing split if the file is already open
|
||||
local function goto_definition_reuse()
|
||||
local params = vim.lsp.util.make_position_params(0, "utf-8")
|
||||
vim.lsp.buf_request(0, "textDocument/definition", params, function(err, result)
|
||||
if err or not result or vim.tbl_isempty(result) then return end
|
||||
local target = result[1] or result
|
||||
local uri = target.uri or target.targetUri
|
||||
local range = target.range or target.targetSelectionRange
|
||||
local bufnr = vim.uri_to_bufnr(uri)
|
||||
-- Check if file is already visible in a window
|
||||
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
||||
if vim.api.nvim_win_get_buf(win) == bufnr then
|
||||
vim.api.nvim_set_current_win(win)
|
||||
local pos = range.start
|
||||
vim.api.nvim_win_set_cursor(win, { pos.line + 1, pos.character })
|
||||
return
|
||||
end
|
||||
end
|
||||
-- Not open anywhere, use default behavior
|
||||
vim.lsp.util.show_document(target, "utf-8", { focus = true })
|
||||
end)
|
||||
end
|
||||
|
||||
-- Navigation
|
||||
vim.keymap.set("n", "gd", goto_definition_reuse, opts)
|
||||
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts)
|
||||
vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts)
|
||||
vim.keymap.set("n", "gr", vim.lsp.buf.references, opts)
|
||||
vim.keymap.set("n", "gt", vim.lsp.buf.type_definition, opts)
|
||||
|
||||
-- Info
|
||||
vim.keymap.set("n", "K", vim.lsp.buf.hover, opts)
|
||||
vim.keymap.set("n", "<C-k>", vim.lsp.buf.signature_help, opts)
|
||||
vim.keymap.set("i", "<C-k>", vim.lsp.buf.signature_help, opts)
|
||||
|
||||
-- Actions
|
||||
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action, opts)
|
||||
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, opts)
|
||||
vim.keymap.set("n", "<leader>f", function() vim.lsp.buf.format({ async = true }) end, opts)
|
||||
|
||||
-- Diagnostics
|
||||
vim.keymap.set("n", "[d", vim.diagnostic.goto_prev, opts)
|
||||
vim.keymap.set("n", "]d", vim.diagnostic.goto_next, opts)
|
||||
vim.keymap.set("n", "<leader>q", vim.diagnostic.setloclist, opts)
|
||||
vim.keymap.set("n", "gl", vim.diagnostic.open_float, opts)
|
||||
end,
|
||||
})
|
||||
|
||||
-- Auto-format and organize imports on save for Go
|
||||
vim.api.nvim_create_autocmd("BufWritePre", {
|
||||
group = vim.api.nvim_create_augroup("go_organize_imports", { clear = true }),
|
||||
pattern = "*.go",
|
||||
callback = function()
|
||||
-- Organize imports via code action
|
||||
local params = vim.lsp.util.make_range_params(0, "utf-8")
|
||||
params.context = { only = { "source.organizeImports" } }
|
||||
local result = vim.lsp.buf_request_sync(0, "textDocument/codeAction", params, 1000)
|
||||
for _, res in pairs(result or {}) do
|
||||
for _, action in pairs(res.result or {}) do
|
||||
if action.edit then
|
||||
vim.lsp.util.apply_workspace_edit(action.edit, "utf-8")
|
||||
elseif action.command then
|
||||
vim.lsp.buf.execute_command(action.command)
|
||||
end
|
||||
end
|
||||
end
|
||||
-- Format
|
||||
vim.lsp.buf.format({ async = false })
|
||||
end,
|
||||
})
|
||||
150
lua/plugins/oil.lua
Normal file
150
lua/plugins/oil.lua
Normal file
@@ -0,0 +1,150 @@
|
||||
-- Track the last focused code window (not oil, not terminal)
|
||||
_G.last_code_win = nil
|
||||
|
||||
vim.api.nvim_create_autocmd("WinEnter", {
|
||||
group = vim.api.nvim_create_augroup("track_code_win", { clear = true }),
|
||||
callback = function()
|
||||
local buf = vim.api.nvim_get_current_buf()
|
||||
local ft = vim.bo[buf].filetype
|
||||
local bt = vim.bo[buf].buftype
|
||||
if ft ~= "oil" and bt ~= "terminal" then
|
||||
_G.last_code_win = vim.api.nvim_get_current_win()
|
||||
end
|
||||
end,
|
||||
})
|
||||
|
||||
require("oil").setup({
|
||||
watch_for_changes = true,
|
||||
keymaps = {
|
||||
["<CR>"] = false, -- disable default, we override below
|
||||
["<C-t>"] = false, -- don't override global <C-t> (popup terminal)
|
||||
},
|
||||
})
|
||||
|
||||
-- Override <CR> in oil buffers to open in last code window
|
||||
vim.api.nvim_create_autocmd("FileType", {
|
||||
group = vim.api.nvim_create_augroup("oil_open_in_code", { clear = true }),
|
||||
pattern = "oil",
|
||||
callback = function(ev)
|
||||
-- Go up a directory with backspace or -
|
||||
vim.keymap.set("n", "<BS>", function()
|
||||
require("oil").open(require("oil").get_current_dir() .. "..")
|
||||
end, { buffer = ev.buf, desc = "Go up directory" })
|
||||
|
||||
vim.keymap.set("n", "-", function()
|
||||
require("oil").open(require("oil").get_current_dir() .. "..")
|
||||
end, { buffer = ev.buf, desc = "Go up directory" })
|
||||
|
||||
-- Delete file under cursor
|
||||
vim.keymap.set("n", "<leader>d", function()
|
||||
local oil = require("oil")
|
||||
local entry = oil.get_cursor_entry()
|
||||
if not entry then return end
|
||||
local dir = oil.get_current_dir()
|
||||
if not dir then return end
|
||||
local path = dir .. entry.name
|
||||
vim.ui.input({ prompt = "Delete " .. entry.name .. "? (y/n): " }, function(input)
|
||||
if input == "y" then
|
||||
vim.fn.delete(path, entry.type == "directory" and "rf" or "")
|
||||
oil.discard_all_changes()
|
||||
end
|
||||
end)
|
||||
end, { buffer = ev.buf, desc = "Delete file/dir" })
|
||||
|
||||
-- Open file in code window, then auto-focus back to code
|
||||
vim.keymap.set("n", "<CR>", function()
|
||||
local oil = require("oil")
|
||||
local entry = oil.get_cursor_entry()
|
||||
if not entry then return end
|
||||
|
||||
-- Directories: navigate normally in oil
|
||||
if entry.type == "directory" then
|
||||
oil.select()
|
||||
return
|
||||
end
|
||||
|
||||
local dir = oil.get_current_dir()
|
||||
if not dir then return end
|
||||
local filepath = dir .. entry.name
|
||||
local target_win = nil
|
||||
|
||||
-- Try last focused code window
|
||||
if _G.last_code_win and vim.api.nvim_win_is_valid(_G.last_code_win) then
|
||||
local buf = vim.api.nvim_win_get_buf(_G.last_code_win)
|
||||
if vim.bo[buf].filetype ~= "oil" and vim.bo[buf].buftype ~= "terminal" then
|
||||
target_win = _G.last_code_win
|
||||
end
|
||||
end
|
||||
|
||||
-- Fallback: find any non-oil, non-terminal window
|
||||
if not target_win then
|
||||
local cur_win = vim.api.nvim_get_current_win()
|
||||
for _, win in ipairs(vim.api.nvim_tabpage_list_wins(0)) do
|
||||
if win ~= cur_win and vim.api.nvim_win_get_config(win).relative == "" then
|
||||
local buf = vim.api.nvim_win_get_buf(win)
|
||||
if vim.bo[buf].filetype ~= "oil" and vim.bo[buf].buftype ~= "terminal" then
|
||||
target_win = win
|
||||
break
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
if target_win then
|
||||
vim.api.nvim_set_current_win(target_win)
|
||||
-- Remember blank buffer to clean up after opening
|
||||
local old_buf = vim.api.nvim_get_current_buf()
|
||||
local is_blank = vim.api.nvim_buf_get_name(old_buf) == ""
|
||||
and not vim.bo[old_buf].modified
|
||||
and vim.api.nvim_buf_line_count(old_buf) <= 1
|
||||
and vim.api.nvim_buf_get_lines(old_buf, 0, 1, false)[1] == ""
|
||||
vim.cmd.edit(vim.fn.fnameescape(filepath))
|
||||
if is_blank and old_buf ~= vim.api.nvim_get_current_buf() then
|
||||
vim.api.nvim_buf_delete(old_buf, { force = true })
|
||||
end
|
||||
else
|
||||
-- No code window exists: create a split to the right
|
||||
vim.cmd("rightbelow vsplit " .. vim.fn.fnameescape(filepath))
|
||||
end
|
||||
end, { buffer = ev.buf, desc = "Open file in code window" })
|
||||
end,
|
||||
})
|
||||
|
||||
-- Toggle file tree on the left with <leader>e
|
||||
_G.oil_tree_win = nil
|
||||
|
||||
local function open_tree()
|
||||
vim.cmd("topleft vsplit | vertical resize 30")
|
||||
_G.oil_tree_win = vim.api.nvim_get_current_win()
|
||||
require("oil").open()
|
||||
end
|
||||
|
||||
vim.keymap.set("n", "<leader>e", function()
|
||||
if _G.oil_tree_win and vim.api.nvim_win_is_valid(_G.oil_tree_win) then
|
||||
vim.api.nvim_win_close(_G.oil_tree_win, true)
|
||||
_G.oil_tree_win = nil
|
||||
else
|
||||
open_tree()
|
||||
end
|
||||
end, { desc = "Toggle file tree" })
|
||||
|
||||
-- Open file tree on startup (deferred so oil is fully loaded)
|
||||
vim.api.nvim_create_autocmd("VimEnter", {
|
||||
group = vim.api.nvim_create_augroup("oil_startup", { clear = true }),
|
||||
callback = function()
|
||||
vim.schedule(function()
|
||||
open_tree()
|
||||
vim.cmd("wincmd l")
|
||||
end)
|
||||
end,
|
||||
})
|
||||
|
||||
-- Keep oil tree pinned at 30 columns after layout changes
|
||||
vim.api.nvim_create_autocmd("WinResized", {
|
||||
group = vim.api.nvim_create_augroup("oil_pin_width", { clear = true }),
|
||||
callback = function()
|
||||
if _G.oil_tree_win and vim.api.nvim_win_is_valid(_G.oil_tree_win) then
|
||||
vim.api.nvim_win_set_width(_G.oil_tree_win, 30)
|
||||
end
|
||||
end,
|
||||
})
|
||||
1
lua/plugins/overseer.lua
Normal file
1
lua/plugins/overseer.lua
Normal file
@@ -0,0 +1 @@
|
||||
require("overseer").setup()
|
||||
5
lua/plugins/theme.lua
Normal file
5
lua/plugins/theme.lua
Normal file
@@ -0,0 +1,5 @@
|
||||
require("kanagawa").setup({
|
||||
theme = "wave",
|
||||
})
|
||||
|
||||
vim.cmd.colorscheme("kanagawa")
|
||||
3
lua/plugins/treesitter.lua
Normal file
3
lua/plugins/treesitter.lua
Normal file
@@ -0,0 +1,3 @@
|
||||
-- nvim-treesitter on 0.12+ only provides :TSInstall for parser management
|
||||
-- Treesitter highlighting is enabled automatically when a parser is available
|
||||
-- Run :TSInstall go bash yaml lua to install parsers
|
||||
Reference in New Issue
Block a user