-- VIM OPTIONS START -- local vim = vim vim.o.number = true vim.o.relativenumber = true vim.o.tabstop = 4 vim.o.shiftwidth = 4 vim.o.expandtab = true vim.o.signcolumn = "yes" vim.o.swapfile = false vim.g.mapleader = " " vim.o.winborder = "single" -- Make 'j' and 'k' navigate visual lines (not logical lines) vim.keymap.set("n", "j", "gj", { noremap = true, silent = true }) vim.keymap.set("n", "k", "gk", { noremap = true, silent = true }) vim.keymap.set("v", "j", "gj", { noremap = true, silent = true }) vim.keymap.set("v", "k", "gk", { noremap = true, silent = true }) -- VIM OPTIONS END -- -- PLUGINS START -- vim.pack.add({ { src = "https://github.com/ellisonleao/gruvbox.nvim" }, { src = "https://github.com/stevearc/oil.nvim" }, { src = "https://github.com/echasnovski/mini.pick" }, { src = "https://github.com/neovim/nvim-lspconfig" }, { src = "https://github.com/nvim-treesitter/nvim-treesitter" }, { src = "https://github.com/nvim-treesitter/nvim-treesitter-textobjects" }, { src = "https://github.com/Saghen/blink.cmp", version = "v1.7.0" }, { src = "https://github.com/mason-org/mason.nvim" }, { src = "https://github.com/nvim-lualine/lualine.nvim.git" }, { src = "https://github.com/chomosuke/typst-preview.nvim" }, { src = "https://github.com/numToStr/Comment.nvim" }, { src = "https://codeberg.org/mfussenegger/nvim-jdtls.git", dependencies = { "https://codeberg.org/mfussenegger/nvim-dap.git" } }, { src = "https://github.com/m4xshen/autoclose.nvim" }, { src = "https://codeberg.org/mfussenegger/nvim-dap.git" }, { src = "https://github.com/romgrk/barbar.nvim" }, { src = "https://github.com/nvim-tree/nvim-web-devicons" }, { src = "https://github.com/lewis6991/gitsigns.nvim" }, { src = "https://github.com/folke/trouble.nvim" }, { src = "https://github.com/rcarriga/nvim-dap-ui", dependencies = { "https://github.com/mfussenegger/nvim-dap", "https://github.com/nvim-neotest/nvim-nio" } }, { src = "https://github.com/nvim-neotest/nvim-nio" }, }) -- Safely load colorscheme pcall(vim.cmd, "colorscheme gruvbox") -- Helper function to safely setup plugins only if they are installed local function setup_plugin(module, opts) local ok, plugin = pcall(require, module) if ok and type(plugin.setup) == "function" then plugin.setup(opts or {}) end end setup_plugin("oil") setup_plugin("mini.pick") setup_plugin("blink.cmp", { keymap = { preset = "super-tab" } }) setup_plugin("nvim-treesitter.configs", { auto_install = true, highlight = { enable = true }, indent = { enable = true }, textobjects = { select = { enable = true, lookahead = true, keymaps = { ["af"] = "@function.outer", ["if"] = "@function.inner", ["ac"] = "@class.outer", ["ic"] = "@class.inner", }, }, }, }) setup_plugin("mason") -- Automatically install these tools via Mason local registry = require("mason-registry") local ensure_installed = { "bash-language-server", "clang-format", "clangd", "java-debug-adapter", "jdtls", "json-lsp", "lua-language-server", "rust-analyzer", "svelte-language-server", "tailwindcss-language-server", "taplo", "typescript-language-server" } -- Refresh the registry and install missing tools registry.refresh(function() for _, tool in ipairs(ensure_installed) do local ok, pkg = pcall(registry.get_package, tool) if ok and not pkg:is_installed() then pkg:install() end end end) setup_plugin("lualine", { options = { theme = "gruvbox_dark" } }) setup_plugin("typst-preview") setup_plugin("autoclose") setup_plugin("trouble") setup_plugin("Comment") -- PLUGINS END -- -- DAP START -- local ok_dap, dap = pcall(require, "dap") local ok_dapui, dapui = pcall(require, "dapui") if ok_dap and ok_dapui then dapui.setup() dap.listeners.before.attach.dapui_config = function() dapui.open() end dap.listeners.before.launch.dapui_config = function() dapui.open() end end -- DAP END -- -- LSP START -- -- Assuming vim.lsp.enable is native to your specific Neovim version vim.lsp.enable({ "lua_ls", "ts_ls", "svelte", "tailwindcss", "cssls", "bashls", "rust_analyzer", "clangd", "clang-format", "taplo", "sourcekit", "lemminx", "tinymist", "jsonls" }) vim.lsp.config["tinymist"] = { cmd = { "tinymist" }, filetypes = { "typst" }, settings = { formatterMode = "typstyle", }, } vim.api.nvim_create_autocmd('FileType', { pattern = 'java', callback = function(args) -- Safely require jdtls so it doesn't crash if uninstalled local ok, jdtls = pcall(require, "jdtls") if not ok then return end local project_name = vim.fn.fnamemodify(vim.fn.getcwd(), ":p:h:t") local workspace_dir = vim.fn.stdpath("data") .. package.config:sub(1, 1) .. "jdtls-workspace" .. package.config:sub(1, 1) .. project_name local os_name = vim.loop.os_uname().sysname local config = { cmd = { "java", "-Declipse.application=org.eclipse.jdt.ls.core.id1", "-Dosgi.bundles.defaultStartLevel=4", "-Declipse.product=org.eclipse.jdt.ls.core.product", "-Dlog.protocol=true", "-Dlog.level=ALL", "-Xmx1g", "--add-modules=ALL-SYSTEM", "--add-opens", "java.base/java.util=ALL-UNNAMED", "--add-opens", "java.base/java.lang=ALL-UNNAMED", "-jar", vim.fn.stdpath("data") .. package.config:sub(1, 1) .. "mason" .. package.config:sub(1, 1) .. "packages" .. package.config:sub(1, 1) .. "jdtls" .. package.config:sub(1, 1) .. "plugins" .. package.config:sub(1, 1) .. "org.eclipse.equinox.launcher_1.7.100.v20251111-0406.jar", "-configuration", vim.fn.stdpath("data") .. package.config:sub(1, 1) .. "mason" .. package.config:sub(1, 1) .. "packages" .. package.config:sub(1, 1) .. "jdtls" .. package.config:sub(1, 1) .. "config_" .. (os_name == "Windows_NT" and "win" or os_name == "Linux" and "linux" or "mac"), "-data", workspace_dir, }, root_dir = require("jdtls.setup").find_root({ ".git", "mvnw", "gradlew" }), settings = { java = {} }, init_options = { bundles = { vim.fn.glob("/home/jannikdonker/.local/share/nvim/mason/share/java-debug-adapter/com.microsoft.java.debug.plugin.jar", 1) }, }, } jdtls.start_or_attach(config) end }) -- LSP END -- -- KEYMAP START -- local map = vim.keymap local opts = { noremap = true, silent = true } map.set("n", "gf", vim.lsp.buf.format) map.set("n", "gd", vim.lsp.buf.definition) map.set("n", "gD", vim.lsp.buf.declaration) map.set("n", "ca", vim.lsp.buf.code_action, { desc = "Code Action" }) map.set("n", "rn", vim.lsp.buf.rename, { desc = "Rename symbol" }) map.set("n", "xx", "Trouble diagnostics toggle focus=true", { desc = "Diagnostics (Trouble)" }) map.set("n", "xX", "Trouble diagnostics toggle filter.buf=0 focus=true", { desc = "Buffer Diagnostics (Trouble)" }) map.set("n", "", ":Pick files") map.set("n", "", ":Pick grep_live") map.set("n", "", ":Pick help") map.set("n", "", ":Oil") -- Wrapped DAP calls in anonymous functions so they don't evaluate before DAP installs map.set("n", "duo", function() require("dapui").open() end) map.set("n", "duc", function() require("dapui").close() end) map.set("n", "dbp", function() require("dap").toggle_breakpoint() end) map.set("n", "drc", function() require("dap").run_to_cursor() end) local is_mac = vim.fn.has("macunix") == 1 local barbarKey = is_mac and "M" or "A" map.set('n', '<' .. barbarKey .. '-,>', 'BufferPrevious', opts) map.set('n', '<' .. barbarKey .. '-.>', 'BufferNext', opts) map.set('n', '<' .. barbarKey .. '-<>', 'BufferMovePrevious', opts) map.set('n', '<' .. barbarKey .. '->>', 'BufferMoveNext', opts) map.set('n', '<' .. barbarKey .. '-1>', 'BufferGoto 1', opts) map.set('n', '<' .. barbarKey .. '-2>', 'BufferGoto 2', opts) map.set('n', '<' .. barbarKey .. '-3>', 'BufferGoto 3', opts) map.set('n', '<' .. barbarKey .. '-4>', 'BufferGoto 4', opts) map.set('n', '<' .. barbarKey .. '-5>', 'BufferGoto 5', opts) map.set('n', '<' .. barbarKey .. '-6>', 'BufferGoto 6', opts) map.set('n', '<' .. barbarKey .. '-7>', 'BufferGoto 7', opts) map.set('n', '<' .. barbarKey .. '-8>', 'BufferGoto 8', opts) map.set('n', '<' .. barbarKey .. '-9>', 'BufferGoto 9', opts) map.set('n', '<' .. barbarKey .. '-0>', 'BufferLast', opts) map.set('n', '<' .. barbarKey .. '-p>', 'BufferPin', opts) map.set('n', '<' .. barbarKey .. '-w>', 'BufferClose', opts) map.set('n', '', 'BufferPick', opts) map.set('n', '', 'BufferPickDelete', opts) -- KEYMAP END -- vim.diagnostic.config({ virtual_text = { prefix = "●", spacing = 2, source = "if_many", }, severity_sort = true, }) vim.keymap.set("n", "sc", function() vim.wo.spell = not vim.wo.spell print("Spell checking: " .. (vim.wo.spell and "ON" or "OFF")) end, { desc = "Toggle spell checking" }) vim.keymap.set("n", "sl", function() local current = vim.opt.spelllang:get()[1] or "" local new_lang = current == "en" and "de" or "en" vim.opt.spelllang = new_lang print("Spell language: " .. new_lang) end, { desc = "Switch spell language" })