repos / dotfiles

my dotfiles

dotfiles / dot_config / nvim
Eric Bower  ·  2025-09-02

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    - plugins must be integral to workflow
 10]]
 11local o = vim.opt
 12o.tabstop = 2
 13o.shiftwidth = 2
 14o.softtabstop = 2
 15o.expandtab = true
 16o.wrap = false
 17o.autoread = true
 18o.list = true -- show trailing characters
 19o.signcolumn = "yes"
 20o.backspace = "indent,eol,start"
 21o.shell = "/bin/bash"
 22o.colorcolumn = "100"
 23o.completeopt = { "menuone", "noselect", "popup" }
 24o.laststatus = 0
 25o.winborder = "rounded"
 26o.undofile = true
 27o.ignorecase = true
 28o.smartcase = true
 29o.swapfile = false
 30o.foldmethod = "expr"
 31o.foldlevel = 99
 32o.foldnestmax = 1
 33vim.g.mapleader = ","
 34vim.g.maplocalleader = ","
 35vim.diagnostic.config({
 36	severity_sort = true,
 37})
 38
 39local opts = { silent = true }
 40local map = vim.keymap.set
 41map("t", "<Esc>", [[<C-\><C-n>]], opts) -- exit terminal mode
 42map("n", "Q", "<nop>", opts) -- disable "Q"
 43map("n", "<C-k>", ":wincmd k<CR>", opts) -- navigate splits
 44map("n", "<C-j>", ":wincmd j<CR>", opts)
 45map("n", "<C-h>", ":wincmd h<CR>", opts)
 46map("n", "<C-l>", ":wincmd l<CR>", opts)
 47map("n", "<leader>t", ":bd<CR>", opts)
 48map("n", "<leader>e", vim.diagnostic.open_float, opts)
 49map("n", "<leader>q", vim.diagnostic.setloclist, opts)
 50map({ "n", "v" }, "<leader>gy", "<cmd>GitLink<cr>", opts)
 51-- https://github.com/shell-pool/shpool/issues/71#issuecomment-2632396805
 52map({ "n", "v", "i", "t" }, "<C-space><C-d>", function()
 53	vim.cmd("!shpool detach")
 54end)
 55-- https://github.com/shell-pool/shpool/issues/240#issuecomment-3097566679
 56map("n", "<leader>l", function()
 57	io.stdout:write("\027[?2048h")
 58end, opts)
 59
 60local augroup = vim.api.nvim_create_augroup("erock.cfg", { clear = true })
 61local autocmd = vim.api.nvim_create_autocmd
 62local makewrap = "setlocal tabstop=4 shiftwidth=4 softtabstop=4"
 63local mdwrap = "setlocal wrap tw=79 formatoptions+=t tabstop=2 shiftwidth=2 softtabstop=2"
 64autocmd("Filetype", { group = augroup, pattern = { "qf" }, command = "setlocal wrap" })
 65autocmd("Filetype", { group = augroup, pattern = { "make" }, command = makewrap })
 66autocmd("Filetype", { group = augroup, pattern = { "markdown" }, command = mdwrap })
 67
 68local function setup_lsp()
 69	vim.lsp.enable({
 70		"cssls", -- npm i -g vscode-langservers-extracted
 71		"gopls",
 72		"html",
 73		"jsonls",
 74		"lua_ls", -- os package mgr: lua-language-server
 75		"pyright", -- npm i -g pyright
 76		"ts_ls", -- npm i -g typescript typescript-language-server
 77	})
 78
 79	autocmd("LspAttach", {
 80		group = augroup,
 81		callback = function(ev)
 82			local client = assert(vim.lsp.get_client_by_id(ev.data.client_id))
 83			local bufopts = { noremap = true, silent = true, buffer = ev.buf }
 84			map("i", "<C-k>", vim.lsp.completion.get, bufopts) -- open completion menu manually
 85			map("n", "grd", vim.lsp.buf.definition, bufopts)
 86
 87			local methods = vim.lsp.protocol.Methods
 88			-- https://github.com/neovim/neovim/blob/b2828af5b5aba044cd40594a519d2d9f5dbb69cb/runtime/lua/vim/lsp/protocol.lua?plain=1#L858
 89			if client:supports_method(methods.textDocument_completion) then
 90				vim.lsp.completion.enable(true, client.id, ev.buf, { autotrigger = true })
 91			end
 92		end,
 93	})
 94end
 95
 96local function setup_fzf()
 97	local fzf = require("fzf-lua")
 98	local noprev = { winopts = { preview = { hidden = "hidden" } } }
 99	local fzf_files = function()
