-- vim: :foldmethod=marker -- === PACKAGE MANAGEMENT === {{{1 local function ensure_plugin(category, name, git_url, opts) opts = opts or {} local pack_path = os.getenv("HOME") .. "/.config/nvim/pack/" .. category .. "/" .. (opts.opt and "opt" or "start") local plugin_path = pack_path .. "/" .. name -- Create pack directory if it doesn't exist vim.fn.system("mkdir -p " .. pack_path) -- Check if plugin exists if vim.fn.isdirectory(plugin_path) == 0 then print("Installing " .. name .. "...") local result = vim.fn.system("git clone --depth=1 " .. git_url .. " " .. plugin_path) if vim.v.shell_error == 0 then print("✓ " .. name .. " installed successfully") else print("✗ Failed to install " .. name .. ": " .. result) return false end end -- Load optional plugin if requested if opts.opt and opts.load then vim.cmd("packadd " .. name) end return true end -- Plugin definitions - add more as needed local plugins = { -- Colorschemes {"colors", "papercolor-theme", "https://github.com/NLKNguyen/papercolor-theme.git"}, {"colors", "tokyonight.nvim", "https://github.com/folke/tokyonight.nvim.git"}, -- Essential plugins {"editor", "telescope.nvim", "https://github.com/nvim-telescope/telescope.nvim.git"}, {"editor", "plenary.nvim", "https://github.com/nvim-lua/plenary.nvim.git"}, -- telescope dependency {"editor", "nvim-web-devicons", "https://github.com/nvim-tree/nvim-web-devicons.git"}, -- telescope dependency -- LSP and completion {"lsp", "nvim-lspconfig", "https://github.com/neovim/nvim-lspconfig.git"}, {"lsp", "mason.nvim", "https://github.com/williamboman/mason.nvim.git"}, {"lsp", "mason-lspconfig.nvim", "https://github.com/williamboman/mason-lspconfig.nvim.git"}, {"lsp", "nvim-cmp", "https://github.com/hrsh7th/nvim-cmp.git"}, {"lsp", "cmp-nvim-lsp", "https://github.com/hrsh7th/cmp-nvim-lsp.git"}, {"lsp", "cmp-buffer", "https://github.com/hrsh7th/cmp-buffer.git"}, {"lsp", "cmp-path", "https://github.com/hrsh7th/cmp-path.git"}, {"lsp", "LuaSnip", "https://github.com/L3MON4D3/LuaSnip.git"}, {"lsp", "cmp_luasnip", "https://github.com/saadparwaiz1/cmp_luasnip.git"}, -- Treesitter {"syntax", "nvim-treesitter", "https://github.com/nvim-treesitter/nvim-treesitter.git"}, -- Git integration {"git", "gitsigns.nvim", "https://github.com/lewis6991/gitsigns.nvim.git"}, {"git", "vim-fugitive", "https://github.com/tpope/vim-fugitive.git"}, -- Tools {"db", "vim-dadbod", "https://github.com/tpope/vim-dadbod.git"}, {"db", "vim-dadbod-completion", "https://github.com/kristijanhusak/vim-dadbod-completion.git"}, {"db", "vim-dadbod-ui", "https://github.com/kristijanhusak/vim-dadbod-ui.git"}, {"env", "dotenv", "https://github.com/tpope/vim-dotenv"}, -- Quality of life {"editor", "which-key.nvim", "https://github.com/folke/which-key.nvim.git"}, {"editor", "Comment.nvim", "https://github.com/numToStr/Comment.nvim.git"}, {"editor", "nvim-surround", "https://github.com/kylechui/nvim-surround.git"}, } -- Install all plugins for _, plugin in ipairs(plugins) do ensure_plugin(plugin[1], plugin[2], plugin[3], plugin[4]) end -- === CORE SETTINGS === {{{1 local o = vim.o local t = vim.t local v = vim.v local g = vim.g local fn = vim.fn local opt = vim.opt local cmd = vim.cmd local api = vim.api local loop = vim.loop local keys = vim.keymap -- Globals g.mapleader = "\\" -- Helper function local function has(val) return fn.has(val) == 1 end -- === APPEARANCE === {{{1 -- Basic UI o.guifont = "Monaco:h13" o.relativenumber = true o.number = true o.signcolumn = "yes" o.termguicolors = true o.laststatus = 2 o.statusline = "%f %h%w%m%y%r%=%(%l,%c%V %= %PT%)" -- Colorscheme and dark mode integration local function change_background() o.background = "light" cmd("colorscheme PaperColor") cmd("redraw!") end if has("gui_macvim") then local AutoDark = api.nvim_create_augroup("AutoDark", {clear = true}) api.nvim_create_autocmd({"OSAppearanceChanged"}, { pattern = "*", group = AutoDark, callback = change_background }) else change_background() end -- === EDITOR BEHAVIOR === {{{1 -- Reading and saving o.autoread = true opt.clipboard:append("unnamedplus") -- Indentation o.autoindent = true o.expandtab = true o.tabstop = 2 o.shiftwidth = 2 -- Folding o.foldmethod = "syntax" -- Splits opt.splitright = true opt.splitbelow = true -- Editing opt.iskeyword:append("-") -- Search o.ignorecase = true o.smartcase = true o.hlsearch = true o.incsearch = true -- === PLUGIN CONFIGURATION === {{{1 -- Telescope pcall(function() require('telescope').setup({ defaults = { file_ignore_patterns = {"node_modules", ".git/"} } }) end) -- Which-key pcall(function() require('which-key').setup({}) end) -- Comment.nvim pcall(function() require('Comment').setup() end) -- nvim-surround pcall(function() require('nvim-surround').setup() end) -- Gitsigns pcall(function() require('gitsigns').setup() end) -- Mason (LSP installer) pcall(function() require('mason').setup() require('mason-lspconfig').setup({ ensure_installed = {"lua_ls", "vtsls", "pyright", "rust_analyzer"} }) end) -- LSP Configuration pcall(function() local lspconfig = require('lspconfig') local capabilities = require('cmp_nvim_lsp').default_capabilities() -- Common LSP setup local servers = {"lua_ls", "vtsls", "pyright", "rust_analyzer"} for _, lsp in ipairs(servers) do lspconfig[lsp].setup({ capabilities = capabilities }) end end) -- Completion setup pcall(function() local cmp = require('cmp') local luasnip = require('luasnip') cmp.setup({ snippet = { expand = function(args) luasnip.lsp_expand(args.body) end, }, mapping = cmp.mapping.preset.insert({ [''] = cmp.mapping.scroll_docs(-4), [''] = cmp.mapping.scroll_docs(4), [''] = cmp.mapping.complete(), [''] = cmp.mapping.confirm({ select = true }), }), sources = cmp.config.sources({ { name = 'nvim_lsp' }, { name = 'luasnip' }, }, { { name = 'buffer' }, { name = 'path' }, }) }) end) -- Treesitter pcall(function() require('nvim-treesitter.configs').setup({ ensure_installed = {"lua", "typescript", "javascript", "python", "rust", "html", "css"}, highlight = { enable = true }, indent = { enable = true } }) end) -- === AUTOCMDS === {{{1 cmd("filetype plugin on") -- TypeScript formatting on save local TypescriptSave = api.nvim_create_augroup("TypescriptSave", {clear = true}) api.nvim_create_autocmd({"BufWritePost"}, { pattern = "*.ts", group = TypescriptSave, command = "silent! !yarn prettier -w :p:S" }) -- Diff mode settings api.nvim_create_autocmd({"VimEnter"}, { pattern = {"*"}, callback = function() if o.diff then o.wrap = true keys.set("n", "ZZ", ":qa") cmd("cnoremap q 'qa'") end end }) -- === KEYMAPS === {{{1 -- Leader key mappings keys.set("n", "rr", ":source $MYVIMRC", {desc = "Reload config"}) -- Basic editing keys.set("i", "jk", "", {desc = "Exit insert mode"}) keys.set("n", "x", '"_x', {desc = "Delete without copying"}) -- Telescope mappings keys.set("n", "ff", ":Telescope find_files", {desc = "Find files"}) keys.set("n", "fg", ":Telescope live_grep", {desc = "Live grep"}) keys.set("n", "fb", ":Telescope buffers", {desc = "Find buffers"}) keys.set("n", "fh", ":Telescope help_tags", {desc = "Help tags"}) -- LSP mappings keys.set("n", "gd", vim.lsp.buf.definition, {desc = "Go to definition"}) keys.set("n", "gD", vim.lsp.buf.declaration, {desc = "Go to declaration"}) keys.set("n", "gr", vim.lsp.buf.references, {desc = "References"}) keys.set("n", "gi", vim.lsp.buf.implementation, {desc = "Implementation"}) keys.set("n", "K", vim.lsp.buf.hover, {desc = "Hover documentation"}) keys.set("n", "ca", vim.lsp.buf.code_action, {desc = "Code actions"}) keys.set("n", "rn", vim.lsp.buf.rename, {desc = "Rename"}) keys.set("n", "d", vim.diagnostic.open_float, {desc = "Show diagnostics"}) keys.set("n", "[d", vim.diagnostic.goto_prev, {desc = "Previous diagnostic"}) keys.set("n", "]d", vim.diagnostic.goto_next, {desc = "Next diagnostic"}) -- Window navigation keys.set("n", "", "h", {desc = "Window left"}) keys.set("n", "", "j", {desc = "Window down"}) keys.set("n", "", "k", {desc = "Window up"}) keys.set("n", "", "l", {desc = "Window right"}) -- Clear search highlighting keys.set("n", "nh", ":nohl", {desc = "Clear highlights"})