From 314ee79f402344ce826a45a92851d24c01ac3a9a Mon Sep 17 00:00:00 2001 From: moritzrfs Date: Sun, 14 Jun 2026 13:17:56 +0200 Subject: [PATCH] Restructure --- .gitignore | 3 + 01-banner.sh => config/motd/01-banner.sh | 0 init.lua => config/nvim/init.lua | 0 config/nvim/lua/core/autocmds.lua | 42 ++++++++++++ config/nvim/lua/core/keymaps.lua | 53 +++++++++++++++ config/nvim/lua/core/options.lua | 57 ++++++++++++++++ config/nvim/lua/core/plugins.lua | 84 ++++++++++++++++++++++++ common.sh => lib/common.sh | 0 8 files changed, 239 insertions(+) create mode 100644 .gitignore rename 01-banner.sh => config/motd/01-banner.sh (100%) rename init.lua => config/nvim/init.lua (100%) create mode 100644 config/nvim/lua/core/autocmds.lua create mode 100644 config/nvim/lua/core/keymaps.lua create mode 100644 config/nvim/lua/core/options.lua create mode 100644 config/nvim/lua/core/plugins.lua rename common.sh => lib/common.sh (100%) diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..75bd6a0 --- /dev/null +++ b/.gitignore @@ -0,0 +1,3 @@ +# nothing host-specific lives in the repo +*.swp +*~ diff --git a/01-banner.sh b/config/motd/01-banner.sh similarity index 100% rename from 01-banner.sh rename to config/motd/01-banner.sh diff --git a/init.lua b/config/nvim/init.lua similarity index 100% rename from init.lua rename to config/nvim/init.lua diff --git a/config/nvim/lua/core/autocmds.lua b/config/nvim/lua/core/autocmds.lua new file mode 100644 index 0000000..1237dfe --- /dev/null +++ b/config/nvim/lua/core/autocmds.lua @@ -0,0 +1,42 @@ +-- core/autocmds.lua +local aug = vim.api.nvim_create_augroup +local au = vim.api.nvim_create_autocmd + +-- highlight yanked text briefly +au("TextYankPost", { + group = aug("highlight_yank", { clear = true }), + callback = function() vim.highlight.on_yank({ timeout = 150 }) end, +}) + +-- restore last cursor position when reopening a file +au("BufReadPost", { + group = aug("last_loc", { clear = true }), + callback = function(ev) + local mark = vim.api.nvim_buf_get_mark(ev.buf, '"') + local lines = vim.api.nvim_buf_line_count(ev.buf) + if mark[1] > 0 and mark[1] <= lines then + pcall(vim.api.nvim_win_set_cursor, 0, mark) + end + end, +}) + +-- trim trailing whitespace on save (skip filetypes where it matters) +au("BufWritePre", { + group = aug("trim_ws", { clear = true }), + callback = function() + if vim.bo.filetype == "diff" or vim.bo.filetype == "markdown" then return end + local view = vim.fn.winsaveview() + vim.cmd([[silent! keeppatterns %s/\s\+$//e]]) + vim.fn.winrestview(view) + end, +}) + +-- auto-create parent dirs on save +au("BufWritePre", { + group = aug("mkdir_on_save", { clear = true }), + callback = function(ev) + if ev.match:match("^%w+://") then return end + local dir = vim.fn.fnamemodify(ev.file, ":p:h") + if vim.fn.isdirectory(dir) == 0 then vim.fn.mkdir(dir, "p") end + end, +}) diff --git a/config/nvim/lua/core/keymaps.lua b/config/nvim/lua/core/keymaps.lua new file mode 100644 index 0000000..e93859a --- /dev/null +++ b/config/nvim/lua/core/keymaps.lua @@ -0,0 +1,53 @@ +-- core/keymaps.lua - leader-based, plugin-free keymaps. +local map = vim.keymap.set + +-- clear search highlight +map("n", "", "nohlsearch", { desc = "clear highlight" }) + +-- save / quit +map("n", "w", "write", { desc = "write" }) +map("n", "q", "quit", { desc = "quit" }) +map("n", "Q", "quitall", { desc = "quit all" }) + +-- window navigation (ctrl + hjkl) +map("n", "", "h", { desc = "win left" }) +map("n", "", "j", { desc = "win down" }) +map("n", "", "k", { desc = "win up" }) +map("n", "", "l", { desc = "win right" }) + +-- resize with arrows +map("n", "", "resize +2") +map("n", "", "resize -2") +map("n", "", "vertical resize -2") +map("n", "", "vertical resize +2") + +-- buffer cycling +map("n", "", "bnext", { desc = "next buffer" }) +map("n", "", "bprevious", { desc = "prev buffer" }) +map("n", "bd", "bdelete", { desc = "delete buffer" }) + +-- keep cursor centered on jumps / search +map("n", "", "zz") +map("n", "", "zz") +map("n", "n", "nzzzv") +map("n", "N", "Nzzzv") + +-- move selected lines (visual) +map("v", "J", ":m '>+1gv=gv", { desc = "move line down" }) +map("v", "K", ":m '<-2gv=gv", { desc = "move line up" }) + +-- keep selection when indenting +map("v", "<", "", ">gv") + +-- paste over selection without clobbering the register +map("x", "p", [["_dP]], { desc = "paste no-yank" }) + +-- yank to system clipboard explicitly +map({ "n", "v" }, "y", [["+y]], { desc = "yank to clipboard" }) + +-- quick edit/reload of config +map("n", "ve", "edit $MYVIMRC", { desc = "edit config" }) + +-- sudo-write a file you opened without permissions (very ops-handy) +map("n", "W", "w !sudo tee % >/dev/null", { desc = "sudo write" }) diff --git a/config/nvim/lua/core/options.lua b/config/nvim/lua/core/options.lua new file mode 100644 index 0000000..372fc46 --- /dev/null +++ b/config/nvim/lua/core/options.lua @@ -0,0 +1,57 @@ +-- core/options.lua - sane editor defaults for server / ops work. +local opt = vim.opt +local g = vim.g + +g.mapleader = " " +g.maplocalleader = " " + +-- ui +opt.number = true +opt.relativenumber = true +opt.cursorline = true +opt.signcolumn = "yes" +opt.scrolloff = 6 +opt.sidescrolloff = 8 +opt.wrap = false +opt.termguicolors = true +opt.showmode = false +opt.laststatus = 3 -- global statusline +opt.title = true -- set terminal title (nice with tmux) +opt.list = true +opt.listchars = { tab = "» ", trail = "·", nbsp = "␣" } + +-- editing +opt.expandtab = true +opt.shiftwidth = 2 +opt.tabstop = 2 +opt.softtabstop = 2 +opt.smartindent = true +opt.breakindent = true + +-- search +opt.ignorecase = true +opt.smartcase = true +opt.hlsearch = true +opt.incsearch = true +opt.inccommand = "split" -- live preview of :substitute + +-- files / undo +opt.undofile = true +opt.swapfile = false +opt.backup = false +opt.updatetime = 250 +opt.timeoutlen = 400 +opt.confirm = true -- ask instead of failing on unsaved quit + +-- splits feel natural +opt.splitright = true +opt.splitbelow = true + +-- clipboard: use system clipboard when available (works over SSH+OSC52 in nvim 0.10+) +opt.clipboard = "unnamedplus" + +-- completion +opt.completeopt = { "menu", "menuone", "noselect" } + +-- mouse on for the occasional copy/resize over ssh +opt.mouse = "a" diff --git a/config/nvim/lua/core/plugins.lua b/config/nvim/lua/core/plugins.lua new file mode 100644 index 0000000..37d2dae --- /dev/null +++ b/config/nvim/lua/core/plugins.lua @@ -0,0 +1,84 @@ +-- core/plugins.lua - optional plugin layer (lazy.nvim). +-- Kept minimal & ops-focused. If the machine is offline at first launch this +-- module raises an error that init.lua catches; the core config still works. + +local lazypath = vim.fn.stdpath("data") .. "/lazy/lazy.nvim" + +if not (vim.uv or vim.loop).fs_stat(lazypath) then + -- only attempt clone if git exists; error out cleanly otherwise + if vim.fn.executable("git") == 0 then + error("git not available; skipping plugins") + end + local out = vim.fn.system({ + "git", "clone", "--filter=blob:none", "--branch=stable", + "https://github.com/folke/lazy.nvim.git", lazypath, + }) + if vim.v.shell_error ~= 0 then + error("lazy.nvim clone failed: " .. out) + end +end +vim.opt.rtp:prepend(lazypath) + +require("lazy").setup({ + -- colorscheme + { + "folke/tokyonight.nvim", + priority = 1000, + config = function() + require("tokyonight").setup({ style = "night" }) + pcall(vim.cmd.colorscheme, "tokyonight") + end, + }, + + -- statusline (light, no icons required so it works in plain TTYs) + { + "nvim-lualine/lualine.nvim", + opts = { + options = { theme = "auto", icons_enabled = false, globalstatus = true }, + }, + }, + + -- fuzzy finder: files / grep / buffers + { + "nvim-telescope/telescope.nvim", + branch = "0.1.x", + dependencies = { "nvim-lua/plenary.nvim" }, + keys = { + { "ff", "Telescope find_files", desc = "find files" }, + { "fg", "Telescope live_grep", desc = "grep (ripgrep)" }, + { "fb", "Telescope buffers", desc = "buffers" }, + { "fh", "Telescope help_tags", desc = "help" }, + }, + }, + + -- treesitter: better syntax highlighting for the configs we actually touch + { + "nvim-treesitter/nvim-treesitter", + build = ":TSUpdate", + opts = { + ensure_installed = { + "lua", "bash", "yaml", "json", "toml", "dockerfile", + "nix", "python", "markdown", "diff", "git_config", + }, + highlight = { enable = true }, + indent = { enable = true }, + }, + config = function(_, opts) + require("nvim-treesitter.configs").setup(opts) + end, + }, + + -- git signs in the gutter + { "lewis6991/gitsigns.nvim", opts = {} }, + + -- show pending keybinds + { "folke/which-key.nvim", event = "VeryLazy", opts = {} }, + + -- quick comment toggling: gcc / gc in visual + { "numToStr/Comment.nvim", opts = {} }, +}, { + install = { colorscheme = { "tokyonight", "habamax" } }, + checker = { enabled = false }, -- don't phone home on managed hosts + change_detection = { notify = false }, + ui = { border = "rounded" }, +}) diff --git a/common.sh b/lib/common.sh similarity index 100% rename from common.sh rename to lib/common.sh