206 lines
7.9 KiB
Lua
206 lines
7.9 KiB
Lua
--[[
|
|
init.lua - Main Neovim configuration entry point
|
|
|
|
HOW THIS WORKS:
|
|
1. Bootstrap lazy.nvim (plugin manager)
|
|
2. Load basic settings
|
|
3. Load all plugins from plugins/ directory
|
|
4. Set global keymaps and LSP keymaps
|
|
]]
|
|
|
|
-- ============================================================================
|
|
-- STEP 0: SETUP NODE PATH (for fnm)
|
|
-- ============================================================================
|
|
local fnm_current = vim.fn.trim(vim.fn.system("fnm current 2>/dev/null"))
|
|
if fnm_current ~= "" then
|
|
local fnm_dir = vim.fn.expand("~/.local/share/fnm")
|
|
local fnm_bin_path = fnm_dir .. "/node-versions/" .. fnm_current .. "/installation/bin"
|
|
vim.env.PATH = fnm_bin_path .. ":" .. vim.env.PATH
|
|
end
|
|
|
|
-- ============================================================================
|
|
-- STEP 1: BOOTSTRAP LAZY.NVIM
|
|
-- ============================================================================
|
|
local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
|
|
if not vim.loop.fs_stat(lazypath) then
|
|
vim.fn.system({
|
|
"git",
|
|
"clone",
|
|
"--filter=blob:none",
|
|
"https://github.com/folke/lazy.nvim.git",
|
|
"--branch=stable",
|
|
lazypath,
|
|
})
|
|
end
|
|
vim.opt.rtp:prepend(lazypath)
|
|
|
|
-- ============================================================================
|
|
-- STEP 2: LOAD SETTINGS
|
|
-- ============================================================================
|
|
require("basic-settings")
|
|
|
|
-- ============================================================================
|
|
-- STEP 3: LOAD PLUGINS
|
|
-- ============================================================================
|
|
require("lazy").setup("plugins")
|
|
|
|
require("diff-base")
|
|
|
|
-- ============================================================================
|
|
-- STEP 4: LSP KEYMAPS
|
|
-- ============================================================================
|
|
local function fix_markdownlint()
|
|
local bufnr = vim.api.nvim_get_current_buf()
|
|
local filename = vim.api.nvim_buf_get_name(bufnr)
|
|
local markdownlint = vim.fn.exepath("markdownlint")
|
|
if markdownlint == "" then
|
|
markdownlint = vim.fn.stdpath("data") .. "/mason/bin/markdownlint"
|
|
end
|
|
|
|
if vim.fn.executable(markdownlint) == 0 then
|
|
vim.notify("markdownlint is not installed", vim.log.levels.WARN)
|
|
return
|
|
end
|
|
|
|
if filename == "" then
|
|
vim.notify("Save the Markdown buffer before fixing it", vim.log.levels.WARN)
|
|
return
|
|
end
|
|
|
|
vim.cmd.write()
|
|
vim.fn.jobstart({ markdownlint, "--fix", filename }, {
|
|
buffer = bufnr,
|
|
on_exit = function(_, exit_code)
|
|
vim.schedule(function()
|
|
if exit_code ~= 0 then
|
|
vim.notify("markdownlint could not fix this file", vim.log.levels.WARN)
|
|
return
|
|
end
|
|
|
|
vim.cmd.checktime()
|
|
vim.notify("markdownlint fixes applied", vim.log.levels.INFO)
|
|
vim.defer_fn(function()
|
|
require("lint").try_lint()
|
|
end, 100)
|
|
end)
|
|
end,
|
|
})
|
|
end
|
|
|
|
vim.keymap.set("n", "gd", vim.lsp.buf.definition, { desc = "Go to definition" })
|
|
vim.keymap.set("n", "gD", vim.lsp.buf.declaration, { desc = "Go to declaration" })
|
|
vim.keymap.set("n", "gi", vim.lsp.buf.implementation, { desc = "Go to implementation" })
|
|
vim.keymap.set("n", "gr", vim.lsp.buf.references, { desc = "Show references" })
|
|
vim.keymap.set("n", "K", vim.lsp.buf.hover, { desc = "Show hover docs" })
|
|
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename, { desc = "Rename symbol" })
|
|
vim.keymap.set("n", "<leader>ca", function()
|
|
if vim.bo.filetype == "markdown" then
|
|
fix_markdownlint()
|
|
return
|
|
end
|
|
vim.lsp.buf.code_action()
|
|
end, { desc = "Code actions / Markdown fixes" })
|
|
vim.keymap.set("n", "<leader>fx", function()
|
|
if vim.bo.filetype == "markdown" then
|
|
fix_markdownlint()
|
|
return
|
|
end
|
|
vim.lsp.buf.code_action({
|
|
context = {
|
|
diagnostics = vim.diagnostic.get(0, {
|
|
lnum = vim.fn.line(".") - 1,
|
|
}),
|
|
},
|
|
})
|
|
end, { desc = "Fix diagnostic" })
|
|
vim.keymap.set("n", "<leader>fA", function()
|
|
vim.lsp.buf.code_action({
|
|
apply = true,
|
|
context = {
|
|
only = { "source.fixAll" },
|
|
},
|
|
})
|
|
end, { desc = "Fix all diagnostics" })
|
|
vim.keymap.set("n", "<leader>e", vim.diagnostic.open_float, { desc = "Show diagnostic" })
|
|
|
|
vim.diagnostic.config({
|
|
virtual_text = { prefix = "●" },
|
|
signs = true,
|
|
float = { border = "rounded" },
|
|
})
|
|
|
|
-- Vue: semantic-token highlight for custom components
|
|
vim.api.nvim_set_hl(0, "@lsp.type.component", { link = "@type" })
|
|
|
|
-- ============================================================================
|
|
-- STEP 5: GLOBAL KEYMAPS
|
|
-- ============================================================================
|
|
vim.keymap.set("n", "<leader>w", ":w<CR>", { desc = "Save file" })
|
|
vim.keymap.set("n", "<leader>q", ":q<CR>", { desc = "Quit" })
|
|
vim.keymap.set("n", "<C-n>", ":Neotree filesystem reveal left<CR>", { desc = "Toggle explorer" })
|
|
vim.keymap.set("n", "<leader>nt", ":Neotree focus<CR>", { desc = "Focus neo-tree" })
|
|
vim.keymap.set("n", "<C-p>", ":Telescope find_files<CR>", { desc = "Find files" })
|
|
|
|
-- Better window navigation
|
|
vim.keymap.set("n", "<C-h>", "<C-w>h", { desc = "Navigate left" })
|
|
vim.keymap.set("n", "<C-j>", "<C-w>j", { desc = "Navigate down" })
|
|
vim.keymap.set("n", "<C-k>", "<C-w>k", { desc = "Navigate up" })
|
|
vim.keymap.set("n", "<C-l>", "<C-w>l", { desc = "Navigate right" })
|
|
|
|
-- Split windows
|
|
vim.keymap.set("n", "<leader>sh", ":split<CR>", { desc = "Split window horizontally" })
|
|
vim.keymap.set("n", "<leader>sv", ":vsplit<CR>", { desc = "Split window vertically" })
|
|
vim.keymap.set("n", "<leader>\"", ":split<CR>", { desc = "Split window horizontally" })
|
|
vim.keymap.set("n", "<leader>%", ":vsplit<CR>", { desc = "Split window vertically" })
|
|
|
|
-- Resize windows
|
|
vim.keymap.set("n", "<C-Up>", ":resize -2<CR>", { desc = "Resize window up" })
|
|
vim.keymap.set("n", "<C-Down>", ":resize +2<CR>", { desc = "Resize window down" })
|
|
vim.keymap.set("n", "<C-Left>", ":vertical resize -2<CR>", { desc = "Resize window left" })
|
|
vim.keymap.set("n", "<C-Right>", ":vertical resize +2<CR>", { desc = "Resize window right" })
|
|
|
|
-- Move text up/down
|
|
vim.keymap.set("n", "<A-j>", ":m .+1<CR>==", { desc = "Move line down" })
|
|
vim.keymap.set("n", "<A-k>", ":m .-2<CR>==", { desc = "Move line up" })
|
|
vim.keymap.set("v", "<A-j>", ":m '>+1<CR>gv=gv", { desc = "Move selection down" })
|
|
vim.keymap.set("v", "<A-k>", ":m '<-2<CR>gv=gv", { desc = "Move selection up" })
|
|
|
|
-- Folding keymaps
|
|
vim.keymap.set("n", "za", "za", { desc = "Toggle fold under cursor" })
|
|
vim.keymap.set("n", "zA", "zA", { desc = "Toggle fold recursively" })
|
|
vim.keymap.set("n", "zR", "zR", { desc = "Open all folds" })
|
|
vim.keymap.set("n", "zM", "zM", { desc = "Close all folds" })
|
|
vim.keymap.set("n", "zo", "zo", { desc = "Open fold under cursor" })
|
|
vim.keymap.set("n", "zc", "zc", { desc = "Close fold under cursor" })
|
|
vim.keymap.set("n", "zO", "zO", { desc = "Open all folds under cursor" })
|
|
vim.keymap.set("n", "zC", "zC", { desc = "Close all folds under cursor" })
|
|
|
|
-- Path of current file to clipboard
|
|
vim.keymap.set("n", "<leader>yp", ":let @+=expand('%:p')<CR>", { desc = "Absolute path of current file to clipboard" })
|
|
vim.keymap.set("n", "<leader>yr", ":let @+=expand('%:.')<CR>", { desc = "Relative path of current file to clipboard" })
|
|
vim.keymap.set("n", "<leader>cf", ":let @+=expand('%:t')<CR>", { desc = "Current filename to clipboard" })
|
|
vim.keymap.set({'n','v'}, '<leader>ya', function()
|
|
local fname = vim.fn.expand('%:.')
|
|
local mode = vim.fn.mode()
|
|
local lines
|
|
if mode:match("[vV\22]") then
|
|
local start_line = vim.fn.line('v')
|
|
local end_line = vim.fn.line('.')
|
|
if start_line > end_line then
|
|
start_line, end_line = end_line, start_line
|
|
end
|
|
lines = tostring(start_line) .. '..' .. tostring(end_line)
|
|
else
|
|
lines = tostring(vim.fn.line('.'))
|
|
end
|
|
local result = fname .. ':' .. lines
|
|
vim.fn.setreg('+', result)
|
|
print('Copied: ' .. result)
|
|
end, {desc = 'Copy file path and line(s) to clipboard'})
|
|
|
|
-- clear search highlighting
|
|
vim.keymap.set("n", "<leader>ch", ":noh<CR>", { desc = "clear search highlighting" })
|
|
|
|
-- toggle word wrap
|
|
vim.keymap.set("n", "<leader>tw", ":set wrap!<CR>", { desc = "toggle word wrap" })
|