repos / dotfiles

my dotfiles

dotfiles / dot_config / nvim
Eric Bower  ·  2025-10-17

init.lua

  1--[[
  2  erock's minimal config
  3  ======================
  4
  5  design goals:
  6    - single file
  7    - use native nvim features (>= v0.12)
  8    - use default keybindings unless painful otherwise
  9    - use built-ins unless painful otherwise
 10    - use default colorschemes
 11    - plugins must be integral to workflow
 12]]
 13local vim = vim -- suppress lsp warnings
 14local o = vim.opt
 15o.tabstop = 2
 16o.shiftwidth = 2
 17o.softtabstop = 2
 18o.expandtab = true
 19o.wrap = false
 20o.autoread = true
 21o.list = true -- show trailing characters
 22o.signcolumn = "yes"
 23o.backspace = "indent,eol,start"
 24o.shell = "/bin/bash"
 25o.colorcolumn = "100"
 26o.completeopt = { "menuone", "noselect", "popup" }
 27o.wildmode = { "lastused", "full" }
 28o.pumheight = 15
 29o.laststatus = 0
 30o.winborder = "rounded"
 31o.undofile = true
 32o.ignorecase = true
 33o.smartcase = true
 34o.swapfile = false
 35o.foldmethod = "indent"
 36o.foldlevelstart = 99
 37o.grepprg = "rg --vimgrep --smart-case --hidden"
 38o.grepformat = "%f:%l:%c:%m"
 39vim.g.mapleader = ","
 40vim.g.maplocalleader = ","
 41
 42local opts = { silent = true }
 43local map = vim.keymap.set
 44map("t", "<Esc>", [[<C-\><C-n>]], opts) -- exit terminal mode
 45map("n", "Q", "<nop>", opts) -- disable "Q"
 46map("n", "<C-k>", "<cmd>wincmd k<cr>", opts) -- navigate splits
 47map("n", "<C-j>", "<cmd>wincmd j<cr>", opts)
 48map("n", "<C-h>", "<cmd>wincmd h<cr>", opts)
 49map("n", "<C-l>", "<cmd>wincmd l<cr>", opts)
 50map("n", "<leader>t", "<cmd>bd!<cr>", opts)
 51map("n", "<leader>f", "<cmd>term fish<cr>", opts)
 52map("n", "<leader>b", ":b ")
 53map({ "n", "v" }, "<leader>u", "<cmd>GitLink<cr>", opts)
 54map("n", "<leader>e", vim.diagnostic.open_float, opts)
 55map("n", "<leader>y", function() -- copy relative filepath to clipboard
 56	vim.fn.setreg("+", vim.fn.expand("%"))
 57end)
 58map("n", "<leader>l", function() -- https://github.com/shell-pool/shpool/issues/240#issuecomment-3097566679
 59	io.stdout:write("\027[?2048h")
 60end, opts)
 61
 62map("n", "<leader>r", function()
 63	local loclist_win = vim.fn.getloclist(0, { winid = 0 }).winid
 64	if loclist_win > 0 then
 65		vim.cmd("lclose")
 66	else
 67		vim.diagnostic.setloclist({ open = true })
 68	end
 69end, opts)
 70map("n", "<leader>q", function()
 71	require("qfutil").toggle_qf() -- toggle quickfix
 72end, opts)
 73map("n", "<leader>g", function() -- grep entire project
 74	vim.ui.input({ prompt = "grep: " }, function(search)
 75		if search == nil then
 76			return
 77		end
 78		vim.cmd(string.format("silent grep! %s", search))
 79		vim.cmd("copen")
 80	end)
 81end, opts)
 82map("n", "<leader>c", function() -- run cmd in scratch buffer
 83	vim.ui.input({ prompt = "cmd: " }, function(cmd)
 84		if cmd == nil then
 85			return
 86		end
 87		vim.cmd("enew")
 88		vim.cmd(string.format("file %s", cmd))
 89		vim.bo.buftype = "nofile"
 90		vim.api.nvim_buf_set_lines(0, 0, -1, false, vim.fn.systemlist(cmd))
 91	end)
 92end, opts)
 93map("n", "<leader>d", "<cmd>Qf git diff --name-only<cr>")
 94map("n", "<leader>s", ":Qfa fd -t f | fzf -f ") -- fuzzy match files into quickfix
 95
 96local augroup = vim.api.nvim_create_augroup("erock.cfg", { clear = true })
 97local autocmd = vim.api.nvim_create_autocmd
 98autocmd("Filetype", { group = augroup, pattern = { "make" }, command = "setlocal noexpandtab tabstop=4 shiftwidth=4" })
 99
100local function setup_lsp()
101	vim.lsp.enable({
102		"gopls", -- os package mgr: gopls
103		"lua_ls", -- os package mgr: lua-language-server
104		"pyright", -- npm i -g pyright
105		"ts_ls", -- npm i -g typescript typescript-language-server
106		"zls", -- os package mgr: zls
107	})
108
109	autocmd("LspAttach", {
110		group = augroup,
111		callback = function(ev)
112			local bufopts = { noremap = true, silent = true, buffer = ev.buf }
113			map("n", "grd", vim.lsp.buf.definition, bufopts)
114			map("i", "<C-k>", vim.lsp.completion.get, bufopts) -- open completion menu manually
115			local client = assert(vim.lsp.get_client_by_id(ev.data.client_id))
116			local methods = vim.lsp.protocol.Methods
117			if client:supports_method(methods.textDocument_completion) then
118				vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true })
119			end
120		end,
121	})
122end
123
124vim.pack.add({
125	"https://github.com/neovim/nvim-lspconfig",
126	"https://github.com/tpope/vim-fugitive",
127	"https://github.com/karb94/neoscroll.nvim",
128	"https://github.com/linrongbin16/gitlinker.nvim",
129	"https://github.com/neurosnap/qfutil.nvim",
130})
131
132require("vim._extui").enable({}) -- https://github.com/neovim/neovim/pull/27855
133setup_lsp()
134require("neoscroll").setup({ duration_multiplier = 0.3 })
135require("gitlinker").setup()
136require("qfutil").setup()