100		fzf.files(noprev)
101	end
102	local fzf_symbols = function()
103		fzf.lsp_document_symbols(noprev)
104	end
105	local fzf_buffers = function()
106		fzf.buffers(noprev)
107	end
108	map("n", "<leader>s", fzf_files, { desc = "fzf files", noremap = true, silent = true })
109	map("n", "<leader>F", fzf_symbols, { desc = "fzf symbols", noremap = true, silent = true })
110	map("n", "<leader>f", fzf_buffers, { desc = "fzf buffers", noremap = true, silent = true })
111	map("n", "<leader>S", fzf.live_grep, { desc = "fzf grep", noremap = true, silent = true })
112	map("n", "<leader>j", fzf.jumps, { desc = "fzf jumplist", noremap = true, silent = true })
113	map("n", "<leader>m", fzf.marks, { desc = "fzf marks", noremap = true, silent = true })
114	fzf.setup({ "max-perf" })
115end
116
117local function setup_treesitter()
118	local ts_parsers = {
119		"bash",
120		"c",
121		"dockerfile",
122		"fish",
123		"git_config",
124		"git_rebase",
125		"gitattributes",
126		"gitcommit",
127		"gitignore",
128		"go",
129		"gomod",
130		"gosum",
131		"html",
132		"javascript",
133		"json",
134		"lua",
135		"make",
136		"markdown",
137		"python",
138		"rust",
139		"sql",
140		"toml",
141		"tsx",
142		"typescript",
143		"typst",
144		"vim",
145		"yaml",
146		"zig",
147	}
148	local nts = require("nvim-treesitter")
149	nts.install(ts_parsers)
150	autocmd("PackChanged", { -- update treesitter parsers/queries with plugin updates
151		group = augroup,
152		callback = function(ev)
153			local spec = ev.data.spec
154			if spec and spec.name == "nvim-treesitter" and ev.data.kind == "update" then
155				vim.schedule(function()
156					nts.update()
157				end)
158			end
159		end,
160	})
161	autocmd("FileType", { -- enable treesitter highlighting and indents
162		group = augroup,
163		callback = function(ev)
164			local filetype = ev.match
165			local lang = vim.treesitter.language.get_lang(filetype)
166			if vim.treesitter.language.add(lang) then
167				if vim.treesitter.query.get(filetype, "indents") then
168					vim.bo.indentexpr = "v:lua.require'nvim-treesitter'.indentexpr()"
169				end
170				if vim.treesitter.query.get(filetype, "folds") then
171					vim.wo.foldexpr = "v:lua.vim.treesitter.foldexpr()"
172				end
173				vim.treesitter.start()
174			end
175		end,
176	})
177end
178
179vim.pack.add({
180  "https://github.com/Mofiqul/dracula.nvim",
181	{ src = "https://github.com/nvim-treesitter/nvim-treesitter", version = "main" },
182	"https://github.com/nvim-treesitter/nvim-treesitter-context",
183	"https://github.com/neovim/nvim-lspconfig",
184	"https://github.com/ibhagwan/fzf-lua",
185	"https://github.com/karb94/neoscroll.nvim",
186	"https://github.com/linrongbin16/gitlinker.nvim",
187	"https://github.com/tpope/vim-fugitive",
188})
189
190require("dracula").setup()
191vim.cmd([[colorscheme dracula]])
192setup_treesitter()
193setup_lsp()
194setup_fzf()
195require("neoscroll").setup({ duration_multiplier = 0.4 })
196require("gitlinker").setup()
197require("treesitter-context").setup({
198	max_lines = 3,
199	multiline_threshold = 1,
200	separator = "-",
201	min_window_height = 20,
202	line_numbers = true,
203})