nvim,tmux,kitty: full config overhaul (AstroNvim → native 0.12)

Replaces AstroNvim v5 with from-scratch Neovim 0.12 config using
vim.lsp.config()/vim.lsp.enable() natively, lazy.nvim, blink.cmp,
and smart-splits tmux integration.

tmux: new C-Space prefix, hjkl pane nav, resize key table, tpm plugins.
kitty: add allow_remote_control for smart-splits.
This commit is contained in:
2026-04-09 23:30:34 +02:00
parent d5d890aa43
commit ca2b441bb7
58 changed files with 2616 additions and 880 deletions

View File

@@ -0,0 +1,34 @@
return {
-- Local AI ghost text via ollama (FIM completion)
{
"huggingface/llm.nvim",
event = "InsertEnter",
keys = {
{ "<leader>ta", "<cmd>LLMToggleAutoSuggest<cr>", desc = "Toggle AI suggestions" },
},
opts = {
backend = "ollama",
model = "qwen2.5-coder:latest",
url = vim.env.OLLAMA_HOST or "http://localhost:11434",
tokens_to_clear = { "<|endoftext|>" },
fim = {
enabled = true,
prefix = "<|fim_prefix|>",
middle = "<|fim_middle|>",
suffix = "<|fim_suffix|>",
},
context_window = 4096,
tokenizer = nil, -- use token estimation
enable_suggestions_on_startup = true,
display = {
renderer = "virtual-text",
virtual_text = {
enabled = true,
hl = "Comment",
},
},
accept_keymap = "<Tab>",
dismiss_keymap = "<C-]>",
},
},
}

View File

@@ -1,83 +1,2 @@
-- AstroCore provides a central place to modify mappings, vim options, autocommands, and more!
-- Configuration documentation can be found with `:h astrocore`
-- NOTE: We highly recommend setting up the Lua Language Server (`:LspInstall lua_ls`)
-- as this provides autocomplete and documentation while editing
---@type LazySpec
return {
"AstroNvim/astrocore",
---@type AstroCoreOpts
opts = {
-- Configure core features of AstroNvim
features = {
large_buf = { size = 1024 * 256, lines = 10000 }, -- set global limits for large files for disabling features like treesitter
autopairs = true, -- enable autopairs at start
cmp = true, -- enable completion at start
diagnostics = { virtual_text = true, virtual_lines = false }, -- diagnostic settings on startup
highlighturl = true, -- highlight URLs at start
notifications = true, -- enable notifications at start
},
-- Diagnostics configuration (for vim.diagnostics.config({...})) when diagnostics are on
diagnostics = {
virtual_text = true,
underline = true,
},
-- passed to `vim.filetype.add`
filetypes = {
-- see `:h vim.filetype.add` for usage
extension = {
foo = "fooscript",
},
filename = {
[".foorc"] = "fooscript",
},
pattern = {
[".*/etc/foo/.*"] = "fooscript",
},
},
-- vim options can be configured here
options = {
opt = { -- vim.opt.<key>
relativenumber = true, -- sets vim.opt.relativenumber
number = true, -- sets vim.opt.number
spell = false, -- sets vim.opt.spell
signcolumn = "yes", -- sets vim.opt.signcolumn to yes
wrap = false, -- sets vim.opt.wrap
},
g = { -- vim.g.<key>
-- configure global vim variables (vim.g)
-- NOTE: `mapleader` and `maplocalleader` must be set in the AstroNvim opts or before `lazy.setup`
-- This can be found in the `lua/lazy_setup.lua` file
},
},
-- Mappings can be configured through AstroCore as well.
-- NOTE: keycodes follow the casing in the vimdocs. For example, `<Leader>` must be capitalized
mappings = {
-- first key is the mode
n = {
-- second key is the lefthand side of the map
-- navigate buffer tabs
["]b"] = { function() require("astrocore.buffer").nav(vim.v.count1) end, desc = "Next buffer" },
["[b"] = { function() require("astrocore.buffer").nav(-vim.v.count1) end, desc = "Previous buffer" },
-- mappings seen under group name "Buffer"
["<Leader>bd"] = {
function()
require("astroui.status.heirline").buffer_picker(
function(bufnr) require("astrocore.buffer").close(bufnr) end
)
end,
desc = "Close buffer from tabline",
},
-- tables with just a `desc` key will be registered with which-key if it's installed
-- this is useful for naming menus
-- ["<Leader>b"] = { desc = "Buffers" },
-- setting a mapping to false will disable it
-- ["<C-S>"] = false,
},
},
},
}
-- AstroNvim removed; core settings live in lua/options.lua and lua/autocmds.lua
return {}

View File

@@ -1,107 +1,2 @@
-- AstroLSP allows you to customize the features in AstroNvim's LSP configuration engine
-- Configuration documentation can be found with `:h astrolsp`
-- NOTE: We highly recommend setting up the Lua Language Server (`:LspInstall lua_ls`)
-- as this provides autocomplete and documentation while editing
---@type LazySpec
return {
"AstroNvim/astrolsp",
---@type AstroLSPOpts
opts = {
-- Configuration table of features provided by AstroLSP
features = {
codelens = true, -- enable/disable codelens refresh on start
inlay_hints = false, -- enable/disable inlay hints on start
semantic_tokens = true, -- enable/disable semantic token highlighting
},
-- customize lsp formatting options
formatting = {
-- control auto formatting on save
format_on_save = {
enabled = true, -- enable or disable format on save globally
allow_filetypes = { -- enable format on save for specified filetypes only
-- "go",
},
ignore_filetypes = { -- disable format on save for specified filetypes
-- "python",
},
},
disabled = { -- disable formatting capabilities for the listed language servers
-- disable lua_ls formatting capability if you want to use StyLua to format your lua code
-- "lua_ls",
},
timeout_ms = 1000, -- default format timeout
-- filter = function(client) -- fully override the default formatting function
-- return true
-- end
},
-- enable servers that you already have installed without mason
servers = {
-- "pyright"
},
-- ensure servers are installed
ensure_installed = {
"ltex",
},
-- customize language server configuration options passed to `lspconfig`
---@diagnostic disable: missing-fields
config = {
-- clangd = { capabilities = { offsetEncoding = "utf-8" } },
},
-- customize how language servers are attached
handlers = {
-- a function without a key is simply the default handler, functions take two parameters, the server name and the configured options table for that server
-- function(server, opts) require("lspconfig")[server].setup(opts) end
-- the key is the server that is being setup with `lspconfig`
-- rust_analyzer = false, -- setting a handler to false will disable the set up of that language server
-- pyright = function(_, opts) require("lspconfig").pyright.setup(opts) end -- or a custom handler function can be passed
},
-- Configure buffer local auto commands to add when attaching a language server
autocmds = {
-- first key is the `augroup` to add the auto commands to (:h augroup)
lsp_codelens_refresh = {
-- Optional condition to create/delete auto command group
-- can either be a string of a client capability or a function of `fun(client, bufnr): boolean`
-- condition will be resolved for each client on each execution and if it ever fails for all clients,
-- the auto commands will be deleted for that buffer
cond = "textDocument/codeLens",
-- cond = function(client, bufnr) return client.name == "lua_ls" end,
-- list of auto commands to set
{
-- events to trigger
event = { "InsertLeave", "BufEnter" },
-- the rest of the autocmd options (:h nvim_create_autocmd)
desc = "Refresh codelens (buffer)",
callback = function(args)
if require("astrolsp").config.features.codelens then vim.lsp.codelens.refresh { bufnr = args.buf } end
end,
},
},
},
-- mappings to be set up on attaching of a language server
mappings = {
n = {
-- a `cond` key can provided as the string of a server capability to be required to attach, or a function with `client` and `bufnr` parameters from the `on_attach` that returns a boolean
gD = {
function() vim.lsp.buf.declaration() end,
desc = "Declaration of current symbol",
cond = "textDocument/declaration",
},
["<Leader>uY"] = {
function() require("astrolsp.toggles").buffer_semantic_tokens() end,
desc = "Toggle LSP semantic highlight (buffer)",
cond = function(client)
return client.supports_method "textDocument/semanticTokens/full" and vim.lsp.semantic_tokens ~= nil
end,
},
},
},
-- A custom `on_attach` function to be run after the default `on_attach` function
-- takes two parameters `client` and `bufnr` (`:h lspconfig-setup`)
on_attach = function(client, bufnr)
-- this would disable semanticTokensProvider for all clients
-- client.server_capabilities.semanticTokensProvider = nil
end,
},
}
-- AstroNvim removed; LSP config uses native vim.lsp.config in lua/lsp/
return {}

