summaryrefslogtreecommitdiff
path: root/arch/nvim
diff options
context:
space:
mode:
Diffstat (limited to 'arch/nvim')
-rw-r--r--arch/nvim/.config/nvim/.stylua.toml3
-rw-r--r--arch/nvim/.config/nvim/init.lua27
-rw-r--r--arch/nvim/.config/nvim/lazy-lock.json30
-rw-r--r--arch/nvim/.config/nvim/lua/keymaps.lua41
-rw-r--r--arch/nvim/.config/nvim/lua/options.lua39
-rw-r--r--arch/nvim/.config/nvim/lua/plugins/colorscheme.lua74
-rw-r--r--arch/nvim/.config/nvim/lua/plugins/completion.lua40
-rw-r--r--arch/nvim/.config/nvim/lua/plugins/editor.lua73
-rw-r--r--arch/nvim/.config/nvim/lua/plugins/extras.lua37
-rw-r--r--arch/nvim/.config/nvim/lua/plugins/formatting.lua47
-rw-r--r--arch/nvim/.config/nvim/lua/plugins/fzf.lua23
-rw-r--r--arch/nvim/.config/nvim/lua/plugins/linting.lua17
-rw-r--r--arch/nvim/.config/nvim/lua/plugins/lsp.lua75
-rw-r--r--arch/nvim/.config/nvim/lua/plugins/nav.lua16
-rw-r--r--arch/nvim/.config/nvim/lua/plugins/treesitter.lua34
-rw-r--r--arch/nvim/.config/nvim/lua/plugins/ui.lua105
-rw-r--r--arch/nvim/.config/nvim/lua/plugins/whichkey.lua25
17 files changed, 706 insertions, 0 deletions
diff --git a/arch/nvim/.config/nvim/.stylua.toml b/arch/nvim/.config/nvim/.stylua.toml
new file mode 100644
index 0000000..e55efd5
--- /dev/null
+++ b/arch/nvim/.config/nvim/.stylua.toml
@@ -0,0 +1,3 @@
+indent_type = "Spaces"
+indent_width = 4
+column_width = 120
diff --git a/arch/nvim/.config/nvim/init.lua b/arch/nvim/.config/nvim/init.lua
new file mode 100644
index 0000000..fb4cadd
--- /dev/null
+++ b/arch/nvim/.config/nvim/init.lua
@@ -0,0 +1,27 @@
+-- Bootstrap lazy.nvim
+local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim"
+if not vim.uv.fs_stat(lazypath) then
+ vim.fn.system({
+ "git", "clone", "--filter=blob:none",
+ "https://github.com/folke/lazy.nvim.git",
+ "--branch=stable", lazypath,
+ })
+end
+vim.opt.rtp:prepend(lazypath)
+
+require("options")
+require("keymaps")
+
+require("lazy").setup("plugins", {
+ performance = {
+ rtp = {
+ disabled_plugins = {
+ "gzip", "matchit", "matchparen", "netrwPlugin",
+ "tarPlugin", "tohtml", "tutor", "zipPlugin",
+ },
+ },
+ },
+ install = { colorscheme = { "habamax" } },
+ checker = { enabled = false },
+ change_detection = { notify = false },
+})
diff --git a/arch/nvim/.config/nvim/lazy-lock.json b/arch/nvim/.config/nvim/lazy-lock.json
new file mode 100644
index 0000000..3480e8d
--- /dev/null
+++ b/arch/nvim/.config/nvim/lazy-lock.json
@@ -0,0 +1,30 @@
+{
+ "LuaSnip": { "branch": "master", "commit": "a62e1083a3cfe8b6b206e7d3d33a51091df25357" },
+ "blink.cmp": { "branch": "main", "commit": "78336bc89ee5365633bcf754d93df01678b5c08f" },
+ "bufferline.nvim": { "branch": "main", "commit": "655133c3b4c3e5e05ec549b9f8cc2894ac6f51b3" },
+ "conform.nvim": { "branch": "master", "commit": "dca1a190aa85f9065979ef35802fb77131911106" },
+ "fidget.nvim": { "branch": "main", "commit": "889e2e96edef4e144965571d46f7a77bcc4d0ddf" },
+ "friendly-snippets": { "branch": "main", "commit": "6cd7280adead7f586db6fccbd15d2cac7e2188b9" },
+ "fzf-lua": { "branch": "main", "commit": "1ae863c83e0823225b4e041845f10c918d5fb882" },
+ "gitsigns.nvim": { "branch": "main", "commit": "6d808f99bd63303646794406e270bd553ad7792e" },
+ "hardtime.nvim": { "branch": "main", "commit": "b4e431934af1fe224a3a801f632c008278cb7628" },
+ "lazy.nvim": { "branch": "main", "commit": "306a05526ada86a7b30af95c5cc81ffba93fef97" },
+ "lazydev.nvim": { "branch": "main", "commit": "ff2cbcba459b637ec3fd165a2be59b7bbaeedf0d" },
+ "leap.nvim": { "branch": "main", "commit": "ebecd4c7957770e21abe71f8b2dd34952850033d" },
+ "lualine.nvim": { "branch": "master", "commit": "a905eeebc4e63fdc48b5135d3bf8aea5618fb21c" },
+ "mini.base16": { "branch": "main", "commit": "800f107b27a00978b0dadd672d6da21a5b12fa9a" },
+ "nui.nvim": { "branch": "main", "commit": "de740991c12411b663994b2860f1a4fd0937c130" },
+ "nvim-autopairs": { "branch": "master", "commit": "59bce2eef357189c3305e25bc6dd2d138c1683f5" },
+ "nvim-lint": { "branch": "master", "commit": "eab58b48eb11d7745c11c505e0f3057165902461" },
+ "nvim-lspconfig": { "branch": "master", "commit": "8fde495949782bb61c2605174e231d145a048d8c" },
+ "nvim-surround": { "branch": "main", "commit": "61319d4bd1c5e336e197defa15bd104c51f0fb29" },
+ "nvim-treesitter": { "branch": "main", "commit": "4916d6592ede8c07973490d9322f187e07dfefac" },
+ "nvim-ufo": { "branch": "main", "commit": "ab3eb124062422d276fae49e0dd63b3ad1062cfc" },
+ "oil.nvim": { "branch": "master", "commit": "0fcc83805ad11cf714a949c98c605ed717e0b83e" },
+ "promise-async": { "branch": "main", "commit": "119e8961014c9bfaf1487bf3c2a393d254f337e2" },
+ "snacks.nvim": { "branch": "main", "commit": "ad9ede6a9cddf16cedbd31b8932d6dcdee9b716e" },
+ "undotree": { "branch": "master", "commit": "6fa6b57cda8459e1e4b2ca34df702f55242f4e4d" },
+ "vim-tmux-navigator": { "branch": "master", "commit": "e41c431a0c7b7388ae7ba341f01a0d217eb3a432" },
+ "vim-tpipeline": { "branch": "master", "commit": "9c1fc6a9aed96a6ff5f5cb0420e3760e95dfb1c1" },
+ "which-key.nvim": { "branch": "main", "commit": "3aab2147e74890957785941f0c1ad87d0a44c15a" }
+}
diff --git a/arch/nvim/.config/nvim/lua/keymaps.lua b/arch/nvim/.config/nvim/lua/keymaps.lua
new file mode 100644
index 0000000..2a38a95
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/keymaps.lua
@@ -0,0 +1,41 @@
+vim.g.mapleader = " "
+vim.g.maplocalleader = " "
+
+local map = vim.keymap.set
+
+-- Disable Space in normal/visual (used as leader)
+map({ "n", "v" }, "<Space>", "<Nop>", { silent = true })
+
+-- Save
+map({ "n", "i" }, "<C-s>", "<cmd>w<CR>", { desc = "Save" })
+
+-- Clear search highlight
+map("n", "<Esc>", "<cmd>nohlsearch<CR>")
+
+-- Exit terminal mode
+map("t", "<Esc><Esc>", "<C-\\><C-n>", { desc = "Exit terminal" })
+
+-- Better up/down on wrapped lines
+map({ "n", "v" }, "j", "gj")
+map({ "n", "v" }, "k", "gk")
+
+-- Buffer navigation
+map("n", "<S-h>", "<cmd>bprevious<CR>", { desc = "Prev buffer" })
+map("n", "<S-l>", "<cmd>bnext<CR>", { desc = "Next buffer" })
+map("n", "<leader>bd", "<cmd>bdelete<CR>", { desc = "Delete buffer" })
+
+-- Splits
+map("n", "<leader>sv", "<C-w>v", { desc = "Split vertical" })
+map("n", "<leader>sh", "<C-w>s", { desc = "Split horizontal" })
+map("n", "<leader>se", "<C-w>=", { desc = "Equal splits" })
+map("n", "<leader>sx", "<cmd>close<CR>", { desc = "Close split" })
+
+-- Move lines
+map("n", "<A-Down>", "<cmd>m .+1<CR>==", { desc = "Move line down" })
+map("n", "<A-Up>", "<cmd>m .-2<CR>==", { desc = "Move line up" })
+map("v", "<A-Down>", ":m '>+1<CR>gv=gv", { desc = "Move selection down" })
+map("v", "<A-Up>", ":m '<-2<CR>gv=gv", { desc = "Move selection up" })
+
+-- Stay in visual after indent
+map("v", "<", "<gv")
+map("v", ">", ">gv")
diff --git a/arch/nvim/.config/nvim/lua/options.lua b/arch/nvim/.config/nvim/lua/options.lua
new file mode 100644
index 0000000..9a97b4b
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/options.lua
@@ -0,0 +1,39 @@
+local opt = vim.opt
+
+-- Line numbers
+opt.number = true
+opt.relativenumber = true
+
+-- Indentation
+opt.expandtab = true
+opt.tabstop = 4
+opt.shiftwidth = 4
+opt.softtabstop = 4
+
+-- Visual
+opt.cursorline = true
+opt.scrolloff = 10
+opt.signcolumn = "yes"
+opt.list = true
+opt.listchars = { tab = " ", trail = "·", nbsp = "␣" }
+opt.termguicolors = true
+opt.colorcolumn = ""
+
+-- Behaviour
+opt.swapfile = false
+opt.undofile = true
+opt.updatetime = 250
+opt.timeoutlen = 300
+opt.splitbelow = true
+opt.splitright = true
+opt.ignorecase = true
+opt.smartcase = true
+opt.inccommand = "split"
+opt.hlsearch = true
+opt.breakindent = true
+
+-- Folding (nvim-ufo)
+opt.foldcolumn = "0"
+opt.foldlevel = 99
+opt.foldlevelstart = 99
+opt.foldenable = true
diff --git a/arch/nvim/.config/nvim/lua/plugins/colorscheme.lua b/arch/nvim/.config/nvim/lua/plugins/colorscheme.lua
new file mode 100644
index 0000000..8198402
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/plugins/colorscheme.lua
@@ -0,0 +1,74 @@
+return {
+ "echasnovski/mini.base16",
+ version = false,
+ lazy = false,
+ priority = 1000,
+ config = function()
+ local palette_path = vim.fn.expand("~/.cache/wallust/nvim.lua")
+
+ local fallback = {
+ base00 = "#1e1e2e", base01 = "#181825", base02 = "#313244",
+ base03 = "#45475a", base04 = "#585b70", base05 = "#cdd6f4",
+ base06 = "#f5c2e7", base07 = "#b4befe", base08 = "#f38ba8",
+ base09 = "#fab387", base0A = "#f9e2af", base0B = "#a6e3a1",
+ base0C = "#94e2d5", base0D = "#89b4fa", base0E = "#cba6f7",
+ base0F = "#f2cdcd",
+ }
+
+ local function load_palette()
+ local ok, p = pcall(dofile, palette_path)
+ return ok and p or fallback
+ end
+
+ local transparent_groups = {
+ "Normal", "NormalNC", "NormalFloat",
+ "SignColumn", "FoldColumn", "EndOfBuffer",
+ "LineNr", "CursorLineNr", "CursorLine",
+ "StatusLine", "StatusLineNC",
+ "TabLine", "TabLineFill", "TabLineSel",
+ "VertSplit", "WinSeparator",
+ "Pmenu", "PmenuSbar", "PmenuThumb",
+ "FloatBorder", "FloatTitle",
+ }
+
+ local function apply_transparent()
+ for _, grp in ipairs(transparent_groups) do
+ vim.cmd("hi " .. grp .. " guibg=NONE ctermbg=NONE")
+ end
+ end
+
+ local function apply(palette)
+ require("mini.base16").setup({ palette = palette })
+ vim.api.nvim_set_hl(0, "LineNr", { fg = palette.base05 })
+ vim.api.nvim_set_hl(0, "LineNrAbove", { fg = palette.base05 })
+ vim.api.nvim_set_hl(0, "LineNrBelow", { fg = palette.base05 })
+ vim.api.nvim_set_hl(0, "CursorLineNr", { fg = palette.base03, bold = true })
+ if vim.g.transparent_bg then
+ apply_transparent()
+ end
+ end
+
+ vim.g.transparent_bg = false
+ apply(load_palette())
+
+ -- Watch wallust output file and reload automatically
+ local watcher = vim.uv.new_fs_event()
+ if watcher then
+ watcher:start(palette_path, {}, vim.schedule_wrap(function()
+ apply(load_palette())
+ end))
+ end
+
+ -- Toggle: wipe background colors so the terminal bg shows through
+ vim.keymap.set("n", "<leader>tt", function()
+ vim.g.transparent_bg = not vim.g.transparent_bg
+ if vim.g.transparent_bg then
+ apply_transparent()
+ vim.notify("Background: transparent", vim.log.levels.INFO)
+ else
+ apply(load_palette())
+ vim.notify("Background: colorscheme", vim.log.levels.INFO)
+ end
+ end, { desc = "Toggle transparent background" })
+ end,
+}
diff --git a/arch/nvim/.config/nvim/lua/plugins/completion.lua b/arch/nvim/.config/nvim/lua/plugins/completion.lua
new file mode 100644
index 0000000..26ab3b6
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/plugins/completion.lua
@@ -0,0 +1,40 @@
+return {
+ {
+ "saghen/blink.cmp",
+ version = "*",
+ dependencies = { "L3MON4D3/LuaSnip", "rafamadriz/friendly-snippets" },
+ opts = {
+ keymap = {
+ preset = "none",
+ ["<C-Space>"] = { "show", "show_documentation", "hide_documentation" },
+ ["<C-e>"] = { "hide" },
+ ["<CR>"] = { "accept", "fallback" },
+ ["<Tab>"] = { "select_next", "snippet_forward", "fallback" },
+ ["<S-Tab>"] = { "select_prev", "snippet_backward", "fallback" },
+ ["<C-b>"] = { "scroll_documentation_up", "fallback" },
+ ["<C-f>"] = { "scroll_documentation_down", "fallback" },
+ ["<C-n>"] = { "select_next", "fallback" },
+ ["<C-p>"] = { "select_prev", "fallback" },
+ },
+ appearance = { nerd_font_variant = "mono" },
+ sources = {
+ default = { "lsp", "path", "snippets", "buffer" },
+ },
+ snippets = { preset = "luasnip" },
+ completion = {
+ documentation = { auto_show = true, auto_show_delay_ms = 200 },
+ ghost_text = { enabled = true },
+ menu = { border = "single" },
+ },
+ signature = { enabled = true, window = { border = "single" } },
+ },
+ },
+ {
+ "L3MON4D3/LuaSnip",
+ event = "InsertEnter",
+ dependencies = { "rafamadriz/friendly-snippets" },
+ config = function()
+ require("luasnip.loaders.from_vscode").lazy_load()
+ end,
+ },
+}
diff --git a/arch/nvim/.config/nvim/lua/plugins/editor.lua b/arch/nvim/.config/nvim/lua/plugins/editor.lua
new file mode 100644
index 0000000..a6ec0e0
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/plugins/editor.lua
@@ -0,0 +1,73 @@
+return {
+ -- Motion: s + two chars to jump anywhere
+ {
+ url = "https://codeberg.org/andyg/leap.nvim",
+ keys = {
+ { "s", "<Plug>(leap)", mode = { "n", "x", "o" }, desc = "Leap" },
+ { "S", "<Plug>(leap-from-window)", mode = { "n", "o" }, desc = "Leap from window" },
+ },
+ },
+ -- Enforce good vim habits
+ {
+ "m4xshen/hardtime.nvim",
+ event = "VeryLazy",
+ dependencies = { "MunifTanjim/nui.nvim" },
+ opts = {
+ max_count = 4,
+ -- Remove arrows from disabled (completely blocked) and add to
+ -- restricted (blocked after max_count, same as hjkl)
+ disabled_keys = {
+ ["<Up>"] = {},
+ ["<Down>"] = {},
+ ["<Left>"] = {},
+ ["<Right>"] = {},
+ },
+ restricted_keys = {
+ ["<Up>"] = { "n", "x" },
+ ["<Down>"] = { "n", "x" },
+ ["<Left>"] = { "n", "x" },
+ ["<Right>"] = { "n", "x" },
+ },
+ },
+ },
+ -- Auto-close brackets/quotes
+ {
+ "windwp/nvim-autopairs",
+ event = "InsertEnter",
+ opts = { check_ts = true },
+ },
+ -- Folding powered by treesitter/LSP
+ {
+ "kevinhwang91/nvim-ufo",
+ dependencies = { "kevinhwang91/promise-async" },
+ event = "BufReadPost",
+ keys = {
+ {
+ "zR",
+ function()
+ require("ufo").openAllFolds()
+ end,
+ desc = "Open all folds",
+ },
+ {
+ "zM",
+ function()
+ require("ufo").closeAllFolds()
+ end,
+ desc = "Close all folds",
+ },
+ },
+ opts = {
+ provider_selector = function()
+ return { "treesitter", "indent" }
+ end,
+ },
+ },
+ -- Surround text objects: ys, ds, cs
+ {
+ "kylechui/nvim-surround",
+ version = "*",
+ event = "VeryLazy",
+ opts = {},
+ },
+}
diff --git a/arch/nvim/.config/nvim/lua/plugins/extras.lua b/arch/nvim/.config/nvim/lua/plugins/extras.lua
new file mode 100644
index 0000000..95366ed
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/plugins/extras.lua
@@ -0,0 +1,37 @@
+return {
+ -- Splash screen / dashboard
+ {
+ "folke/snacks.nvim",
+ priority = 1000,
+ lazy = false,
+ opts = {
+ dashboard = {
+ sections = {
+ { section = "header" },
+ { section = "keys", gap = 1, padding = 1 },
+ { section = "startup" },
+ },
+ },
+ },
+ },
+ -- Undo history tree
+ {
+ "mbbill/undotree",
+ keys = {
+ { "<leader>u", "<cmd>UndotreeToggle<CR>", desc = "Undo tree" },
+ },
+ },
+ -- Buffer-based file explorer
+ {
+ "stevearc/oil.nvim",
+ lazy = false,
+ keys = {
+ { "<leader>e", "<cmd>Oil<CR>", desc = "File explorer" },
+ { "-", "<cmd>Oil<CR>", desc = "Open parent dir" },
+ },
+ opts = {
+ default_file_explorer = true,
+ view_options = { show_hidden = true },
+ },
+ },
+}
diff --git a/arch/nvim/.config/nvim/lua/plugins/formatting.lua b/arch/nvim/.config/nvim/lua/plugins/formatting.lua
new file mode 100644
index 0000000..912a6a8
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/plugins/formatting.lua
@@ -0,0 +1,47 @@
+return {
+ "stevearc/conform.nvim",
+ event = "BufWritePre",
+ cmd = { "ConformInfo", "FormatToggle" },
+ keys = {
+ {
+ "<leader>cF",
+ function()
+ vim.g.format_on_save = not vim.g.format_on_save
+ vim.notify(
+ "Format on save: " .. (vim.g.format_on_save and "enabled" or "disabled"),
+ vim.log.levels.INFO,
+ { title = "conform" }
+ )
+ end,
+ desc = "Toggle autoformat",
+ },
+ {
+ "<leader>cf",
+ function() require("conform").format({ async = true, lsp_fallback = true }) end,
+ desc = "Format buffer",
+ },
+ },
+ config = function()
+ vim.g.format_on_save = true
+
+ require("conform").setup({
+ formatters_by_ft = {
+ c = { "clang_format" },
+ cpp = { "clang_format" },
+ python = { "isort", "black" },
+ lua = { "stylua" },
+ haskell = { "ormolu" },
+ },
+ format_on_save = function(bufnr)
+ if not vim.g.format_on_save then return end
+ if vim.g.disable_autoformat_buf and vim.g.disable_autoformat_buf[bufnr] then return end
+ return { timeout_ms = 500, lsp_fallback = true }
+ end,
+ })
+
+ vim.api.nvim_create_user_command("FormatToggle", function()
+ vim.g.format_on_save = not vim.g.format_on_save
+ vim.notify("Format on save: " .. (vim.g.format_on_save and "on" or "off"))
+ end, {})
+ end,
+}
diff --git a/arch/nvim/.config/nvim/lua/plugins/fzf.lua b/arch/nvim/.config/nvim/lua/plugins/fzf.lua
new file mode 100644
index 0000000..e507348
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/plugins/fzf.lua
@@ -0,0 +1,23 @@
+return {
+ "ibhagwan/fzf-lua",
+ cmd = "FzfLua",
+ keys = {
+ { "<leader>ff", "<cmd>FzfLua files<CR>", desc = "Find files" },
+ { "<leader>fg", "<cmd>FzfLua live_grep<CR>", desc = "Live grep" },
+ { "<leader>fb", "<cmd>FzfLua buffers<CR>", desc = "Buffers" },
+ { "<leader>fs", "<cmd>FzfLua grep_cword<CR>", desc = "Grep word under cursor" },
+ { "<leader>fr", "<cmd>FzfLua oldfiles<CR>", desc = "Recent files" },
+ { "<leader>fc", "<cmd>FzfLua commands<CR>", desc = "Commands" },
+ { "<leader>fd", "<cmd>FzfLua diagnostics_document<CR>", desc = "Document diagnostics" },
+ { "<leader>/", "<cmd>FzfLua blines<CR>", desc = "Search current buffer" },
+ },
+ opts = {
+ winopts = {
+ height = 0.6,
+ width = 0.8,
+ border = "single",
+ preview = { border = "single" },
+ },
+ fzf_opts = { ["--cycle"] = true },
+ },
+}
diff --git a/arch/nvim/.config/nvim/lua/plugins/linting.lua b/arch/nvim/.config/nvim/lua/plugins/linting.lua
new file mode 100644
index 0000000..bbbeaa7
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/plugins/linting.lua
@@ -0,0 +1,17 @@
+return {
+ "mfussenegger/nvim-lint",
+ event = { "BufReadPost", "BufWritePost", "InsertLeave" },
+ config = function()
+ require("lint").linters_by_ft = {
+ c = { "cppcheck" },
+ cpp = { "cppcheck" },
+ python = { "ruff" },
+ }
+
+ vim.api.nvim_create_autocmd({ "BufWritePost", "BufReadPost", "InsertLeave" }, {
+ callback = function()
+ require("lint").try_lint()
+ end,
+ })
+ end,
+}
diff --git a/arch/nvim/.config/nvim/lua/plugins/lsp.lua b/arch/nvim/.config/nvim/lua/plugins/lsp.lua
new file mode 100644
index 0000000..17c5c64
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/plugins/lsp.lua
@@ -0,0 +1,75 @@
+return {
+ {
+ "neovim/nvim-lspconfig",
+ event = { "BufReadPre", "BufNewFile" },
+ dependencies = {
+ "saghen/blink.cmp",
+ {
+ "folke/lazydev.nvim",
+ ft = "lua",
+ opts = { library = { { path = "luvit-meta/library", words = { "vim%.uv" } } } },
+ },
+ },
+ config = function()
+ -- nvim 0.11+ API: vim.lsp.config / vim.lsp.enable
+ -- nvim-lspconfig provides default server configs in its runtime lsp/*.lua files
+
+ local caps = require("blink.cmp").get_lsp_capabilities()
+
+ -- Apply capabilities to all servers
+ vim.lsp.config("*", { capabilities = caps })
+
+ -- Server-specific overrides
+ vim.lsp.config("lua_ls", {
+ settings = {
+ Lua = {
+ diagnostics = { globals = { "vim" } },
+ workspace = { checkThirdParty = false },
+ },
+ },
+ })
+
+ -- Enable servers (default configs come from nvim-lspconfig runtime)
+ vim.lsp.enable({ "clangd", "pyright", "lua_ls", "hls" })
+
+ -- Keymaps on attach
+ vim.api.nvim_create_autocmd("LspAttach", {
+ callback = function(ev)
+ local map = function(keys, func, desc)
+ vim.keymap.set("n", keys, func, { buffer = ev.buf, desc = "LSP: " .. desc })
+ end
+ map("gd", vim.lsp.buf.definition, "Goto definition")
+ map("gD", vim.lsp.buf.declaration, "Goto declaration")
+ map("gr", vim.lsp.buf.references, "Goto references")
+ map("gI", vim.lsp.buf.implementation,"Goto implementation")
+ map("K", vim.lsp.buf.hover, "Hover docs")
+ map("<leader>rn", vim.lsp.buf.rename, "Rename")
+ map("<leader>ca", vim.lsp.buf.code_action, "Code action")
+ map("[d", vim.diagnostic.goto_prev, "Prev diagnostic")
+ map("]d", vim.diagnostic.goto_next, "Next diagnostic")
+ map("<leader>e", vim.diagnostic.open_float, "Show diagnostic")
+ end,
+ })
+
+ vim.diagnostic.config({
+ virtual_text = false,
+ signs = {
+ text = {
+ [vim.diagnostic.severity.ERROR] = " ",
+ [vim.diagnostic.severity.WARN] = " ",
+ [vim.diagnostic.severity.INFO] = " ",
+ [vim.diagnostic.severity.HINT] = " ",
+ },
+ },
+ float = { border = "single" },
+ underline = true,
+ update_in_insert = false,
+ })
+ end,
+ },
+ {
+ "j-hui/fidget.nvim",
+ event = "LspAttach",
+ opts = { notification = { window = { winblend = 0 } } },
+ },
+}
diff --git a/arch/nvim/.config/nvim/lua/plugins/nav.lua b/arch/nvim/.config/nvim/lua/plugins/nav.lua
new file mode 100644
index 0000000..827da07
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/plugins/nav.lua
@@ -0,0 +1,16 @@
+return {
+ "christoomey/vim-tmux-navigator",
+ cmd = {
+ "TmuxNavigateLeft", "TmuxNavigateDown",
+ "TmuxNavigateUp", "TmuxNavigateRight",
+ },
+ keys = {
+ { "<C-Left>", "<cmd>TmuxNavigateLeft<CR>", desc = "Pane left", mode = { "n", "t" } },
+ { "<C-Down>", "<cmd>TmuxNavigateDown<CR>", desc = "Pane down", mode = { "n", "t" } },
+ { "<C-Up>", "<cmd>TmuxNavigateUp<CR>", desc = "Pane up", mode = { "n", "t" } },
+ { "<C-Right>", "<cmd>TmuxNavigateRight<CR>", desc = "Pane right", mode = { "n", "t" } },
+ },
+ init = function()
+ vim.g.tmux_navigator_no_mappings = 1
+ end,
+}
diff --git a/arch/nvim/.config/nvim/lua/plugins/treesitter.lua b/arch/nvim/.config/nvim/lua/plugins/treesitter.lua
new file mode 100644
index 0000000..b31fd1c
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/plugins/treesitter.lua
@@ -0,0 +1,34 @@
+return {
+ "nvim-treesitter/nvim-treesitter",
+ build = ":TSUpdate",
+ event = { "BufReadPre", "BufNewFile" },
+ opts = {
+ ensure_installed = {
+ "c",
+ "cpp",
+ "python",
+ "lua",
+ "haskell",
+ "vim",
+ "vimdoc",
+ "query",
+ "bash",
+ "markdown",
+ "markdown_inline",
+ "json",
+ "toml",
+ "yaml",
+ },
+ highlight = { enable = true },
+ indent = { enable = true },
+ auto_install = false,
+ },
+ config = function(_, opts)
+ local ok = pcall(require, "nvim-treesitter.configs")
+ if ok then
+ require("nvim-treesitter.configs").setup(opts)
+ else
+ require("nvim-treesitter").setup(opts)
+ end
+ end,
+}
diff --git a/arch/nvim/.config/nvim/lua/plugins/ui.lua b/arch/nvim/.config/nvim/lua/plugins/ui.lua
new file mode 100644
index 0000000..f0f8a27
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/plugins/ui.lua
@@ -0,0 +1,105 @@
+return {
+ -- Statusline
+ {
+ "nvim-lualine/lualine.nvim",
+ event = "VeryLazy",
+ config = function()
+ local function make_theme()
+ local ok, p = pcall(dofile, vim.fn.expand("~/.cache/wallust/nvim.lua"))
+ if not ok then
+ p = { base0D = "#89b4fa", base05 = "#cdd6f4", base04 = "#585b70",
+ base0B = "#a6e3a1", base0E = "#cba6f7", base08 = "#f38ba8", base0A = "#f9e2af" }
+ end
+ return {
+ normal = { a = { fg = p.base0D, bg = "NONE", gui = "bold" }, b = { fg = p.base05, bg = "NONE" }, c = { fg = p.base04, bg = "NONE" } },
+ insert = { a = { fg = p.base0B, bg = "NONE", gui = "bold" } },
+ visual = { a = { fg = p.base0E, bg = "NONE", gui = "bold" } },
+ replace = { a = { fg = p.base08, bg = "NONE", gui = "bold" } },
+ command = { a = { fg = p.base0A, bg = "NONE", gui = "bold" } },
+ inactive = { a = { fg = p.base04, bg = "NONE" }, b = { fg = p.base04, bg = "NONE" }, c = { fg = p.base04, bg = "NONE" } },
+ }
+ end
+
+ -- lualine.setup() (and every ColorScheme reload of it) asserts
+ -- laststatus=3. Register the guard first so it catches every future
+ -- write, then immediately fix the one we're about to trigger.
+ vim.api.nvim_create_autocmd("OptionSet", {
+ pattern = "laststatus",
+ callback = function()
+ if vim.o.laststatus ~= 0 then
+ vim.o.laststatus = 0
+ end
+ end,
+ })
+
+ require("lualine").setup({
+ options = {
+ theme = make_theme(),
+ 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 = { "encoding", "filetype" },
+ lualine_y = { "progress" },
+ lualine_z = { "location" },
+ },
+ })
+ vim.o.laststatus = 0 -- synchronous fix for the setup() call above
+
+ vim.api.nvim_create_autocmd("ColorScheme", {
+ callback = function()
+ require("lualine").setup({ options = { theme = make_theme() } })
+ vim.o.laststatus = 0
+ end,
+ })
+ end,
+ },
+ -- Pipe lualine into the tmux status bar
+ {
+ "vimpostor/vim-tpipeline",
+ event = "VeryLazy",
+ init = function()
+ vim.g.tpipeline_restore = 0 -- clear files on exit rather than restore broken format
+ vim.g.tpipeline_embedopts = {} -- tmux.conf owns status-left/right format
+ end,
+ },
+ -- Buffer tabs
+ {
+ "akinsho/bufferline.nvim",
+ version = "*",
+ event = "VeryLazy",
+ keys = {
+ { "<leader>bp", "<cmd>BufferLinePick<CR>", desc = "Pick buffer" },
+ { "<leader>bo", "<cmd>BufferLineCloseOthers<CR>", desc = "Close others" },
+ { "<leader>bc", "<cmd>BufferLinePickClose<CR>", desc = "Close (pick)" },
+ },
+ opts = {
+ options = {
+ mode = "buffers",
+ show_buffer_close_icons = false,
+ show_close_icon = false,
+ separator_style = "thin",
+ always_show_bufferline = false,
+ diagnostics = "nvim_lsp",
+ },
+ },
+ },
+ -- Git signs in the gutter
+ {
+ "lewis6991/gitsigns.nvim",
+ event = { "BufReadPre", "BufNewFile" },
+ opts = {
+ signs = {
+ add = { text = "▎" },
+ change = { text = "▎" },
+ delete = { text = "" },
+ topdelete = { text = "" },
+ changedelete = { text = "▎" },
+ },
+ },
+ },
+}
diff --git a/arch/nvim/.config/nvim/lua/plugins/whichkey.lua b/arch/nvim/.config/nvim/lua/plugins/whichkey.lua
new file mode 100644
index 0000000..97e8b19
--- /dev/null
+++ b/arch/nvim/.config/nvim/lua/plugins/whichkey.lua
@@ -0,0 +1,25 @@
+return {
+ "folke/which-key.nvim",
+ event = "VeryLazy",
+ opts = {
+ icons = { mappings = false },
+ delay = 300,
+ spec = {
+ { "<leader>f", group = "find" },
+ { "<leader>b", group = "buffer" },
+ { "<leader>s", group = "split" },
+ { "<leader>r", group = "refactor" },
+ { "<leader>c", group = "code" },
+ { "<leader>cF", desc = "Toggle autoformat" },
+ { "<leader>cf", desc = "Format buffer" },
+ { "<leader>e", desc = "File explorer" },
+ { "<leader>u", desc = "Undo tree" },
+ { "<leader>bp", desc = "Pick buffer" },
+ { "<leader>bo", desc = "Close others" },
+ { "<leader>bc", desc = "Close (pick)" },
+ },
+ },
+ keys = {
+ { "<leader>?", function() require("which-key").show({ global = false }) end, desc = "Buffer keymaps" },
+ },
+}