diff --git a/lazy-lock.json b/lazy-lock.json index 9b8e931..c329503 100644 --- a/lazy-lock.json +++ b/lazy-lock.json @@ -1,27 +1,47 @@ { - "LuaSnip": { "branch": "master", "commit": "ccf25a5452b8697a823de3e5ecda63ed3d723b79" }, + "LuaSnip": { "branch": "master", "commit": "dae4f5aaa3574bd0c2b9dd20fb9542a02c10471c" }, "alpha-nvim": { "branch": "main", "commit": "3979b01cb05734331c7873049001d3f2bb8477f4" }, + "auto-session": { "branch": "main", "commit": "292492ab7af4bd8b9e37e28508bc8ce995722fd5" }, + "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" }, + "catppuccin": { "branch": "main", "commit": "beaf41a30c26fd7d6c386d383155cbd65dd554cd" }, "cmp-buffer": { "branch": "main", "commit": "b74fab3656eea9de20a9b8116afa3cfc4ec09657" }, - "cmp-nvim-lsp": { "branch": "main", "commit": "bd5a7d6db125d4654b50eeae9f5217f24bb22fd3" }, + "cmp-nvim-lsp": { "branch": "main", "commit": "cbc7b02bb99fae35cb42f514762b89b5126651ef" }, "cmp-path": { "branch": "main", "commit": "c642487086dbd9a93160e1679a1327be111cbc25" }, "cmp_luasnip": { "branch": "master", "commit": "98d9cb5c2c38532bd9bdb481067b20fea8f32e90" }, - "conform.nvim": { "branch": "master", "commit": "235dd79731c1dc51ec04abb4045cbc54727a172a" }, + "conform.nvim": { "branch": "master", "commit": "c2526f1cde528a66e086ab1668e996d162c75f4f" }, + "crates.nvim": { "branch": "main", "commit": "ac9fa498a9edb96dc3056724ff69d5f40b898453" }, "diffview.nvim": { "branch": "main", "commit": "4516612fe98ff56ae0415a259ff6361a89419b0a" }, - "friendly-snippets": { "branch": "main", "commit": "572f5660cf05f8cd8834e096d7b4c921ba18e175" }, - "gitsigns.nvim": { "branch": "main", "commit": "42d6aed4e94e0f0bbced16bbdcc42f57673bd75e" }, - "kanagawa": { "branch": "master", "commit": "aef7f5cec0a40dbe7f3304214850c472e2264b10" }, - "lazy.nvim": { "branch": "main", "commit": "1ea3c4085785f460fb0e46d2fe1ee895f5f9e7c1" }, - "lualine.nvim": { "branch": "master", "commit": "3946f0122255bc377d14a59b27b609fb3ab25768" }, - "mason-lspconfig.nvim": { "branch": "main", "commit": "2304ff65ecc8cb2afc2484de3e2ed9a407edf0b9" }, - "mason.nvim": { "branch": "main", "commit": "ad7146aa61dcaeb54fa900144d768f040090bff0" }, - "nvim-cmp": { "branch": "main", "commit": "a7bcf1d88069fc67c9ace8a62ba480b8fe879025" }, - "nvim-colorizer.lua": { "branch": "master", "commit": "51cf7c995ed1eb6642aecf19067ee634fa1b6ba2" }, - "nvim-lspconfig": { "branch": "master", "commit": "e5c61b02f33b5c6538be25b2696b33b4cc91e667" }, - "nvim-tree.lua": { "branch": "master", "commit": "64e2192f5250796aa4a7f33c6ad888515af50640" }, - "nvim-treesitter": { "branch": "master", "commit": "42fc28ba918343ebfd5565147a42a26580579482" }, - "nvim-web-devicons": { "branch": "master", "commit": "b8221e42cf7287c4dcde81f232f58d7b947c210d" }, + "friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" }, + "gitsigns.nvim": { "branch": "main", "commit": "abf82a65f185bd54adc0679f74b7d6e1ada690c9" }, + "hererocks": { "branch": "master", "commit": "3856f1b4fb69a9f683f1eb146a4cd49a67478419" }, + "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" }, + "lualine.nvim": { "branch": "master", "commit": "47f91c416daef12db467145e16bed5bbfe00add8" }, + "markdown-preview.nvim": { "branch": "master", "commit": "a923f5fc5ba36a3b17e289dc35dc17f66d0548ee" }, + "mason-lspconfig.nvim": { "branch": "main", "commit": "4823a251e7578a835bb979c37df390fca692ba39" }, + "mason.nvim": { "branch": "main", "commit": "44d1e90e1f66e077268191e3ee9d2ac97cc18e65" }, + "noice.nvim": { "branch": "main", "commit": "7bfd942445fb63089b59f97ca487d605e715f155" }, + "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" }, + "nvim-cmp": { "branch": "main", "commit": "da88697d7f45d16852c6b2769dc52387d1ddc45f" }, + "nvim-colorizer.lua": { "branch": "master", "commit": "81e676d3203c9eb6e4c0ccf1eba1679296ef923f" }, + "nvim-dap": { "branch": "master", "commit": "085386b9359ddf8d76ad89b98973b8e332dc5ba3" }, + "nvim-dap-python": { "branch": "master", "commit": "1808458eba2b18f178f990e01376941a42c7f93b" }, + "nvim-dap-ui": { "branch": "master", "commit": "cf91d5e2d07c72903d052f5207511bf7ecdb7122" }, + "nvim-dap-virtual-text": { "branch": "master", "commit": "fbdb48c2ed45f4a8293d0d483f7730d24467ccb6" }, + "nvim-dap-vscode-js": { "branch": "main", "commit": "03bd29672d7fab5e515fc8469b7d07cc5994bbf6" }, + "nvim-lspconfig": { "branch": "master", "commit": "419b082102fa813739588dd82e19a8b6b2442855" }, + "nvim-nio": { "branch": "master", "commit": "21f5324bfac14e22ba26553caf69ec76ae8a7662" }, + "nvim-notify": { "branch": "master", "commit": "8701bece920b38ea289b457f902e2ad184131a5d" }, + "nvim-tree.lua": { "branch": "master", "commit": "5757bcf0447d22d8f78826bc5c59b28da2824c3b" }, + "nvim-treesitter": { "branch": "main", "commit": "88f1dfc211c3a2fb47f1451fd5edc972ec697e58" }, + "nvim-web-devicons": { "branch": "master", "commit": "803353450c374192393f5387b6a0176d0972b848" }, "plenary.nvim": { "branch": "master", "commit": "b9fd5226c2f76c951fc8ed5923d85e4de065e509" }, - "telescope.nvim": { "branch": "master", "commit": "b4da76be54691e854d3e0e02c36b0245f945c2c7" }, - "typescript-tools.nvim": { "branch": "master", "commit": "bf11d98ad5736e1cbc1082ca9a03196d45c701f1" }, + "rest.nvim": { "branch": "main", "commit": "714d5512aaec5565d55652480c16c26f8d95645d" }, + "telescope.nvim": { "branch": "master", "commit": "ad7d9580338354ccc136e5b8f0aa4f880434dcdc" }, + "toggleterm.nvim": { "branch": "main", "commit": "50ea089fc548917cc3cc16b46a8211833b9e3c7c" }, + "typescript-tools.nvim": { "branch": "master", "commit": "c2f5910074103705661e9651aa841e0d7eea9932" }, + "vim-dadbod": { "branch": "master", "commit": "6d1d41da4873a445c5605f2005ad2c68c99d8770" }, + "vim-dadbod-completion": { "branch": "master", "commit": "a8dac0b3cf6132c80dc9b18bef36d4cf7a9e1fe6" }, + "vim-dadbod-ui": { "branch": "master", "commit": "48c4f271da13d380592f4907e2d1d5558044e4e5" }, + "vscode-js-debug": { "branch": "main", "commit": "4330850d72ee5816914a3188d2a6771854e1c61f" }, "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" } } diff --git a/lua/core/keymaps.lua b/lua/core/keymaps.lua index 92a1a18..4851b00 100644 --- a/lua/core/keymaps.lua +++ b/lua/core/keymaps.lua @@ -8,6 +8,7 @@ keymap('n', 'e', ':NvimTreeToggle', { desc = "Toggle file explorer" keymap('n', 'ff', 'Telescope find_files', { desc = "Find files" }) keymap('n', 'fg', 'Telescope live_grep', { desc = "Live grep" }) keymap('n', 'fb', 'Telescope buffers', { desc = "Find buffers" }) +keymap('n', 'fr', 'Telescope oldfiles', { desc = "Recent files" }) -- Git (Telescope pickers) keymap('n', 'gt', 'Telescope git_status', { desc = "Git status" }) @@ -24,3 +25,74 @@ keymap('n', '', 'l') -- Quick save and quit keymap('n', 'w', ':w', { desc = "Save" }) keymap('n', 'q', ':q', { desc = "Quit" }) + +-- Buffer navigation (bufferline) +keymap('n', 'bp', 'BufferLineTogglePin', { desc = "Pin buffer" }) +keymap('n', 'bP', 'BufferLineGroupClose ungrouped', { desc = "Close non-pinned" }) +keymap('n', 'bo', 'BufferLineCloseOthers', { desc = "Close other buffers" }) +keymap('n', 'bl', 'BufferLineCloseRight', { desc = "Close buffers to right" }) +keymap('n', 'bh', 'BufferLineCloseLeft', { desc = "Close buffers to left" }) +keymap('n', '1', 'BufferLineGoToBuffer 1', { desc = "Go to buffer 1" }) +keymap('n', '2', 'BufferLineGoToBuffer 2', { desc = "Go to buffer 2" }) +keymap('n', '3', 'BufferLineGoToBuffer 3', { desc = "Go to buffer 3" }) +keymap('n', '4', 'BufferLineGoToBuffer 4', { desc = "Go to buffer 4" }) +keymap('n', '5', 'BufferLineGoToBuffer 5', { desc = "Go to buffer 5" }) +keymap('n', 'bd', 'bdelete', { desc = "Delete buffer" }) +keymap('n', '', 'BufferLineCycleNext', { desc = "Next buffer" }) +keymap('n', '', 'BufferLineCyclePrev', { desc = "Previous buffer" }) + +-- Terminal (toggleterm) +keymap('n', 'tf', 'ToggleTerm direction=float', { desc = "Float terminal" }) +keymap('n', 'th', 'ToggleTerm direction=horizontal', { desc = "Horizontal terminal" }) +keymap('n', 'tv', 'ToggleTerm direction=vertical', { desc = "Vertical terminal" }) +keymap('n', 'tt', 'ToggleTerm', { desc = "Toggle terminal" }) +keymap('n', 'tg', 'lua _LAZYGIT_TOGGLE()', { desc = "Lazygit" }) +keymap('n', 'tp', 'lua _PYTHON_TOGGLE()', { desc = "Python REPL" }) +keymap('n', 'tn', 'lua _NODE_TOGGLE()', { desc = "Node REPL" }) + +-- Terminal mode escape +keymap('t', '', [[]], { desc = "Exit terminal mode" }) +keymap('t', '', [[wincmd h]], { desc = "Window left" }) +keymap('t', '', [[wincmd j]], { desc = "Window down" }) +keymap('t', '', [[wincmd k]], { desc = "Window up" }) +keymap('t', '', [[wincmd l]], { desc = "Window right" }) + +-- Session management +keymap('n', 'ss', 'SessionSave', { desc = "Save session" }) +keymap('n', 'sr', 'SessionRestore', { desc = "Restore session" }) +keymap('n', 'sd', 'SessionDelete', { desc = "Delete session" }) + +-- DAP (debugging) +keymap('n', 'db', 'lua require("dap").toggle_breakpoint()', { desc = "Toggle breakpoint" }) +keymap('n', 'dB', 'lua require("dap").set_breakpoint(vim.fn.input("Condition: "))', { desc = "Conditional breakpoint" }) +keymap('n', 'dc', 'lua require("dap").continue()', { desc = "Continue" }) +keymap('n', 'di', 'lua require("dap").step_into()', { desc = "Step into" }) +keymap('n', 'do', 'lua require("dap").step_over()', { desc = "Step over" }) +keymap('n', 'dO', 'lua require("dap").step_out()', { desc = "Step out" }) +keymap('n', 'dr', 'lua require("dap").repl.toggle()', { desc = "Toggle REPL" }) +keymap('n', 'dl', 'lua require("dap").run_last()', { desc = "Run last" }) +keymap('n', 'du', 'lua require("dapui").toggle()', { desc = "Toggle DAP UI" }) +keymap('n', 'dt', 'lua require("dap").terminate()', { desc = "Terminate" }) +keymap('n', '', 'lua require("dap").continue()', { desc = "Debug: Continue" }) +keymap('n', '', 'lua require("dap").step_over()', { desc = "Debug: Step Over" }) +keymap('n', '', 'lua require("dap").step_into()', { desc = "Debug: Step Into" }) +keymap('n', '', 'lua require("dap").step_out()', { desc = "Debug: Step Out" }) + +-- Noice (notifications) +keymap('n', 'nl', 'Noice last', { desc = "Last notification" }) +keymap('n', 'nh', 'Noice history', { desc = "Notification history" }) +keymap('n', 'na', 'Noice all', { desc = "All notifications" }) +keymap('n', 'nd', 'Noice dismiss', { desc = "Dismiss notifications" }) + +-- Markdown preview +keymap('n', 'mp', 'MarkdownPreviewToggle', { desc = "Toggle markdown preview" }) + +-- Database +keymap('n', 'Du', 'DBUIToggle', { desc = "Toggle DBUI" }) +keymap('n', 'Df', 'DBUIFindBuffer', { desc = "Find DB buffer" }) +keymap('n', 'Da', 'DBUIAddConnection', { desc = "Add DB connection" }) + +-- HTTP client +keymap('n', 'hr', 'lua require("rest-nvim").run()', { desc = "Run HTTP request" }) +keymap('n', 'hp', 'lua require("rest-nvim").run(true)', { desc = "Preview HTTP request" }) +keymap('n', 'hl', 'lua require("rest-nvim").last()', { desc = "Re-run last request" }) diff --git a/lua/plugins/plugin.lua b/lua/plugins/plugin.lua index 4c2eb8f..9222345 100644 --- a/lua/plugins/plugin.lua +++ b/lua/plugins/plugin.lua @@ -1,35 +1,63 @@ return { - -- Color scheme + -- Color scheme (Catppuccin Mocha) { - "rebelot/kanagawa.nvim", - name = "kanagawa", + "catppuccin/nvim", + name = "catppuccin", priority = 1000, config = function() - require('kanagawa').setup({ - compile = true, -- enable compiling the colorscheme - undercurl = true, -- enable undercurls - commentStyle = { italic = true }, - functionStyle = {}, - keywordStyle = { italic = true }, - statementStyle = { bold = true }, - typeStyle = {}, - transparent = false, -- do not set background color - dimInactive = false, -- dim inactive window `:h hl-NormalNC` - terminalColors = true, -- define vim.g.terminal_color_{0,17} - colors = { -- add/modify theme and palette colors - palette = {}, - theme = { wave = {}, lotus = {}, dragon = {}, all = {} }, + require("catppuccin").setup({ + flavour = "mocha", + background = { + light = "latte", + dark = "mocha", }, - overrides = function(colors) -- add/modify highlights - return {} - end, - theme = "wave", -- Load "wave" theme - background = { -- map the value of 'background' option to a theme - dark = "wave", -- try "dragon" ! - light = "lotus" + transparent_background = false, + show_end_of_buffer = false, + term_colors = true, + dim_inactive = { + enabled = false, + shade = "dark", + percentage = 0.15, + }, + styles = { + comments = { "italic" }, + conditionals = { "italic" }, + loops = {}, + functions = {}, + keywords = { "italic" }, + strings = {}, + variables = {}, + numbers = {}, + booleans = {}, + properties = {}, + types = {}, + operators = {}, + }, + integrations = { + cmp = true, + gitsigns = true, + nvimtree = true, + telescope = { enabled = true }, + treesitter = true, + which_key = true, + alpha = true, + mason = true, + noice = true, + notify = true, + dap = true, + dap_ui = true, + native_lsp = { + enabled = true, + underlines = { + errors = { "undercurl" }, + hints = { "undercurl" }, + warnings = { "undercurl" }, + information = { "undercurl" }, + }, + }, }, }) - vim.cmd("colorscheme kanagawa") + vim.cmd.colorscheme("catppuccin") end, }, @@ -42,6 +70,203 @@ return { end, }, + -- Bufferline (tab management) + { + "akinsho/bufferline.nvim", + version = "*", + dependencies = { "nvim-tree/nvim-web-devicons", "catppuccin/nvim" }, + config = function() + require("bufferline").setup({ + options = { + mode = "buffers", + themable = true, + numbers = "ordinal", + close_command = "bdelete! %d", + right_mouse_command = "bdelete! %d", + indicator = { + icon = "| ", + style = "icon", + }, + buffer_close_icon = "", + modified_icon = "●", + close_icon = "", + left_trunc_marker = "", + right_trunc_marker = "", + diagnostics = "nvim_lsp", + diagnostics_indicator = function(count, level) + local icon = level:match("error") and " " or " " + return " " .. icon .. count + end, + offsets = { + { + filetype = "NvimTree", + text = "File Explorer", + highlight = "Directory", + separator = true, + }, + }, + color_icons = true, + show_buffer_icons = true, + show_buffer_close_icons = true, + show_close_icon = true, + show_tab_indicators = true, + separator_style = "slant", + always_show_bufferline = true, + hover = { + enabled = true, + delay = 200, + reveal = { "close" }, + }, + }, + highlights = require("catppuccin.groups.integrations.bufferline").get(), + }) + end, + }, + + -- Toggleterm (integrated terminal) + { + "akinsho/toggleterm.nvim", + version = "*", + config = function() + require("toggleterm").setup({ + size = function(term) + if term.direction == "horizontal" then + return 15 + elseif term.direction == "vertical" then + return vim.o.columns * 0.4 + end + end, + open_mapping = [[]], + hide_numbers = true, + shade_terminals = true, + shading_factor = 2, + start_in_insert = true, + insert_mappings = true, + terminal_mappings = true, + persist_size = true, + persist_mode = true, + direction = "float", + close_on_exit = true, + shell = vim.o.shell, + auto_scroll = true, + float_opts = { + border = "curved", + winblend = 0, + }, + }) + + local Terminal = require("toggleterm.terminal").Terminal + + -- Lazygit terminal + local lazygit = Terminal:new({ + cmd = "lazygit", + dir = "git_dir", + direction = "float", + float_opts = { border = "double" }, + on_open = function(term) + vim.cmd("startinsert!") + end, + }) + + function _G._LAZYGIT_TOGGLE() + lazygit:toggle() + end + + -- Python REPL + local python = Terminal:new({ + cmd = "python3", + direction = "horizontal", + }) + + function _G._PYTHON_TOGGLE() + python:toggle() + end + + -- Node REPL + local node = Terminal:new({ + cmd = "node", + direction = "horizontal", + }) + + function _G._NODE_TOGGLE() + node:toggle() + end + end, + }, + + -- Session management + { + "rmagatti/auto-session", + config = function() + require("auto-session").setup({ + log_level = "error", + auto_session_suppress_dirs = { "~/", "~/Projects", "~/Downloads", "/" }, + auto_session_use_git_branch = true, + auto_save_enabled = true, + auto_restore_enabled = true, + auto_session_root_dir = vim.fn.stdpath("data") .. "/sessions/", + }) + end, + }, + + -- Notifications + { + "rcarriga/nvim-notify", + config = function() + require("notify").setup({ + background_colour = "#000000", + fps = 60, + render = "default", + stages = "fade_in_slide_out", + timeout = 3000, + top_down = true, + }) + vim.notify = require("notify") + end, + }, + + -- Noice (enhanced UI) + { + "folke/noice.nvim", + event = "VeryLazy", + dependencies = { + "MunifTanjim/nui.nvim", + "rcarriga/nvim-notify", + }, + config = function() + require("noice").setup({ + lsp = { + override = { + ["vim.lsp.util.convert_input_to_markdown_lines"] = true, + ["vim.lsp.util.stylize_markdown"] = true, + ["cmp.entry.get_documentation"] = true, + }, + hover = { enabled = true }, + signature = { enabled = true }, + }, + presets = { + bottom_search = true, + command_palette = true, + long_message_to_split = true, + inc_rename = false, + lsp_doc_border = true, + }, + views = { + cmdline_popup = { + position = { row = 5, col = "50%" }, + size = { width = 60, height = "auto" }, + }, + }, + routes = { + { + filter = { event = "msg_show", kind = "", find = "written" }, + opts = { skip = true }, + }, + }, + }) + end, + }, + -- Git signs { "lewis6991/gitsigns.nvim", @@ -98,6 +323,7 @@ return { opts = { format_on_save = { timeout_ms = 1000, lsp_fallback = true }, formatters_by_ft = { + -- Web javascript = { "prettierd", "prettier" }, javascriptreact = { "prettierd", "prettier" }, typescript = { "prettierd", "prettier" }, @@ -106,6 +332,15 @@ return { css = { "prettierd", "prettier" }, html = { "prettierd", "prettier" }, markdown = { "prettierd", "prettier" }, + -- Rust + rust = { "rustfmt" }, + -- Python + python = { "ruff_format" }, + -- C/C++ + c = { "clang_format" }, + cpp = { "clang_format" }, + -- Lua + lua = { "stylua" }, }, }, }, @@ -117,11 +352,32 @@ return { config = function() require("nvim-treesitter.configs").setup({ ensure_installed = { - "lua", "vim", "bash", "javascript", "typescript", "tsx", "json", "yaml", "html", "css", "prisma", - "graphql" + -- Existing + "lua", "vim", "vimdoc", "bash", + -- Web + "javascript", "typescript", "tsx", "json", "yaml", "html", "css", "prisma", "graphql", + -- Rust + "rust", "toml", + -- Python + "python", + -- C/C++ + "c", "cpp", + -- Markdown + "markdown", "markdown_inline", + -- Tools + "sql", "http", }, highlight = { enable = true }, indent = { enable = true }, + incremental_selection = { + enable = true, + keymaps = { + init_selection = "", + node_incremental = "", + scope_incremental = false, + node_decremental = "", + }, + }, }) end, }, @@ -147,16 +403,30 @@ return { mapping = cmp.mapping.preset.insert({ [""] = cmp.mapping.complete(), [""] = cmp.mapping.confirm({ select = true }), - [""] = cmp.mapping.select_next_item(), - [""] = cmp.mapping.select_prev_item(), + [""] = cmp.mapping.select_next_item(), + [""] = cmp.mapping.select_prev_item(), }), sources = { { name = "nvim_lsp" }, { name = "path" }, { name = "buffer" }, { name = "luasnip" }, + { name = "crates" }, }, }) + + -- SQL files completion + vim.api.nvim_create_autocmd("FileType", { + pattern = { "sql", "mysql", "plsql" }, + callback = function() + cmp.setup.buffer({ + sources = { + { name = "vim-dadbod-completion" }, + { name = "buffer" }, + }, + }) + end, + }) end, }, @@ -171,7 +441,17 @@ return { dependencies = { "williamboman/mason.nvim" }, config = function() require("mason-lspconfig").setup({ - ensure_installed = { "ts_ls", "eslint", "jsonls", "html", "cssls", "tailwindcss" }, + ensure_installed = { + -- Web + "ts_ls", "eslint", "jsonls", "html", "cssls", "tailwindcss", + -- Rust + "rust_analyzer", + -- Python + "pyright", "ruff", + -- C/C++ + "clangd", + }, + automatic_installation = true, }) end, }, @@ -182,6 +462,111 @@ return { "williamboman/mason-lspconfig.nvim", "hrsh7th/cmp-nvim-lsp", }, + config = function() + local capabilities = require("cmp_nvim_lsp").default_capabilities() + + -- LSP keymaps on attach + vim.api.nvim_create_autocmd("LspAttach", { + callback = function(args) + local opts = { buffer = args.buf, silent = true } + vim.keymap.set("n", "gD", vim.lsp.buf.declaration, opts) + vim.keymap.set("n", "gd", vim.lsp.buf.definition, opts) + vim.keymap.set("n", "K", vim.lsp.buf.hover, opts) + vim.keymap.set("n", "gi", vim.lsp.buf.implementation, opts) + vim.keymap.set("n", "", vim.lsp.buf.signature_help, opts) + vim.keymap.set("n", "rn", vim.lsp.buf.rename, opts) + vim.keymap.set("n", "ca", vim.lsp.buf.code_action, opts) + vim.keymap.set("n", "gr", vim.lsp.buf.references, opts) + vim.keymap.set("n", "lf", function() + vim.lsp.buf.format({ async = true }) + end, opts) + end, + }) + + -- Rust + vim.lsp.config("rust_analyzer", { + capabilities = capabilities, + settings = { + ["rust-analyzer"] = { + cargo = { allFeatures = true }, + checkOnSave = { command = "clippy" }, + inlayHints = { + bindingModeHints = { enable = true }, + chainingHints = { enable = true }, + closingBraceHints = { enable = true }, + closureReturnTypeHints = { enable = "always" }, + lifetimeElisionHints = { enable = "always" }, + parameterHints = { enable = true }, + typeHints = { enable = true }, + }, + }, + }, + }) + + -- Python (Pyright) + vim.lsp.config("pyright", { + capabilities = capabilities, + settings = { + python = { + analysis = { + autoSearchPaths = true, + diagnosticMode = "workspace", + useLibraryCodeForTypes = true, + typeCheckingMode = "basic", + }, + }, + }, + }) + + -- Python (Ruff for linting) + vim.lsp.config("ruff", { + capabilities = capabilities, + on_attach = function(client, bufnr) + client.server_capabilities.hoverProvider = false + end, + }) + + -- C/C++ + vim.lsp.config("clangd", { + capabilities = capabilities, + cmd = { + "clangd", + "--background-index", + "--clang-tidy", + "--header-insertion=iwyu", + "--completion-style=detailed", + "--function-arg-placeholders", + }, + }) + + -- JSON + vim.lsp.config("jsonls", { capabilities = capabilities }) + + -- HTML + vim.lsp.config("html", { capabilities = capabilities }) + + -- CSS + vim.lsp.config("cssls", { capabilities = capabilities }) + + -- Tailwind + vim.lsp.config("tailwindcss", { capabilities = capabilities }) + + -- ESLint + vim.lsp.config("eslint", { capabilities = capabilities }) + + -- Enable all configured servers + vim.lsp.enable({ + "rust_analyzer", + "pyright", + "ruff", + "clangd", + "jsonls", + "html", + "cssls", + "tailwindcss", + "eslint", + }) + end, }, { "pmizio/typescript-tools.nvim", @@ -198,6 +583,244 @@ return { end, }, + -- Crates.nvim (Rust Cargo.toml) + { + "saecki/crates.nvim", + event = { "BufRead Cargo.toml" }, + dependencies = { "nvim-lua/plenary.nvim" }, + config = function() + require("crates").setup({ + smart_insert = true, + insert_closing_quote = true, + autoload = true, + autoupdate = true, + loading_indicator = true, + popup = { + autofocus = false, + hide_on_select = false, + copy_register = '"', + style = "minimal", + border = "rounded", + show_version_date = true, + max_height = 30, + min_width = 20, + }, + completion = { + cmp = { enabled = true }, + }, + }) + + -- Crates keymaps + vim.api.nvim_create_autocmd("BufRead", { + pattern = "Cargo.toml", + callback = function() + local crates = require("crates") + vim.keymap.set("n", "ct", crates.toggle, { buffer = true, desc = "Toggle crates" }) + vim.keymap.set("n", "cr", crates.reload, { buffer = true, desc = "Reload crates" }) + vim.keymap.set("n", "cv", crates.show_versions_popup, { buffer = true, desc = "Show versions" }) + vim.keymap.set("n", "cf", crates.show_features_popup, { buffer = true, desc = "Show features" }) + vim.keymap.set("n", "cd", crates.show_dependencies_popup, { buffer = true, desc = "Show dependencies" }) + vim.keymap.set("n", "cu", crates.update_crate, { buffer = true, desc = "Update crate" }) + vim.keymap.set("n", "cU", crates.upgrade_crate, { buffer = true, desc = "Upgrade crate" }) + end, + }) + end, + }, + + -- DAP (debugging) + { + "mfussenegger/nvim-dap", + dependencies = { + "rcarriga/nvim-dap-ui", + "nvim-neotest/nvim-nio", + "theHamsta/nvim-dap-virtual-text", + }, + config = function() + local dap = require("dap") + local dapui = require("dapui") + + dapui.setup({ + icons = { expanded = "", collapsed = "", current_frame = "" }, + mappings = { + expand = { "", "<2-LeftMouse>" }, + open = "o", + remove = "d", + edit = "e", + repl = "r", + toggle = "t", + }, + layouts = { + { + elements = { + { id = "scopes", size = 0.25 }, + "breakpoints", + "stacks", + "watches", + }, + size = 40, + position = "left", + }, + { + elements = { "repl", "console" }, + size = 0.25, + position = "bottom", + }, + }, + }) + + require("nvim-dap-virtual-text").setup({ + enabled = true, + enabled_commands = true, + highlight_changed_variables = true, + highlight_new_as_changed = false, + show_stop_reason = true, + commented = false, + }) + + dap.listeners.after.event_initialized["dapui_config"] = function() + dapui.open() + end + dap.listeners.before.event_terminated["dapui_config"] = function() + dapui.close() + end + dap.listeners.before.event_exited["dapui_config"] = function() + dapui.close() + end + + vim.fn.sign_define("DapBreakpoint", { text = "", texthl = "DiagnosticSignError" }) + vim.fn.sign_define("DapBreakpointCondition", { text = "", texthl = "DiagnosticSignWarn" }) + vim.fn.sign_define("DapLogPoint", { text = "", texthl = "DiagnosticSignInfo" }) + vim.fn.sign_define("DapStopped", { text = "", texthl = "DiagnosticSignHint", linehl = "Visual" }) + vim.fn.sign_define("DapBreakpointRejected", { text = "", texthl = "DiagnosticSignError" }) + end, + }, + + -- Python DAP + { + "mfussenegger/nvim-dap-python", + dependencies = { "mfussenegger/nvim-dap" }, + ft = "python", + config = function() + require("dap-python").setup("python3") + end, + }, + + -- JS/TS DAP + { + "mxsdev/nvim-dap-vscode-js", + dependencies = { + "mfussenegger/nvim-dap", + { + "microsoft/vscode-js-debug", + build = "npm install --legacy-peer-deps && npx gulp vsDebugServerBundle && mv dist out", + }, + }, + config = function() + require("dap-vscode-js").setup({ + debugger_path = vim.fn.stdpath("data") .. "/lazy/vscode-js-debug", + adapters = { "pwa-node", "pwa-chrome", "pwa-msedge", "node-terminal", "pwa-extensionHost" }, + }) + + for _, language in ipairs({ "typescript", "javascript", "typescriptreact", "javascriptreact" }) do + require("dap").configurations[language] = { + { + type = "pwa-node", + request = "launch", + name = "Launch file", + program = "${file}", + cwd = "${workspaceFolder}", + }, + { + type = "pwa-node", + request = "attach", + name = "Attach", + processId = require("dap.utils").pick_process, + cwd = "${workspaceFolder}", + }, + { + type = "pwa-chrome", + request = "launch", + name = "Launch Chrome", + url = "http://localhost:3000", + webRoot = "${workspaceFolder}", + }, + } + end + end, + }, + + -- Markdown preview + { + "iamcco/markdown-preview.nvim", + cmd = { "MarkdownPreviewToggle", "MarkdownPreview", "MarkdownPreviewStop" }, + ft = { "markdown" }, + build = function() vim.fn["mkdp#util#install"]() end, + config = function() + vim.g.mkdp_auto_start = 0 + vim.g.mkdp_auto_close = 1 + vim.g.mkdp_refresh_slow = 0 + vim.g.mkdp_browser = "" + vim.g.mkdp_preview_options = { + mkit = {}, + katex = {}, + uml = {}, + maid = {}, + disable_sync_scroll = 0, + sync_scroll_type = "middle", + hide_yaml_meta = 1, + } + end, + }, + + -- Database client + { + "tpope/vim-dadbod", + cmd = { "DB", "DBUI", "DBUIToggle", "DBUIAddConnection" }, + }, + { + "kristijanhusak/vim-dadbod-ui", + dependencies = { + { "tpope/vim-dadbod", lazy = true }, + { "kristijanhusak/vim-dadbod-completion", ft = { "sql", "mysql", "plsql" }, lazy = true }, + }, + cmd = { "DBUI", "DBUIToggle", "DBUIAddConnection", "DBUIFindBuffer" }, + init = function() + vim.g.db_ui_use_nerd_fonts = 1 + vim.g.db_ui_save_location = vim.fn.stdpath("data") .. "/db_ui" + end, + }, + + -- HTTP client + { + "rest-nvim/rest.nvim", + dependencies = { "nvim-lua/plenary.nvim" }, + ft = "http", + config = function() + require("rest-nvim").setup({ + result_split_horizontal = false, + result_split_in_place = false, + skip_ssl_verification = false, + encode_url = true, + highlight = { + enabled = true, + timeout = 150, + }, + result = { + show_url = true, + show_curl_command = false, + show_http_info = true, + show_headers = true, + formatters = { + json = "jq", + }, + }, + jump_to_request = false, + env_file = ".env", + yank_dry_run = true, + }) + end, + }, + -- Colorizer { "NvChad/nvim-colorizer.lua", @@ -210,7 +833,7 @@ return { dependencies = { "nvim-tree/nvim-web-devicons" }, config = function() require("lualine").setup({ - options = { theme = "kanagawa" }, + options = { theme = "catppuccin" }, }) end, }, @@ -234,6 +857,16 @@ return { { "g", group = "Git" }, { "w", desc = "Save" }, { "q", desc = "Quit" }, + { "b", group = "Buffers" }, + { "t", group = "Terminal" }, + { "d", group = "Debug" }, + { "l", group = "LSP" }, + { "c", group = "Crates (Rust)" }, + { "s", group = "Session" }, + { "n", group = "Notifications" }, + { "h", group = "HTTP" }, + { "D", group = "Database" }, + { "m", group = "Markdown" }, }) end, }, @@ -253,14 +886,14 @@ return { dashboard.section.buttons.val = { dashboard.button("e", " New file", ":ene startinsert "), - dashboard.button("f", "󰍉 Find file", ":lua require('fzf-lua').files() "), + dashboard.button("f", "󰍉 Find file", ":Telescope find_files"), + dashboard.button("r", " Recent files", ":Telescope oldfiles"), dashboard.button("t", " Browse cwd", ":NvimTreeOpen"), - dashboard.button("r", " Browse src", ":e ~/.local/src/"), - dashboard.button("s", "󰯂 Browse scripts", ":e ~/scripts/"), + dashboard.button("s", " Restore session", ":SessionRestore"), + dashboard.button("g", "󰊢 Lazygit", ":lua _LAZYGIT_TOGGLE()"), dashboard.button("c", " Config", ":e ~/.config/nvim/"), - dashboard.button("m", " Mappings", ":e ~/.config/nvim/lua/core/keymaps.lua"), - dashboard.button("p", " Plugins", ":PlugInstall"), - dashboard.button("q", "󰅙 Quit", ":q!"), + dashboard.button("p", " Plugins", ":Lazy"), + dashboard.button("q", "󰅙 Quit", ":qa"), } dashboard.section.footer.val = function()