View File

@@ -0,0 +1,2 @@
-- AstroNvim removed; colorscheme is set via vim.cmd.colorscheme("apex-neon") in init.lua
return {}

View File

@@ -1,37 +0,0 @@
-- AstroUI provides the basis for configuring the AstroNvim User Interface
-- Configuration documentation can be found with `:h astroui`
-- NOTE: We highly recommend setting up the Lua Language Server (`:LspInstall lua_ls`)
-- as this provides autocomplete and documentation while editing
---@type LazySpec
return {
"AstroNvim/astroui",
---@type AstroUIOpts
opts = {
-- change colorscheme
colorscheme = "{{ .chezmoi.config.data.theme }}",
-- AstroUI allows you to easily modify highlight groups easily for any and all colorschemes
highlights = {
init = { -- this table overrides highlights in all themes
-- Normal = { bg = "#000000" },
},
astrodark = { -- a table of overrides/changes when applying the astrotheme theme
-- Normal = { bg = "#000000" },
},
},
-- Icons can be configured throughout the interface
icons = {
-- configure the loading of the lsp in the status line
LSPLoading1 = "⠋",
LSPLoading2 = "⠙",
LSPLoading3 = "⠹",
LSPLoading4 = "⠸",
LSPLoading5 = "⠼",
LSPLoading6 = "⠴",
LSPLoading7 = "⠦",
LSPLoading8 = "⠧",
LSPLoading9 = "⠇",
LSPLoading10 = "⠏",
},
},
}

View File

@@ -1,29 +1,2 @@
return {
"windwp/nvim-autopairs",
config = function(plugin, opts)
require "astronvim.plugins.configs.nvim-autopairs"(plugin, opts) -- include the default astronvim config that calls the setup call
-- add more custom autopairs configuration such as custom rules
local npairs = require "nvim-autopairs"
local Rule = require "nvim-autopairs.rule"
local cond = require "nvim-autopairs.conds"
npairs.add_rules(
{
Rule("$", "$", { "tex", "latex" })
-- don't add a pair if the next character is %
:with_pair(cond.not_after_regex "%%")
-- don't add a pair if the previous character is xxx
:with_pair(
cond.not_before_regex("xxx", 3)
)
-- don't move right when repeat character
:with_move(cond.none())
-- don't delete if the next character is xx
:with_del(cond.not_after_regex "xx")
-- disable adding a newline when you press <cr>
:with_cr(cond.none()),
},
-- disable for .vim files, but it work for another filetypes
Rule("a", "a", "-vim")
)
end,
}
-- nvim-autopairs is configured in editing.lua
return {}

View File

@@ -1,39 +1,2 @@
return {
-- Let blink.cmp consume nvim-cmp sources
{ "saghen/blink.compat", version = "2.*", lazy = true, opts = {} },
-- Add vimtex + latex symbol sources to blink.cmp
{
"Saghen/blink.cmp",
optional = true,
dependencies = {
"micangl/cmp-vimtex", -- environments, \cite, \ref, etc. via vimtex
"kdheepak/cmp-latex-symbols", -- math symbols via LaTeX macros
},
opts = function(_, opts)
opts.sources = opts.sources or {}
opts.sources.providers = opts.sources.providers or {}
opts.sources.default = opts.sources.default or { "lsp", "path", "snippets", "buffer" }
-- Only turn on the LaTeX sources for TeX filetypes
opts.sources.per_filetype = vim.tbl_deep_extend("force", opts.sources.per_filetype or {}, {
tex = { inherit_defaults = true, "vimtex", "latex_symbols" },
plaintex = { inherit_defaults = true, "vimtex", "latex_symbols" },
})
-- Expose nvim-cmp sources to blink via blink.compat
opts.sources.providers.vimtex = {
name = "vimtex",
module = "blink.compat.source",
}
opts.sources.providers.latex_symbols = {
name = "latex_symbols",
module = "blink.compat.source",
-- Insert LaTeX commands (e.g. \alpha) instead of Unicode characters:
opts = { strategy = 2 }, -- documented in cmp-latex-symbols README
score_offset = -2, -- keep it below LSP/snippets in relevance
}
return opts
end,
},
}
-- blink.cmp LaTeX sources are configured in completion.lua
return {}

View File

@@ -0,0 +1,101 @@
return {
-- Snippet engine
{
"L3MON4D3/LuaSnip",
version = "v2.*",
build = "make install_jsregexp",
dependencies = { "rafamadriz/friendly-snippets" },
opts = {
enable_autosnippets = true,
history = true,
update_events = "TextChanged,TextChangedI",
},
config = function(_, opts)
require("luasnip").setup(opts)
require("luasnip.loaders.from_vscode").lazy_load()
-- Extend js snippets to ts
require("luasnip").filetype_extend("typescript", { "javascript" })
require("luasnip").filetype_extend("svelte", { "javascript", "html" })
end,
},
-- Castel-style LaTeX snippets (autosnippets for math mode)
{
"iurimateus/luasnip-latex-snippets.nvim",
ft = { "tex", "plaintex", "markdown" },
dependencies = { "L3MON4D3/LuaSnip", "lervag/vimtex" },
opts = { use_treesitter = false, allow_on_markdown = true },
config = function(_, opts)
require("luasnip-latex-snippets").setup(opts)
end,
},
-- blink.compat: exposes nvim-cmp sources to blink.cmp
{ "saghen/blink.compat", version = "2.*", lazy = true, opts = {} },
-- LaTeX completion sources (via blink.compat)
{
"micangl/cmp-vimtex",
lazy = true,
},
{
"kdheepak/cmp-latex-symbols",
lazy = true,
},
-- Main completion engine
{
"saghen/blink.cmp",
version = "v0.*",
dependencies = {
"L3MON4D3/LuaSnip",
"saghen/blink.compat",
"micangl/cmp-vimtex",
"kdheepak/cmp-latex-symbols",
},
opts = {
keymap = {
preset = "default",
["<Tab>"] = { "select_next", "fallback" },
["<S-Tab>"] = { "select_prev", "fallback" },
["<CR>"] = { "accept", "fallback" },
["<C-space>"] = { "show", "show_documentation", "hide_documentation" },
["<C-e>"] = { "hide" },
["<C-b>"] = { "scroll_documentation_up", "fallback" },
["<C-f>"] = { "scroll_documentation_down", "fallback" },
},
completion = {
ghost_text = { enabled = true },
documentation = { auto_show = true, auto_show_delay_ms = 200 },
menu = {
draw = {
treesitter = { "lsp" },
},
},
},
snippets = {
preset = "luasnip",
},
sources = {
default = { "lsp", "snippets", "buffer", "path" },
per_filetype = {
tex = { inherit_defaults = true, "vimtex", "latex_symbols" },
plaintex = { inherit_defaults = true, "vimtex", "latex_symbols" },
},
providers = {
vimtex = {
name = "vimtex",
module = "blink.compat.source",
},
latex_symbols = {
name = "latex_symbols",
module = "blink.compat.source",
opts = { strategy = 2 }, -- insert LaTeX commands, not Unicode
score_offset = -2,
},
},
},
signature = { enabled = true },
},
},
}

View File

