-- Encoding / basics vim.opt.encoding = "utf-8" vim.opt.number = true vim.opt.relativenumber = true vim.opt.wrap = false -- Toggle relative numbers in insert mode local auto_numbers = vim.api.nvim_create_augroup("auto_numbers", { clear = true }) vim.api.nvim_create_autocmd("InsertEnter", { group = auto_numbers, callback = function() vim.opt.relativenumber = false end, }) vim.api.nvim_create_autocmd("InsertLeave", { group = auto_numbers, callback = function() vim.opt.number = true vim.opt.relativenumber = true end, }) -- Files / UI vim.opt.backup = false vim.opt.swapfile = false vim.opt.mouse = "n" vim.opt.path:append("**") vim.opt.wildmenu = true vim.opt.lazyredraw = true vim.opt.maxmempattern = 20000 -- Tabs vim.opt.tabstop = 2 vim.opt.shiftwidth = 2 vim.opt.softtabstop = 2 vim.opt.expandtab = true vim.opt.smarttab = true -- Splits vim.opt.splitbelow = true vim.opt.splitright = true -- Autoreload changed files on disk vim.opt.autoread = true local auto_reload = vim.api.nvim_create_augroup("auto_reload", { clear = true }) vim.api.nvim_create_autocmd({ "FocusGained", "BufEnter", "CursorHold", "CursorHoldI" }, { group = auto_reload, callback = function() -- Don't mess with special modes / cmdwin if vim.fn.getcmdwintype() ~= "" then return end local m = vim.fn.mode() if m:match("^[c]") then return end -- command-line mode if m:match("^r") then return end -- hit-enter / prompt if m == "!" then return end -- shell / external cmd if m == "t" then return end -- terminal-mode -- checktime triggers FileChangedShellPost when needed vim.cmd("checktime") end, }) vim.api.nvim_create_autocmd("FileChangedShellPost", { group = auto_reload, callback = function() vim.notify("File changed on disk. Buffer reloaded.", vim.log.levels.WARN) end, }) -- Odin: format on save local odin = vim.api.nvim_create_augroup("odin", { clear = true }) vim.api.nvim_create_autocmd("BufWritePre", { group = odin, pattern = "*.odin", callback = function(args) -- Avoid formatting if no LSP attached local clients = vim.lsp.get_clients({ bufnr = args.buf }) if #clients == 0 then return end -- Modern API; async=false keeps it "format-before-write" vim.lsp.buf.format({ bufnr = args.buf, async = false }) end, }) -- netrw vim.g.netrw_bufsettings = "noma nomod nu nowrap ro nobl" -- Eyecandy: cursorline only in active window vim.opt.cursorline = true local dynamic_cursorline = vim.api.nvim_create_augroup("dynamic_cursorline", { clear = true }) vim.api.nvim_create_autocmd({ "WinEnter", "BufEnter", "BufWinEnter" }, { group = dynamic_cursorline, callback = function() vim.opt_local.cursorline = true end, }) vim.api.nvim_create_autocmd({ "WinLeave", "BufLeave", "BufWinLeave" }, { group = dynamic_cursorline, callback = function() vim.opt_local.cursorline = false end, }) -- vim.cmd("highlight clear") vim.opt.background = "dark" vim.opt.termguicolors = true vim.cmd.colorscheme "catppuccin" -- Split / UI vim.opt.fillchars = { vert = "│" } vim.opt.signcolumn = "auto:2" -- Neovim note: VertSplit highlight group was replaced by WinSeparator in newer versions. -- Setting both keeps it working across versions/colorschemes. vim.api.nvim_set_hl(0, "VertSplit", { fg = "darkgray" }) vim.api.nvim_set_hl(0, "WinSeparator",{ fg = "darkgray" }) -- folds vim.keymap.set("n", "", "za", { desc = "Toggle fold" }) vim.opt.foldmethod = "indent" vim.opt.foldenable = false -- set nofoldenable