385 lines
11 KiB
Lua
385 lines
11 KiB
Lua
-- ~/.config/nvim/init.lua
|
|
-- Complete VSCode-like Neovim Config with All Requested Keybindings
|
|
|
|
-- ======================
|
|
-- 1. Basic Configuration
|
|
-- ======================
|
|
vim.g.mapleader = " "
|
|
vim.g.maplocalleader = " "
|
|
|
|
-- Editor Settings (unchanged from previous)
|
|
vim.opt.number = true
|
|
vim.opt.relativenumber = true
|
|
vim.opt.mouse = "a"
|
|
vim.opt.showmode = false
|
|
vim.opt.clipboard = "unnamedplus"
|
|
vim.opt.breakindent = true
|
|
vim.opt.undofile = true
|
|
vim.opt.ignorecase = true
|
|
vim.opt.smartcase = true
|
|
vim.opt.signcolumn = "yes"
|
|
vim.opt.updatetime = 250
|
|
vim.opt.timeoutlen = 300
|
|
vim.opt.splitright = true
|
|
vim.opt.splitbelow = true
|
|
vim.opt.list = true
|
|
vim.opt.listchars = { tab = "» ", trail = "·", nbsp = "␣" }
|
|
vim.opt.inccommand = "split"
|
|
vim.opt.cursorline = true
|
|
vim.opt.scrolloff = 10
|
|
vim.opt.hlsearch = true
|
|
vim.opt.termguicolors = true
|
|
vim.opt.expandtab = true
|
|
vim.opt.tabstop = 2
|
|
vim.opt.shiftwidth = 2
|
|
vim.opt.smartindent = true
|
|
vim.opt.wrap = false
|
|
vim.opt.swapfile = false
|
|
vim.opt.backup = false
|
|
vim.opt.writebackup = false
|
|
|
|
-- ======================
|
|
-- 2. Plugin Management
|
|
-- ======================
|
|
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)
|
|
|
|
-- ======================
|
|
-- 3. Plugin Specifications
|
|
-- ======================
|
|
local plugins = {
|
|
-- Theme (unchanged)
|
|
{
|
|
"drewtempelmeyer/palenight.vim",
|
|
priority = 1000,
|
|
config = function()
|
|
vim.g.palenight_terminal_italics = 1
|
|
vim.cmd("colorscheme palenight")
|
|
end,
|
|
},
|
|
|
|
-- File Explorer
|
|
{
|
|
"nvim-neo-tree/neo-tree.nvim",
|
|
branch = "v3.x",
|
|
dependencies = { "nvim-lua/plenary.nvim", "nvim-tree/nvim-web-devicons", "MunifTanjim/nui.nvim" },
|
|
},
|
|
|
|
-- Fuzzy Finder
|
|
{ "nvim-telescope/telescope.nvim", dependencies = { "nvim-lua/plenary.nvim" } },
|
|
|
|
-- LSP Configuration
|
|
{
|
|
"neovim/nvim-lspconfig",
|
|
dependencies = {
|
|
"williamboman/mason.nvim",
|
|
"williamboman/mason-lspconfig.nvim",
|
|
"WhoIsSethDaniel/mason-tool-installer.nvim",
|
|
{ "j-hui/fidget.nvim", opts = {} },
|
|
{ "folke/neodev.nvim", opts = {} },
|
|
},
|
|
},
|
|
|
|
-- Enhanced Autocompletion
|
|
{
|
|
"hrsh7th/nvim-cmp",
|
|
event = "InsertEnter",
|
|
dependencies = {
|
|
"L3MON4D3/LuaSnip",
|
|
"saadparwaiz1/cmp_luasnip",
|
|
"hrsh7th/cmp-nvim-lsp",
|
|
"hrsh7th/cmp-path",
|
|
"hrsh7th/cmp-buffer",
|
|
"rafamadriz/friendly-snippets",
|
|
},
|
|
},
|
|
|
|
-- Auto Pairs
|
|
{
|
|
"windwp/nvim-autopairs",
|
|
event = "InsertEnter",
|
|
config = function()
|
|
require("nvim-autopairs").setup({
|
|
check_ts = true,
|
|
ts_config = {
|
|
lua = { "string", "source" },
|
|
javascript = { "string", "template_string" },
|
|
typescript = { "string", "template_string" },
|
|
},
|
|
disable_filetype = { "TelescopePrompt", "spectre_panel" },
|
|
fast_wrap = {
|
|
map = "<M-e>",
|
|
chars = { "{", "[", "(", '"', "'", "<" },
|
|
pattern = [=[[%'%"%)%>%]%)%}%,]]=],
|
|
end_key = "$",
|
|
highlight = "Search",
|
|
highlight_grey = "Comment",
|
|
},
|
|
})
|
|
|
|
local cmp_autopairs = require("nvim-autopairs.completion.cmp")
|
|
local cmp = require("cmp")
|
|
cmp.event:on("confirm_done", cmp_autopairs.on_confirm_done())
|
|
end,
|
|
},
|
|
|
|
-- Git Integration
|
|
{ "lewis6991/gitsigns.nvim", opts = {} },
|
|
{ "tpope/vim-fugitive" },
|
|
{ "kdheepak/lazygit.nvim", dependencies = { "nvim-lua/plenary.nvim" } },
|
|
{ "akinsho/git-conflict.nvim", version = "*" },
|
|
|
|
-- UI Enhancements
|
|
{ "nvim-lualine/lualine.nvim", dependencies = { "nvim-tree/nvim-web-devicons" } },
|
|
{ "akinsho/bufferline.nvim", version = "*", dependencies = "nvim-tree/nvim-web-devicons" },
|
|
{ "lukas-reineke/indent-blankline.nvim", main = "ibl", opts = {} },
|
|
|
|
-- Syntax & Editing
|
|
{ "nvim-treesitter/nvim-treesitter", build = ":TSUpdate" },
|
|
{ "numToStr/Comment.nvim", opts = {} },
|
|
|
|
-- Productivity
|
|
{ "akinsho/toggleterm.nvim", version = "*", config = true },
|
|
{ "folke/which-key.nvim", event = "VimEnter" },
|
|
{ "stevearc/conform.nvim" },
|
|
{ "mfussenegger/nvim-lint", event = { "BufReadPre", "BufNewFile" } },
|
|
}
|
|
|
|
-- ======================
|
|
-- 4. Plugin Configuration
|
|
-- ======================
|
|
require("lazy").setup(plugins, {
|
|
ui = {
|
|
icons = vim.g.have_nerd_font and {} or {
|
|
cmd = "⌘",
|
|
config = "🛠",
|
|
event = "📅",
|
|
ft = "📂",
|
|
init = "⚙",
|
|
keys = "🗝",
|
|
plugin = "🔌",
|
|
runtime = "💻",
|
|
require = "🌙",
|
|
source = "📄",
|
|
start = "🚀",
|
|
task = "📌",
|
|
lazy = "💤",
|
|
},
|
|
},
|
|
})
|
|
|
|
-- Neo-tree Configuration with Keymaps
|
|
require("neo-tree").setup({
|
|
close_if_last_window = false,
|
|
popup_border_style = "rounded",
|
|
enable_git_status = true,
|
|
enable_diagnostics = true,
|
|
filesystem = {
|
|
follow_current_file = { enabled = true },
|
|
hijack_netrw_behavior = "open_current",
|
|
use_libuv_file_watcher = true,
|
|
},
|
|
window = {
|
|
position = "right",
|
|
width = 30,
|
|
mappings = {
|
|
["<space>"] = "none", -- disable space as it's our leader key
|
|
["o"] = "open",
|
|
["<CR>"] = "open",
|
|
["t"] = "open_tabnew",
|
|
["v"] = "open_vsplit",
|
|
["s"] = "open_split",
|
|
["r"] = "rename",
|
|
["d"] = "delete",
|
|
["a"] = "add",
|
|
["A"] = "add_directory",
|
|
["R"] = "refresh",
|
|
["."] = "toggle_hidden",
|
|
},
|
|
},
|
|
})
|
|
|
|
-- Telescope Configuration with Keymaps
|
|
require("telescope").setup({
|
|
defaults = {
|
|
mappings = {
|
|
i = {
|
|
["<C-n>"] = "move_selection_next",
|
|
["<C-p>"] = "move_selection_previous",
|
|
["<C-j>"] = "move_selection_next",
|
|
["<C-k>"] = "move_selection_previous",
|
|
["<C-t>"] = "select_tab",
|
|
["<C-v>"] = "select_vertical",
|
|
["<C-x>"] = "select_horizontal",
|
|
["<C-u>"] = "clear_prompt",
|
|
["<C-c>"] = "close",
|
|
},
|
|
},
|
|
},
|
|
})
|
|
|
|
-- LSP Setup
|
|
local capabilities = vim.lsp.protocol.make_client_capabilities()
|
|
capabilities = require("cmp_nvim_lsp").default_capabilities(capabilities)
|
|
capabilities.textDocument.completion.completionItem.snippetSupport = true
|
|
|
|
require("mason").setup()
|
|
require("mason-lspconfig").setup({
|
|
ensure_installed = {
|
|
"lua_ls", "pyright", "ruff", "ls_ls", "html", "cssls",
|
|
"tailwindcss", "bashls", "jsonls", "yamlls", "dockerls"
|
|
},
|
|
})
|
|
|
|
local lspconfig = require("lspconfig")
|
|
lspconfig.lua_ls.setup({
|
|
capabilities = capabilities,
|
|
settings = {
|
|
Lua = {
|
|
completion = { callSnippet = "Replace" },
|
|
diagnostics = { globals = { "vim" } },
|
|
workspace = { checkThirdParty = false },
|
|
telemetry = { enable = false },
|
|
},
|
|
},
|
|
})
|
|
|
|
for _, server in ipairs({ "pyright", "ts_ls", "html", "cssls", "bashls", "jsonls" }) do
|
|
lspconfig[server].setup({ capabilities = capabilities })
|
|
end
|
|
|
|
-- Completion Setup
|
|
local cmp = require("cmp")
|
|
local luasnip = require("luasnip")
|
|
require("luasnip.loaders.from_vscode").lazy_load()
|
|
|
|
local has_words_before = function()
|
|
unpack = unpack or table.unpack
|
|
local line, col = unpack(vim.api.nvim_win_get_cursor(0))
|
|
return col ~= 0 and vim.api.nvim_buf_get_lines(0, line - 1, line, true)[1]:sub(col, col):match("%s") == nil
|
|
end
|
|
|
|
cmp.setup({
|
|
snippet = {
|
|
expand = function(args)
|
|
luasnip.lsp_expand(args.body)
|
|
end,
|
|
},
|
|
mapping = cmp.mapping.preset.insert({
|
|
["<Tab>"] = cmp.mapping(function(fallback)
|
|
if cmp.visible() then
|
|
cmp.select_next_item()
|
|
elseif luasnip.expand_or_locally_jumpable() then
|
|
luasnip.expand_or_jump()
|
|
elseif has_words_before() then
|
|
cmp.complete()
|
|
else
|
|
fallback()
|
|
end
|
|
end, { "i", "s" }),
|
|
|
|
["<S-Tab>"] = cmp.mapping(function(fallback)
|
|
if cmp.visible() then
|
|
cmp.select_prev_item()
|
|
elseif luasnip.jumpable(-1) then
|
|
luasnip.jump(-1)
|
|
else
|
|
fallback()
|
|
end
|
|
end, { "i", "s" }),
|
|
|
|
["<CR>"] = cmp.mapping.confirm({
|
|
behavior = cmp.ConfirmBehavior.Replace,
|
|
select = false,
|
|
}),
|
|
["<C-Space>"] = cmp.mapping.complete(),
|
|
}),
|
|
sources = cmp.config.sources({
|
|
{ name = "nvim_lsp" },
|
|
{ name = "luasnip" },
|
|
{ name = "path" },
|
|
{ name = "buffer" },
|
|
}),
|
|
})
|
|
|
|
-- ======================
|
|
-- 5. Key Mappings
|
|
-- ======================
|
|
|
|
-- 🚀 General Keybinds
|
|
vim.keymap.set("n", "<leader>e", vim.diagnostic.open_float)
|
|
vim.keymap.set("n", "[d", vim.diagnostic.goto_prev)
|
|
vim.keymap.set("n", "]d", vim.diagnostic.goto_next)
|
|
vim.keymap.set("n", "<leader>n", ":Neotree toggle<CR>")
|
|
vim.keymap.set("n", "<leader>ff", ":Telescope find_files<CR>")
|
|
vim.keymap.set("n", "<leader>fg", ":Telescope live_grep<CR>")
|
|
vim.keymap.set("n", "<leader>gs", ":Git<CR>")
|
|
vim.keymap.set("n", "<leader>gg", ":LazyGit<CR>")
|
|
|
|
-- 📝 Editing
|
|
vim.keymap.set("n", "gd", vim.lsp.buf.definition)
|
|
vim.keymap.set("n", "gr", vim.lsp.buf.references)
|
|
vim.keymap.set("n", "K", vim.lsp.buf.hover)
|
|
vim.keymap.set("n", "<leader>rn", vim.lsp.buf.rename)
|
|
|
|
-- 💻 LSP
|
|
vim.keymap.set("n", "<leader>d", vim.diagnostic.setloclist)
|
|
vim.keymap.set("n", "<leader>ca", vim.lsp.buf.code_action)
|
|
vim.keymap.set("n", "<leader>f", function() vim.lsp.buf.format({ async = true }) end)
|
|
vim.keymap.set("n", "<leader>wa", vim.lsp.buf.add_workspace_folder)
|
|
vim.keymap.set("n", "<leader>wr", vim.lsp.buf.remove_workspace_folder)
|
|
vim.keymap.set("n", "<leader>wl", function() print(vim.inspect(vim.lsp.buf.list_workspace_folders())) end)
|
|
|
|
-- 💾 Buffer Management
|
|
vim.keymap.set("n", "<leader>bd", ":bdelete<CR>")
|
|
vim.keymap.set("n", "<leader>bn", ":bnext<CR>")
|
|
vim.keymap.set("n", "<leader>bp", ":bprevious<CR>")
|
|
vim.keymap.set("n", "<leader>bl", ":Telescope buffers<CR>")
|
|
|
|
-- 🐱 Git
|
|
vim.keymap.set("n", "<leader>gc", ":Git commit<CR>")
|
|
vim.keymap.set("n", "<leader>gp", ":Git push<CR>")
|
|
vim.keymap.set("n", "<leader>gl", ":Telescope git_commits<CR>")
|
|
vim.keymap.set("n", "<leader>gd", ":Gdiff<CR>")
|
|
vim.keymap.set("n", "<leader>gb", ":Git blame<CR>")
|
|
|
|
-- 🔄 Terminal
|
|
vim.keymap.set("t", "<C-\\>", "<C-\\><C-n>") -- Escape terminal mode
|
|
vim.keymap.set("t", "<Esc><Esc>", "<C-\\><C-n>") -- Alternative escape
|
|
vim.keymap.set("n", "<leader>tt", ":ToggleTerm<CR>")
|
|
vim.keymap.set("n", "<leader>tf", ":ToggleTerm direction=float<CR>")
|
|
|
|
-- ======================
|
|
-- 6. Autocommands
|
|
-- ======================
|
|
vim.api.nvim_create_autocmd("TextYankPost", {
|
|
pattern = "*",
|
|
callback = function()
|
|
vim.highlight.on_yank()
|
|
end,
|
|
})
|
|
|
|
vim.api.nvim_create_autocmd("BufWritePre", {
|
|
pattern = "*",
|
|
callback = function()
|
|
require("conform").format({ async = false, lsp_fallback = true })
|
|
end,
|
|
})
|
|
|
|
-- Enable treesitter
|
|
require("nvim-treesitter.configs").setup({
|
|
ensure_installed = { "lua", "python", "javascript", "typescript", "html", "css", "bash", "json", "yaml" },
|
|
highlight = { enable = true },
|
|
indent = { enable = true },
|
|
})
|