@@ -0,0 +1,79 @@
return {
-- Debug Adapter Protocol base
{
"mfussenegger/nvim-dap",
dependencies = {
"rcarriga/nvim-dap-ui",
"theHamsta/nvim-dap-virtual-text",
"nvim-neotest/nvim-nio",
},
keys = {
{ "<leader>db", function() require("dap").toggle_breakpoint() end, desc = "Toggle breakpoint" },
{ "<leader>dB", function() require("dap").set_breakpoint(vim.fn.input("Condition: ")) end, desc = "Conditional breakpoint" },
{ "<leader>dc", function() require("dap").continue() end, desc = "Continue" },
{ "<leader>di", function() require("dap").step_into() end, desc = "Step into" },
{ "<leader>do", function() require("dap").step_over() end, desc = "Step over" },
{ "<leader>dO", function() require("dap").step_out() end, desc = "Step out" },
{ "<leader>dr", function() require("dap").repl.open() end, desc = "Open REPL" },
{ "<leader>du", function() require("dapui").toggle() end, desc = "Toggle DAP UI" },
{ "<leader>dv", function() require("nvim-dap-virtual-text").toggle() end, desc = "Toggle virtual text" },
},
config = function()
local dap = require("dap")
local dapui = require("dapui")
-- Auto-open/close DAP UI
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
-- Load language-specific configs
require("plugins.dap.rust")
require("plugins.dap.js")
end,
},
-- DAP UI panels
{
"rcarriga/nvim-dap-ui",
lazy = true,
dependencies = { "mfussenegger/nvim-dap", "nvim-neotest/nvim-nio" },
opts = {
icons = { expanded = "", collapsed = "", current_frame = "" },
layouts = {
{
elements = {
{ id = "scopes", size = 0.25 },
{ id = "breakpoints", size = 0.25 },
{ id = "stacks", size = 0.25 },
{ id = "watches", size = 0.25 },
},
size = 40,
position = "left",
},
{
elements = {
{ id = "repl", size = 0.5 },
{ id = "console", size = 0.5 },
},
size = 10,
position = "bottom",
},
},
},
},
-- Inline variable values during debug session
{
"theHamsta/nvim-dap-virtual-text",
lazy = true,
opts = {
enabled = true,
enabled_commands = true,
highlight_changed_variables = true,
highlight_new_as_changed = false,
commented = false,
virt_text_pos = "eol",
},
},
}

View File

@@ -0,0 +1,41 @@
local M = {}
local function setup()
local dap = require("dap")
local mason_path = vim.fn.stdpath("data") .. "/mason/packages/js-debug-adapter"
dap.adapters["pwa-node"] = {
type = "server",
host = "localhost",
port = "${port}",
executable = {
command = "node",
args = { mason_path .. "/js-debug/src/dapDebugServer.js", "${port}" },
},
}
local js_config = {
{
type = "pwa-node",
request = "launch",
name = "Launch file",
program = "${file}",
cwd = "${workspaceFolder}",
sourceMaps = true,
},
{
type = "pwa-node",
request = "attach",
name = "Attach",
processId = require("dap.utils").pick_process,
cwd = "${workspaceFolder}",
},
}
for _, lang in ipairs({ "javascript", "typescript", "svelte" }) do
dap.configurations[lang] = js_config
end
end
setup()
return M

View File

@@ -0,0 +1,43 @@
local M = {}
local function setup()
local dap = require("dap")
local mason_path = vim.fn.stdpath("data") .. "/mason/packages/codelldb"
dap.adapters.codelldb = {
type = "server",
port = "${port}",
executable = {
command = mason_path .. "/extension/adapter/codelldb",
args = { "--port", "${port}" },
},
}
dap.configurations.rust = {
{
name = "Launch (Rust)",
type = "codelldb",
request = "launch",
program = function()
return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/target/debug/", "file")
end,
cwd = "${workspaceFolder}",
stopOnEntry = false,
args = {},
},
{
name = "Launch Tauri (Rust)",
type = "codelldb",
request = "launch",
program = function()
return vim.fn.input("Path to executable: ", vim.fn.getcwd() .. "/src-tauri/target/debug/", "file")
end,
cwd = "${workspaceFolder}/src-tauri",
stopOnEntry = false,
args = {},
},
}
end
setup()
return M

View File

@@ -0,0 +1,68 @@
return {
-- Auto-close brackets, with LaTeX math guard
{
"windwp/nvim-autopairs",
event = "InsertEnter",
config = function()
local npairs = require("nvim-autopairs")
local Rule = require("nvim-autopairs.rule")
local cond = require("nvim-autopairs.conds")
npairs.setup({
check_ts = true,
ts_config = { java = false }, -- disable for Java (interferes with jdtls)
fast_wrap = { map = "<M-e>" },
})
-- LaTeX inline math: $...$ pair
npairs.add_rules({
Rule("$", "$", { "tex", "latex" })
:with_pair(cond.not_after_regex("%%")) -- don't pair after %
:with_move(cond.none())
:with_del(cond.not_after_regex("xx"))
:with_cr(cond.none()),
})
end,
},
-- Surround operations: ys, cs, ds
{
"kylechui/nvim-surround",
version = "*",
event = "VeryLazy",
opts = {},
},
-- Formatter (format on save)
{
"stevearc/conform.nvim",
event = "BufWritePre",
cmd = "ConformInfo",
keys = {
{ "<leader>lf", function() require("conform").format({ async = true, lsp_fallback = true }) end, desc = "Format" },
},
opts = {
formatters_by_ft = {
lua = { "stylua" },
rust = { "rustfmt" },
javascript = { "prettier" },
typescript = { "prettier" },
javascriptreact = { "prettier" },
typescriptreact = { "prettier" },
svelte = { "prettier" },
java = { "google-java-format" },
json = { "prettier" },
yaml = { "prettier" },
toml = { "taplo" },
html = { "prettier" },
css = { "prettier" },
markdown = { "prettier" },
["jinja.html"] = { "djlint" },
},
format_on_save = {
timeout_ms = 2000,
lsp_fallback = true,
},
},
},
}

View File

@@ -0,0 +1,63 @@
return {
-- Gutter signs, hunk navigation, inline blame
{
"lewis6991/gitsigns.nvim",
event = { "BufReadPost", "BufNewFile" },
opts = {
signs = {
add = { text = "" },
change = { text = "" },
delete = { text = "" },
topdelete = { text = "" },
changedelete = { text = "" },
untracked = { text = "" },
},
on_attach = function(bufnr)
local gs = package.loaded.gitsigns
local map = function(mode, lhs, rhs, desc)
vim.keymap.set(mode, lhs, rhs, { buffer = bufnr, desc = desc })
end
-- Navigation
map("n", "]h", function()
if vim.wo.diff then return "]h" end
vim.schedule(function() gs.next_hunk() end)
return "<Ignore>"
end, "Next hunk")
map("n", "[h", function()
if vim.wo.diff then return "[h" end
vim.schedule(function() gs.prev_hunk() end)
return "<Ignore>"
end, "Prev hunk")
-- Actions
map("n", "<leader>hs", gs.stage_hunk, "Stage hunk")
map("n", "<leader>gu", gs.undo_stage_hunk, "Undo stage hunk")
map("n", "<leader>gh", gs.preview_hunk, "Preview hunk")
map("n", "<leader>hb", gs.toggle_current_line_blame, "Toggle blame")
map("n", "<leader>gb", gs.toggle_current_line_blame, "Toggle blame")
map("n", "<leader>gd", gs.diffthis, "Diff this")
end,
},
},
-- Magit-style full git interface
{
"NeogitOrg/neogit",
dependencies = {
"nvim-lua/plenary.nvim",
"sindrets/diffview.nvim",
"nvim-telescope/telescope.nvim",
},
cmd = "Neogit",
keys = {
{ "<leader>gg", "<cmd>Neogit<cr>", desc = "Neogit" },
},
opts = {
integrations = {
telescope = true,
diffview = true,
},
},
},
}

View File

@@ -0,0 +1,105 @@
return {
{
"mfussenegger/nvim-jdtls",
ft = "java",
config = function()
local jdtls = require("jdtls")
local jdtls_path = vim.fn.stdpath("data") .. "/mason/packages/jdtls"
local lombok_jar = jdtls_path .. "/lombok.jar"
-- Find project root
local root_markers = { ".git", "mvnw", "gradlew", "pom.xml", "build.gradle" }
local root_dir = require("jdtls.setup").find_root(root_markers)
if not root_dir then
return
end
-- Unique workspace per project
local project_name = vim.fn.fnamemodify(root_dir, ":p:h:t")
local workspace_dir = vim.fn.stdpath("data") .. "/jdtls-workspace/" .. project_name
-- Find launcher jar and platform config
local jdtls_launcher = vim.fn.glob(jdtls_path .. "/plugins/org.eclipse.equinox.launcher_*.jar")
local jdtls_config_dir
if vim.fn.has("linux") == 1 then
jdtls_config_dir = jdtls_path .. "/config_linux"
elseif vim.fn.has("mac") == 1 then
jdtls_config_dir = jdtls_path .. "/config_mac"
end
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",
-- Lombok support
vim.fn.filereadable(lombok_jar) == 1 and "-javaagent:" .. lombok_jar or nil,
"-jar", jdtls_launcher,
"-configuration", jdtls_config_dir,
"-data", workspace_dir,
},
root_dir = root_dir,
settings = {
java = {
eclipse = { downloadSources = true },
configuration = { updateBuildConfiguration = "interactive" },
maven = { downloadSources = true },
implementationsCodeLens = { enabled = true },
referencesCodeLens = { enabled = true },
references = { includeDecompiledSources = true },
inlayHints = { parameterNames = { enabled = "none" } }, -- too noisy for Java
format = { enabled = true },
},
signatureHelp = { enabled = true },
completion = {
favoriteStaticMembers = {
"org.hamcrest.MatcherAssert.assertThat",
"org.hamcrest.Matchers.*",
"org.junit.Assert.*",
"org.junit.Assume.*",
"org.junit.jupiter.api.Assertions.*",
"org.mockito.Mockito.*",
},
},
},
init_options = {
bundles = {},
},
on_attach = function(client, bufnr)
-- Enable navic for breadcrumbs
local ok, navic = pcall(require, "nvim-navic")
if ok then navic.attach(client, bufnr) end
-- Java-specific keymaps
local map = function(keys, func, desc)
vim.keymap.set("n", keys, func, { buffer = bufnr, desc = "Java: " .. desc })
end
map("<leader>jo", jdtls.organize_imports, "Organize imports")
map("<leader>jv", jdtls.extract_variable, "Extract variable")
map("<leader>jm", function() jdtls.extract_method(true) end, "Extract method")
map("<leader>jc", "<cmd>!javac %<cr>", "Compile file")
map("<leader>jf", jdtls.rename_file, "Rename file (+ class)")
-- DAP: enable Java debugging if nvim-dap is available
local ok_dap, dap = pcall(require, "jdtls.dap")
if ok_dap then
dap.setup_dap_main_class_configs()
end
end,
capabilities = vim.lsp.protocol.make_client_capabilities(),
}
-- Filter nil from cmd array
config.cmd = vim.tbl_filter(function(v) return v ~= nil end, config.cmd)
jdtls.start_or_attach(config)
end,
},
}

View File

@@ -1,17 +1,2 @@
-- Gilles Castel-style LaTeX snippets for LuaSnip
return {
-- Make sure autosnippets are enabled globally
{
"L3MON4D3/LuaSnip",
opts = function(_, opts) opts.enable_autosnippets = true end,
},
-- The LaTeX snippets themselves
{
"iurimateus/luasnip-latex-snippets.nvim",
ft = { "tex", "plaintex", "markdown" },
dependencies = { "L3MON4D3/LuaSnip", "lervag/vimtex" },
opts = { use_treesitter = false, allow_on_markdown = true }, -- use vimtex to detect math mode
config = function(_, opts) require("luasnip-latex-snippets").setup(opts) end,
},
}
-- luasnip-latex-snippets is configured in completion.lua
return {}

View File

@@ -0,0 +1,79 @@
return {
-- Mason: installs LSP servers, formatters, DAP adapters
{
"williamboman/mason.nvim",
cmd = "Mason",
build = ":MasonUpdate",
opts = {
ui = { icons = { package_installed = "", package_pending = "", package_uninstalled = "" } },
},
},
-- mason-lspconfig bridges mason ↔ vim.lsp.enable
{
"williamboman/mason-lspconfig.nvim",
dependencies = { "williamboman/mason.nvim" },
opts = {
ensure_installed = {
"lua_ls", "rust_analyzer", "ts_ls", "svelte",
"html", "texlab", "marksman", "yamlls", "taplo",
-- ltex managed via mason-tool-installer for version control
},
automatic_installation = false,
},
},
-- mason-tool-installer: formatters, linters, DAP, extra servers
{
"WhoIsSethDaniel/mason-tool-installer.nvim",
dependencies = { "williamboman/mason.nvim" },
opts = {
ensure_installed = {
-- LSP servers
"lua-language-server",
"rust-analyzer",
"typescript-language-server",
"svelte-language-server",
"html-lsp",
"texlab",
"marksman",
"yaml-language-server",
"taplo",
"ltex-ls",
-- Formatters
"stylua",
"prettier",
"rustfmt",
"google-java-format",
"djlint",
-- DAP
"codelldb",
"js-debug-adapter",
},
auto_update = false,
run_on_start = true,
},
config = function(_, opts)
require("mason-tool-installer").setup(opts)
-- Enable servers after mason installs them
-- Server configs loaded by init.lua (lua/lsp/*.lua)
vim.api.nvim_create_autocmd("User", {
pattern = "MasonToolsStartingInstall",
once = true,
callback = function()
vim.schedule(function()
vim.lsp.enable({
"lua_ls", "rust_analyzer", "ts_ls", "svelte",
"html", "texlab", "marksman", "yamlls", "taplo", "ltex",
})
end)
end,
})
-- Also enable on startup (for machines where tools are already installed)
vim.lsp.enable({
"lua_ls", "rust_analyzer", "ts_ls", "svelte",
"html", "texlab", "marksman", "yamlls", "taplo", "ltex",
})
end,
},
}

View File

@@ -1,5 +1,2 @@
return {
"ray-x/lsp_signature.nvim",
event = "BufRead",
config = function() require("lsp_signature").setup() end,
}
-- Removed: not part of the from-scratch config
return {}

View File

@@ -1,66 +1,9 @@
-- Grammar & spell checking for LaTeX/Markdown via LanguageTool (LTeX-LS)
return {
-- Tell AstroLSP to manage the ltex server and pass our settings
{
"AstroNvim/astrolsp",
---@param opts AstroLSPOpts
opts = function(_, opts)
opts.servers = opts.servers or {}
if not vim.tbl_contains(opts.servers, "ltex") then table.insert(opts.servers, "ltex") end
-- Extend the ltex server configuration
opts.config = require("astrocore").extend_tbl(opts.config or {}, {
ltex = {
filetypes = { "tex", "plaintex", "bib", "markdown" },
settings = {
ltex = {
-- Run checks on save for performance; switch to "edit" if you prefer live feedback
checkFrequency = "save",
-- Pick the language you want LTeX to check as the document language
language = "en-GB",
-- Mother tongue helps the grammar engine (adjust to your preference)
additionalRules = { motherTongue = "de-DE" },
-- Let ltex_extra manage dictionaries/rules on disk
dictionary = {
["en-GB"] = {},
["de-DE"] = {},
["fr-FR"] = {},
},
disabledRules = {
["en-GB"] = {},
["de-DE"] = {},
["fr-FR"] = {},
},
hiddenFalsePositives = {
["en-GB"] = {},
["de-DE"] = {},
["fr-FR"] = {},
},
},
},
-- hook up ltex_extra when the server attaches
on_attach = function(client, bufnr)
local ok, ltex_extra = pcall(require, "ltex_extra")
if ok then
ltex_extra.setup {
-- load both EN+DE dictionaries; change to your set
load_langs = { "en-GB", "de-DE", "fr-FR" },
init_check = true,
-- store per-project files in .ltex (add to .gitignore if you want)
path = ".ltex",
log_level = "none",
}
end
end,
},
})
end,
},
-- Companion plugin: add-to-dictionary / disable-rule / hide-false-positive
-- ltex_extra: persist custom dictionary/rules to disk
{
"barreiroleo/ltex_extra.nvim",
ft = { "tex", "plaintex", "markdown" },
ft = { "tex", "plaintex", "bib", "markdown" },
lazy = true,
-- Actual setup happens in lua/lsp/ltex.lua on_attach
},
}

View File

@@ -1,18 +1,2 @@
return {
"L3MON4D3/LuaSnip",
enabled = true,
version = "v2.*",
build = "make install_jsregexp",
event = "InsertEnter",
dependencies = {
"rafamadriz/friendly-snippets",
},
config = function(plugin, opts)
-- run the default astronvim config that calls the setup call
require "astronvim.plugins.configs.luasnip"(plugin, opts)
-- lazy load snippets from friendly-snippets
require("luasnip.loaders.from_vscode").lazy_load()
-- add more custom luasnip configuration such as filetype extend or custom snippets
require("luasnip").filetype_extend("javascript", { "javascriptreact" })
end,
}
-- LuaSnip is configured in completion.lua
return {}

View File

@@ -1,28 +1,2 @@
if true then return {} end -- WARN: REMOVE THIS LINE TO ACTIVATE THIS FILE
-- Customize Mason
---@type LazySpec
return {
-- use mason-tool-installer for automatically installing Mason packages
{
"WhoIsSethDaniel/mason-tool-installer.nvim",
-- overrides `require("mason-tool-installer").setup(...)`
opts = {
-- Make sure to use the names found in `:Mason`
ensure_installed = {
-- install language servers
"lua-language-server",
-- install formatters
"stylua",
-- install debuggers
"debugpy",
-- install any other package
"tree-sitter-cli",
},
},
},
}
-- Mason is configured in lsp.lua
return {}

View File

@@ -1,135 +1,2 @@
-- Minimal Markdown + math workflow (FOSS/KISS):
-- - Blink completion of LaTeX symbols in Markdown
-- - :MdPdf for one-shot Pandoc -> PDF (LuaLaTeX) and open in Zathura (auto-reload)
-- - :MdWatch / :MdWatchStop to rebuild on save via `entr`
return {
-- Markdown gets LaTeX symbol completion (inserts \alpha, not α)
{
"Saghen/blink.cmp",
optional = true,
opts = function(_, opts)
opts.sources = opts.sources or {}
opts.sources.per_filetype = vim.tbl_deep_extend("force", opts.sources.per_filetype or {}, {
markdown = { inherit_defaults = true, "latex_symbols" },
})
return opts
end,
},
-- Ensure Treesitter grammars for Markdown editing
{
"nvim-treesitter/nvim-treesitter",
opts = function(_, opts)
opts.ensure_installed = opts.ensure_installed or {}
for _, lang in ipairs { "markdown", "markdown_inline" } do
if not vim.tbl_contains(opts.ensure_installed, lang) then table.insert(opts.ensure_installed, lang) end
end
end,
},
-- Commands + keymaps
{
"AstroNvim/astrocore",
init = function()
local function have(bin) return vim.fn.executable(bin) == 1 end
local function pandoc_cmd(input_md)
local stem = input_md:gsub("%.md$", "")
local md = vim.fn.shellescape(input_md)
local pdf = vim.fn.shellescape(stem .. ".pdf")
local cmd = ("pandoc %s -o %s --from=markdown+tex_math_dollars+raw_tex --pdf-engine=lualatex --citeproc"):format(
md,
pdf
)
return cmd, (stem .. ".pdf")
end
-- One-shot: build PDF and open Zathura once (it auto-reloads)
vim.api.nvim_create_user_command("MdPdf", function()
if not have "pandoc" then
vim.notify("MdPdf: pandoc not found. Install pandoc.", vim.log.levels.ERROR)
return
end
local name = vim.api.nvim_buf_get_name(0)
if name == "" or not name:match "%.md$" then
vim.notify("MdPdf: open a Markdown (*.md) file", vim.log.levels.WARN)
return
end
local cmd, pdf = pandoc_cmd(name)
vim.fn.jobstart({ "sh", "-c", cmd }, {
detach = true,
on_exit = function()
if have "zathura" and not vim.g._mdpdf_zathura_opened then
vim.g._mdpdf_zathura_opened = true
vim.fn.jobstart({ "zathura", "--fork", pdf }, { detach = true })
end
end,
})
end, {})
-- Continuous: watch with entr and rebuild on change
vim.api.nvim_create_user_command("MdWatch", function()
if not have "pandoc" then
vim.notify("MdWatch: pandoc not found. Install pandoc.", vim.log.levels.ERROR)
return
end
if not have "entr" then
vim.notify("MdWatch: entr not found. Install entr.", vim.log.levels.ERROR)
return
end
local buf = vim.api.nvim_get_current_buf()
local name = vim.api.nvim_buf_get_name(buf)
if name == "" or not name:match "%.md$" then
vim.notify("MdWatch: open a Markdown (*.md) file", vim.log.levels.WARN)
return
end
-- First build (also opens Zathura once)
vim.cmd "MdPdf"
local cmd, _ = pandoc_cmd(name)
local qfile = vim.fn.shellescape(name)
local pipeline = ("printf %%s\\n %s | entr -r sh -c %s"):format(qfile, vim.fn.shellescape(cmd))
local jobid = vim.fn.jobstart({ "sh", "-c", pipeline }, { detach = false })
if jobid <= 0 then
vim.notify("MdWatch: failed to start entr", vim.log.levels.ERROR)
return
end
vim.b.md_kiss_watch_job = jobid
vim.notify("MdWatch: watching " .. name .. " (use :MdWatchStop to stop)", vim.log.levels.INFO)
-- Auto-stop when buffer unloads
vim.api.nvim_create_autocmd({ "BufUnload", "BufWipeout" }, {
buffer = buf,
once = true,
callback = function()
if vim.b.md_kiss_watch_job then pcall(vim.fn.jobstop, vim.b.md_kiss_watch_job) end
end,
})
end, {})
vim.api.nvim_create_user_command("MdWatchStop", function()
local job = vim.b.md_kiss_watch_job
if job then
pcall(vim.fn.jobstop, job)
vim.b.md_kiss_watch_job = nil
vim.notify("MdWatch: stopped", vim.log.levels.INFO)
else
vim.notify("MdWatch: no watcher running for this buffer", vim.log.levels.WARN)
end
end, {})
-- Buffer-local keymaps for Markdown
local group = vim.api.nvim_create_augroup("md_kiss_keys", { clear = true })
vim.api.nvim_create_autocmd("FileType", {
group = group,
pattern = "markdown",
callback = function(args)
vim.keymap.set("n", "<leader>mP", "<cmd>MdPdf<CR>", { buffer = args.buf, desc = "Markdown → PDF (Pandoc)" })
vim.keymap.set("n", "<leader>mw", "<cmd>MdWatch<CR>", { buffer = args.buf, desc = "Watch & rebuild (entr)" })
vim.keymap.set("n", "<leader>mW", "<cmd>MdWatchStop<CR>", { buffer = args.buf, desc = "Stop watch" })
end,
})
end,
},
}
-- Removed: not part of the from-scratch config
return {}

View File

@@ -1,19 +1,2 @@
-- Lightweight inline ASCII preview for LaTeX math
return {
"jbyuki/nabla.nvim",
ft = { "tex", "plaintex", "markdown" },
keys = {
-- Popup preview for the expression under cursor
{ "<leader>mp", function() require("nabla").popup() end, desc = "Math: popup preview" },
-- Toggle inline virtual rendering; re-enable wrap after toggle (nabla toggles it off)
{
"<leader>mv",
function()
require("nabla").toggle_virt { autogen = true }
vim.wo.wrap = true
end,
desc = "Math: toggle inline preview",
},
},
}
-- Removed: not part of the from-scratch config
return {}

View File

@@ -1,14 +1,2 @@
---@type LazySpec
return {
"2kabhishek/nerdy.nvim",
cmd = "Nerdy",
dependencies = {
"folke/snacks.nvim",
},
opts = {
max_recents = 30,
add_default_keybindings = true,
copy_to_clipboard = false,
copy_register = "+",
},
}
-- Removed: not part of the from-scratch config
return {}

View File

@@ -1,24 +1,2 @@
if true then return {} end -- WARN: REMOVE THIS LINE TO ACTIVATE THIS FILE
-- Customize None-ls sources
---@type LazySpec
return {
"nvimtools/none-ls.nvim",
opts = function(_, opts)
-- opts variable is the default configuration table for the setup function call
-- local null_ls = require "null-ls"
-- Check supported formatters and linters
-- https://github.com/nvimtools/none-ls.nvim/tree/main/lua/null-ls/builtins/formatting
-- https://github.com/nvimtools/none-ls.nvim/tree/main/lua/null-ls/builtins/diagnostics
-- Only insert new sources, do not replace the existing ones
-- (If you wish to replace, use `opts.sources = {}` instead of the `list_insert_unique` function)
opts.sources = require("astrocore").list_insert_unique(opts.sources, {
-- Set a formatter
-- null_ls.builtins.formatting.stylua,
-- null_ls.builtins.formatting.prettier,
})
end,
}
-- none-ls replaced by conform.nvim in editing.lua
return {}

View File

@@ -1,40 +1,2 @@
---@type LazySpec
return {
"obsidian-nvim/obsidian.nvim",
version = "*", -- recommended, use latest release instead of latest commit
lazy = true,
ft = "markdown",
-- Replace the above line with this if you only want to load obsidian.nvim for markdown files in your vault:
-- event = {
-- -- If you want to use the home shortcut '~' here you need to call 'vim.fn.expand'.
-- -- E.g. "BufReadPre " .. vim.fn.expand "~" .. "/my-vault/*.md"
-- -- refer to `:h file-pattern` for more examples
-- "BufReadPre path/to/my-vault/*.md",
-- "BufNewFile path/to/my-vault/*.md",
-- },
dependencies = {
-- Required.
"nvim-lua/plenary.nvim",
-- see above for full list of optional dependencies ☝️
},
---@module 'obsidian'
---@type obsidian.config.ClientOpts
opts = {
workspaces = {
{
name = "uni",
path = "~/Documents/uni",
},
},
-- Optional, completion of wiki links, local markdown links, and tags using nvim-cmp.
completion = {
-- Enables completion using nvim_cmp
nvim_cmp = false,
-- Enables completion using blink.cmp
blink = true,
-- Trigger completion at 2 chars.
min_chars = 2,
},
},
}
-- Removed: not part of the from-scratch config
return {}

View File

@@ -1,25 +1,2 @@
-- A vimtex-like workflow for compiling Markdown to PDF using pandoc
return {
"arminveres/md-pdf.nvim",
lazy = true,
-- Set up a keymap for compiling
keys = {
{
"<Leader>mc",
function()
-- The plugin's main function to convert markdown to pdf
require("md-pdf").convert_md_to_pdf()
end,
desc = "Markdown Compile",
},
},
-- Configure the plugin
opts = {
-- Set zathura as the PDF viewer to match the vimtex setup
preview_cmd = function()
return "zathura"
end,
-- other options...
ignore_viewer_state = true, -- Auto-recompile PDF on each write
},
}
-- Removed: not part of the from-scratch config
return {}

View File

@@ -1,4 +1,2 @@
return {
"andweeb/presence.nvim",
event = "VimEnter",
}
-- Removed: not part of the from-scratch config
return {}

View File

@@ -1,22 +1,2 @@
return {
"folke/snacks.nvim",
opts = {
dashboard = {
preset = {
header = table.concat({
" █████ ███████ ████████ ██████ ██████ ",
"██ ██ ██ ██ ██ ██ ██ ██",
"███████ ███████ ██ ██████ ██ ██",
"██ ██ ██ ██ ██ ██ ██ ██",
"██ ██ ███████ ██ ██ ██ ██████ ",
"",
"███  ██ ██  ██ ██ ███  ███",
"████  ██ ██  ██ ██ ████  ████",
"██ ██  ██ ██  ██ ██ ██ ████ ██",
"██  ██ ██  ██  ██  ██ ██  ██  ██",
"██   ████   ████   ██ ██  ██",
}, "\n"),
},
},
},
}
-- Removed: not part of the from-scratch config
return {}

View File

@@ -0,0 +1,44 @@
return {
{
"nvim-telescope/telescope.nvim",
branch = "0.1.x",
dependencies = {
"nvim-lua/plenary.nvim",
{
"nvim-telescope/telescope-fzf-native.nvim",
build = "make",
cond = function()
return vim.fn.executable("make") == 1
end,
},
},
cmd = "Telescope",
keys = {
{ "<leader>ff", "<cmd>Telescope find_files<cr>", desc = "Find files" },
{ "<leader>fg", "<cmd>Telescope live_grep<cr>", desc = "Live grep" },
{ "<leader>fb", "<cmd>Telescope buffers<cr>", desc = "Buffers" },
{ "<leader>fs", "<cmd>Telescope lsp_document_symbols<cr>", desc = "LSP symbols" },
{ "<leader>fd", "<cmd>Telescope diagnostics<cr>", desc = "Diagnostics" },
{ "<leader>fr", "<cmd>Telescope oldfiles<cr>", desc = "Recent files" },
{ "<leader>fw", "<cmd>Telescope grep_string<cr>", desc = "Grep word under cursor" },
{ "<leader>fp", "<cmd>Telescope projects<cr>", desc = "Projects" },
{ "<leader>fh", "<cmd>Telescope help_tags<cr>", desc = "Help tags" },
},
config = function()
local telescope = require("telescope")
telescope.setup({
defaults = {
prompt_prefix = " ",
selection_caret = " ",
path_display = { "smart" },
file_ignore_patterns = { ".git/", "node_modules/", "target/" },
},
pickers = {
find_files = { hidden = true },
},
})
pcall(telescope.load_extension, "fzf")
pcall(telescope.load_extension, "projects")
end,
},
}

View File

@@ -0,0 +1,70 @@
return {
-- Floating terminal
{
"akinsho/toggleterm.nvim",
version = "*",
keys = {
{ "<C-\\>", "<cmd>ToggleTerm direction=float<cr>", mode = { "n", "t" }, desc = "Toggle float terminal" },
},
opts = {
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 = nil, -- managed via keymaps above
hide_numbers = true,
shade_terminals = false,
start_in_insert = true,
insert_mappings = false,
terminal_mappings = false,
persist_size = true,
direction = "float",
close_on_exit = true,
float_opts = {
border = "curved",
winblend = 3,
},
on_open = function(term)
vim.cmd("startinsert!")
vim.api.nvim_buf_set_keymap(term.bufnr, "t", "<Esc>", "<C-\\><C-n>", { noremap = true, silent = true })
end,
},
config = function(_, opts)
require("toggleterm").setup(opts)
-- Named terminals
local Terminal = require("toggleterm.terminal").Terminal
-- Tauri dev server
local tauri_term = Terminal:new({
cmd = "cargo tauri dev",
direction = "float",
hidden = true,
display_name = "Tauri Dev",
})
-- Test runner
local test_term = Terminal:new({
direction = "horizontal",
hidden = true,
display_name = "Tests",
})
-- Claude Code
local claude_term = Terminal:new({
cmd = "claude",
direction = "float",
hidden = true,
display_name = "Claude Code",
float_opts = { border = "curved" },
})
vim.keymap.set("n", "<leader>tt", function() tauri_term:toggle() end, { desc = "Toggle Tauri dev" })
vim.keymap.set("n", "<leader>te", function() test_term:toggle() end, { desc = "Toggle test terminal" })
vim.keymap.set("n", "<leader>cc", function() claude_term:toggle() end, { desc = "Claude Code" })
end,
},
}

View File

@@ -0,0 +1,33 @@
return {
{
"nvim-neotest/neotest",
dependencies = {
"nvim-lua/plenary.nvim",
"nvim-treesitter/nvim-treesitter",
"nvim-neotest/nvim-nio",
"rouge8/neotest-rust",
"rcasia/neotest-java",
},
keys = {
{ "<leader>tr", function() require("neotest").run.run() end, desc = "Run nearest test" },
{ "<leader>ts", function() require("neotest").run.run(vim.fn.expand("%")) end, desc = "Run test suite" },
{ "<leader>tl", function() require("neotest").run.run_last() end, desc = "Run last test" },
{ "<leader>to", function() require("neotest").output.open({ enter = true }) end, desc = "Open test output" },
{ "<leader>tp", function() require("neotest").output_panel.toggle() end, desc = "Toggle test panel" },
{ "<leader>ts", function() require("neotest").summary.toggle() end, desc = "Toggle summary" },
},
opts = function()
return {
adapters = {
require("neotest-rust")({ args = { "--no-capture" } }),
require("neotest-java")({
ignore_wrapper = false,
}),
},
output = { open_on_run = false },
quickfix = { open = false },
status = { virtual_text = true },
}
end,
},
}

View File

@@ -1,15 +1,70 @@
if true then return {} end -- WARN: REMOVE THIS LINE TO ACTIVATE THIS FILE
-- Customize Treesitter
---@type LazySpec
return {
"nvim-treesitter/nvim-treesitter",
opts = {
ensure_installed = {
"lua",
"vim",
-- add more arguments for adding more treesitter parsers
{
"nvim-treesitter/nvim-treesitter",
build = ":TSUpdate",
event = { "BufReadPost", "BufNewFile" },
dependencies = {
"nvim-treesitter/nvim-treesitter-textobjects",
},
opts = {
ensure_installed = {
"lua", "rust", "typescript", "javascript", "svelte",
"java", "latex", "markdown", "markdown_inline",
"yaml", "toml", "bash", "html", "css", "jinja",
"json", "vim", "vimdoc", "regex",
},
auto_install = true,
highlight = {
enable = true,
additional_vim_regex_highlighting = { "latex" }, -- needed for vimtex
},
indent = { enable = true },
incremental_selection = {
enable = true,
keymaps = {
init_selection = "<C-space>",
node_incremental = "<C-space>",
scope_incremental = false,
node_decremental = "<bs>",
},
},
textobjects = {
select = {
enable = true,
lookahead = true,
keymaps = {
["am"] = "@function.outer",
["im"] = "@function.inner",
["ac"] = "@class.outer",
["ic"] = "@class.inner",
["a,"] = "@parameter.outer",
["i,"] = "@parameter.inner",
},
},
move = {
enable = true,
set_jumps = true,
goto_next_start = {
["]m"] = "@function.outer",
["]c"] = "@class.outer",
},
goto_next_end = {
["]M"] = "@function.outer",
["]C"] = "@class.outer",
},
goto_previous_start = {
["[m"] = "@function.outer",
["[c"] = "@class.outer",
},
goto_previous_end = {
["[M"] = "@function.outer",
["[C"] = "@class.outer",
},
},
},
},
config = function(_, opts)
require("nvim-treesitter.configs").setup(opts)
end,
},
}

View File

@@ -0,0 +1,341 @@
return {
-- Seamless navigation between nvim splits and tmux panes
{
"mrjones2014/smart-splits.nvim",
lazy = false,
opts = {
multiplexer_integration = "tmux",
cursor_follows_swapped_panes = false,
},
keys = {
-- Navigate
{ "<C-h>", function() require("smart-splits").move_cursor_left() end, mode = { "n", "t" }, desc = "Move to left split/pane" },
{ "<C-j>", function() require("smart-splits").move_cursor_down() end, mode = { "n", "t" }, desc = "Move to lower split/pane" },
{ "<C-k>", function() require("smart-splits").move_cursor_up() end, mode = { "n", "t" }, desc = "Move to upper split/pane" },
{ "<C-l>", function() require("smart-splits").move_cursor_right() end, mode = { "n", "t" }, desc = "Move to right split/pane" },
-- Resize
{ "<C-A-h>", function() require("smart-splits").resize_left() end, desc = "Resize left" },
{ "<C-A-j>", function() require("smart-splits").resize_down() end, desc = "Resize down" },
{ "<C-A-k>", function() require("smart-splits").resize_up() end, desc = "Resize up" },
{ "<C-A-l>", function() require("smart-splits").resize_right() end, desc = "Resize right" },
},
},
-- Breadcrumbs: current file > class > method via LSP
{
"SmiteshP/nvim-navic",
lazy = true, -- attached via LspAttach in autocmds.lua
opts = {
icons = {
File = "󰈙 ", Module = " ", Namespace = "󰌗 ", Package = " ",
Class = "󰌗 ", Method = "󰆧 ", Property = " ", Field = " ",
Constructor = " ", Enum = "󰕘", Interface = "󰕘", Function = "󰊕 ",
Variable = "󰆧 ", Constant = "󰏿 ", String = "󰀬 ", Number = "󰎠 ",
Boolean = "", Array = "󰅪 ", Object = "󰅩 ", Key = "󰌋 ",
Null = "󰟢 ", EnumMember = " ", Struct = "󰌗 ", Event = " ",
Operator = "󰆕 ", TypeParameter = "󰊄 ",
},
lsp = { auto_attach = false }, -- we attach manually in autocmds.lua
highlight = true,
separator = " ",
},
},
-- Statusline
{
"nvim-lualine/lualine.nvim",
dependencies = { "nvim-tree/nvim-web-devicons", "SmiteshP/nvim-navic" },
event = "VeryLazy",
config = function()
local navic = require("nvim-navic")
require("lualine").setup({
options = {
theme = require("apex-neon").lualine,
globalstatus = true,
component_separators = { left = "", right = "" },
section_separators = { left = "", right = "" },
},
sections = {
lualine_a = { "mode" },
lualine_b = { "branch", "diff", "diagnostics" },
lualine_c = { { "filename", path = 1 } },
lualine_x = {
{
-- Show recording macro indicator
function()
local reg = vim.fn.reg_recording()
return reg ~= "" and "Recording @" .. reg or ""
end,
color = { fg = "#ffb700" },
},
"encoding", "fileformat", "filetype",
},
lualine_y = { "progress" },
lualine_z = { "location" },
},
winbar = {
lualine_c = {
{
function()
return navic.is_available() and navic.get_location() or ""
end,
},
},
},
inactive_winbar = {
lualine_c = { { "filename", path = 1 } },
},
})
end,
},
-- Buffer tabs at top
{
"akinsho/bufferline.nvim",
version = "*",
dependencies = "nvim-tree/nvim-web-devicons",
event = "VeryLazy",
opts = {
options = {
mode = "buffers",
separator_style = "slant",
show_buffer_close_icons = true,
show_close_icon = false,
color_icons = true,
diagnostics = "nvim_lsp",
offsets = {
{ filetype = "aerial", text = "Symbols", text_align = "center", separator = true },
},
},
},
},
-- Scoped buffers per tab
{
"tiagovla/scope.nvim",
event = "VeryLazy",
opts = {},
},
-- Keymap discovery
{
"folke/which-key.nvim",
event = "VeryLazy",
opts = {
preset = "modern",
icons = { mappings = false },
},
config = function(_, opts)
local wk = require("which-key")
wk.setup(opts)
wk.add({
{ "<leader>f", group = "Find / Telescope" },
{ "<leader>g", group = "Git" },
{ "<leader>l", group = "LSP" },
{ "<leader>r", group = "Refactor" },
{ "<leader>x", group = "Diagnostics / Trouble" },
{ "<leader>d", group = "Debug (DAP)" },
{ "<leader>t", group = "Test" },
{ "<leader>u", group = "UI Toggles" },
{ "<leader>S", group = "Sessions" },
{ "<leader>j", group = "Java" },
{ "<leader>c", group = "AI / Claude" },
{ "<leader>h", group = "Git Hunks" },
})
-- UI toggle keymaps (no plugin dependency)
local map = vim.keymap.set
map("n", "<leader>uw", function() vim.opt.wrap = not vim.wo.wrap end, { desc = "Toggle wrap" })
map("n", "<leader>uf", "zA", { desc = "Toggle all folds" })
end,
},
-- Indentation guides
{
"lukas-reineke/indent-blankline.nvim",
main = "ibl",
event = { "BufReadPost", "BufNewFile" },
keys = {
{ "<leader>ui", "<cmd>IBLToggle<cr>", desc = "Toggle indent guides" },
},
opts = {
indent = { char = "" },
scope = { enabled = true },
},
},
-- Rendered markdown in buffer
{
"MeanderingProgrammer/render-markdown.nvim",
ft = { "markdown" },
dependencies = { "nvim-treesitter/nvim-treesitter", "nvim-tree/nvim-web-devicons" },
opts = {
heading = { enabled = true },
code = { enabled = true, style = "full" },
bullet = { enabled = true },
},
},
-- File explorer as buffer
{
"stevearc/oil.nvim",
dependencies = { "nvim-tree/nvim-web-devicons" },
cmd = "Oil",
keys = {
{ "-", "<cmd>Oil --float<cr>", desc = "Open oil (float)" },
},
opts = {
default_file_explorer = true,
float = { padding = 2 },
view_options = { show_hidden = true },
},
},
-- Symbols outline panel
{
"stevearc/aerial.nvim",
dependencies = { "nvim-treesitter/nvim-treesitter", "nvim-tree/nvim-web-devicons" },
keys = {
{ "<leader>uo", "<cmd>AerialToggle!<cr>", desc = "Symbols outline" },
},
opts = {
attach_mode = "global",
backends = { "lsp", "treesitter", "markdown", "man" },
layout = { min_width = 28 },
show_guides = true,
},
},
-- Diagnostics list
{
"folke/trouble.nvim",
version = "v3.*",
cmd = "Trouble",
keys = {
{ "<leader>xx", "<cmd>Trouble diagnostics toggle<cr>", desc = "Workspace diagnostics" },
{ "<leader>xd", "<cmd>Trouble diagnostics toggle filter.buf=0<cr>", desc = "Document diagnostics" },
{ "<leader>xq", "<cmd>Trouble qflist toggle<cr>", desc = "Quickfix list" },
{ "<leader>xl", "<cmd>Trouble loclist toggle<cr>", desc = "Location list" },
{ "<leader>xs", "<cmd>Trouble lsp toggle focus=false win.position=right<cr>", desc = "LSP definitions" },
},
opts = { use_diagnostic_signs = true },
},
-- Better notifications
{
"rcarriga/nvim-notify",
lazy = false,
priority = 1000,
config = function()
local notify = require("notify")
notify.setup({
timeout = 3000,
max_width = 80,
stages = "fade_in_slide_out",
render = "default",
background_colour = "#050505",
})
vim.notify = notify
end,
keys = {
{ "<leader>un", function() require("notify").dismiss({ silent = true, pending = true }) end, desc = "Dismiss notifications" },
},
},
-- Sign column + fold gutter management
{
"luukvbaal/statuscol.nvim",
event = "BufReadPost",
config = function()
local builtin = require("statuscol.builtin")
require("statuscol").setup({
relculright = true,
segments = {
{ text = { builtin.foldfunc }, click = "v:lua.ScFa" },
{ text = { "%s" }, click = "v:lua.ScSa" },
{ text = { builtin.lnumfunc, " " }, click = "v:lua.ScLa" },
},
})
end,
},
-- Scrollbar with diagnostic + git marks
{
"lewis6991/satellite.nvim",
event = "BufReadPost",
opts = {
current_only = false,
winblend = 50,
handlers = {
cursor = { enable = true },
search = { enable = true },
marks = { enable = true },
quickfix = { enable = false },
gitsigns = { enable = true },
diagnostics = { enable = true, min_severity = vim.diagnostic.severity.WARN },
},
},
},
-- Session save/restore per directory
{
"folke/persistence.nvim",
event = "BufReadPre",
opts = { dir = vim.fn.stdpath("state") .. "/sessions/" },
keys = {
{ "<leader>Ss", function() require("persistence").save() end, desc = "Save session" },
{ "<leader>Sr", function() require("persistence").load() end, desc = "Restore session" },
{ "<leader>Sl", function() require("persistence").load({ last = true }) end, desc = "Last session" },
},
},
-- Project-wide search and replace
{
"MagicDuck/grug-far.nvim",
cmd = "GrugFar",
keys = {
{ "<leader>sr", "<cmd>GrugFar<cr>", desc = "Search & replace" },
{ "<leader>rs", "<cmd>GrugFar<cr>", desc = "Search & replace" },
{ "<leader>sw", function() require("grug-far").open({ prefills = { search = vim.fn.expand("<cword>") } }) end, desc = "Search word" },
},
opts = { headerMaxWidth = 80 },
},
-- Code action preview (diff before applying)
{
"aznhe21/actions-preview.nvim",
event = "LspAttach",
keys = {
{ "<leader>la", function() require("actions-preview").code_actions() end, mode = { "n", "v" }, desc = "Code actions (preview)" },
},
opts = {},
},
-- Multi-cursor (Ctrl+N equivalent)
{
"mg979/vim-visual-multi",
event = "VeryLazy",
init = function()
vim.g.VM_maps = {
["Find Under"] = "<C-n>",
["Find Subword Under"] = "<C-n>",
}
end,
},
-- Project switcher (auto-detect project root)
{
"ahmedkhalf/project.nvim",
lazy = false,
config = function()
require("project_nvim").setup({
detection_methods = { "lsp", "pattern" },
patterns = { ".git", "_darcs", ".hg", ".bzr", ".svn", "Makefile", "package.json", "Cargo.toml" },
silent_chdir = true,
})
end,
},
-- UI Toggles
-- (wrap, fold, spell are just keymap + vim.opt calls — no plugin needed)
}

View File

@@ -1,22 +1,28 @@
return {
"lervag/vimtex",
ft = { "tex", "latex" }, -- lazy-load on filetype
init = function()
-- Viewer
vim.g.vimtex_view_method = "zathura"
-- Compiler: latexmk + LuaLaTeX
vim.g.vimtex_compiler_method = "latexmk"
-- Option A: pass -lualatex explicitly to latexmk
vim.g.vimtex_compiler_latexmk = {
options = {
"-lualatex",
"-synctex=1",
"-interaction=nonstopmode",
"-file-line-error",
},
}
-- Option B (also helpful): make LuaLaTeX the default engine for latexmk
vim.g.vimtex_compiler_latexmk_engines = { _ = "-lualatex" }
end,
-- VimTeX: LaTeX compilation, navigation, text objects
{
"lervag/vimtex",
ft = { "tex", "plaintex", "bib" },
init = function()
-- Must be set before vimtex loads
vim.g.vimtex_view_method = "zathura"
vim.g.vimtex_compiler_method = "latexmk"
vim.g.vimtex_compiler_latexmk = {
options = {
"-pdf",
"-shell-escape",
"-verbose",
"-file-line-error",
"-synctex=1",
"-interaction=nonstopmode",
"-lualatex",
},
}
-- Disable vimtex completion (blink.cmp handles it via cmp-vimtex)
vim.g.vimtex_complete_enabled = 0
-- Disable vimtex's own syntax (use treesitter instead, with vim regex fallback)
vim.g.vimtex_syntax_enabled = 1
vim.g.vimtex_syntax_conceal_disable = 0
end,
},
}